diff options
Diffstat (limited to 'sim/testsuite')
-rw-r--r-- | sim/testsuite/ChangeLog | 17 | ||||
-rwxr-xr-x | sim/testsuite/configure | 3 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/allinsn.exp | 26 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/alu.s | 109 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/alu32.s | 99 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/endbe.s | 46 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/endle.s | 43 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/jmp.s | 120 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/jmp32.s | 120 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/ldabs.s | 87 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/mem.s | 56 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/mov.s | 54 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/testutils.inc | 38 | ||||
-rw-r--r-- | sim/testsuite/sim/bpf/xadd.s | 44 |
14 files changed, 862 insertions, 0 deletions
diff --git a/sim/testsuite/ChangeLog b/sim/testsuite/ChangeLog index e3b47aa..f2df734 100644 --- a/sim/testsuite/ChangeLog +++ b/sim/testsuite/ChangeLog @@ -1,3 +1,20 @@ +2020-08-04 David Faust <david.faust@oracle.com> + Jose E. Marchesi <jose.marchesi@oracle.com> + + * configure: Regenerate. + * sim/bpf/allinsn.exp: New file. + * sim/bpf/alu.s: Likewise. + * sim/bpf/alu32.s: Likewise. + * sim/bpf/endbe.s: Likewise. + * sim/bpf/endle.s: Likewise. + * sim/bpf/jmp.s: Likewise. + * sim/bpf/jmp32.s: Likewise. + * sim/bpf/ldabs.s: Likewise. + * sim/bpf/mem.s: Likewise. + * sim/bpf/mov.s: Likewise. + * sim/bpf/testutils.inc: Likewise. + * sim/bpf/xadd.s: Likewise. + 2020-07-29 Simon Marchi <simon.marchi@efficios.com> * configure: Re-generate. diff --git a/sim/testsuite/configure b/sim/testsuite/configure index d15fbba..c3674c2 100755 --- a/sim/testsuite/configure +++ b/sim/testsuite/configure @@ -1875,6 +1875,9 @@ case "${target}" in bfin-*-*) sim_arch=bfin ;; + bpf-*-*) + sim_arch=bpf + ;; cr16*-*-*) sim_arch=cr16 ;; diff --git a/sim/testsuite/sim/bpf/allinsn.exp b/sim/testsuite/sim/bpf/allinsn.exp new file mode 100644 index 0000000..2cca770 --- /dev/null +++ b/sim/testsuite/sim/bpf/allinsn.exp @@ -0,0 +1,26 @@ +# eBPF simulator testsuite + +if [istarget bpf-unknown-none] { + # all machines + set all_machs "bpf" + + global global_sim_options + if ![info exists global_sim_options] { + set global_sim_options "--memory-size=4Mb" + } + + global global_ld_options + if ![info exists global_ld_options] { + set global_ld_options "-Ttext=0x0" + } + + foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.s]] { + # If we're only testing specific files and this isn't one of them, + # skip it. + if ![runtest_file_p $runtests $src] { + continue + } + + run_sim_test $src $all_machs + } +} diff --git a/sim/testsuite/sim/bpf/alu.s b/sim/testsuite/sim/bpf/alu.s new file mode 100644 index 0000000..6013ac7 --- /dev/null +++ b/sim/testsuite/sim/bpf/alu.s @@ -0,0 +1,109 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;;; alu.s +;;; Tests for ALU64 BPF instructions in simulator + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + mov %r1, 0 + mov %r2, -1 + + ;; add + add %r1, 1 + add %r2, -1 + add %r1, %r2 + fail_ne %r1, -1 + + ;; sub + sub %r1, %r1 + fail_ne %r1, 0 + sub %r1, 10 + sub %r2, %r1 + fail_ne %r2, 8 + + ;; mul + mul %r2, %r2 ; r2 = 64 + mul %r2, 3 ; r2 = 192 + mov %r1, -3 + mul %r1, %r2 ; r1 = -576 + mul %r2, 0 + fail_ne %r1, -576 + fail_ne %r2, 0 + mul %r1, %r1 + mul %r1, %r1 + fail_ne %r1, 110075314176 + + ;; div + div %r2, %r1 + fail_ne %r2, 0 + div %r1, -10000 + fail_ne %r1, -11007531 + div %r1, %r1 + fail_ne %r1, 1 + + ;; and + lddw %r1, 0xaaaaaaaa55555555 + and %r1, 0x55aaaaaa ; we still only have 32-bit imm. + fail_ne %r1, 0x0000000055000000 + lddw %r2, 0x5555555a5aaaaaaa + and %r2, %r1 + fail_ne %r2, 0x0000000050000000 + + ;; or + or %r2, 0xdeadbeef + fail_ne %r2, 0xffffffffdeadbeef ; 0xdeadbeef gets sign extended + lddw %r1, 0xdead00000000beef + lddw %r2, 0x0000123456780000 + or %r1, %r2 + fail_ne %r1, 0xdead12345678beef + + ;; lsh + mov %r1, 0xdeadbeef + lsh %r1, 11 + fail_ne %r1, 0xfffffef56df77800 ; because deadbeef gets sign ext. + mov %r2, 21 + lsh %r1, %r2 + fail_ne %r1, 0xdeadbeef00000000 + + ;; rsh + rsh %r1, 11 + fail_ne %r1, 0x001bd5b7dde00000 ; 0xdeadbeef 00000000 >> 0xb + rsh %r1, %r2 + fail_ne %r1, 0x00000000deadbeef + + ;; arsh + arsh %r1, 8 + fail_ne %r1, 0x0000000000deadbe + lsh %r1, 40 ; r1 = 0xdead be00 0000 0000 + arsh %r1, %r2 ; r1 arsh (r2 == 21) + fail_ne %r1, 0xfffffef56df00000 + + ;; mod + mov %r1, 1025 + mod %r1, -16 + fail_ne %r1, 1 + mov %r1, -25 + mov %r2, 5 + mod %r1, %r2 + fail_ne %r1, 0 + + ;; xor + xor %r1, %r2 + fail_ne %r1, 5 + xor %r1, 0x7eadbeef + fail_ne %r1, 0x7eadbeea + xor %r1, %r1 + fail_ne %r1, 0 + + ;; neg + neg %r2 + fail_ne %r2, -5 + mov %r1, -1025 + neg %r1 + fail_ne %r1, 1025 + + pass diff --git a/sim/testsuite/sim/bpf/alu32.s b/sim/testsuite/sim/bpf/alu32.s new file mode 100644 index 0000000..fcd6699 --- /dev/null +++ b/sim/testsuite/sim/bpf/alu32.s @@ -0,0 +1,99 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;; alu32.s +;; Tests for ALU(32) BPF instructions in simulator + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + mov32 %r1, 10 ; r1 = 10 + mov32 %r2, -5 ; r2 = -5 + + ;; add + add32 %r1, 1 ; r1 += 1 (r1 = 11) + add32 %r2, -1 ; r2 += -1 (r2 = -6) + add32 %r1, %r2 ; r1 += r2 (r1 = 11 + -6 = 5) + fail_ne32 %r1, 5 + + ;; sub + sub32 %r1, 5 ; r1 -= 5 (r1 = 0) + sub32 %r1, -5 ; r1 -= -5 (r1 = 5) + sub32 %r1, %r2 ; r1 -= r2 (r1 = 5 - -6 = 11) + fail_ne32 %r1, 11 + + ;; mul + mul32 %r1, 2 ; r1 *= 2 (r1 = 22) + mul32 %r1, -2 ; r1 *= -2 (r1 = -44) + mul32 %r1, %r2 ; r1 *= r2 (r1 = -44 * -6 = 264) + fail_ne32 %r1, 264 + + ;; div + div32 %r1, %r2 ; r1 /= r2 (r1 = 264 / -6 = -44) + div32 %r1, -2 ; r1 /= -2 (r1 = 22) + div32 %r1, 2 ; r1 /= 2 (r1 = 11) + fail_ne32 %r1, 11 + + ;; and (bitwise) + mov32 %r1, 0xb ; r1 = (0xb = 0b1011) + mov32 %r2, 0x5 ; r2 = (0x5 = 0b0101) + and32 %r1, 0xa ; r1 &= (0xa = 0b1010) = (0b1010 = 0xa) + fail_ne32 %r1, 0xa + and32 %r1, %r2 ; r1 &= r2 = 0x0 + fail_ne32 %r1, 0x0 + + ;; or (bitwise) + or32 %r1, 0xb + or32 %r1, %r2 + fail_ne32 %r1, 0xf + + ;; lsh (left shift) + lsh32 %r1, 4 ; r1 <<= 4 (r1 = 0xf0) + mov32 %r2, 24 ; r2 = 24 + lsh32 %r1, %r2 + fail_ne32 %r1, 0xf0000000 + + ;; rsh (right logical shift) + rsh32 %r1, 2 + rsh32 %r1, %r2 + fail_ne32 %r1, 0x3c ; (0xf000 0000 >> 26) + + ;; arsh (right arithmetic shift) + arsh32 %r1, 1 + or32 %r1, 0x80000000 + mov32 %r2, 3 + arsh32 %r1, %r2 + fail_ne %r1, 0x00000000F0000003 + ; Note: make sure r1 is NOT sign-extended + ; i.e. upper-32 bits should be untouched + + ;; mod + mov32 %r1, -25 + mov32 %r2, 4 + mod32 %r1, %r2 + fail_ne32 %r1, -1 + mov32 %r1, 25 + mod32 %r1, 5 + fail_ne32 %r1, 0 + + ;; xor + xor32 %r1, %r2 + fail_ne32 %r1, 4 + xor32 %r1, 0xF000000F + fail_ne %r1, 0xF000000B ; Note: check for (bad) sign-extend + xor32 %r1, %r1 + fail_ne %r1, 0 + + ;; neg + mov32 %r1, -1 + mov32 %r2, 0x7fffffff + neg32 %r1 + neg32 %r2 + fail_ne32 %r1, 1 + fail_ne %r2, 0x80000001 ; Note: check for (bad) sign-extend + neg32 %r2 + fail_ne32 %r2, 0x7fffffff + + pass diff --git a/sim/testsuite/sim/bpf/endbe.s b/sim/testsuite/sim/bpf/endbe.s new file mode 100644 index 0000000..2f662ae --- /dev/null +++ b/sim/testsuite/sim/bpf/endbe.s @@ -0,0 +1,46 @@ +# mach: bpf +# as: --EB +# ld: --EB +# sim: -E big +# output: pass\nexit 0 (0x0)\n +;;; endbe.s +;;; Tests for BPF endianness-conversion instructions in simulator +;;; running in BIG ENDIAN +;;; +;;; Both 'be' and 'le' ISAs have both endbe and endle instructions. + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + lddw %r1, 0x12345678deadbeef + endle %r1, 64 + fail_ne %r1, 0xefbeadde78563412 + endle %r1, 64 + fail_ne %r1, 0x12345678deadbeef + + ;; `bitsize` < 64 will truncate + endle %r1, 32 + fail_ne %r1, 0xefbeadde + endle %r1, 32 + fail_ne %r1, 0xdeadbeef + + endle %r1, 16 + fail_ne %r1, 0xefbe + endle %r1, 16 + fail_ne %r1, 0xbeef + + ;; endbe on be should be noop (except truncate) + lddw %r1, 0x12345678deadbeef + endbe %r1, 64 + fail_ne %r1, 0x12345678deadbeef + + endbe %r1, 32 + fail_ne %r1, 0xdeadbeef + + endbe %r1, 16 + fail_ne %r1, 0xbeef + + pass diff --git a/sim/testsuite/sim/bpf/endle.s b/sim/testsuite/sim/bpf/endle.s new file mode 100644 index 0000000..d8f5ceb --- /dev/null +++ b/sim/testsuite/sim/bpf/endle.s @@ -0,0 +1,43 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;;; endle.s +;;; Tests for BPF endianness-conversion instructions in simulator +;;; running in LITTLE ENDIAN +;;; +;;; Both 'be' and 'le' ISAs have both endbe and endle instructions. + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + lddw %r1, 0x12345678deadbeef + endbe %r1, 64 + fail_ne %r1, 0xefbeadde78563412 + endbe %r1, 64 + fail_ne %r1, 0x12345678deadbeef + + ;; `bitsize` < 64 will truncate + endbe %r1, 32 + fail_ne %r1, 0xefbeadde + endbe %r1, 32 + fail_ne %r1, 0xdeadbeef + + endbe %r1, 16 + fail_ne %r1, 0xefbe + endbe %r1, 16 + fail_ne %r1, 0xbeef + + ;; endle on le should be noop (except truncate) + lddw %r1, 0x12345678deadbeef + endle %r1, 64 + fail_ne %r1, 0x12345678deadbeef + + endle %r1, 32 + fail_ne %r1, 0xdeadbeef + + endle %r1, 16 + fail_ne %r1, 0xbeef + + pass diff --git a/sim/testsuite/sim/bpf/jmp.s b/sim/testsuite/sim/bpf/jmp.s new file mode 100644 index 0000000..5ab5de0 --- /dev/null +++ b/sim/testsuite/sim/bpf/jmp.s @@ -0,0 +1,120 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;;; jmp.s +;;; Tests for eBPF JMP instructions in simulator + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + mov %r1, 5 + mov %r2, 2 + mov %r3, 7 + mov %r4, -1 + + ;; ja - jump absolute (unconditional) + ja 2f +1: fail + +2: ;; jeq - jump eq + jeq %r1, 4, 1b ; no + jeq %r1, %r2, 1b ; no + jeq %r1, 5, 2f ; yes + fail +2: jeq %r1, %r1, 2f ; yes + fail + +2: ;; jgt - jump (unsigned) greater-than + jgt %r1, 6, 1b ; no + jgt %r1, -5, 1b ; no - unsigned + jgt %r1, %r4, 1b ; no - unsigned + jgt %r1, 4, 2f ; yes + fail +2: jgt %r1, %r2, 2f ; yes + fail + +2: ;; jge - jump (unsigned) greater-than-or-equal-to + jge %r1, 6, 1b ; no + jge %r1, 5, 2f ; yes + fail +2: jge %r1, %r3, 1b ; no + jge %r1, -5, 1b ; no - unsigned + jge %r1, %r2, 2f ; yes + fail + +2: ;; jlt - jump (unsigned) less-than + jlt %r1, 5, 1b ; no + jlt %r1, %r2, 1b ; no + jlt %r4, %r1, 1b ; no - unsigned + jlt %r1, 6, 2f ; yes + fail +2: + jlt %r1, %r3, 2f ; yes + fail + +2: ;; jle - jump (unsigned) less-than-or-equal-to + jle %r1, 4, 1b ; no + jle %r1, %r2, 1b ; no + jle %r4, %r1, 1b ; no + jle %r1, 5, 2f ; yes + fail +2: jle %r1, %r1, 2f ; yes + fail + +2: ;; jset - jump "test" (AND) + jset %r1, 2, 1b ; no (5 & 2 = 0) + jset %r1, %r2, 1b ; no (same) + jset %r1, 4, 2f ; yes (5 & 4 != 0) + fail + +2: ;; jne - jump not-equal-to + jne %r1, 5, 1b ; no + jne %r1, %r1, 1b ; no + jne %r1, 6, 2f ; yes + fail +2: jne %r1, %r4, 2f ; yes + fail + +2: ;; jsgt - jump (signed) greater-than + jsgt %r1, %r3, 1b ; no + jsgt %r1, %r1, 1b ; no + jsgt %r1, 5, 1b ; no + jsgt %r1, -4, 2f ; yes + fail +2: jsgt %r1, %r4, 2f ; yes + fail + +2: ;; jsge - jump (signed) greater-than-or-equal-to + jsge %r1, %r3, 1b ; no + jsge %r1, %r1, 2f ; yes + fail +2: jsge %r1, 7, 1b ; no + jsge %r1, -4, 2f ; yes + fail +2: jsge %r1, %r4, 2f ; yes + fail + +2: ;; jslt - jump (signed) less-than + jslt %r1, 5, 1b ; no + jslt %r1, %r2, 1b ; no + jslt %r4, %r1, 2f ; yes + fail +2: jslt %r1, 6, 2f ; yes + fail +2: jslt %r1, %r3, 2f ; yes + fail + +2: ;; jsle - jump (signed) less-than-or-equal-to + jsle %r1, 4, 1b ; no + jsle %r1, %r2, 1b ; no + jsle %r4, %r1, 2f ; yes + fail +2: jsle %r1, 5, 2f ; yes + fail +2: jsle %r1, %r3, 2f ; yes + fail + +2: + pass diff --git a/sim/testsuite/sim/bpf/jmp32.s b/sim/testsuite/sim/bpf/jmp32.s new file mode 100644 index 0000000..a6074cd --- /dev/null +++ b/sim/testsuite/sim/bpf/jmp32.s @@ -0,0 +1,120 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;;; jmp32.s +;;; Tests for eBPF JMP32 instructions in simulator + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + mov32 %r1, 5 + mov32 %r2, 2 + mov32 %r3, 7 + mov32 %r4, -1 + + ;; ja - jump absolute (unconditional) + ja 2f +1: fail + +2: ;; jeq - jump eq + jeq32 %r1, 4, 1b ; no + jeq32 %r1, %r2, 1b ; no + jeq32 %r1, 5, 2f ; yes + fail +2: jeq32 %r1, %r1, 2f ; yes + fail + +2: ;; jgt - jump (unsigned) greater-than + jgt32 %r1, 6, 1b ; no + jgt32 %r1, -5, 1b ; no - unsigned + jgt32 %r1, %r4, 1b ; no - unsigned + jgt32 %r1, 4, 2f ; yes + fail +2: jgt32 %r1, %r2, 2f ; yes + fail + +2: ;; jge - jump (unsigned) greater-than-or-equal-to + jge32 %r1, 6, 1b ; no + jge32 %r1, 5, 2f ; yes + fail +2: jge32 %r1, %r3, 1b ; no + jge32 %r1, -5, 1b ; no - unsigned + jge32 %r1, %r2, 2f ; yes + fail + +2: ;; jlt - jump (unsigned) less-than + jlt32 %r1, 5, 1b ; no + jlt32 %r1, %r2, 1b ; no + jlt32 %r4, %r1, 1b ; no - unsigned + jlt32 %r1, 6, 2f ; yes + fail +2: + jlt32 %r1, %r3, 2f ; yes + fail + +2: ;; jle - jump (unsigned) less-than-or-equal-to + jle32 %r1, 4, 1b ; no + jle32 %r1, %r2, 1b ; no + jle32 %r4, %r1, 1b ; no + jle32 %r1, 5, 2f ; yes + fail +2: jle32 %r1, %r1, 2f ; yes + fail + +2: ;; jset - jump "test" (AND) + jset32 %r1, 2, 1b ; no (5 & 2 = 0) + jset32 %r1, %r2, 1b ; no (same) + jset32 %r1, 4, 2f ; yes (5 & 4 != 0) + fail + +2: ;; jne - jump not-equal-to + jne32 %r1, 5, 1b ; no + jne32 %r1, %r1, 1b ; no + jne32 %r1, 6, 2f ; yes + fail +2: jne32 %r1, %r4, 2f ; yes + fail + +2: ;; jsgt - jump (signed) greater-than + jsgt32 %r1, %r3, 1b ; no + jsgt32 %r1, %r1, 1b ; no + jsgt32 %r1, 5, 1b ; no + jsgt32 %r1, -4, 2f ; yes + fail +2: jsgt32 %r1, %r4, 2f ; yes + fail + +2: ;; jsge - jump (signed) greater-than-or-equal-to + jsge32 %r1, %r3, 1b ; no + jsge32 %r1, %r1, 2f ; yes + fail +2: jsge32 %r1, 7, 1b ; no + jsge32 %r1, -4, 2f ; yes + fail +2: jsge32 %r1, %r4, 2f ; yes + fail + +2: ;; jslt - jump (signed) less-than + jslt32 %r1, 5, 1b ; no + jslt32 %r1, %r2, 1b ; no + jslt32 %r4, %r1, 2f ; yes + fail +2: jslt32 %r1, 6, 2f ; yes + fail +2: jslt32 %r1, %r3, 2f ; yes + fail + +2: ;; jsle - jump (signed) less-than-or-equal-to + jsle32 %r1, 4, 1b ; no + jsle32 %r1, %r2, 1b ; no + jsle32 %r4, %r1, 2f ; yes + fail +2: jsle32 %r1, 5, 2f ; yes + fail +2: jsle32 %r1, %r3, 2f ; yes + fail + +2: + pass diff --git a/sim/testsuite/sim/bpf/ldabs.s b/sim/testsuite/sim/bpf/ldabs.s new file mode 100644 index 0000000..ae777f1 --- /dev/null +++ b/sim/testsuite/sim/bpf/ldabs.s @@ -0,0 +1,87 @@ +# mach: bpf +# sim: --skb-data-offset=0x20 +# output: pass\nexit 0 (0x0)\n +;;; ldabs.s +;;; Tests for non-generic BPF load instructions in simulator. +;;; These instructions (ld{abs,ind}{b,h,w,dw}) are used to access +;;; kernel socket data from BPF programs for high performance filters. +;;; +;;; Register r6 is an implicit input holding a pointer to a struct sk_buff. +;;; Register r0 is an implicit output, holding the fetched data. +;;; +;;; e.g. +;;; ldabsw means: +;;; r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + imm32)) +;;; +;;; ldindw means +;;; r0 = ntohl (*(u32 *) (((struct sk_buff *)r6)->data + src_reg + imm32)) + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + ;; R6 holds a pointer to a struct sk_buff, which we pretend + ;; exists at 0x1000 + mov %r6, 0x1000 + + ;; We configure skb-data-offset=0x20 + ;; This specifies offsetof(struct sk_buff, data), where the field 'data' + ;; is a pointer a data buffer, in this case at 0x2000 + stw [%r6+0x20], 0x2000 + + ;; Write the value 0x7eadbeef into memory at 0x2004 + ;; i.e. offset 4 within the data buffer pointed to by + ;; ((struct sk_buff *)r6)->data + stw [%r6+0x1004], 0xdeadbeef + + ;; Now load data[4] into r0 using the ldabsw instruction + ldabsw 0x4 + + ;; ...and compare to what we expect + fail_ne32 %r0, 0xdeadbeef + + ;; Repeat for a half-word (2-bytes) + sth [%r6+0x1008], 0x1234 + ldabsh 0x8 + fail_ne32 %r0, 0x1234 + + ;; Repeat for a single byte + stb [%r6+0x1010], 0x5a + ldabsb 0x10 + fail_ne32 %r0, 0x5a + + ;; Repeat for a double-word (8-byte) + ;; (note: fail_ne macro uses r0, so copy to another r1 to compare) + lddw %r2, 0x1234deadbeef5678 + stxdw [%r6+0x1018], %r2 + ldabsdw 0x18 + mov %r1, %r0 + fail_ne %r1, 0x1234deadbeef5678 + + ;; Now, we do the same for the indirect loads + mov %r7, 0x100 + stw [%r6+0x1100], 0xfeedbeef + + ldindw %r7, 0x0 + fail_ne32 %r0, 0xfeedbeef + + ;; half-word + sth [%r6+0x1104], 0x6789 + ldindh %r7, 0x4 + fail_ne32 %r0, 0x6789 + + ;; byte + stb [%r6+0x1108], 0x5f + ldindb %r7, 0x8 + fail_ne32 %r0, 0x5f + + ;; double-word + lddw %r2, 0xcafe12345678d00d + stxdw [%r6+0x1110], %r2 + ldinddw %r7, 0x10 + mov %r1, %r0 + fail_ne %r1, 0xcafe12345678d00d + + pass diff --git a/sim/testsuite/sim/bpf/mem.s b/sim/testsuite/sim/bpf/mem.s new file mode 100644 index 0000000..f9c6a19 --- /dev/null +++ b/sim/testsuite/sim/bpf/mem.s @@ -0,0 +1,56 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;;; mem.s +;;; Tests for BPF memory (ldx, stx, ..) instructions in simulator + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + lddw %r1, 0x1234deadbeef5678 + mov %r2, 0x1000 + + ;; basic store/load check + stxb [%r2+0], %r1 + stxh [%r2+2], %r1 + stxw [%r2+4], %r1 + stxdw [%r2+8], %r1 + + stb [%r2+16], 0x5a + sth [%r2+18], 0xcafe + stw [%r2+20], 0xbeefface + stdw [%r2+24], 0x7eadbeef + + ldxb %r1, [%r2+16] + fail_ne %r1, 0x5a + ldxh %r1, [%r2+18] + fail_ne %r1, 0xffffffffffffcafe + ldxw %r1, [%r2+20] + fail_ne %r1, 0xffffffffbeefface + ldxdw %r1, [%r2+24] + fail_ne %r1, 0x7eadbeef + + ldxb %r3, [%r2+0] + fail_ne %r3, 0x78 + ldxh %r3, [%r2+2] + fail_ne %r3, 0x5678 + ldxw %r3, [%r2+4] + fail_ne %r3, 0xffffffffbeef5678 + ldxdw %r3, [%r2+8] + fail_ne %r3, 0x1234deadbeef5678 + + ldxw %r4, [%r2+10] + fail_ne %r4, 0xffffffffdeadbeef + + ;; negative offsets + add %r2, 16 + ldxh %r5, [%r2+-14] + fail_ne %r5, 0x5678 + ldxw %r5, [%r2+-12] + fail_ne %r5, 0xffffffffbeef5678 + ldxdw %r5, [%r2+-8] + fail_ne %r5, 0x1234deadbeef5678 + + pass diff --git a/sim/testsuite/sim/bpf/mov.s b/sim/testsuite/sim/bpf/mov.s new file mode 100644 index 0000000..6665450 --- /dev/null +++ b/sim/testsuite/sim/bpf/mov.s @@ -0,0 +1,54 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;; mov.s +;; Tests for mov and mov32 instructions + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + ;; some basic sanity checks + mov32 %r1, 5 + fail_ne %r1, 5 + + mov32 %r2, %r1 + fail_ne %r2, 5 + + mov %r2, %r1 + fail_ne %r2, 5 + + mov %r1, -666 + fail_ne %r1, -666 + + ;; should NOT sign extend + mov32 %r1, -1 + fail_ne %r1, 0x00000000ffffffff + + ;; should sign extend + mov %r2, -1 + fail_ne %r2, 0xffffffffffffffff + + mov %r3, 0x80000000 + + ;; should NOT sign extend + mov32 %r4, %r3 + fail_ne %r4, 0x0000000080000000 + + ;; should sign extend + mov %r5, %r3 + fail_ne %r5, 0xffffffff80000000 + + mov32 %r1, -2147483648 + mov32 %r1, %r1 + fail_ne32 %r1, -2147483648 + + ;; casting shenanigans + mov %r1, %r1 + fail_ne %r1, +2147483648 + mov32 %r2, -1 + mov %r2, %r2 + fail_ne %r2, +4294967295 + + pass diff --git a/sim/testsuite/sim/bpf/testutils.inc b/sim/testsuite/sim/bpf/testutils.inc new file mode 100644 index 0000000..d3d6b17 --- /dev/null +++ b/sim/testsuite/sim/bpf/testutils.inc @@ -0,0 +1,38 @@ + + ;; Print "pass\n" and 'exit 0' + .macro pass + .data +mpass: + .string "pass\n" + .text +_pass: + mov %r1, mpass ; point to "pass\n" string + mov %r2, 5 ; strlen mpass + call 7 ; printk + mov %r0, 0 ; + exit ; exit 0 + .endm + +;;; MACRO fail +;;; Exit with status 1 + .macro fail + mov %r0, 1 + exit + .endm + +;;; MACRO fail_ne32 +;;; Exit with status 1 if \reg32 != \val + .macro fail_ne32 reg val + jeq32 \reg, \val, 2 + mov %r0, 1 + exit + .endm + +;;; MACRO fail_ne +;;; Exit with status1 if \reg ne \val + .macro fail_ne reg val + lddw %r0, \val + jeq \reg, %r0, 2 + mov %r0, 1 + exit + .endm diff --git a/sim/testsuite/sim/bpf/xadd.s b/sim/testsuite/sim/bpf/xadd.s new file mode 100644 index 0000000..be60714 --- /dev/null +++ b/sim/testsuite/sim/bpf/xadd.s @@ -0,0 +1,44 @@ +# mach: bpf +# output: pass\nexit 0 (0x0)\n +;;; xadd.s +;;; Tests for BPF atomic exchange-and-add instructions in simulator +;;; +;;; The xadd instructions (XADDW, XADDDW) operate on a memory location +;;; specified in $dst + offset16, atomically adding the value in $src. +;;; +;;; In the simulator, there isn't anything else happening. The atomic +;;; instructions are identical to a non-atomic load/add/store. + + .include "testutils.inc" + + .text + .global main + .type main, @function +main: + mov %r1, 0x1000 + mov %r2, 5 + + ;; basic xadd w + stw [%r1+0], 10 + xaddw [%r1+0], %r2 + ldxw %r3, [%r1+0] + fail_ne %r3, 15 + + ;; basic xadd dw + stdw [%r1+8], 42 + xadddw [%r1+8], %r2 + ldxdw %r3, [%r1+8] + fail_ne %r3, 47 + + ;; xadd w negative value + mov %r4, -1 + xaddw [%r1+0], %r4 + ldxw %r3, [%r1+0] + fail_ne %r3, 14 + + ;; xadd dw negative val + xadddw [%r1+8], %r4 + ldxdw %r3, [%r1+8] + fail_ne %r3, 46 + + pass |