1153151Sjkim/*- 2181648Sjkim * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) 3199492Sjkim * Copyright (C) 2005-2009 Jung-uk Kim <jkim@FreeBSD.org> 4153151Sjkim * All rights reserved. 5153151Sjkim * 6153151Sjkim * Redistribution and use in source and binary forms, with or without 7153151Sjkim * modification, are permitted provided that the following conditions 8153151Sjkim * are met: 9153151Sjkim * 10153151Sjkim * 1. Redistributions of source code must retain the above copyright 11153151Sjkim * notice, this list of conditions and the following disclaimer. 12153151Sjkim * 2. Redistributions in binary form must reproduce the above copyright 13153151Sjkim * notice, this list of conditions and the following disclaimer in the 14153151Sjkim * documentation and/or other materials provided with the distribution. 15153151Sjkim * 3. Neither the name of the Politecnico di Torino nor the names of its 16153151Sjkim * contributors may be used to endorse or promote products derived from 17153151Sjkim * this software without specific prior written permission. 18153151Sjkim * 19153151Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20153151Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21153151Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22153151Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23153151Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24153151Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25153151Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26182173Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27153151Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28153151Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29153151Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30153151Sjkim * 31153151Sjkim * $FreeBSD$ 32153151Sjkim */ 33153151Sjkim 34153151Sjkim#ifndef _BPF_JIT_MACHDEP_H_ 35153151Sjkim#define _BPF_JIT_MACHDEP_H_ 36153151Sjkim 37153151Sjkim/* 38153151Sjkim * Registers 39153151Sjkim */ 40153151Sjkim#define RAX 0 41153151Sjkim#define RCX 1 42153151Sjkim#define RDX 2 43153151Sjkim#define RBX 3 44153151Sjkim#define RSP 4 45153151Sjkim#define RBP 5 46153151Sjkim#define RSI 6 47153151Sjkim#define RDI 7 48181644Sjkim#define R8 0 49181644Sjkim#define R9 1 50181644Sjkim#define R10 2 51181644Sjkim#define R11 3 52181644Sjkim#define R12 4 53181644Sjkim#define R13 5 54181644Sjkim#define R14 6 55181644Sjkim#define R15 7 56153151Sjkim 57153151Sjkim#define EAX 0 58153151Sjkim#define ECX 1 59153151Sjkim#define EDX 2 60153151Sjkim#define EBX 3 61153151Sjkim#define ESP 4 62153151Sjkim#define EBP 5 63153151Sjkim#define ESI 6 64153151Sjkim#define EDI 7 65181644Sjkim#define R8D 0 66181644Sjkim#define R9D 1 67181644Sjkim#define R10D 2 68181644Sjkim#define R11D 3 69181644Sjkim#define R12D 4 70181644Sjkim#define R13D 5 71181644Sjkim#define R14D 6 72181644Sjkim#define R15D 7 73153151Sjkim 74153151Sjkim#define AX 0 75153151Sjkim#define CX 1 76153151Sjkim#define DX 2 77153151Sjkim#define BX 3 78153151Sjkim#define SP 4 79153151Sjkim#define BP 5 80153151Sjkim#define SI 6 81153151Sjkim#define DI 7 82153151Sjkim 83153151Sjkim#define AL 0 84153151Sjkim#define CL 1 85153151Sjkim#define DL 2 86153151Sjkim#define BL 3 87153151Sjkim 88199619Sjkim/* Optimization flags */ 89199721Sjkim#define BPF_JIT_FRET 0x01 90199721Sjkim#define BPF_JIT_FPKT 0x02 91199721Sjkim#define BPF_JIT_FMEM 0x04 92199721Sjkim#define BPF_JIT_FJMP 0x08 93199721Sjkim#define BPF_JIT_FLEN 0x10 94199619Sjkim 95199619Sjkim#define BPF_JIT_FLAG_ALL \ 96199721Sjkim (BPF_JIT_FPKT | BPF_JIT_FMEM | BPF_JIT_FJMP | BPF_JIT_FLEN) 97199619Sjkim 98199619Sjkim/* A stream of native binary code */ 99153151Sjkimtypedef struct bpf_bin_stream { 100153151Sjkim /* Current native instruction pointer. */ 101153151Sjkim int cur_ip; 102153151Sjkim 103153151Sjkim /* 104153151Sjkim * Current BPF instruction pointer, i.e. position in 105153151Sjkim * the BPF program reached by the jitter. 106153151Sjkim */ 107153151Sjkim int bpf_pc; 108153151Sjkim 109153151Sjkim /* Instruction buffer, contains the generated native code. */ 110153151Sjkim char *ibuf; 111153151Sjkim 112153151Sjkim /* Jumps reference table. */ 113153151Sjkim u_int *refs; 114153151Sjkim} bpf_bin_stream; 115153151Sjkim 116153151Sjkim/* 117153151Sjkim * Prototype of the emit functions. 118153151Sjkim * 119153151Sjkim * Different emit functions are used to create the reference table and 120153151Sjkim * to generate the actual filtering code. This allows to have simpler 121153151Sjkim * instruction macros. 122153151Sjkim * The first parameter is the stream that will receive the data. 123153151Sjkim * The second one is a variable containing the data. 124153151Sjkim * The third one is the length, that can be 1, 2, or 4 since it is possible 125153151Sjkim * to emit a byte, a short, or a word at a time. 126153151Sjkim */ 127153151Sjkimtypedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n); 128153151Sjkim 129153151Sjkim/* 130199619Sjkim * Native instruction macros 131153151Sjkim */ 132153151Sjkim 133179967Sjkim/* movl i32,r32 */ 134179967Sjkim#define MOVid(i32, r32) do { \ 135153151Sjkim emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1); \ 136153151Sjkim emitm(&stream, i32, 4); \ 137153151Sjkim} while (0) 138153151Sjkim 139179967Sjkim/* movq i64,r64 */ 140179967Sjkim#define MOViq(i64, r64) do { \ 141153151Sjkim emitm(&stream, 0x48, 1); \ 142153151Sjkim emitm(&stream, (11 << 4) | (1 << 3) | (r64 & 0x7), 1); \ 143153151Sjkim emitm(&stream, i64, 4); \ 144153151Sjkim emitm(&stream, (i64 >> 32), 4); \ 145153151Sjkim} while (0) 146153151Sjkim 147179967Sjkim/* movl sr32,dr32 */ 148179967Sjkim#define MOVrd(sr32, dr32) do { \ 149179977Sjkim emitm(&stream, 0x89, 1); \ 150153151Sjkim emitm(&stream, \ 151179977Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 152153151Sjkim} while (0) 153153151Sjkim 154181644Sjkim/* movl sr32,dr32 (dr32 = %r8-15d) */ 155181644Sjkim#define MOVrd2(sr32, dr32) do { \ 156181644Sjkim emitm(&stream, 0x8941, 2); \ 157181644Sjkim emitm(&stream, \ 158181644Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 159181644Sjkim} while (0) 160181644Sjkim 161181644Sjkim/* movl sr32,dr32 (sr32 = %r8-15d) */ 162181644Sjkim#define MOVrd3(sr32, dr32) do { \ 163181644Sjkim emitm(&stream, 0x8944, 2); \ 164181644Sjkim emitm(&stream, \ 165181644Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 166181644Sjkim} while (0) 167181644Sjkim 168179967Sjkim/* movq sr64,dr64 */ 169179967Sjkim#define MOVrq(sr64, dr64) do { \ 170179977Sjkim emitm(&stream, 0x8948, 2); \ 171153151Sjkim emitm(&stream, \ 172179977Sjkim (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ 173153151Sjkim} while (0) 174153151Sjkim 175181644Sjkim/* movq sr64,dr64 (dr64 = %r8-15) */ 176181644Sjkim#define MOVrq2(sr64, dr64) do { \ 177181644Sjkim emitm(&stream, 0x8949, 2); \ 178153151Sjkim emitm(&stream, \ 179181644Sjkim (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ 180153151Sjkim} while (0) 181153151Sjkim 182181644Sjkim/* movq sr64,dr64 (sr64 = %r8-15) */ 183181644Sjkim#define MOVrq3(sr64, dr64) do { \ 184181644Sjkim emitm(&stream, 0x894c, 2); \ 185153151Sjkim emitm(&stream, \ 186181644Sjkim (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ 187153151Sjkim} while (0) 188153151Sjkim 189179967Sjkim/* movl (sr64,or64,1),dr32 */ 190179967Sjkim#define MOVobd(sr64, or64, dr32) do { \ 191179977Sjkim emitm(&stream, 0x8b, 1); \ 192153151Sjkim emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1); \ 193153156Sjkim emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ 194153151Sjkim} while (0) 195153151Sjkim 196179967Sjkim/* movw (sr64,or64,1),dr16 */ 197179967Sjkim#define MOVobw(sr64, or64, dr16) do { \ 198179977Sjkim emitm(&stream, 0x8b66, 2); \ 199179967Sjkim emitm(&stream, ((dr16 & 0x7) << 3) | 4, 1); \ 200153156Sjkim emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ 201153151Sjkim} while (0) 202153151Sjkim 203179967Sjkim/* movb (sr64,or64,1),dr8 */ 204179967Sjkim#define MOVobb(sr64, or64, dr8) do { \ 205153151Sjkim emitm(&stream, 0x8a, 1); \ 206153151Sjkim emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1); \ 207153156Sjkim emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ 208153151Sjkim} while (0) 209153151Sjkim 210179967Sjkim/* movl sr32,(dr64,or64,1) */ 211179967Sjkim#define MOVomd(sr32, dr64, or64) do { \ 212153151Sjkim emitm(&stream, 0x89, 1); \ 213153151Sjkim emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1); \ 214153156Sjkim emitm(&stream, ((or64 & 0x7) << 3) | (dr64 & 0x7), 1); \ 215153151Sjkim} while (0) 216153151Sjkim 217179967Sjkim/* bswapl dr32 */ 218153151Sjkim#define BSWAP(dr32) do { \ 219153151Sjkim emitm(&stream, 0xf, 1); \ 220153151Sjkim emitm(&stream, (0x19 << 3) | dr32, 1); \ 221153151Sjkim} while (0) 222153151Sjkim 223179967Sjkim/* xchgb %al,%ah */ 224153151Sjkim#define SWAP_AX() do { \ 225179977Sjkim emitm(&stream, 0xc486, 2); \ 226153151Sjkim} while (0) 227153151Sjkim 228199603Sjkim/* pushq r64 */ 229199603Sjkim#define PUSH(r64) do { \ 230199603Sjkim emitm(&stream, (5 << 4) | (0 << 3) | (r64 & 0x7), 1); \ 231153151Sjkim} while (0) 232153151Sjkim 233199619Sjkim/* leaveq */ 234199619Sjkim#define LEAVE() do { \ 235199619Sjkim emitm(&stream, 0xc9, 1); \ 236199603Sjkim} while (0) 237199603Sjkim 238199619Sjkim/* retq */ 239199619Sjkim#define RET() do { \ 240199619Sjkim emitm(&stream, 0xc3, 1); \ 241199619Sjkim} while (0) 242199619Sjkim 243179967Sjkim/* addl sr32,dr32 */ 244179967Sjkim#define ADDrd(sr32, dr32) do { \ 245179977Sjkim emitm(&stream, 0x01, 1); \ 246153151Sjkim emitm(&stream, \ 247179977Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 248153151Sjkim} while (0) 249153151Sjkim 250179967Sjkim/* addl i32,%eax */ 251153151Sjkim#define ADD_EAXi(i32) do { \ 252153151Sjkim emitm(&stream, 0x05, 1); \ 253153151Sjkim emitm(&stream, i32, 4); \ 254153151Sjkim} while (0) 255153151Sjkim 256179967Sjkim/* addl i8,r32 */ 257179967Sjkim#define ADDib(i8, r32) do { \ 258153151Sjkim emitm(&stream, 0x83, 1); \ 259153151Sjkim emitm(&stream, (24 << 3) | r32, 1); \ 260153151Sjkim emitm(&stream, i8, 1); \ 261153151Sjkim} while (0) 262153151Sjkim 263179967Sjkim/* subl sr32,dr32 */ 264179967Sjkim#define SUBrd(sr32, dr32) do { \ 265179977Sjkim emitm(&stream, 0x29, 1); \ 266153151Sjkim emitm(&stream, \ 267179977Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 268153151Sjkim} while (0) 269153151Sjkim 270179967Sjkim/* subl i32,%eax */ 271153151Sjkim#define SUB_EAXi(i32) do { \ 272153151Sjkim emitm(&stream, 0x2d, 1); \ 273153151Sjkim emitm(&stream, i32, 4); \ 274153151Sjkim} while (0) 275153151Sjkim 276199603Sjkim/* subq i8,r64 */ 277199603Sjkim#define SUBib(i8, r64) do { \ 278199603Sjkim emitm(&stream, 0x8348, 2); \ 279199603Sjkim emitm(&stream, (29 << 3) | (r64 & 0x7), 1); \ 280199603Sjkim emitm(&stream, i8, 1); \ 281199603Sjkim} while (0) 282199603Sjkim 283179967Sjkim/* mull r32 */ 284153151Sjkim#define MULrd(r32) do { \ 285153151Sjkim emitm(&stream, 0xf7, 1); \ 286153151Sjkim emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ 287153151Sjkim} while (0) 288153151Sjkim 289179967Sjkim/* divl r32 */ 290153151Sjkim#define DIVrd(r32) do { \ 291153151Sjkim emitm(&stream, 0xf7, 1); \ 292153151Sjkim emitm(&stream, (15 << 4) | (r32 & 0x7), 1); \ 293153151Sjkim} while (0) 294153151Sjkim 295179967Sjkim/* andb i8,r8 */ 296179967Sjkim#define ANDib(i8, r8) do { \ 297179977Sjkim if (r8 == AL) { \ 298179977Sjkim emitm(&stream, 0x24, 1); \ 299179977Sjkim } else { \ 300179977Sjkim emitm(&stream, 0x80, 1); \ 301179977Sjkim emitm(&stream, (7 << 5) | r8, 1); \ 302179977Sjkim } \ 303153151Sjkim emitm(&stream, i8, 1); \ 304153151Sjkim} while (0) 305153151Sjkim 306179967Sjkim/* andl i32,r32 */ 307179967Sjkim#define ANDid(i32, r32) do { \ 308153151Sjkim if (r32 == EAX) { \ 309153151Sjkim emitm(&stream, 0x25, 1); \ 310153151Sjkim } else { \ 311153151Sjkim emitm(&stream, 0x81, 1); \ 312153151Sjkim emitm(&stream, (7 << 5) | r32, 1); \ 313153151Sjkim } \ 314179977Sjkim emitm(&stream, i32, 4); \ 315153151Sjkim} while (0) 316153151Sjkim 317179967Sjkim/* andl sr32,dr32 */ 318179967Sjkim#define ANDrd(sr32, dr32) do { \ 319179977Sjkim emitm(&stream, 0x21, 1); \ 320153151Sjkim emitm(&stream, \ 321179977Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 322153151Sjkim} while (0) 323153151Sjkim 324181697Sjkim/* testl i32,r32 */ 325181697Sjkim#define TESTid(i32, r32) do { \ 326181697Sjkim if (r32 == EAX) { \ 327181697Sjkim emitm(&stream, 0xa9, 1); \ 328181697Sjkim } else { \ 329181697Sjkim emitm(&stream, 0xf7, 1); \ 330181697Sjkim emitm(&stream, (3 << 6) | r32, 1); \ 331181697Sjkim } \ 332181697Sjkim emitm(&stream, i32, 4); \ 333181697Sjkim} while (0) 334181697Sjkim 335181697Sjkim/* testl sr32,dr32 */ 336181697Sjkim#define TESTrd(sr32, dr32) do { \ 337181697Sjkim emitm(&stream, 0x85, 1); \ 338181697Sjkim emitm(&stream, \ 339181697Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 340181697Sjkim} while (0) 341181697Sjkim 342179967Sjkim/* orl sr32,dr32 */ 343179967Sjkim#define ORrd(sr32, dr32) do { \ 344179977Sjkim emitm(&stream, 0x09, 1); \ 345153151Sjkim emitm(&stream, \ 346179977Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 347153151Sjkim} while (0) 348153151Sjkim 349179967Sjkim/* orl i32,r32 */ 350179967Sjkim#define ORid(i32, r32) do { \ 351153151Sjkim if (r32 == EAX) { \ 352153151Sjkim emitm(&stream, 0x0d, 1); \ 353153151Sjkim } else { \ 354153151Sjkim emitm(&stream, 0x81, 1); \ 355153151Sjkim emitm(&stream, (25 << 3) | r32, 1); \ 356153151Sjkim } \ 357179977Sjkim emitm(&stream, i32, 4); \ 358153151Sjkim} while (0) 359153151Sjkim 360179967Sjkim/* shll i8,r32 */ 361179967Sjkim#define SHLib(i8, r32) do { \ 362153151Sjkim emitm(&stream, 0xc1, 1); \ 363153151Sjkim emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ 364153151Sjkim emitm(&stream, i8, 1); \ 365153151Sjkim} while (0) 366153151Sjkim 367179967Sjkim/* shll %cl,dr32 */ 368153151Sjkim#define SHL_CLrb(dr32) do { \ 369153151Sjkim emitm(&stream, 0xd3, 1); \ 370153151Sjkim emitm(&stream, (7 << 5) | (dr32 & 0x7), 1); \ 371153151Sjkim} while (0) 372153151Sjkim 373179967Sjkim/* shrl i8,r32 */ 374179967Sjkim#define SHRib(i8, r32) do { \ 375153151Sjkim emitm(&stream, 0xc1, 1); \ 376153151Sjkim emitm(&stream, (29 << 3) | (r32 & 0x7), 1); \ 377153151Sjkim emitm(&stream, i8, 1); \ 378153151Sjkim} while (0) 379153151Sjkim 380179967Sjkim/* shrl %cl,dr32 */ 381153151Sjkim#define SHR_CLrb(dr32) do { \ 382153151Sjkim emitm(&stream, 0xd3, 1); \ 383153151Sjkim emitm(&stream, (29 << 3) | (dr32 & 0x7), 1); \ 384153151Sjkim} while (0) 385153151Sjkim 386179967Sjkim/* negl r32 */ 387153151Sjkim#define NEGd(r32) do { \ 388153151Sjkim emitm(&stream, 0xf7, 1); \ 389153151Sjkim emitm(&stream, (27 << 3) | (r32 & 0x7), 1); \ 390153151Sjkim} while (0) 391153151Sjkim 392179967Sjkim/* cmpl sr32,dr32 */ 393179967Sjkim#define CMPrd(sr32, dr32) do { \ 394179977Sjkim emitm(&stream, 0x39, 1); \ 395153151Sjkim emitm(&stream, \ 396179977Sjkim (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ 397153151Sjkim} while (0) 398153151Sjkim 399179967Sjkim/* cmpl i32,dr32 */ 400179967Sjkim#define CMPid(i32, dr32) do { \ 401153151Sjkim if (dr32 == EAX){ \ 402153151Sjkim emitm(&stream, 0x3d, 1); \ 403153151Sjkim emitm(&stream, i32, 4); \ 404153151Sjkim } else { \ 405153151Sjkim emitm(&stream, 0x81, 1); \ 406153151Sjkim emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1); \ 407153151Sjkim emitm(&stream, i32, 4); \ 408153151Sjkim } \ 409153151Sjkim} while (0) 410153151Sjkim 411181848Sjkim/* jb off8 */ 412181848Sjkim#define JBb(off8) do { \ 413181848Sjkim emitm(&stream, 0x72, 1); \ 414181848Sjkim emitm(&stream, off8, 1); \ 415181848Sjkim} while (0) 416181848Sjkim 417181848Sjkim/* jae off8 */ 418181848Sjkim#define JAEb(off8) do { \ 419181848Sjkim emitm(&stream, 0x73, 1); \ 420181848Sjkim emitm(&stream, off8, 1); \ 421181848Sjkim} while (0) 422181848Sjkim 423179967Sjkim/* jne off8 */ 424153151Sjkim#define JNEb(off8) do { \ 425153151Sjkim emitm(&stream, 0x75, 1); \ 426153151Sjkim emitm(&stream, off8, 1); \ 427153151Sjkim} while (0) 428153151Sjkim 429181848Sjkim/* ja off8 */ 430181848Sjkim#define JAb(off8) do { \ 431181848Sjkim emitm(&stream, 0x77, 1); \ 432153151Sjkim emitm(&stream, off8, 1); \ 433153151Sjkim} while (0) 434153151Sjkim 435153151Sjkim/* jmp off32 */ 436153151Sjkim#define JMP(off32) do { \ 437153151Sjkim emitm(&stream, 0xe9, 1); \ 438153151Sjkim emitm(&stream, off32, 4); \ 439153151Sjkim} while (0) 440153151Sjkim 441179977Sjkim/* xorl r32,r32 */ 442179977Sjkim#define ZEROrd(r32) do { \ 443153151Sjkim emitm(&stream, 0x31, 1); \ 444179977Sjkim emitm(&stream, (3 << 6) | ((r32 & 0x7) << 3) | (r32 & 0x7), 1); \ 445153151Sjkim} while (0) 446153151Sjkim 447181697Sjkim/* 448181697Sjkim * Conditional long jumps 449181697Sjkim */ 450181697Sjkim#define JB 0x82 451181697Sjkim#define JAE 0x83 452181697Sjkim#define JE 0x84 453181697Sjkim#define JNE 0x85 454181697Sjkim#define JBE 0x86 455181697Sjkim#define JA 0x87 456181697Sjkim 457181697Sjkim#define JCC(t, f) do { \ 458181697Sjkim if (ins->jt != 0 && ins->jf != 0) { \ 459181697Sjkim /* 5 is the size of the following jmp */ \ 460181697Sjkim emitm(&stream, ((t) << 8) | 0x0f, 2); \ 461181697Sjkim emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ 462181697Sjkim stream.refs[stream.bpf_pc] + 5, 4); \ 463181697Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - \ 464181697Sjkim stream.refs[stream.bpf_pc]); \ 465181697Sjkim } else if (ins->jt != 0) { \ 466181697Sjkim emitm(&stream, ((t) << 8) | 0x0f, 2); \ 467181697Sjkim emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ 468181697Sjkim stream.refs[stream.bpf_pc], 4); \ 469181697Sjkim } else { \ 470181697Sjkim emitm(&stream, ((f) << 8) | 0x0f, 2); \ 471181697Sjkim emitm(&stream, stream.refs[stream.bpf_pc + ins->jf] - \ 472181697Sjkim stream.refs[stream.bpf_pc], 4); \ 473181697Sjkim } \ 474181697Sjkim} while (0) 475181697Sjkim 476207081Sjkim#define JUMP(off) do { \ 477207081Sjkim if ((off) != 0) \ 478207081Sjkim JMP(stream.refs[stream.bpf_pc + (off)] - \ 479207081Sjkim stream.refs[stream.bpf_pc]); \ 480207081Sjkim} while (0) 481207081Sjkim 482153151Sjkim#endif /* _BPF_JIT_MACHDEP_H_ */ 483