| # Blackfin testcase for push/pop multiples instructions | |
| # mach: bfin | |
| .include "testutils.inc" | |
| # Tests follow the pattern: | |
| # - do the push multiple | |
| # - write a garbage value to all registers pushed | |
| # - do the pop multiple | |
| # - check all registers popped against known values | |
| start | |
| # Repeat the same operation multiple times, so this: | |
| # do_x moo, R, 1 | |
| # becomes this: | |
| # moo R1, 0x11111111 | |
| # moo R0, 0x00000000 | |
| .macro _do_x func:req, reg:req, max:req, x:req | |
| .ifle (\max - \x) | |
| \func \reg\()\x, 0x\x\x\x\x\x\x\x\x | |
| .endif | |
| .endm | |
| .macro do_x func:req, reg:req, max:req | |
| .ifc \reg, R | |
| _do_x \func, \reg, \max, 7 | |
| _do_x \func, \reg, \max, 6 | |
| .endif | |
| _do_x \func, \reg, \max, 5 | |
| _do_x \func, \reg, \max, 4 | |
| _do_x \func, \reg, \max, 3 | |
| _do_x \func, \reg, \max, 2 | |
| _do_x \func, \reg, \max, 1 | |
| _do_x \func, \reg, \max, 0 | |
| .endm | |
| # Keep the garbage value in I0 | |
| .macro loadi reg:req, val:req | |
| \reg = I0; | |
| .endm | |
| imm32 I0, 0xAABCDEFF | |
| # | |
| # Test push/pop multiples with (R7:x) syntax | |
| # | |
| _push_r_tests: | |
| # initialize all Rx regs with a known value | |
| do_x imm32, R, 0 | |
| .macro checkr tochk:req, val:req | |
| P0 = \tochk; | |
| imm32 P1, \val | |
| CC = P0 == P1; | |
| IF !CC JUMP 8f; | |
| .endm | |
| .macro pushr maxr:req | |
| _push_r\maxr: | |
| [--SP] = (R7:\maxr); | |
| do_x loadi, R, \maxr | |
| (R7:\maxr) = [SP++]; | |
| do_x checkr, R, \maxr | |
| # need to do a long jump to avoid PCREL issues | |
| jump 9f; | |
| 8: jump.l 1f; | |
| 9: | |
| .endm | |
| pushr 7 | |
| pushr 6 | |
| pushr 5 | |
| pushr 4 | |
| pushr 3 | |
| pushr 2 | |
| pushr 1 | |
| pushr 0 | |
| # | |
| # Test push/pop multiples with (P5:x) syntax | |
| # | |
| _push_p_tests: | |
| # initialize all Px regs with a known value | |
| do_x imm32, P, 0 | |
| .macro checkp tochk:req, val:req | |
| R0 = \tochk; | |
| imm32 R1, \val | |
| CC = R0 == R1; | |
| IF !CC JUMP 8f; | |
| .endm | |
| .macro pushp maxp:req | |
| _push_p\maxp: | |
| [--SP] = (P5:\maxp); | |
| do_x loadi, P, \maxp | |
| (P5:\maxp) = [SP++]; | |
| do_x checkp, P, \maxp | |
| # need to do a long jump to avoid PCREL issues | |
| jump 9f; | |
| 8: jump.l 1f; | |
| 9: | |
| .endm | |
| # checkp func clobbers R0/R1 | |
| L0 = R0; | |
| L1 = R1; | |
| pushp 5 | |
| pushp 4 | |
| pushp 3 | |
| pushp 2 | |
| pushp 1 | |
| pushp 0 | |
| R0 = L0; | |
| R1 = L1; | |
| # | |
| # Test push/pop multiples with (R7:x, P5:x) syntax | |
| # | |
| _push_rp_tests: | |
| .macro _pushrp maxr:req, maxp:req | |
| _push_r\maxr\()_p\maxp: | |
| [--SP] = (R7:\maxr, P5:\maxp); | |
| do_x loadi, R, \maxr | |
| do_x loadi, P, \maxp | |
| (R7:\maxr, P5:\maxp) = [SP++]; | |
| # checkr func clobbers P0/P1 | |
| L0 = P0; | |
| L1 = P1; | |
| do_x checkr, R, \maxr | |
| P1 = L1; | |
| P0 = L0; | |
| # checkp func clobbers R0/R1 | |
| L0 = R0; | |
| L1 = R1; | |
| do_x checkp, P, \maxp | |
| R0 = L0; | |
| R1 = L1; | |
| # need to do a long jump to avoid PCREL issues | |
| jump 9f; | |
| 8: jump.l 1f; | |
| 9: | |
| .endm | |
| .macro pushrp maxr:req | |
| _pushrp \maxr, 5 | |
| _pushrp \maxr, 4 | |
| _pushrp \maxr, 3 | |
| _pushrp \maxr, 2 | |
| _pushrp \maxr, 1 | |
| _pushrp \maxr, 0 | |
| .endm | |
| pushrp 7 | |
| pushrp 6 | |
| pushrp 5 | |
| pushrp 4 | |
| pushrp 3 | |
| pushrp 2 | |
| pushrp 1 | |
| pushrp 0 | |
| pass | |
| 1: | |
| fail |