diff options
Diffstat (limited to 'sim/testsuite/bfin/testutils.inc')
-rw-r--r-- | sim/testsuite/bfin/testutils.inc | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/sim/testsuite/bfin/testutils.inc b/sim/testsuite/bfin/testutils.inc new file mode 100644 index 0000000..991d167 --- /dev/null +++ b/sim/testsuite/bfin/testutils.inc @@ -0,0 +1,295 @@ +# R0 and P0 are used as tmps, consider them call clobbered by these macros. + +# To build for hardware, use: +# bfin-linux-uclibc-gcc -nostdlib -g -Wa,--defsym,BFIN_HOST=1 foo.s + +# MACRO: start +# All assembler tests should start with a call to "start" + .macro start + .text + # Pad with EMUEXCPT to make sure "jump to 0" always fails +__panic: + .rep 0xf + .word 0x0025 + .endr + abort; + jump __panic; + + .global __pass +__pass: + write 1, _passmsg, 5 + exit 0 +.ifdef BFIN_JTAG +__emu_out: + /* DBGSTAT */ + imm32 P0 0xFFE05008; + +1: R7 = [P0]; + CC = BITTST (R7,0); + IF CC JUMP 1b; + + EMUDAT = R0; + RTS; +.endif + .global __fail +__fail: +.ifndef BFIN_HOST + P0.H = _rets; + P0.L = _rets; + R0 = RETS; + R0 += -4; + P1 = 8; + R2 = '9'; + LSETUP (1f, 3f) LC0 = P1; +1: + R1 = R0; + R1 >>= 28; + R1 += 0x30; + CC = R2 < R1; + IF !CC jump 2f; + R1 += 7; +2: + B[P0++] = R1; +3: + R0 <<= 4; + + write 1, _failmsg, 22 +.else + write 1, _failmsg, 5 +.endif + exit 1 + +.ifndef BFIN_HOST + .data +_failmsg: + .ascii "fail at PC=0x" +_rets: + .ascii "12345678\n" +_passmsg: + .ascii "pass\n" + .align 4 +_params: + .long 0 + .long 0 + .long 0 + .long 0 + + .text + .global __start +__start: +.else +.global ___uClibc_main; +___uClibc_main: +.global _main; +_main: +.endif + .endm + +# MACRO: system_call +# Make a libgloss/Linux system call + .macro system_call nr:req + P0 = \nr (X); + EXCPT 0; + .endm + +# MACRO: exit +# Quit the current test + .macro exit rc:req + R0 = \rc (X); +.ifndef BFIN_HOST + P0.H = _params; + P0.L = _params; + [P0] = R0; + R0 = P0; +.endif + system_call 1 + .endm + +# MACRO: pass +# Write 'pass' to stdout via syscalls and quit; +# meant for non-OS operating environments + .macro pass + CALL __pass; + .endm + +# MACRO: fail +# Write 'fail' to stdout via syscalls and quit; +# meant for non-OS operating environments + .macro fail + CALL __fail; + .endm + +# MACRO: write +# Just like the write() C function; uses system calls + .macro write fd:req, buf:req, count:req +.ifndef BFIN_HOST + P0.H = _params; + P0.L = _params; + R0 = \fd (X); + [P0] = R0; + R0.H = \buf; + R0.L = \buf; + [P0 + 4] = R0; + R0 = \count (X); + [P0 + 8] = R0; + R0 = P0; + system_call 5 +.endif + .endm + +# MACRO: outc_str +# Output a string using the debug OUTC insn + .macro outc_str ch:req, more:vararg + OUTC \ch; + .ifnb \more + outc_str \more + .endif + .endm + +# MACRO: dbg_pass +# Write 'pass' to stdout and quit (all via debug insns); +# meant for OS operating environments + .macro dbg_pass +.ifdef BFIN_JTAG + R0 = 6; + CALL __emu_out; + R0.L = 0x6170; /* 'p'=0x70 'a'=0x70 */ + R0.H = 0x7373; /* 's'=0x73 */ + CALL __emu_out; + + R0.L = 0x0A; /* newline */ + R0.H = 0x0000; + CALL __emu_out; +1: + EMUEXCPT; + JUMP 1b; +.else + outc_str 'p', 'a', 's', 's', '\n' + HLT; +.endif + .endm + +# MACRO: dbg_fail +# Write 'fail' to stdout and quit (all via debug insns); +# meant for OS operating environments + .macro dbg_fail +.ifdef BFIN_JTAG + R0 = 6; + CALL __emu_out; + R0.L = 0x6166; /* 'f'=0x66 'a'=0x61 */ + R0.H = 0x6c69; /* 'i'=0x69 'l'=0x6c */ + CALL __emu_out; + + R0.L = 0x0A; /* newline */ + R0.H = 0x0000; + CALL __emu_out; +1: + EMUEXCPT; + JUMP 1b; +.else + outc_str 'f', 'a', 'i', 'l', '\n' +.endif + ABORT; + .endm + +# MACRO: imm32 +# Load a 32bit immediate directly into a register + .macro imm32 reg:req, val:req + .if (\val) & ~0x7fff + \reg\().L = ((\val) & 0xffff); + \reg\().H = (((\val) >> 16) & 0xffff); + .else + \reg = \val; + .endif + .endm + +# MACRO: dmm32 +# Load a 32bit immediate indirectly into a register + .macro dmm32 reg:req, val:req + [--SP] = R0; + imm32 R0, \val + \reg = R0; + R0 = [SP++]; + .endm + +# MACRO: loadsym +# Load a symbol directly into a register +.ifndef BFIN_HOST + .macro loadsym reg:req, sym:req, offset=0 + \reg\().L = (\sym\() + \offset\()); + \reg\().H = (\sym\() + \offset\()); + .endm +.else + .macro loadsym reg:req, sym:req, offset=0 + [--SP] = R0; + R0 = [P3 + \sym\()@GOT17M4]; + .if \offset + [--SP] = R1; + R1 = \offset\() (Z); + R0 = R0 + R1; + R1 = [SP++]; + .endif + \reg = R0; + R0 = [SP++]; + .endm +.endif + +# MACRO: CHECKREG +# Use debug insns to verify the value of a register matches + .macro CHECKREG reg:req, val:req + DBGAL (\reg, ((\val) & 0xffff)); + DBGAH (\reg, (((\val) >> 16) & 0xffff)); + .endm + +# internal helper macros; ignore them + .macro __init_regs reg:req, max:req, x:req, val:req + .ifle (\x - \max) + imm32 \reg\()\x, \val + .endif + .endm + .macro _init_regs reg:req, max:req, val:req + __init_regs \reg, \max, 0, \val + __init_regs \reg, \max, 1, \val + __init_regs \reg, \max, 2, \val + __init_regs \reg, \max, 3, \val + __init_regs \reg, \max, 4, \val + __init_regs \reg, \max, 5, \val + __init_regs \reg, \max, 6, \val + __init_regs \reg, \max, 7, \val + .endm + +# MACRO: init_r_regs +# MACRO: init_p_regs +# MACRO: init_b_regs +# MACRO: init_i_regs +# MACRO: init_l_regs +# MACRO: init_m_regs +# Set the specified group of regs to the specified value + .macro init_r_regs val:req + _init_regs R, 7, \val + .endm + .macro init_p_regs val:req + _init_regs P, 5, \val + .endm + .macro init_b_regs val:req + _init_regs B, 3, \val + .endm + .macro init_i_regs val:req + _init_regs I, 3, \val + .endm + .macro init_l_regs val:req + _init_regs L, 3, \val + .endm + .macro init_m_regs val:req + _init_regs M, 3, \val + .endm + + // the test framework needs things to be quiet, so don't + // print things out by default. + .macro _DBG reg:req + //DBG \reg; + .endm + + .macro _DBGCMPLX reg:req + // + .endm |