1;; Linux BPF CPU description -*- Scheme -*- 2;; Copyright (C) 2019 Free Software Foundation, Inc. 3;; 4;; Contributed by Oracle Inc. 5;; 6;; This file is part of the GNU Binutils and of GDB. 7;; 8;; This program is free software; you can redistribute it and/or 9;; modify it under the terms of the GNU General Public License as 10;; published by the Free Software Foundation; either version 3 of the 11;; License, or (at your option) any later version. 12;; 13;; This program is distributed in the hope that it will be useful, but 14;; WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16;; General Public License for more details. 17;; 18;; You should have received a copy of the GNU General Public License 19;; along with this program; if not, write to the Free Software 20;; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 21;; 02110-1301, USA. 22 23;; This file contains a CGEN CPU description for the Linux kernel eBPF 24;; instruction set. eBPF is documented in the linux kernel source 25;; tree. See linux/Documentation/networking/filter.txt, and also the 26;; sources in the networking subsystem, notably 27;; linux/net/core/filter.c. 28 29(include "simplify.inc") 30 31(define-arch 32 (name bpf) 33 (comment "Linux kernel BPF") 34 (insn-lsb0? #t) 35 ;; XXX explain the default-alignment setting is for the simulator. 36 ;; It is confusing that the simulator follows the emulated memory 37 ;; access conventions for fetching instructions by pieces... 38 (default-alignment unaligned) 39 (machs bpf xbpf) 40 (isas ebpfle ebpfbe xbpfle xbpfbe)) 41 42;;;; The ISAs 43 44;; Logically, eBPF comforms a single instruction set featuring two 45;; kind of instructions: 64-bit instructions and 128-bit instructions. 46;; 47;; The 64-bit instructions have the form: 48;; 49;; code:8 regs:8 offset:16 imm:32 50;; 51;; Whereas the 128-bit instructions (at the moment there is only one 52;; of such instructions, lddw) have the form: 53;; 54;; code:8 regs:8 offset:16 imm:32 unused:32 imm:32 55;; 56;; In both formats `regs' is itself composed by two fields: 57;; 58;; dst:4 src:4 59;; 60;; The ISA is supposed to be orthogonal to endianness: the endianness 61;; of the instruction fields follow the endianness of the host running 62;; the eBPF program, and that's all. However, this is not entirely 63;; true. The definition of an eBPF code in the Linux kernel is: 64;; 65;; struct bpf_insn { 66;; __u8 code; /* opcode */ 67;; __u8 dst_reg:4; /* dest register */ 68;; __u8 src_reg:4; /* source register */ 69;; __s16 off; /* signed offset */ 70;; __s32 imm; /* signed immediate constant */ 71;; }; 72;; 73;; Since the ordering of fields in C bitmaps is defined by the 74;; implementation, the impact of endianness in the encoding of eBPF 75;; instructions is effectively defined by GCC. In particular, GCC 76;; places dst_reg before src_reg in little-endian code, and the other 77;; way around in big-endian code. 78;; 79;; So, in reality, eBPF comprises two instruction sets: one for 80;; little-endian with instructions like: 81;; 82;; code:8 src:4 dst:4 offset:16 imm:32 [unused:32 imm:32] 83;; 84;; and another for big-endian with instructions like: 85;; 86;; code:8 dst:4 src:4 offset:16 imm:32 [unused:32 imm:32] 87;; 88;; where `offset' and the immediate fields are encoded in 89;; little-endian and big-endian byte-order, respectively. 90 91(define-pmacro (define-bpf-isa x-endian) 92 (define-isa 93 (name (.sym ebpf x-endian)) 94 (comment "The eBPF instruction set") 95 ;; Default length to record in ifields. This is used in 96 ;; calculations involving bit numbers. 97 (default-insn-word-bitsize 64) 98 ;; Length of an unknown instruction. Used by disassembly and by the 99 ;; simulator's invalid insn handler. 100 (default-insn-bitsize 64) 101 ;; Number of bits of insn that can be initially fetched. This is 102 ;; the size of the smallest insn. 103 (base-insn-bitsize 64))) 104 105(define-bpf-isa le) 106(define-bpf-isa be) 107 108(define-pmacro (define-xbpf-isa x-endian) 109 (define-isa 110 (name (.sym xbpf x-endian)) 111 (comment "The xBPF instruction set") 112 (default-insn-word-bitsize 64) 113 (default-insn-bitsize 64) 114 (base-insn-bitsize 64))) 115 116(define-xbpf-isa le) 117(define-xbpf-isa be) 118 119(define-pmacro all-isas () (ISA ebpfle,ebpfbe,xbpfle,xbpfbe)) 120(define-pmacro xbpf-isas () (ISA xbpfle,xbpfbe)) 121 122(define-pmacro (endian-isas x-endian) 123 ((ISA (.sym ebpf x-endian) (.sym xbpf x-endian)))) 124 125;;;; Hardware Hierarchy 126 127;; 128;; bpf architecture 129;; | 130;; bpfbf cpu-family 131;; / \ 132;; bpf xbpf machine 133;; | | 134;; bpf-def xbpf-def model 135 136(define-cpu 137 (name bpfbf) 138 (comment "Linux kernel eBPF virtual CPU") 139 (insn-endian big) 140 (word-bitsize 64)) 141 142(define-mach 143 (name bpf) 144 (comment "Linux eBPF") 145 (cpu bpfbf) 146 (isas ebpfle ebpfbe)) 147 148(define-model 149 (name bpf-def) 150 (comment "Linux eBPF default model") 151 (mach bpf) 152 (unit u-exec "execution unit" () 153 1 ; issue 154 1 ; done 155 () ; state 156 () ; inputs 157 () ; outputs 158 () ; profile action (default) 159 )) 160 161(define-mach 162 (name xbpf) 163 (comment "Experimental BPF") 164 (cpu bpfbf) 165 (isas ebpfle ebpfbe xbpfle xbpfbe)) 166 167(define-model 168 (name xbpf-def) 169 (comment "xBPF default model") 170 (mach xbpf) 171 (unit u-exec "execution unit" () 172 1 ; issue 173 1 ; done 174 () ; state 175 () ; inputs 176 () ; outputs 177 () ; profile action (default) 178 )) 179 180;;;; Hardware Elements 181 182;; eBPF programs can access 10 general-purpose registers which are 183;; 64-bit. 184 185(define-hardware 186 (name h-gpr) 187 (comment "General Purpose Registers") 188 (attrs all-isas (MACH bpf xbpf)) 189 (type register DI (16)) 190 (indices keyword "%" 191 ;; XXX the frame pointer fp is read-only, so it should 192 ;; go in a different hardware. 193 (;; ABI names. Take priority when disassembling. 194 (r0 0) (r1 1) (r2 2) (r3 3) (r4 4) (r5 5) (r6 6) 195 (r7 7) (r8 8) (r9 9) (fp 10) 196 ;; Additional names recognized when assembling. 197 (r0 0) (r6 6) (r10 10)))) 198 199;; The program counter. CGEN requires it, even if it is not visible 200;; to eBPF programs. 201 202(define-hardware 203 (name h-pc) 204 (comment "program counter") 205 (attrs PC PROFILE all-isas) 206 (type pc UDI) 207 (get () (raw-reg h-pc)) 208 (set (newval) (set (raw-reg h-pc) newval))) 209 210;; A 64-bit h-sint to be used by the imm64 operand below. XXX this 211;; shouldn't be needed, as h-sint is supposed to be able to hold 212;; 64-bit values. However, in practice CGEN limits h-sint to 32 bits 213;; in 32-bit hosts. To be fixed in CGEN. 214 215(dnh h-sint64 "signed 64-bit integer" (all-isas) (immediate DI) 216 () () ()) 217 218;;;; The Instruction Sets 219 220;;; Fields and Opcodes 221 222;; Convenience macro to shorten the definition of the fields below. 223(define-pmacro (dwf x-name x-comment x-attrs 224 x-word-offset x-word-length x-start x-length 225 x-mode) 226 "Define a field including its containing word." 227 (define-ifield 228 (name x-name) 229 (comment x-comment) 230 (.splice attrs (.unsplice x-attrs)) 231 (word-offset x-word-offset) 232 (word-length x-word-length) 233 (start x-start) 234 (length x-length) 235 (mode x-mode))) 236 237;; For arithmetic and jump instructions the 8-bit code field is 238;; subdivided in: 239;; 240;; op-code:4 op-src:1 op-class:3 241 242(dwf f-op-code "eBPF opcode code" (all-isas) 0 8 7 4 UINT) 243(dwf f-op-src "eBPF opcode source" (all-isas) 0 8 3 1 UINT) 244(dwf f-op-class "eBPF opcode instruction class" (all-isas) 0 8 2 3 UINT) 245 246(define-normal-insn-enum insn-op-code-alu "eBPF instruction codes" 247 (all-isas) OP_CODE_ f-op-code 248 (;; Codes for OP_CLASS_ALU and OP_CLASS_ALU64 249 (ADD #x0) (SUB #x1) (MUL #x2) (DIV #x3) (OR #x4) (AND #x5) 250 (LSH #x6) (RSH #x7) (NEG #x8) (MOD #x9) (XOR #xa) (MOV #xb) 251 (ARSH #xc) (END #xd) 252 ;; Codes for OP_CLASS_JMP 253 (JA #x0) (JEQ #x1) (JGT #x2) (JGE #x3) (JSET #x4) 254 (JNE #x5) (JSGT #x6) (JSGE #x7) (CALL #x8) (EXIT #x9) 255 (JLT #xa) (JLE #xb) (JSLT #xc) (JSLE #xd))) 256 257(define-normal-insn-enum insn-op-src "eBPF instruction source" 258 (all-isas) OP_SRC_ f-op-src 259 ;; X => use `src' as source operand. 260 ;; K => use `imm32' as source operand. 261 ((K #b0) (X #b1))) 262 263(define-normal-insn-enum insn-op-class "eBPF instruction class" 264 (all-isas) OP_CLASS_ f-op-class 265 ((LD #b000) (LDX #b001) (ST #b010) (STX #b011) 266 (ALU #b100) (JMP #b101) (JMP32 #b110) (ALU64 #b111))) 267 268;; For load/store instructions, the 8-bit code field is subdivided in: 269;; 270;; op-mode:3 op-size:2 op-class:3 271 272(dwf f-op-mode "eBPF opcode mode" (all-isas) 0 8 7 3 UINT) 273(dwf f-op-size "eBPF opcode size" (all-isas) 0 8 4 2 UINT) 274 275(define-normal-insn-enum insn-op-mode "eBPF load/store instruction modes" 276 (all-isas) OP_MODE_ f-op-mode 277 ((IMM #b000) (ABS #b001) (IND #b010) (MEM #b011) 278 ;; #b100 and #b101 are used in classic BPF only, reserved in eBPF. 279 (XADD #b110))) 280 281(define-normal-insn-enum insn-op-size "eBPF load/store instruction sizes" 282 (all-isas) OP_SIZE_ f-op-size 283 ((W #b00) ;; Word: 4 byte 284 (H #b01) ;; Half-word: 2 byte 285 (B #b10) ;; Byte: 1 byte 286 (DW #b11))) ;; Double-word: 8 byte 287 288;; The fields for the source and destination registers are a bit 289;; tricky. Due to the bizarre nibble swap between little-endian and 290;; big-endian ISAs we need to keep different variants of the fields. 291;; 292;; Note that f-regs is used in the format spec of instructions that do 293;; NOT use registers, where endianness is irrelevant i.e. f-regs is a 294;; constant 0 opcode. 295 296(dwf f-dstle "eBPF dst register field" ((ISA ebpfle xbpfle)) 8 8 3 4 UINT) 297(dwf f-srcle "eBPF source register field" ((ISA ebpfle xbpfle)) 8 8 7 4 UINT) 298 299(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe xbpfbe)) 8 8 7 4 UINT) 300(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe xbpfbe)) 8 8 3 4 UINT) 301 302(dwf f-regs "eBPF registers field" (all-isas) 8 8 7 8 UINT) 303 304;; Finally, the fields for the immediates. 305;; 306;; The 16-bit offsets and 32-bit immediates do not present any special 307;; difficulty: we put them in their own instruction word so the 308;; byte-endianness will be properly applied. 309 310(dwf f-offset16 "eBPF offset field" (all-isas) 16 16 15 16 HI) 311(dwf f-imm32 "eBPF 32-bit immediate field" (all-isas) 32 32 31 32 INT) 312 313;; For the disjoint 64-bit signed immediate, however, we need to use a 314;; multi-ifield. 315 316(dwf f-imm64-a "eBPF 64-bit immediate a" (all-isas) 32 32 31 32 UINT) 317(dwf f-imm64-b "eBPF 64-bit immediate b" (all-isas) 64 32 31 32 UINT) 318(dwf f-imm64-c "eBPF 64-bit immediate c" (all-isas) 96 32 31 32 UINT) 319 320(define-multi-ifield 321 (name f-imm64) 322 (comment "eBPF 64-bit immediate field") 323 (attrs all-isas) 324 (mode DI) 325 (subfields f-imm64-a f-imm64-b f-imm64-c) 326 (insert (sequence () 327 (set (ifield f-imm64-b) (const 0)) 328 (set (ifield f-imm64-c) (srl (ifield f-imm64) (const 32))) 329 (set (ifield f-imm64-a) (and (ifield f-imm64) (const #xffffffff))))) 330 (extract (sequence () 331 (set (ifield f-imm64) 332 (or (sll UDI (zext UDI (ifield f-imm64-c)) (const 32)) 333 (zext UDI (ifield f-imm64-a))))))) 334 335;;; Operands 336 337;; A couple of source and destination register operands are defined 338;; for each ISA: ebpfle and ebpfbe. 339 340(dno dstle "destination register" ((ISA ebpfle xbpfle)) h-gpr f-dstle) 341(dno srcle "source register" ((ISA ebpfle xbpfle)) h-gpr f-srcle) 342 343(dno dstbe "destination register" ((ISA ebpfbe xbpfbe)) h-gpr f-dstbe) 344(dno srcbe "source register" ((ISA ebpfbe xbpfbe)) h-gpr f-srcbe) 345 346;; Jump instructions have a 16-bit PC-relative address. 347;; CALL instructions have a 32-bit PC-relative address. 348 349(dno disp16 "16-bit PC-relative address" (all-isas PCREL-ADDR) h-sint 350 f-offset16) 351(dno disp32 "32-bit PC-relative address" (all-isas PCREL-ADDR) h-sint 352 f-imm32) 353 354;; Immediate operands in eBPF are signed, and we want the disassembler 355;; to print negative values in a sane way. Therefore we use the macro 356;; below to register a printer, which is itself defined as a C 357;; function in bpf.opc. 358 359;; define-normal-signed-immediate-operand 360(define-pmacro (dnsio x-name x-comment x-attrs x-type x-index) 361 (define-operand 362 (name x-name) 363 (comment x-comment) 364 (.splice attrs (.unsplice x-attrs)) 365 (type x-type) 366 (index x-index) 367 (handlers (print "immediate")))) 368 369(dnsio imm32 "32-bit immediate" (all-isas) h-sint f-imm32) 370(dnsio offset16 "16-bit offset" (all-isas) h-sint f-offset16) 371 372;; The 64-bit immediate cannot use the default 373;; cgen_parse_signed_integer, because it assumes operands are at much 374;; 32-bit wide. Use our own. 375 376(define-operand 377 (name imm64) 378 (comment "64-bit immediate") 379 (attrs all-isas) 380 (type h-sint64) 381 (index f-imm64) 382 (handlers (parse "imm64") (print "immediate"))) 383 384;; The endle/endbe instructions take an operand to specify the word 385;; width in endianness conversions. We use both a parser and printer, 386;; which are defined as C functions in bpf.opc. 387 388(define-operand 389 (name endsize) 390 (comment "endianness size immediate: 16, 32 or 64") 391 (attrs all-isas) 392 (type h-uint) 393 (index f-imm32) 394 (handlers (parse "endsize") (print "endsize"))) 395 396;;; ALU instructions 397 398;; For each opcode in insn-op-code-alu representing and integer 399;; arithmetic instruction (ADD, SUB, etc) we define a bunch of 400;; instruction variants: 401;; 402;; ADD[32]{i,r}le for the little-endian ISA 403;; ADD[32]{i,r}be for the big-endian ISA 404;; 405;; The `i' variants perform `dst OP imm32 -> dst' operations. 406;; The `r' variants perform `dst OP src -> dst' operations. 407;; 408;; The variants with 32 in their name are of ALU class. Otherwise 409;; they are ALU64 class. 410 411(define-pmacro (define-alu-insn-un x-basename x-suffix x-op-class x-op-code 412 x-endian x-mode x-semop) 413 (dni (.sym x-basename x-suffix x-endian) 414 (.str x-basename x-suffix) 415 (endian-isas x-endian) 416 (.str x-basename x-suffix " $dst" x-endian) 417 (+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) 418 x-op-class OP_SRC_K x-op-code) 419 (set x-mode (.sym dst x-endian) (x-semop x-mode (.sym dst x-endian))) 420 ())) 421 422(define-pmacro (define-alu-insn-bin x-basename x-suffix x-op-class x-op-code 423 x-endian x-mode x-semop) 424 (begin 425 ;; dst = dst OP immediate 426 (dni (.sym x-basename x-suffix "i" x-endian) 427 (.str x-basename x-suffix " immediate") 428 (endian-isas x-endian) 429 (.str x-basename x-suffix " $dst" x-endian ",$imm32") 430 (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) 431 x-op-class OP_SRC_K x-op-code) 432 (set x-mode (.sym dst x-endian) (x-semop x-mode (.sym dst x-endian) imm32)) 433 ()) 434 ;; dst = dst OP src 435 (dni (.sym x-basename x-suffix "r" x-endian) 436 (.str x-basename x-suffix " register") 437 (endian-isas x-endian) 438 (.str x-basename x-suffix " $dst" x-endian ",$src" x-endian) 439 (+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian) 440 x-op-class OP_SRC_X x-op-code) 441 (set x-mode (.sym dst x-endian) 442 (x-semop x-mode (.sym dst x-endian) (.sym src x-endian))) 443 ()))) 444 445(define-pmacro (define-alu-insn-mov x-basename x-suffix x-op-class x-op-code 446 x-endian x-mode) 447 (begin 448 (dni (.sym mov x-suffix "i" x-endian) 449 (.str mov x-suffix " immediate") 450 (endian-isas x-endian) 451 (.str x-basename x-suffix " $dst" x-endian ",$imm32") 452 (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) 453 x-op-class OP_SRC_K x-op-code) 454 (set x-mode (.sym dst x-endian) imm32) 455 ()) 456 (dni (.sym mov x-suffix "r" x-endian) 457 (.str mov x-suffix " register") 458 (endian-isas x-endian) 459 (.str x-basename x-suffix " $dst" x-endian ",$src" x-endian) 460 (+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian) 461 x-op-class OP_SRC_X x-op-code) 462 (set x-mode (.sym dst x-endian) (.sym src x-endian)) 463 ()))) 464 465 466;; Unary ALU instructions (neg) 467(define-pmacro (daiu x-basename x-op-code x-endian x-semop) 468 (begin 469 (define-alu-insn-un x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI x-semop) 470 (define-alu-insn-un x-basename "32" OP_CLASS_ALU x-op-code x-endian USI x-semop))) 471 472;; Binary ALU instructions (all the others) 473;; For ALU32: DST = (u32) DST OP (u32) SRC is correct semantics 474(define-pmacro (daib x-basename x-op-code x-endian x-semop) 475 (begin 476 (define-alu-insn-bin x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI x-semop) 477 (define-alu-insn-bin x-basename "32" OP_CLASS_ALU x-op-code x-endian USI x-semop))) 478 479;; Move ALU instructions (mov) 480(define-pmacro (daim x-basename x-op-code x-endian) 481 (begin 482 (define-alu-insn-mov x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI) 483 (define-alu-insn-mov x-basename "32" OP_CLASS_ALU x-op-code x-endian USI))) 484 485(define-pmacro (define-alu-instructions x-endian) 486 (begin 487 (daib add OP_CODE_ADD x-endian add) 488 (daib sub OP_CODE_SUB x-endian sub) 489 (daib mul OP_CODE_MUL x-endian mul) 490 (daib div OP_CODE_DIV x-endian udiv) 491 (daib or OP_CODE_OR x-endian or) 492 (daib and OP_CODE_AND x-endian and) 493 (daib lsh OP_CODE_LSH x-endian sll) 494 (daib rsh OP_CODE_RSH x-endian srl) 495 (daib mod OP_CODE_MOD x-endian umod) 496 (daib xor OP_CODE_XOR x-endian xor) 497 (daib arsh OP_CODE_ARSH x-endian sra) 498 (daiu neg OP_CODE_NEG x-endian neg) 499 (daim mov OP_CODE_MOV x-endian))) 500 501(define-alu-instructions le) 502(define-alu-instructions be) 503 504;;; Endianness conversion instructions 505 506;; The endianness conversion instructions come in several variants: 507;; 508;; END{le,be}le for the little-endian ISA 509;; END{le,be}be for the big-endian ISA 510;; 511;; Please do not be confused by the repeated `be' and `le' here. Each 512;; ISA has both endle and endbe instructions. It is the disposition 513;; of the source and destination register fields that change between 514;; ISAs, not the semantics of the instructions themselves (see section 515;; "The ISAs" above in this very file.) 516 517(define-pmacro (define-endian-insn x-suffix x-op-src x-endian) 518 (dni (.sym "end" x-suffix x-endian) 519 (.str "end" x-suffix " register") 520 (endian-isas x-endian) 521 (.str "end" x-suffix " $dst" x-endian ",$endsize") 522 (+ (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) endsize 523 OP_CLASS_ALU x-op-src OP_CODE_END) 524 (set (.sym dst x-endian) 525 (c-call DI (.str "bpfbf_end" x-suffix) (.sym dst x-endian) endsize)) 526 ())) 527 528(define-endian-insn "le" OP_SRC_K le) 529(define-endian-insn "be" OP_SRC_X le) 530(define-endian-insn "le" OP_SRC_K be) 531(define-endian-insn "be" OP_SRC_X be) 532 533;;; Load/Store instructions 534 535;; The lddw instruction takes a 64-bit immediate as an operand. Since 536;; this instruction also takes a `dst' operand, we need to define a 537;; variant for each ISA: 538;; 539;; LDDWle for the little-endian ISA 540;; LDDWbe for the big-endian ISA 541 542(define-pmacro (define-lddw x-endian) 543 (dni (.sym lddw x-endian) 544 (.str "lddw" x-endian) 545 (endian-isas x-endian) 546 (.str "lddw $dst" x-endian ",$imm64") 547 (+ imm64 (f-offset16 0) ((.sym f-src x-endian) 0) 548 (.sym dst x-endian) 549 OP_CLASS_LD OP_SIZE_DW OP_MODE_IMM) 550 (set DI (.sym dst x-endian) imm64) 551 ())) 552 553(define-lddw le) 554(define-lddw be) 555 556;; The absolute load instructions are non-generic loads designed to be 557;; used in socket filters. They come in several variants: 558;; 559;; LDABS{w,h,b,dw} 560 561(define-pmacro (dlabs x-suffix x-size x-smode) 562 (dni (.sym "ldabs" x-suffix) 563 (.str "ldabs" x-suffix) 564 (all-isas) 565 (.str "ldabs" x-suffix " $imm32") 566 (+ imm32 (f-offset16 0) (f-regs 0) 567 OP_CLASS_LD OP_MODE_ABS (.sym OP_SIZE_ x-size)) 568 (set x-smode 569 (reg x-smode h-gpr 0) 570 (mem x-smode 571 (add DI 572 (mem DI 573 (add DI 574 (reg DI h-gpr 6) ;; Pointer to struct sk_buff 575 (c-call "bpfbf_skb_data_offset"))) 576 imm32))) 577 ;; XXX this clobbers R1-R5 578 ())) 579 580(dlabs "w" W SI) 581(dlabs "h" H HI) 582(dlabs "b" B QI) 583(dlabs "dw" DW DI) 584 585;; The indirect load instructions are non-generic loads designed to be 586;; used in socket filters. They come in several variants: 587;; 588;; LDIND{w,h,b,dw}le for the little-endian ISA 589;; LDIND[w,h,b,dw}be for the big-endian ISA 590 591(define-pmacro (dlind x-suffix x-size x-endian x-smode) 592 (dni (.sym "ldind" x-suffix x-endian) 593 (.str "ldind" x-suffix) 594 (endian-isas x-endian) 595 (.str "ldind" x-suffix " $src" x-endian ",$imm32") 596 (+ imm32 (f-offset16 0) ((.sym f-dst x-endian) 0) (.sym src x-endian) 597 OP_CLASS_LD OP_MODE_IND (.sym OP_SIZE_ x-size)) 598 (set x-smode 599 (reg x-smode h-gpr 0) 600 (mem x-smode 601 (add DI 602 (mem DI 603 (add DI 604 (reg DI h-gpr 6) ;; Pointer to struct sk_buff 605 (c-call "bpfbf_skb_data_offset"))) 606 (add DI 607 (.sym src x-endian) 608 imm32)))) 609 ;; XXX this clobbers R1-R5 610 ())) 611 612(define-pmacro (define-ldind x-endian) 613 (begin 614 (dlind "w" W x-endian SI) 615 (dlind "h" H x-endian HI) 616 (dlind "b" B x-endian QI) 617 (dlind "dw" DW x-endian DI))) 618 619(define-ldind le) 620(define-ldind be) 621 622;; Generic load and store instructions are provided for several word 623;; sizes. They come in several variants: 624;; 625;; LDX{b,h,w,dw}le, STX{b,h,w,dw}le for the little-endian ISA 626;; 627;; LDX{b,h,w,dw}be, STX{b,h,w,dw}be for the big-endian ISA 628;; 629;; Loads operate on [$SRC+-OFFSET] -> $DST 630;; Stores operate on $SRC -> [$DST+-OFFSET] 631 632(define-pmacro (dxli x-basename x-suffix x-size x-endian x-mode) 633 (dni (.sym x-basename x-suffix x-endian) 634 (.str x-basename x-suffix) 635 (endian-isas x-endian) 636 (.str x-basename x-suffix " $dst" x-endian ",[$src" x-endian "+$offset16]") 637 (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian) 638 OP_CLASS_LDX (.sym OP_SIZE_ x-size) OP_MODE_MEM) 639 (set x-mode 640 (.sym dst x-endian) 641 (mem x-mode (add DI (.sym src x-endian) offset16))) 642 ())) 643 644(define-pmacro (dxsi x-basename x-suffix x-size x-endian x-mode) 645 (dni (.sym x-basename x-suffix x-endian) 646 (.str x-basename x-suffix) 647 (endian-isas x-endian) 648 (.str x-basename x-suffix " [$dst" x-endian "+$offset16],$src" x-endian) 649 (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian) 650 OP_CLASS_STX (.sym OP_SIZE_ x-size) OP_MODE_MEM) 651 (set x-mode 652 (mem x-mode (add DI (.sym dst x-endian) offset16)) 653 (.sym src x-endian)) ;; XXX address is section-relative 654 ())) 655 656(define-pmacro (define-ldstx-insns x-endian) 657 (begin 658 (dxli "ldx" "w" W x-endian SI) 659 (dxli "ldx" "h" H x-endian HI) 660 (dxli "ldx" "b" B x-endian QI) 661 (dxli "ldx" "dw" DW x-endian DI) 662 663 (dxsi "stx" "w" W x-endian SI) 664 (dxsi "stx" "h" H x-endian HI) 665 (dxsi "stx" "b" B x-endian QI) 666 (dxsi "stx" "dw" DW x-endian DI))) 667 668(define-ldstx-insns le) 669(define-ldstx-insns be) 670 671;; Generic store instructions of the form IMM32 -> [$DST+OFFSET] are 672;; provided in several variants: 673;; 674;; ST{b,h,w,dw}le for the little-endian ISA 675;; ST{b,h,w,dw}be for the big-endian ISA 676 677(define-pmacro (dsti x-suffix x-size x-endian x-mode) 678 (dni (.sym "st" x-suffix x-endian) 679 (.str "st" x-suffix) 680 (endian-isas x-endian) 681 (.str "st" x-suffix " [$dst" x-endian "+$offset16],$imm32") 682 (+ imm32 offset16 ((.sym f-src x-endian) 0) (.sym dst x-endian) 683 OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM) 684 (set x-mode 685 (mem x-mode (add DI (.sym dst x-endian) offset16)) 686 imm32) ;; XXX address is section-relative 687 ())) 688 689(define-pmacro (define-st-insns x-endian) 690 (begin 691 (dsti "b" B x-endian QI) 692 (dsti "h" H x-endian HI) 693 (dsti "w" W x-endian SI) 694 (dsti "dw" DW x-endian DI))) 695 696(define-st-insns le) 697(define-st-insns be) 698 699;;; Jump instructions 700 701;; Compare-and-jump instructions, on the other hand, make use of 702;; registers. Therefore, we need to define several variants in both 703;; ISAs: 704;; 705;; J{eq,gt,ge,lt,le,set,ne,sgt,sge,slt,sle}[32]{i,r}le for the 706;; little-endian ISA. 707;; J{eq,gt,ge,lt,le,set,ne.sgt,sge,slt,sle}[32]{i,r}be for the 708;; big-endian ISA. 709 710(define-pmacro (define-cond-jump-insn x-cond x-suffix x-op-class x-op-code x-endian x-mode x-semop) 711 (begin 712 (dni (.sym j x-cond x-suffix i x-endian) 713 (.str j x-cond x-suffix " i") 714 (endian-isas x-endian) 715 (.str "j" x-cond x-suffix " $dst" x-endian ",$imm32,$disp16") 716 (+ imm32 disp16 ((.sym f-src x-endian) 0) (.sym dst x-endian) 717 x-op-class OP_SRC_K (.sym OP_CODE_ x-op-code)) 718 (if VOID (x-semop x-mode (.sym dst x-endian) imm32) 719 (set DI 720 (reg DI h-pc) (add DI (reg DI h-pc) 721 (mul DI (add HI disp16 1) 8)))) 722 ()) 723 (dni (.sym j x-cond x-suffix r x-endian) 724 (.str j x-cond x-suffix " r") 725 (endian-isas x-endian) 726 (.str "j" x-cond x-suffix " $dst" x-endian ",$src" x-endian ",$disp16") 727 (+ (f-imm32 0) disp16 (.sym src x-endian) (.sym dst x-endian) 728 x-op-class OP_SRC_X (.sym OP_CODE_ x-op-code)) 729 (if VOID (x-semop x-mode (.sym dst x-endian) (.sym src x-endian)) 730 (set DI 731 (reg DI h-pc) (add DI (reg DI h-pc) 732 (mul DI (add HI disp16 1) 8)))) 733 ()))) 734 735(define-pmacro (dcji x-cond x-op-code x-endian x-semop) 736 (begin 737 (define-cond-jump-insn x-cond "" OP_CLASS_JMP x-op-code x-endian DI x-semop) 738 (define-cond-jump-insn x-cond "32" OP_CLASS_JMP32 x-op-code x-endian SI x-semop ))) 739 740(define-pmacro (define-condjump-insns x-endian) 741 (begin 742 (dcji "eq" JEQ x-endian eq) 743 (dcji "gt" JGT x-endian gtu) 744 (dcji "ge" JGE x-endian geu) 745 (dcji "lt" JLT x-endian ltu) 746 (dcji "le" JLE x-endian leu) 747 (dcji "set" JSET x-endian and) 748 (dcji "ne" JNE x-endian ne) 749 (dcji "sgt" JSGT x-endian gt) 750 (dcji "sge" JSGE x-endian ge) 751 (dcji "slt" JSLT x-endian lt) 752 (dcji "sle" JSLE x-endian le))) 753 754(define-condjump-insns le) 755(define-condjump-insns be) 756 757;; The `call' instruction doesn't make use of registers, but the 758;; semantic routine should have access to the src register in order to 759;; properly interpret the meaning of disp32. Therefore we need one 760;; version per ISA. 761 762(define-pmacro (define-call-insn x-endian) 763 (dni (.sym call x-endian) 764 "call" 765 (endian-isas x-endian) 766 "call $disp32" 767 (+ disp32 (f-offset16 0) (f-regs 0) 768 OP_CLASS_JMP OP_SRC_K OP_CODE_CALL) 769 (c-call VOID 770 "bpfbf_call" disp32 (ifield (.sym f-src x-endian))) 771 ())) 772 773(define-call-insn le) 774(define-call-insn be) 775 776(define-pmacro (define-callr-insn x-endian) 777 (dni (.sym callr x-endian) 778 "callr" 779 ((ISA (.sym xbpf x-endian))) 780 (.str "call $dst" x-endian) 781 (+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) 782 OP_CLASS_JMP OP_SRC_X OP_CODE_CALL) 783 (c-call VOID 784 "bpfbf_callr" (ifield (.sym f-dst x-endian))) 785 ())) 786 787(define-callr-insn le) 788(define-callr-insn be) 789 790;; The jump-always and `exit' instructions dont make use of either 791;; source nor destination registers, so only one variant per 792;; instruction is defined. 793 794(dni ja "ja" (all-isas) "ja $disp16" 795 (+ (f-imm32 0) disp16 (f-regs 0) 796 OP_CLASS_JMP OP_SRC_K OP_CODE_JA) 797 (set DI (reg DI h-pc) (add DI (reg DI h-pc) 798 (mul DI (add HI disp16 1) 8))) 799 ()) 800 801(dni "exit" "exit" (all-isas) "exit" 802 (+ (f-imm32 0) (f-offset16 0) (f-regs 0) 803 OP_CLASS_JMP (f-op-src 0) OP_CODE_EXIT) 804 (c-call VOID "bpfbf_exit") 805 ()) 806 807;;; Atomic instructions 808 809;; The atomic exchange-and-add instructions come in two flavors: one 810;; for swapping 64-bit quantities and another for 32-bit quantities. 811 812(define-pmacro (sem-exchange-and-add x-endian x-mode) 813 (sequence VOID ((x-mode tmp)) 814 ;; XXX acquire lock in simulator... as a hardware element? 815 (set x-mode tmp (mem x-mode (add DI (.sym dst x-endian) offset16))) 816 (set x-mode 817 (mem x-mode (add DI (.sym dst x-endian) offset16)) 818 (add x-mode tmp (.sym src x-endian))))) 819 820(define-pmacro (define-atomic-insns x-endian) 821 (begin 822 (dni (.str "xadddw" x-endian) 823 "xadddw" 824 (endian-isas x-endian) 825 (.str "xadddw [$dst" x-endian "+$offset16],$src" x-endian) 826 (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian) 827 offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX) 828 (sem-exchange-and-add x-endian DI) 829 ()) 830 (dni (.str "xaddw" x-endian) 831 "xaddw" 832 (endian-isas x-endian) 833 (.str "xaddw [$dst" x-endian "+$offset16],$src" x-endian) 834 (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian) 835 offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX) 836 (sem-exchange-and-add x-endian SI) 837 ()))) 838 839(define-atomic-insns le) 840(define-atomic-insns be) 841 842;;; Breakpoint instruction 843 844;; The brkpt instruction is used by the BPF simulator and it doesn't 845;; really belong to the eBPF instruction set. 846 847(dni "brkpt" "brkpt" (all-isas) "brkpt" 848 (+ (f-imm32 0) (f-offset16 0) (f-regs 0) 849 OP_CLASS_ALU OP_SRC_X OP_CODE_NEG) 850 (c-call VOID "bpfbf_breakpoint") 851 ()) 852