1 # R0 and P0 are used as tmps, consider them call clobbered by these macros. 2 3 # To build for hardware, use: 4 # bfin-linux-uclibc-gcc -nostdlib -g -Wa,--defsym,BFIN_HOST=1 foo.s 5 6 # MACRO: start 7 # All assembler tests should start with a call to "start" 8 .macro start 9 .text 10 # Pad with EMUEXCPT to make sure "jump to 0" always fails 11 __panic: 12 .rep 0xf 13 .word 0x0025 14 .endr 15 abort; 16 jump __panic; 17 18 .global __pass 19 __pass: 20 write 1, _passmsg, 5 21 exit 0 22 .ifdef BFIN_JTAG 23 __emu_out: 24 /* DBGSTAT */ 25 imm32 P0 0xFFE05008; 26 27 1: R7 = [P0]; 28 CC = BITTST (R7,0); 29 IF CC JUMP 1b; 30 31 EMUDAT = R0; 32 RTS; 33 .endif 34 .global __fail 35 __fail: 36 .ifndef BFIN_HOST 37 P0.H = _rets; 38 P0.L = _rets; 39 R0 = RETS; 40 R0 += -4; 41 P1 = 8; 42 R2 = '9'; 43 LSETUP (1f, 3f) LC0 = P1; 44 1: 45 R1 = R0; 46 R1 >>= 28; 47 R1 += 0x30; 48 CC = R2 < R1; 49 IF !CC jump 2f; 50 R1 += 7; 51 2: 52 B[P0++] = R1; 53 3: 54 R0 <<= 4; 55 56 write 1, _failmsg, 22 57 .else 58 write 1, _failmsg, 5 59 .endif 60 exit 1 61 62 .ifndef BFIN_HOST 63 .data 64 _failmsg: 65 .ascii "fail at PC=0x" 66 _rets: 67 .ascii "12345678\n" 68 _passmsg: 69 .ascii "pass\n" 70 .align 4 71 _params: 72 .long 0 73 .long 0 74 .long 0 75 .long 0 76 77 .text 78 .global __start 79 __start: 80 .else 81 .global ___uClibc_main; 82 ___uClibc_main: 83 .global _main; 84 _main: 85 .endif 86 .endm 87 88 # MACRO: system_call 89 # Make a libgloss/Linux system call 90 .macro system_call nr:req 91 P0 = \nr (X); 92 EXCPT 0; 93 .endm 94 95 # MACRO: exit 96 # Quit the current test 97 .macro exit rc:req 98 R0 = \rc (X); 99 .ifndef BFIN_HOST 100 P0.H = _params; 101 P0.L = _params; 102 [P0] = R0; 103 R0 = P0; 104 .endif 105 system_call 1 106 .endm 107 108 # MACRO: pass 109 # Write 'pass' to stdout via syscalls and quit; 110 # meant for non-OS operating environments 111 .macro pass 112 CALL __pass; 113 .endm 114 115 # MACRO: fail 116 # Write 'fail' to stdout via syscalls and quit; 117 # meant for non-OS operating environments 118 .macro fail 119 CALL __fail; 120 .endm 121 122 # MACRO: write 123 # Just like the write() C function; uses system calls 124 .macro write fd:req, buf:req, count:req 125 .ifndef BFIN_HOST 126 P0.H = _params; 127 P0.L = _params; 128 R0 = \fd (X); 129 [P0] = R0; 130 R0.H = \buf; 131 R0.L = \buf; 132 [P0 + 4] = R0; 133 R0 = \count (X); 134 [P0 + 8] = R0; 135 R0 = P0; 136 system_call 5 137 .endif 138 .endm 139 140 # MACRO: outc_str 141 # Output a string using the debug OUTC insn 142 .macro outc_str ch:req, more:vararg 143 OUTC \ch; 144 .ifnb \more 145 outc_str \more 146 .endif 147 .endm 148 149 # MACRO: dbg_pass 150 # Write 'pass' to stdout and quit (all via debug insns); 151 # meant for OS operating environments 152 .macro dbg_pass 153 .ifdef BFIN_JTAG 154 R0 = 6; 155 CALL __emu_out; 156 R0.L = 0x6170; /* 'p'=0x70 'a'=0x70 */ 157 R0.H = 0x7373; /* 's'=0x73 */ 158 CALL __emu_out; 159 160 R0.L = 0x0A; /* newline */ 161 R0.H = 0x0000; 162 CALL __emu_out; 163 1: 164 EMUEXCPT; 165 JUMP 1b; 166 .else 167 outc_str 'p', 'a', 's', 's', '\n' 168 HLT; 169 .endif 170 .endm 171 172 # MACRO: dbg_fail 173 # Write 'fail' to stdout and quit (all via debug insns); 174 # meant for OS operating environments 175 .macro dbg_fail 176 .ifdef BFIN_JTAG 177 R0 = 6; 178 CALL __emu_out; 179 R0.L = 0x6166; /* 'f'=0x66 'a'=0x61 */ 180 R0.H = 0x6c69; /* 'i'=0x69 'l'=0x6c */ 181 CALL __emu_out; 182 183 R0.L = 0x0A; /* newline */ 184 R0.H = 0x0000; 185 CALL __emu_out; 186 1: 187 EMUEXCPT; 188 JUMP 1b; 189 .else 190 outc_str 'f', 'a', 'i', 'l', '\n' 191 .endif 192 ABORT; 193 .endm 194 195 # MACRO: imm32 196 # Load a 32bit immediate directly into a register 197 .macro imm32 reg:req, val:req 198 .if (\val) & ~0x7fff 199 \reg\().L = ((\val) & 0xffff); 200 \reg\().H = (((\val) >> 16) & 0xffff); 201 .else 202 \reg = \val; 203 .endif 204 .endm 205 206 # MACRO: dmm32 207 # Load a 32bit immediate indirectly into a register 208 .macro dmm32 reg:req, val:req 209 [--SP] = R0; 210 imm32 R0, \val 211 \reg = R0; 212 R0 = [SP++]; 213 .endm 214 215 # MACRO: loadsym 216 # Load a symbol directly into a register 217 .ifndef BFIN_HOST 218 .macro loadsym reg:req, sym:req, offset=0 219 \reg\().L = (\sym\() + \offset\()); 220 \reg\().H = (\sym\() + \offset\()); 221 .endm 222 .else 223 .macro loadsym reg:req, sym:req, offset=0 224 [--SP] = R0; 225 R0 = [P3 + \sym\()@GOT17M4]; 226 .if \offset 227 [--SP] = R1; 228 R1 = \offset\() (Z); 229 R0 = R0 + R1; 230 R1 = [SP++]; 231 .endif 232 \reg = R0; 233 R0 = [SP++]; 234 .endm 235 .endif 236 237 # MACRO: CHECKREG 238 # Use debug insns to verify the value of a register matches 239 .macro CHECKREG reg:req, val:req 240 DBGAL (\reg, ((\val) & 0xffff)); 241 DBGAH (\reg, (((\val) >> 16) & 0xffff)); 242 .endm 243 244 # internal helper macros; ignore them 245 .macro __init_regs reg:req, max:req, x:req, val:req 246 .ifle (\x - \max) 247 imm32 \reg\()\x, \val 248 .endif 249 .endm 250 .macro _init_regs reg:req, max:req, val:req 251 __init_regs \reg, \max, 0, \val 252 __init_regs \reg, \max, 1, \val 253 __init_regs \reg, \max, 2, \val 254 __init_regs \reg, \max, 3, \val 255 __init_regs \reg, \max, 4, \val 256 __init_regs \reg, \max, 5, \val 257 __init_regs \reg, \max, 6, \val 258 __init_regs \reg, \max, 7, \val 259 .endm 260 261 # MACRO: init_r_regs 262 # MACRO: init_p_regs 263 # MACRO: init_b_regs 264 # MACRO: init_i_regs 265 # MACRO: init_l_regs 266 # MACRO: init_m_regs 267 # Set the specified group of regs to the specified value 268 .macro init_r_regs val:req 269 _init_regs R, 7, \val 270 .endm 271 .macro init_p_regs val:req 272 _init_regs P, 5, \val 273 .endm 274 .macro init_b_regs val:req 275 _init_regs B, 3, \val 276 .endm 277 .macro init_i_regs val:req 278 _init_regs I, 3, \val 279 .endm 280 .macro init_l_regs val:req 281 _init_regs L, 3, \val 282 .endm 283 .macro init_m_regs val:req 284 _init_regs M, 3, \val 285 .endm 286 287 // the test framework needs things to be quiet, so don't 288 // print things out by default. 289 .macro _DBG reg:req 290 //DBG \reg; 291 .endm 292 293 .macro _DBGCMPLX reg:req 294 // 295 .endm 296