7ff8d2b9fa0b55d1e6877236de8b06314128386e
[external/binutils.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         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