OLD | NEW |
(Empty) | |
| 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 |
OLD | NEW |