]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/testsuite/sim/bfin/se_allopcodes.h
sim: bfin: speed up all insn testcases slightly
[thirdparty/binutils-gdb.git] / sim / testsuite / sim / bfin / se_allopcodes.h
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 CC = R7 == 0;
106 IF CC jump _new_instruction;
107
108 /* is the opcode (R0) greater than the 2nd entry in the table (R6) */
109 /* if so look at the next line in the table */
110 CC = R6 < R0;
111 if CC jump _match;
112
113 /* is the opcode (R0) smaller than the first entry in the table (R7) */
114 /* this means it's somewhere between the two lines, and should be legal */
115 CC = R7 <= R0;
116 if !CC jump _legal_instruction;
117
118 /* is the current EXCAUSE (R3), the same as the table (R5) */
119 /* if not, fail */
120 CC = R3 == R5
121 if !CC jump fail_lvl;
122
123 _match_done:
124 /* back up, and store the location to search next */
125 [P4] = P2;
126
127 /* it matches, so fall through */
128 jump _next_instruction;
129
130 _new_instruction:
131 /* The table is generated in memory and can be extracted:
132 (gdb) dump binary memory bin &table next_location
133
134 16bit:
135 $ od -j6 -x --width=4 bin | \
136 awk '{ s=last; e=strtonum("0x"$2); \
137 printf "\t.dw 0x%04x,\t0x%04x,\t\t0x%02x\n", \
138 s, e-1, strtonum("0x"seq); \
139 last=e; seq=$3}'
140
141 32bit:
142 $ od -j12 -x --width=8 bin | \
143 awk '{ s=last; e=strtonum("0x"$3$2); \
144 printf "\t.dw 0x%04x, 0x%04x,\t0x%04x, 0x%04x,\t\t0x%02x, 0\n", \
145 and(s,0xffff), rshift(s,16), and(e-1,0xffff), rshift(e-1,16), \
146 strtonum("0x"seq); \
147 last=e; seq=$3}'
148
149 This should be much faster than dumping over serial/jtag. */
150 se_all_new_insn_stub
151
152 /* output the insn (R0) and excause (R3) if diff from last */
153 loadsym P0, _last_excause;
154 R2 = [P0];
155 CC = R2 == R3;
156 IF CC jump _next_instruction;
157 [P0] = R3;
158
159 se_all_new_insn_log
160
161 _legal_instruction:
162 R4 = 0x10;
163 CC = R3 == R4;
164 IF !CC JUMP fail_lvl;
165 /* it wasn't in the list, and was a single step, so fall through */
166
167 _next_instruction:
168 se_all_next_insn
169
170 .ifdef BFIN_JTAG
171 /* Make sure the opcode isn't in a write buffer */
172 SSYNC;
173 .endif
174
175 R1 = P5;
176 RETX = R1;
177
178 /* set up pointers to valid data (32Meg), to reduce address violations */
179 reset_dags
180 RETS = r0;
181
182 RTX;
183
184 .section .text.usr
185 .align 4
186 _usr:
187 se_all_insn_init
188 loadsym P0, fail_lvl;
189 JUMP (P0);
190
191 .data
192 .align 4;
193 _last_excause:
194 .dd 0xffff
195 _next_location:
196 .dd _table_end
197 _location:
198 .dd 0
199 _table:
200 se_all_insn_table
201 _table_end:
202 .endm
203
204 .macro se_all_load_table
205 R7 = LOAD_PFX[P1++];
206 R6 = LOAD_PFX[P1++];
207 R5 = LOAD_PFX[P1++];
208 .endm
209
210 #ifndef SE_ALL_NEW_INSN_STUB
211 .macro se_all_new_insn_stub
212 jump fail_lvl;
213 .endm
214 #endif
215
216 .macro se_all_new_insn_log
217 .ifdef BFIN_JTAG_xxxxx
218 R1 = R0;
219 #if SE_ALL_BITS == 32
220 R0 = 0x8;
221 call __emu_out;
222 R0 = R1;
223 call __emu_out;
224 R0 = R3;
225 #else
226 R0 = 0x4;
227 call __emu_out;
228 R0 = R1 << 16;
229 R0 = R0 | R3;
230 #endif
231 call __emu_out;
232 .else
233 loadsym P0, _next_location;
234 P1 = [P0];
235 LOAD_PFX[P1++] = R0;
236 LOAD_PFX[P1++] = R3;
237 [P0] = P1;
238 .endif
239 .endm