sim: h8300: invert sim_state storage
[binutils-gdb.git] / cpu / bpf.cpu
index dcfb0ca8cf1dc8f833277c9b8bf69e2e64297be2..13dde7094c8b2557719ab8976e424553cf7ea64e 100644 (file)
@@ -36,8 +36,8 @@
   ;; It is confusing that the simulator follows the emulated memory
   ;; access conventions for fetching instructions by pieces...
   (default-alignment unaligned)
-  (machs bpf)
-  (isas ebpfle ebpfbe))
+  (machs bpf xbpf)
+  (isas ebpfle ebpfbe xbpfle xbpfbe))
 
 ;;;; The ISAs
 
 (define-bpf-isa le)
 (define-bpf-isa be)
 
-(define-pmacro all-isas () (ISA ebpfle,ebpfbe))
+(define-pmacro (define-xbpf-isa x-endian)
+  (define-isa
+    (name (.sym xbpf x-endian))
+    (comment "The xBPF instruction set")
+    (default-insn-word-bitsize 64)
+    (default-insn-bitsize 64)
+    (base-insn-bitsize 64)))
+
+(define-xbpf-isa le)
+(define-xbpf-isa be)
+
+(define-pmacro all-isas () (ISA ebpfle,ebpfbe,xbpfle,xbpfbe))
+(define-pmacro xbpf-isas () (ISA xbpfle,xbpfbe))
+
+(define-pmacro (endian-isas x-endian)
+  ((ISA (.sym ebpf x-endian) (.sym xbpf x-endian))))
 
 ;;;; Hardware Hierarchy
 
 ;;
-;;     bpf         architecture
-;;      |
-;;    bpfbf        cpu-family
-;;      |
-;;     bpf         machine
-;;      |
-;;   bpf-def       model
+;;         bpf            architecture
+;;          |
+;;        bpfbf           cpu-family
+;;      /       \
+;;     bpf     xbpf       machine
+;;      |       |
+;;   bpf-def  xbpf-def    model
 
 (define-cpu
   (name bpfbf)
     () ; profile action (default)
     ))
 
+(define-mach
+  (name xbpf)
+  (comment "Experimental BPF")
+  (cpu bpfbf)
+  (isas ebpfle ebpfbe xbpfle xbpfbe))
+
+(define-model
+  (name xbpf-def)
+  (comment "xBPF default model")
+  (mach xbpf)
+  (unit u-exec "execution unit" ()
+    1 ; issue
+    1 ; done
+    () ; state
+    () ; inputs
+    () ; outputs
+    () ; profile action (default)
+    ))
+
 ;;;; Hardware Elements
 
 ;; eBPF programs can access 10 general-purpose registers which are
 (define-hardware
   (name h-gpr)
   (comment "General Purpose Registers")
-  (attrs all-isas (MACH bpf))
+  (attrs all-isas (MACH bpf xbpf))
   (type register DI (16))
   (indices keyword "%"
            ;; XXX the frame pointer fp is read-only, so it should
    (ADD #x0) (SUB #x1) (MUL #x2) (DIV #x3) (OR #x4) (AND #x5)
    (LSH #x6) (RSH #x7) (NEG #x8) (MOD #x9) (XOR #xa) (MOV #xb)
    (ARSH #xc) (END #xd)
+   ;; xBPF-only: signed div, signed mod
+   (SDIV #xe) (SMOD #xf)
    ;; Codes for OP_CLASS_JMP
    (JA #x0) (JEQ #x1) (JGT #x2) (JGE #x3) (JSET #x4)
    (JNE #x5) (JSGT #x6) (JSGE #x7) (CALL #x8) (EXIT #x9)
 ;; NOT use registers, where endianness is irrelevant i.e. f-regs is a
 ;; constant 0 opcode.
 
-(dwf f-dstle "eBPF dst register field" ((ISA ebpfle)) 8 8 3 4 UINT)
-(dwf f-srcle "eBPF source register field" ((ISA ebpfle)) 8 8 7 4 UINT)
+(dwf f-dstle "eBPF dst register field" ((ISA ebpfle xbpfle)) 8 8 3 4 UINT)
+(dwf f-srcle "eBPF source register field" ((ISA ebpfle xbpfle)) 8 8 7 4 UINT)
 
-(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe)) 8 8 7 4 UINT)
-(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe)) 8 8 3 4 UINT)
+(dwf f-dstbe "eBPF dst register field" ((ISA ebpfbe xbpfbe)) 8 8 7 4 UINT)
+(dwf f-srcbe "eBPF source register field" ((ISA ebpfbe xbpfbe)) 8 8 3 4 UINT)
 
 (dwf f-regs "eBPF registers field" (all-isas) 8 8 7 8 UINT)
 
 ;; difficulty: we put them in their own instruction word so the
 ;; byte-endianness will be properly applied.
 
-(dwf f-offset16 "eBPF offset field" (all-isas) 16 16 15 16 INT)
+(dwf f-offset16 "eBPF offset field" (all-isas) 16 16 15 16 HI)
 (dwf f-imm32 "eBPF 32-bit immediate field" (all-isas) 32 32 31 32 INT)
 
 ;; For the disjoint 64-bit signed immediate, however, we need to use a
 ;; A couple of source and destination register operands are defined
 ;; for each ISA: ebpfle and ebpfbe.
 
-(dno dstle "destination register" ((ISA ebpfle)) h-gpr f-dstle)
-(dno srcle "source register" ((ISA ebpfle)) h-gpr f-srcle)
+(dno dstle "destination register" ((ISA ebpfle xbpfle)) h-gpr f-dstle)
+(dno srcle "source register" ((ISA ebpfle xbpfle)) h-gpr f-srcle)
 
-(dno dstbe "destination register" ((ISA ebpfbe)) h-gpr f-dstbe)
-(dno srcbe "source register" ((ISA ebpfbe)) h-gpr f-srcbe)
+(dno dstbe "destination register" ((ISA ebpfbe xbpfbe)) h-gpr f-dstbe)
+(dno srcbe "source register" ((ISA ebpfbe xbpfbe)) h-gpr f-srcbe)
 
 ;; Jump instructions have a 16-bit PC-relative address.
 ;; CALL instructions have a 32-bit PC-relative address.
                  x-endian x-mode x-semop)
   (dni (.sym x-basename x-suffix x-endian)
        (.str x-basename x-suffix)
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str x-basename x-suffix " $dst" x-endian)
        (+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
           x-op-class OP_SRC_K x-op-code)
        ()))
 
 (define-pmacro (define-alu-insn-bin x-basename x-suffix x-op-class x-op-code
-                 x-endian x-mode x-semop)
+                 x-endian x-mode x-semop x-isas)
   (begin
     ;; dst = dst OP immediate
     (dni (.sym x-basename x-suffix "i" x-endian)
          (.str x-basename x-suffix " immediate")
-         ((ISA (.sym ebpf x-endian)))
+         (.splice (.unsplice x-isas))
          (.str x-basename x-suffix " $dst" x-endian ",$imm32")
          (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
             x-op-class OP_SRC_K x-op-code)
     ;; dst = dst OP src
     (dni (.sym x-basename x-suffix "r" x-endian)
          (.str x-basename x-suffix " register")
-         ((ISA (.sym ebpf x-endian)))
+         (.splice (.unsplice x-isas))
          (.str x-basename x-suffix " $dst" x-endian ",$src" x-endian)
          (+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian)
             x-op-class OP_SRC_X x-op-code)
   (begin
     (dni (.sym mov x-suffix "i" x-endian)
          (.str mov x-suffix " immediate")
-         ((ISA (.sym ebpf x-endian)))
+         (endian-isas x-endian)
          (.str x-basename x-suffix " $dst" x-endian ",$imm32")
          (+ imm32 (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
             x-op-class OP_SRC_K x-op-code)
          ())
     (dni (.sym mov x-suffix "r" x-endian)
          (.str mov x-suffix " register")
-         ((ISA (.sym ebpf x-endian)))
+         (endian-isas x-endian)
          (.str x-basename x-suffix " $dst" x-endian ",$src" x-endian)
          (+ (f-imm32 0) (f-offset16 0) (.sym src x-endian) (.sym dst x-endian)
             x-op-class OP_SRC_X x-op-code)
 
 ;; Binary ALU instructions (all the others)
 ;; For ALU32: DST = (u32) DST OP (u32) SRC is correct semantics
-(define-pmacro (daib x-basename x-op-code x-endian x-semop)
+(define-pmacro (daib x-basename x-op-code x-endian x-semop x-isas)
   (begin
-    (define-alu-insn-bin x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI x-semop)
-    (define-alu-insn-bin x-basename "32" OP_CLASS_ALU x-op-code x-endian USI x-semop)))
+    (define-alu-insn-bin x-basename "" OP_CLASS_ALU64 x-op-code x-endian DI x-semop x-isas)
+    (define-alu-insn-bin x-basename "32" OP_CLASS_ALU x-op-code x-endian USI x-semop x-isas)))
 
 ;; Move ALU instructions (mov)
 (define-pmacro (daim x-basename x-op-code x-endian)
 
 (define-pmacro (define-alu-instructions x-endian)
   (begin
-    (daib add OP_CODE_ADD x-endian add)
-    (daib sub OP_CODE_SUB x-endian sub)
-    (daib mul OP_CODE_MUL x-endian mul)
-    (daib div OP_CODE_DIV x-endian div)
-    (daib or  OP_CODE_OR x-endian or)
-    (daib and OP_CODE_AND x-endian and)
-    (daib lsh OP_CODE_LSH x-endian sll)
-    (daib rsh OP_CODE_RSH x-endian srl)
-    (daib mod OP_CODE_MOD x-endian mod)
-    (daib xor OP_CODE_XOR x-endian xor)
-    (daib arsh OP_CODE_ARSH x-endian sra)
+    (daib add OP_CODE_ADD x-endian add (endian-isas x-endian))
+    (daib sub OP_CODE_SUB x-endian sub (endian-isas x-endian))
+    (daib mul OP_CODE_MUL x-endian mul (endian-isas x-endian))
+    (daib div OP_CODE_DIV x-endian udiv (endian-isas x-endian))
+    (daib or  OP_CODE_OR x-endian or (endian-isas x-endian))
+    (daib and OP_CODE_AND x-endian and (endian-isas x-endian))
+    (daib lsh OP_CODE_LSH x-endian sll (endian-isas x-endian))
+    (daib rsh OP_CODE_RSH x-endian srl (endian-isas x-endian))
+    (daib mod OP_CODE_MOD x-endian umod (endian-isas x-endian))
+    (daib xor OP_CODE_XOR x-endian xor (endian-isas x-endian))
+    (daib arsh OP_CODE_ARSH x-endian sra (endian-isas x-endian))
+    (daib sdiv OP_CODE_SDIV x-endian div ((ISA (.sym xbpf x-endian))))
+    (daib smod OP_CODE_SMOD x-endian mod ((ISA (.sym xbpf x-endian))))
     (daiu neg OP_CODE_NEG x-endian neg)
     (daim mov OP_CODE_MOV x-endian)))
 
 (define-pmacro (define-endian-insn x-suffix x-op-src x-endian)
   (dni (.sym "end" x-suffix x-endian)
        (.str "end" x-suffix " register")
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str "end" x-suffix " $dst" x-endian ",$endsize")
        (+  (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian) endsize
            OP_CLASS_ALU x-op-src OP_CODE_END)
        (set (.sym dst x-endian)
-            (c-call DI "bpfbf_end" (.sym dst x-endian) endsize))
+            (c-call DI (.str "bpfbf_end" x-suffix) (.sym dst x-endian) endsize))
        ()))
 
 (define-endian-insn "le" OP_SRC_K le)
 (define-pmacro (define-lddw x-endian)
   (dni (.sym lddw x-endian)
        (.str "lddw" x-endian)
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str "lddw $dst" x-endian ",$imm64")
        (+ imm64 (f-offset16 0) ((.sym f-src x-endian) 0)
           (.sym dst x-endian)
                       (mem DI
                            (add DI
                                 (reg DI h-gpr 6) ;; Pointer to struct sk_buff
-                                (const DI 0)))   ;; XXX offsetof
-                      ;; (struct sk_buff, data) XXX but the offset
-                      ;; depends on CONFIG_* options, so this should
-                      ;; be configured in the simulator and driven by
-                      ;; command-line options.  Handle with a c-call.
+                                (c-call "bpfbf_skb_data_offset")))
                       imm32)))
        ;; XXX this clobbers R1-R5
        ()))
 (define-pmacro (dlind x-suffix x-size x-endian x-smode)
   (dni (.sym "ldind" x-suffix x-endian)
        (.str "ldind" x-suffix)
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str "ldind" x-suffix " $src" x-endian ",$imm32")
        (+ imm32 (f-offset16 0) ((.sym f-dst x-endian) 0) (.sym src x-endian)
           OP_CLASS_LD OP_MODE_IND (.sym OP_SIZE_ x-size))
                       (mem DI
                            (add DI
                                 (reg DI h-gpr 6) ;; Pointer to struct sk_buff
-                                (const DI 0)))   ;; XXX offsetof
-                      ;; (struct sk_buff, data) XXX but the offset
-                      ;; depends on CONFIG_* options, so this should
-                      ;; be configured in the simulator and driven by
-                      ;; command-line options.  Handle with a c-call.
+                                (c-call "bpfbf_skb_data_offset")))
                       (add DI
                            (.sym src x-endian)
                            imm32))))
 (define-pmacro (dxli x-basename x-suffix x-size x-endian x-mode)
   (dni (.sym x-basename x-suffix x-endian)
        (.str x-basename x-suffix)
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str x-basename x-suffix " $dst" x-endian ",[$src" x-endian "+$offset16]")
        (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian)
           OP_CLASS_LDX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
        (set x-mode
             (.sym dst x-endian)
-            (mem x-mode (add DI (.sym src x-endian) (ext DI (trunc HI offset16)))))
+            (mem x-mode (add DI (.sym src x-endian) offset16)))
        ()))
 
 (define-pmacro (dxsi x-basename x-suffix x-size x-endian x-mode)
   (dni (.sym x-basename x-suffix x-endian)
        (.str x-basename x-suffix)
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str x-basename x-suffix " [$dst" x-endian "+$offset16],$src" x-endian)
        (+ (f-imm32 0) offset16 (.sym src x-endian) (.sym dst x-endian)
           OP_CLASS_STX (.sym OP_SIZE_ x-size) OP_MODE_MEM)
        (set x-mode
-            (mem x-mode (add DI (.sym dst x-endian) (ext DI (trunc HI offset16))))
+            (mem x-mode (add DI (.sym dst x-endian) offset16))
             (.sym src x-endian)) ;; XXX address is section-relative
        ()))
 
 (define-pmacro (dsti x-suffix x-size x-endian x-mode)
   (dni (.sym "st" x-suffix x-endian)
        (.str "st" x-suffix)
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        (.str "st" x-suffix " [$dst" x-endian "+$offset16],$imm32")
        (+ imm32 offset16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
           OP_CLASS_ST (.sym OP_SIZE_ x-size) OP_MODE_MEM)
   (begin
     (dni (.sym j x-cond x-suffix i x-endian)
          (.str j x-cond x-suffix " i")
-         ((ISA (.sym ebpf x-endian)))
+         (endian-isas x-endian)
          (.str "j" x-cond x-suffix " $dst" x-endian ",$imm32,$disp16")
          (+ imm32 disp16 ((.sym f-src x-endian) 0) (.sym dst x-endian)
             x-op-class OP_SRC_K (.sym OP_CODE_ x-op-code))
          ())
     (dni (.sym j x-cond x-suffix r x-endian)
          (.str j x-cond x-suffix " r")
-         ((ISA (.sym ebpf x-endian)))
+         (endian-isas x-endian)
          (.str "j" x-cond x-suffix " $dst" x-endian ",$src" x-endian ",$disp16")
          (+ (f-imm32 0) disp16 (.sym src x-endian) (.sym dst x-endian)
             x-op-class OP_SRC_X (.sym OP_CODE_ x-op-code))
 (define-pmacro (define-call-insn x-endian)
   (dni (.sym call x-endian)
        "call"
-       ((ISA (.sym ebpf x-endian)))
+       (endian-isas x-endian)
        "call $disp32"
        (+ disp32 (f-offset16 0) (f-regs 0)
           OP_CLASS_JMP OP_SRC_K OP_CODE_CALL)
 (define-call-insn le)
 (define-call-insn be)
 
+(define-pmacro (define-callr-insn x-endian)
+  (dni (.sym callr x-endian)
+       "callr"
+       ((ISA (.sym xbpf x-endian)))
+       (.str "call $dst" x-endian)
+       (+ (f-imm32 0) (f-offset16 0) ((.sym f-src x-endian) 0) (.sym dst x-endian)
+          OP_CLASS_JMP OP_SRC_X OP_CODE_CALL)
+       (c-call VOID
+               "bpfbf_callr" (ifield (.sym f-dst x-endian)))
+       ()))
+
+(define-callr-insn le)
+(define-callr-insn be)
+
 ;; The jump-always and `exit' instructions dont make use of either
 ;; source nor destination registers, so only one variant per
 ;; instruction is defined.
   (begin
     (dni (.str "xadddw" x-endian)
          "xadddw"
-         ((ISA (.sym ebpf x-endian)))
+         (endian-isas x-endian)
          (.str "xadddw [$dst" x-endian "+$offset16],$src" x-endian)
          (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
             offset16 OP_MODE_XADD OP_SIZE_DW OP_CLASS_STX)
          ())
     (dni (.str "xaddw" x-endian)
          "xaddw"
-         ((ISA (.sym ebpf x-endian)))
+         (endian-isas x-endian)
          (.str "xaddw [$dst" x-endian "+$offset16],$src" x-endian)
          (+ (f-imm32 0) (.sym src x-endian) (.sym dst x-endian)
             offset16 OP_MODE_XADD OP_SIZE_W OP_CLASS_STX)