The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/amd64/amd64/bpf_jit_machdep.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2002 - 2003 NetGroup, Politecnico di Torino (Italy)
    3  * Copyright (c) 2005 Jung-uk Kim <jkim@FreeBSD.org>
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  *
   10  * 1. Redistributions of source code must retain the above copyright
   11  * notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  * notice, this list of conditions and the following disclaimer in the
   14  * documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the Politecnico di Torino nor the names of its
   16  * contributors may be used to endorse or promote products derived from
   17  * this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS intERRUPTION) HOWEVER CAUSED AND ON ANY
   27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 
   34 #ifndef _BPF_JIT_MACHDEP_H_
   35 #define _BPF_JIT_MACHDEP_H_
   36 
   37 /*
   38  * Registers
   39  */
   40 #define RAX     0
   41 #define RCX     1
   42 #define RDX     2
   43 #define RBX     3
   44 #define RSP     4
   45 #define RBP     5
   46 #define RSI     6
   47 #define RDI     7
   48 
   49 #define EAX     0
   50 #define ECX     1
   51 #define EDX     2
   52 #define EBX     3
   53 #define ESP     4
   54 #define EBP     5
   55 #define ESI     6
   56 #define EDI     7
   57 
   58 #define AX      0
   59 #define CX      1
   60 #define DX      2
   61 #define BX      3
   62 #define SP      4
   63 #define BP      5
   64 #define SI      6
   65 #define DI      7
   66 
   67 #define AL      0
   68 #define CL      1
   69 #define DL      2
   70 #define BL      3
   71 
   72 /* A stream of native binary code.*/
   73 typedef struct bpf_bin_stream {
   74         /* Current native instruction pointer. */
   75         int             cur_ip;
   76 
   77         /*
   78          * Current BPF instruction pointer, i.e. position in
   79          * the BPF program reached by the jitter.
   80          */
   81         int             bpf_pc;
   82 
   83         /* Instruction buffer, contains the generated native code. */
   84         char            *ibuf;
   85 
   86         /* Jumps reference table. */
   87         u_int           *refs;
   88 } bpf_bin_stream;
   89 
   90 /*
   91  * Prototype of the emit functions.
   92  *
   93  * Different emit functions are used to create the reference table and
   94  * to generate the actual filtering code. This allows to have simpler
   95  * instruction macros.
   96  * The first parameter is the stream that will receive the data.
   97  * The second one is a variable containing the data.
   98  * The third one is the length, that can be 1, 2, or 4 since it is possible
   99  * to emit a byte, a short, or a word at a time.
  100  */
  101 typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n);
  102 
  103 /*
  104  * native Instruction Macros
  105  */
  106 
  107 /* mov r32,i32 */
  108 #define MOVid(r32, i32) do {                                            \
  109         emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1);          \
  110         emitm(&stream, i32, 4);                                         \
  111 } while (0)
  112 
  113 /* mov r64,i64 */
  114 #define MOViq(r64, i64) do {                                            \
  115         emitm(&stream, 0x48, 1);                                        \
  116         emitm(&stream, (11 << 4) | (1 << 3) | (r64 & 0x7), 1);          \
  117         emitm(&stream, i64, 4);                                         \
  118         emitm(&stream, (i64 >> 32), 4);                                 \
  119 } while (0)
  120 
  121 /* mov dr32,sr32 */
  122 #define MOVrd(dr32, sr32) do {                                          \
  123         emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);                     \
  124         emitm(&stream,                                                  \
  125             (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);          \
  126 } while (0)
  127 
  128 /* mov dr64,sr64 */
  129 #define MOVrq(dr64, sr64) do {                                          \
  130         emitm(&stream, 0x48, 1);                                        \
  131         emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);                     \
  132         emitm(&stream,                                                  \
  133             (3 << 6) | ((dr64 & 0x7) << 3) | (sr64 & 0x7), 1);          \
  134 } while (0)
  135 
  136 /* mov dr32,sr64[off] */
  137 #define MOVodd(dr32, sr64, off) do {                                    \
  138         emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);                     \
  139         emitm(&stream,                                                  \
  140             (1 << 6) | ((dr32 & 0x7) << 3) | (sr64 & 0x7), 1);          \
  141         emitm(&stream, off, 1);                                         \
  142 } while (0)
  143 
  144 /* mov dr64[off],sr32 */
  145 #define MOVoqd(dr64, off, sr32) do {                                    \
  146         emitm(&stream, (8 << 4) | 1 | (1 << 3), 1);                     \
  147         emitm(&stream,                                                  \
  148             (1 << 6) | ((sr32 & 0x7) << 3) | (dr64 & 0x7), 1);          \
  149         emitm(&stream, off, 1);                                         \
  150 } while (0)
  151 
  152 /* mov dr32,sr64[or64] */
  153 #define MOVobd(dr32, sr64, or64) do {                                   \
  154         emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);                     \
  155         emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1);                     \
  156         emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1);          \
  157 } while (0)
  158 
  159 /* mov dr16,sr64[or64] */
  160 #define MOVobw(dr32, sr64, or64) do {                                   \
  161         emitm(&stream, 0x66, 1);                                        \
  162         emitm(&stream, (8 << 4) | 3 | (1 << 3), 1);                     \
  163         emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1);                     \
  164         emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1);          \
  165 } while (0)
  166 
  167 /* mov dr8,sr64[or64] */
  168 #define MOVobb(dr8, sr64, or64) do {                                    \
  169         emitm(&stream, 0x8a, 1);                                        \
  170         emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1);                      \
  171         emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1);          \
  172 } while (0)
  173 
  174 /* mov [dr64][or64],sr32 */
  175 #define MOVomd(dr64, or64, sr32) do {                                   \
  176         emitm(&stream, 0x89, 1);                                        \
  177         emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1);                     \
  178         emitm(&stream, ((or64 & 0x7) << 3) | (dr64 & 0x7), 1);          \
  179 } while (0)
  180 
  181 /* bswap dr32 */
  182 #define BSWAP(dr32) do {                                                \
  183         emitm(&stream, 0xf, 1);                                         \
  184         emitm(&stream, (0x19 << 3) | dr32, 1);                          \
  185 } while (0)
  186 
  187 /* xchg al,ah */
  188 #define SWAP_AX() do {                                                  \
  189         emitm(&stream, 0x86, 1);                                        \
  190         emitm(&stream, 0xc4, 1);                                        \
  191 } while (0)
  192 
  193 /* push r64 */
  194 #define PUSH(r64) do {                                                  \
  195         emitm(&stream, (5 << 4) | (0 << 3) | (r64 & 0x7), 1);           \
  196 } while (0)
  197 
  198 /* pop r64 */
  199 #define POP(r64) do {                                                   \
  200         emitm(&stream, (5 << 4) | (1 << 3) | (r64 & 0x7), 1);           \
  201 } while (0)
  202 
  203 /* leave/ret */
  204 #define LEAVE_RET() do {                                                \
  205         emitm(&stream, 0xc9, 1);                                        \
  206         emitm(&stream, 0xc3, 1);                                        \
  207 } while (0)
  208 
  209 /* add dr32,sr32 */
  210 #define ADDrd(dr32, sr32) do {                                          \
  211         emitm(&stream, 0x03, 1);                                        \
  212         emitm(&stream,                                                  \
  213             (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);  \
  214 } while (0)
  215 
  216 /* add eax,i32 */
  217 #define ADD_EAXi(i32) do {                                              \
  218         emitm(&stream, 0x05, 1);                                        \
  219         emitm(&stream, i32, 4);                                         \
  220 } while (0)
  221 
  222 /* add r32,i32 */
  223 #define ADDid(r32, i32) do {                                            \
  224         emitm(&stream, 0x81, 1);                                        \
  225         emitm(&stream, (24 << 3) | r32, 1);                             \
  226         emitm(&stream, i32, 4);                                         \
  227 } while (0)
  228 
  229 /* add r32,i8 */
  230 #define ADDib(r32, i8) do {                                             \
  231         emitm(&stream, 0x83, 1);                                        \
  232         emitm(&stream, (24 << 3) | r32, 1);                             \
  233         emitm(&stream, i8, 1);                                          \
  234 } while (0)
  235 
  236 /* sub dr32,sr32 */
  237 #define SUBrd(dr32, sr32) do {                                          \
  238         emitm(&stream, 0x2b, 1);                                        \
  239         emitm(&stream,                                                  \
  240             (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);          \
  241 } while (0)
  242 
  243 /* sub eax,i32 */
  244 #define SUB_EAXi(i32) do {                                              \
  245         emitm(&stream, 0x2d, 1);                                        \
  246         emitm(&stream, i32, 4);                                         \
  247 } while (0)
  248 
  249 /* mul r32 */
  250 #define MULrd(r32) do {                                                 \
  251         emitm(&stream, 0xf7, 1);                                        \
  252         emitm(&stream, (7 << 5) | (r32 & 0x7), 1);                      \
  253 } while (0)
  254 
  255 /* div r32 */
  256 #define DIVrd(r32) do {                                                 \
  257         emitm(&stream, 0xf7, 1);                                        \
  258         emitm(&stream, (15 << 4) | (r32 & 0x7), 1);                     \
  259 } while (0)
  260 
  261 /* and r8,i8 */
  262 #define ANDib(r8, i8) do {                                              \
  263         emitm(&stream, 0x80, 1);                                        \
  264         emitm(&stream, (7 << 5) | r8, 1);                               \
  265         emitm(&stream, i8, 1);                                          \
  266 } while (0)
  267 
  268 /* and r32,i32 */
  269 #define ANDid(r32, i32) do {                                            \
  270         if (r32 == EAX) {                                               \
  271                 emitm(&stream, 0x25, 1);                                \
  272                 emitm(&stream, i32, 4);                                 \
  273         } else {                                                        \
  274                 emitm(&stream, 0x81, 1);                                \
  275                 emitm(&stream, (7 << 5) | r32, 1);                      \
  276                 emitm(&stream, i32, 4);                                 \
  277         }                                                               \
  278 } while (0)
  279 
  280 /* and dr32,sr32 */
  281 #define ANDrd(dr32, sr32) do {                                          \
  282         emitm(&stream, 0x23, 1);                                        \
  283         emitm(&stream,                                                  \
  284             (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);          \
  285 } while (0)
  286 
  287 /* or dr32,sr32 */
  288 #define ORrd(dr32, sr32) do {                                           \
  289         emitm(&stream, 0x0b, 1);                                        \
  290         emitm(&stream,                                                  \
  291             (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);          \
  292 } while (0)
  293 
  294 /* or r32,i32 */
  295 #define ORid(r32, i32) do {                                             \
  296         if (r32 == EAX) {                                               \
  297                 emitm(&stream, 0x0d, 1);                                \
  298                 emitm(&stream, i32, 4);                                 \
  299         } else {                                                        \
  300                 emitm(&stream, 0x81, 1);                                \
  301                 emitm(&stream, (25 << 3) | r32, 1);                     \
  302                 emitm(&stream, i32, 4);                                 \
  303         }                                                               \
  304 } while (0)
  305 
  306 /* shl r32,i8 */
  307 #define SHLib(r32, i8) do {                                             \
  308         emitm(&stream, 0xc1, 1);                                        \
  309         emitm(&stream, (7 << 5) | (r32 & 0x7), 1);                      \
  310         emitm(&stream, i8, 1);                                          \
  311 } while (0)
  312 
  313 /* shl dr32,cl */
  314 #define SHL_CLrb(dr32) do {                                             \
  315         emitm(&stream, 0xd3, 1);                                        \
  316         emitm(&stream, (7 << 5) | (dr32 & 0x7), 1);                     \
  317 } while (0)
  318 
  319 /* shr r32,i8 */
  320 #define SHRib(r32, i8) do {                                             \
  321         emitm(&stream, 0xc1, 1);                                        \
  322         emitm(&stream, (29 << 3) | (r32 & 0x7), 1);                     \
  323         emitm(&stream, i8, 1);                                          \
  324 } while (0)
  325 
  326 /* shr dr32,cl */
  327 #define SHR_CLrb(dr32) do {                                             \
  328         emitm(&stream, 0xd3, 1);                                        \
  329         emitm(&stream, (29 << 3) | (dr32 & 0x7), 1);                    \
  330 } while (0)
  331 
  332 /* neg r32 */
  333 #define NEGd(r32) do {                                                  \
  334         emitm(&stream, 0xf7, 1);                                        \
  335         emitm(&stream, (27 << 3) | (r32 & 0x7), 1);                     \
  336 } while (0)
  337 
  338 /* cmp dr32,sr64[off] */
  339 #define CMPodd(dr32, sr64, off) do {                                    \
  340         emitm(&stream, (3 << 4) | 3 | (1 << 3), 1);                     \
  341         emitm(&stream,                                                  \
  342             (1 << 6) | ((dr32 & 0x7) << 3) | (sr64 & 0x7), 1);          \
  343         emitm(&stream, off, 1);                                         \
  344 } while (0)
  345 
  346 /* cmp dr32,sr32 */
  347 #define CMPrd(dr32, sr32) do {                                          \
  348         emitm(&stream, 0x3b, 1);                                        \
  349         emitm(&stream,                                                  \
  350             (3 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1);          \
  351 } while (0)
  352 
  353 /* cmp dr32,i32 */
  354 #define CMPid(dr32, i32) do {                                           \
  355         if (dr32 == EAX){                                               \
  356                 emitm(&stream, 0x3d, 1);                                \
  357                 emitm(&stream, i32, 4);                                 \
  358         } else {                                                        \
  359                 emitm(&stream, 0x81, 1);                                \
  360                 emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1);          \
  361                 emitm(&stream, i32, 4);                                 \
  362         }                                                               \
  363 } while (0)
  364 
  365 /* jne off32 */
  366 #define JNEb(off8) do {                                                 \
  367         emitm(&stream, 0x75, 1);                                        \
  368         emitm(&stream, off8, 1);                                        \
  369 } while (0)
  370 
  371 /* je off32 */
  372 #define JE(off32) do {                                                  \
  373         emitm(&stream, 0x0f, 1);                                        \
  374         emitm(&stream, 0x84, 1);                                        \
  375         emitm(&stream, off32, 4);                                       \
  376 } while (0)
  377 
  378 /* jle off32 */
  379 #define JLE(off32) do {                                                 \
  380         emitm(&stream, 0x0f, 1);                                        \
  381         emitm(&stream, 0x8e, 1);                                        \
  382         emitm(&stream, off32, 4);                                       \
  383 } while (0)
  384 
  385 /* jle off8 */
  386 #define JLEb(off8) do {                                                 \
  387         emitm(&stream, 0x7e, 1);                                        \
  388         emitm(&stream, off8, 1);                                        \
  389 } while (0)
  390 
  391 /* ja off32 */
  392 #define JA(off32) do {                                                  \
  393         emitm(&stream, 0x0f, 1);                                        \
  394         emitm(&stream, 0x87, 1);                                        \
  395         emitm(&stream, off32, 4);                                       \
  396 } while (0)
  397 
  398 /* jae off32 */
  399 #define JAE(off32) do {                                                 \
  400         emitm(&stream, 0x0f, 1);                                        \
  401         emitm(&stream, 0x83, 1);                                        \
  402         emitm(&stream, off32, 4);                                       \
  403 } while (0)
  404 
  405 /* jg off32 */
  406 #define JG(off32) do {                                                  \
  407         emitm(&stream, 0x0f, 1);                                        \
  408         emitm(&stream, 0x8f, 1);                                        \
  409         emitm(&stream, off32, 4);                                       \
  410 } while (0)
  411 
  412 /* jge off32 */
  413 #define JGE(off32) do {                                                 \
  414         emitm(&stream, 0x0f, 1);                                        \
  415         emitm(&stream, 0x8d, 1);                                        \
  416         emitm(&stream, off32, 4);                                       \
  417 } while (0)
  418 
  419 /* jmp off32 */
  420 #define JMP(off32) do {                                                 \
  421         emitm(&stream, 0xe9, 1);                                        \
  422         emitm(&stream, off32, 4);                                       \
  423 } while (0)
  424 
  425 /* xor eax,eax */
  426 #define ZERO_EAX() do {                                                 \
  427         emitm(&stream, 0x31, 1);                                        \
  428         emitm(&stream, 0xc0, 1);                                        \
  429 } while (0)
  430 
  431 /* xor edx,edx */
  432 #define ZERO_EDX() do {                                                 \
  433         emitm(&stream, 0x31, 1);                                        \
  434         emitm(&stream, 0xd2, 1);                                        \
  435 } while (0)
  436 
  437 #endif  /* _BPF_JIT_MACHDEP_H_ */

Cache object: f7b33e145ba92150e17c847b6b3c1300


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.