1 /* 2 * set up pointers to valid data (32Meg), to reduce address violations 3 */ 4 .macro reset_dags 5 imm32 r0, 0x2000000; 6 l0 = 0; l1 = 0; l2 = 0; l3 = 0; 7 p0 = r0; p1 = r0; p2 = r0; p3 = r0; p4 = r0; p5 = r0; 8 usp = r0; fp = r0; 9 i0 = r0; i1 = r0; i2 = r0; i3 = r0; 10 b0 = r0; b1 = r0; b2 = r0; b3 = r0; 11 .endm 12 13 #if SE_ALL_BITS == 32 14 # define LOAD_PFX 15 #elif SE_ALL_BITS == 16 16 # define LOAD_PFX W 17 #else 18 # error "Please define SE_ALL_BITS" 19 #endif 20 21 /* 22 * execute a test of an opcode space. host test 23 * has to fill out a number of callbacks. 24 * 25 * se_all_insn_init 26 * the first insn to start executing 27 * se_all_insn_table 28 * the table of insn ranges and expected seqstat 29 * 30 * se_all_load_insn 31 * in: P5 32 * out: R0, R2 33 * scratch: R1 34 * load current user insn via register P5 into R0. 35 * register R2 is available for caching with se_all_next_insn. 36 * se_all_load_table 37 * in: P1 38 * out: R7, R6, R5 39 * scratch: R1 40 * load insn range/seqstat entry from table via register P1 41 * R7: low range 42 * R6: high range 43 * R5: seqstat 44 * 45 * se_all_next_insn 46 * in: P5, R2 47 * out: <nothing> 48 * scratch: all but P5 49 * advance current insn to next one for testing. register R2 50 * is retained from se_all_load_insn. write out new insn to 51 * the location via register P5. 52 * 53 * se_all_new_insn_stub 54 * se_all_new_insn_log 55 * for handling of new insns ... generally not needed once done 56 */ 57 .macro se_all_test 58 start 59 60 /* Set up exception handler */ 61 imm32 P4, EVT3; 62 loadsym R1, _evx; 63 [P4] = R1; 64 65 /* set up the _location */ 66 loadsym P0, _location 67 loadsym P1, _table; 68 [P0] = P1; 69 70 /* Enable single stepping */ 71 R0 = 1; 72 SYSCFG = R0; 73 74 /* Lower to the code we want to single step through */ 75 loadsym P1, _usr; 76 RETI = P1; 77 78 /* set up pointers to valid data (32Meg), to reduce address violations */ 79 reset_dags 80 81 RTI; 82 83 pass_lvl: 84 dbg_pass; 85 fail_lvl: 86 dbg_fail; 87 88 _evx: 89 /* Make sure exception reason is as we expect */ 90 R3 = SEQSTAT; 91 R4 = 0x3f; 92 R3 = R3 & R4; 93 94 /* find a match */ 95 loadsym P5, _usr; 96 loadsym P4, _location; 97 P1 = [P4]; 98 se_all_load_insn 99 100 _match: 101 P2 = P1; 102 se_all_load_table 103 104 /* is this the end of the table? */ 105 R4 = 0; 106 CC = R4 == R7; 107 IF CC jump _new_instruction; 108 109 /* is the opcode (R0) greater than the 2nd entry in the table (R6) */ 110 /* if so look at the next line in the table */ 111 CC = R6 < R0; 112 if CC jump _match; 113 114 /* is the opcode (R0) smaller than the first entry in the table (R7) */ 115 /* this means it's somewhere between the two lines, and should be legal */ 116 CC = R7 <= R0; 117 if !CC jump _legal_instruction; 118 119 /* is the current EXCAUSE (R3), the same as the table (R5) */ 120 /* if not, fail */ 121 CC = R3 == R5 122 if !CC jump fail_lvl; 123 124 _match_done: 125 /* back up, and store the location to search next */ 126 [P4] = P2; 127 128 /* it matches, so fall through */ 129 jump _next_instruction; 130 131 _new_instruction: 132 se_all_new_insn_stub 133 134 /* output the insn (R0) and excause (R3) if diff from last */ 135 loadsym P0, _last_excause; 136 R2 = [P0]; 137 CC = R2 == R3; 138 IF CC jump _next_instruction; 139 [P0] = R3; 140 141 se_all_new_insn_log 142 143 _legal_instruction: 144 R4 = 0x10; 145 CC = R3 == R4; 146 IF !CC JUMP fail_lvl; 147 /* it wasn't in the list, and was a single step, so fall through */ 148 149 _next_instruction: 150 se_all_next_insn 151 152 /* Make sure the opcode isn't in a write buffer */ 153 SSYNC; 154 155 R1 = P5; 156 RETX = R1; 157 158 /* set up pointers to valid data (32Meg), to reduce address violations */ 159 reset_dags 160 RETS = r0; 161 RETN = r0; 162 RETE = r0; 163 RETI = r0; 164 165 RTX; 166 167 .section .text.usr 168 .align 4 169 _usr: 170 se_all_insn_init 171 loadsym P0, fail_lvl; 172 JUMP (P0); 173 174 .data 175 .align 4; 176 _last_excause: 177 .dd 0xffff 178 _next_location: 179 .dd _table_end 180 _location: 181 .dd 0 182 _table: 183 se_all_insn_table 184 _table_end: 185 .endm 186 187 .macro se_all_load_table 188 R7 = LOAD_PFX[P1++]; 189 R6 = LOAD_PFX[P1++]; 190 R5 = LOAD_PFX[P1++]; 191 .endm 192 193 #ifndef SE_ALL_NEW_INSN_STUB 194 .macro se_all_new_insn_stub 195 jump fail_lvl; 196 .endm 197 #endif 198 199 .macro se_all_new_insn_log 200 .ifdef BFIN_JTAG_xxxxx 201 R1 = R0; 202 #if SE_ALL_BITS == 32 203 R0 = 0x8; 204 call __emu_out; 205 R0 = R1; 206 call __emu_out; 207 R0 = R3; 208 #else 209 R0 = 0x4; 210 call __emu_out; 211 R0 = R1 << 16; 212 R0 = R0 | R3; 213 #endif 214 call __emu_out; 215 .else 216 loadsym P0, _next_location; 217 P1 = [P0]; 218 LOAD_PFX[P1++] = R0; 219 LOAD_PFX[P1++] = R3; 220 [P0] = P1; 221 .endif 222 .endm 223