Commit | Line | Data |
---|---|---|
cce4814f NC |
1 | #ifndef TEST_GEN_C |
2 | #define TEST_GEN_C 1 | |
3 | ||
4 | /* Copyright (C) 2000, 2003 Free Software Foundation | |
5 | Contributed by Alexandre Oliva <aoliva@cygnus.com> | |
6 | ||
7 | This file is free software; you can redistribute it and/or modify it | |
8 | under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 2 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, but | |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program; if not, write to the Free Software | |
4b4da160 | 19 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ |
cce4814f NC |
20 | |
21 | /* This is a source file with infra-structure to test generators for | |
22 | assemblers and disassemblers. | |
23 | ||
24 | The strategy to generate testcases is as follows. We'll output to | |
25 | two streams: one will get the assembly source, and the other will | |
26 | get regexps that match the expected binary patterns. | |
27 | ||
28 | To generate each instruction, the functions of a func[] are called, | |
29 | each with the corresponding func_arg. Each function should set | |
30 | members of insn_data, to decide what it's going to output to the | |
31 | assembly source, the corresponding output for the disassembler | |
32 | tester, and the bits to be set in the instruction word. The | |
33 | strings to be output must have been allocated with strdup() or | |
34 | malloc(), so that they can be freed. A function may also modify | |
35 | insn_size. More details in test-gen.c | |
36 | ||
37 | Because this would have generated too many tests, we have chosen to | |
38 | define ``random'' sequences of numbers/registers, and simply | |
39 | generate each instruction a couple of times, which should get us | |
40 | enough coverage. | |
41 | ||
42 | In general, test generators should be compiled/run as follows: | |
43 | ||
44 | % gcc test.c -o test | |
45 | % ./test > test.s 2 > test.d | |
46 | ||
47 | Please note that this file contains a couple of GCC-isms, such as | |
48 | macro varargs (also available in C99, but with a difference syntax) | |
49 | and labeled elements in initializers (so that insn definitions are | |
50 | simpler and safer). | |
51 | ||
52 | It is assumed that the test generator #includes this file after | |
53 | defining any of the preprocessor macros documented below. The test | |
54 | generator is supposed to define instructions, at least one group of | |
55 | instructions, optionally, a sequence of groups. | |
56 | ||
57 | It should also define a main() function that outputs the initial | |
58 | lines of the assembler input and of the test control file, that | |
59 | also contains the disassembler output. The main() funcion may | |
60 | optionally set skip_list too, before calling output_groups() or | |
61 | output_insns(). */ | |
62 | ||
63 | /* Define to 1 to avoid repeating instructions and to use a simpler | |
64 | register/constant generation mechanism. This makes it much easier | |
65 | to verify that the generated bit patterns are correct. */ | |
66 | #ifndef SIMPLIFY_OUTPUT | |
67 | #define SIMPLIFY_OUTPUT 0 | |
68 | #endif | |
69 | ||
70 | /* Define to 0 to avoid generating disassembler tests. */ | |
71 | #ifndef DISASSEMBLER_TEST | |
72 | #define DISASSEMBLER_TEST 1 | |
73 | #endif | |
74 | ||
75 | /* Define to the number of times to repeat the generation of each | |
76 | insn. It's best to use prime numbers, to improve randomization. */ | |
77 | #ifndef INSN_REPEAT | |
78 | #define INSN_REPEAT 5 | |
79 | #endif | |
80 | ||
81 | /* Define in order to get randomization_counter printed, as a comment, | |
82 | in the disassembler output, after each insn is emitted. */ | |
83 | #ifndef OUTPUT_RANDOMIZATION_COUNTER | |
84 | #define OUTPUT_RANDOMIZATION_COUNTER 0 | |
85 | #endif | |
86 | ||
87 | /* Other configuration macros are DEFINED_WORD and DEFINED_FUNC_ARG, | |
88 | see below. */ | |
89 | ||
90 | #include <stdio.h> | |
91 | #include <string.h> | |
92 | #include <stdlib.h> | |
93 | ||
94 | /* It is expected that the main program defines the type `word' before | |
95 | includeing this. */ | |
96 | #ifndef DEFINED_WORD | |
97 | typedef unsigned long long word; | |
98 | #endif | |
99 | ||
100 | /* This struct is used as the output area for each function. It | |
101 | should store in as_in a pointer to the string to be output to the | |
102 | assembler; in dis_out, the string to be expected in return from the | |
103 | disassembler, and in bits the bits of the instruction word that are | |
104 | enabled by the assembly fragment. */ | |
105 | typedef struct | |
106 | { | |
107 | char * as_in; | |
108 | char * dis_out; | |
109 | word bits; | |
110 | } insn_data; | |
111 | ||
112 | #ifndef DEFINED_FUNC_ARG | |
113 | /* This is the struct that feeds information to each function. You're | |
114 | free to extend it, by `typedef'ing it before including this file, | |
115 | and defining DEFINED_FUNC_ARG. You may even reorder the fields, | |
116 | but do not remove any of the existing fields. */ | |
117 | typedef struct | |
118 | { | |
119 | int i1; | |
120 | int i2; | |
121 | int i3; | |
122 | void * p1; | |
123 | void * p2; | |
124 | word w; | |
125 | } func_arg; | |
126 | #endif | |
127 | ||
128 | /* This is the struct whose arrays define insns. Each func in the | |
129 | array will be called, in sequence, being given a pointer to the | |
130 | associated arg and a pointer to a zero-initialized output area, | |
131 | that it may fill in. */ | |
132 | typedef struct | |
133 | { | |
134 | int (* func) (func_arg *, insn_data *); | |
135 | func_arg arg; | |
136 | } func; | |
137 | ||
138 | /* Use this to group insns under a name. */ | |
139 | typedef struct | |
140 | { | |
141 | const char * name; | |
142 | func ** insns; | |
143 | } group_t; | |
144 | ||
145 | /* This is the size of each instruction. Use `insn_size_bits' instead | |
146 | of `insn_bits' in an insn defition to modify it. */ | |
147 | int insn_size = 4; | |
148 | ||
149 | /* The offset of the next insn, as expected in the disassembler | |
150 | output. */ | |
151 | int current_offset = 0; | |
152 | ||
153 | /* The offset and name of the last label to be emitted. */ | |
154 | int last_label_offset = 0; | |
155 | const char * last_label_name = 0; | |
156 | ||
157 | /* This variable may be initialized in main() to `argv+1', if | |
158 | `argc>1', so that tests are emitted only for instructions that | |
159 | match exactly one of the given command-line arguments. If it is | |
160 | NULL, tests for all instructions are emitted. It must be a | |
161 | NULL-terminated array of pointers to strings (just like | |
162 | `argv+1'). */ | |
163 | char ** skip_list = 0; | |
164 | ||
165 | /* This is a counter used to walk the various arrays of ``random'' | |
166 | operand generation. In simplified output mode, it is zeroed after | |
167 | each insn, otherwise it just keeps growing. */ | |
168 | unsigned randomization_counter = 0; | |
169 | ||
170 | /* Use `define_insn' to create an array of funcs to define an insn, | |
171 | then `insn' to refer to that insn when defining an insn group. */ | |
172 | #define define_insn(insname, funcs...) \ | |
173 | func i_ ## insname[] = { funcs, { 0 } } | |
174 | #define insn(insname) (i_ ## insname) | |
175 | ||
176 | /* Use these to output a comma followed by an optional space, a single | |
177 | space, a plus sign, left and right square brackets and parentheses, | |
178 | all of them properly quoted. */ | |
179 | #define comma literal_q (", ", ", ?") | |
180 | #define space literal (" ") | |
181 | #define tab literal ("\t") | |
182 | #define plus literal_q ("+", "\\+") | |
183 | #define lsqbkt literal_q ("[", "\\[") | |
184 | #define rsqbkt literal_q ("]", "\\]") | |
185 | #define lparen literal_q ("(", "\\(") | |
186 | #define rparen literal_q (")", "\\)") | |
187 | ||
188 | /* Use this as a placeholder when you define a macro that expects an | |
189 | argument, but you don't have anything to output there. */ | |
190 | int | |
191 | nothing (func_arg *arg, insn_data *data) | |
192 | #define nothing { nothing } | |
193 | { | |
194 | return 0; | |
195 | } | |
196 | ||
197 | /* This is to be used in the argument list of define_insn, causing a | |
198 | string to be copied into both the assembly and the expected | |
199 | disassembler output. It is assumed not to modify the binary | |
200 | encoding of the insn. */ | |
201 | int | |
202 | literal (func_arg *arg, insn_data *data) | |
203 | #define literal(s) { literal, { p1: (s) } } | |
204 | { | |
205 | data->as_in = data->dis_out = strdup ((char *) arg->p1); | |
206 | return 0; | |
207 | } | |
208 | ||
209 | /* The characters `[', `]', `\\' and `^' must be quoted in the | |
210 | disassembler-output matcher. If a literal string contains any of | |
211 | these characters, use literal_q instead of literal, and specify the | |
212 | unquoted version (for as input) as the first argument, and the | |
213 | quoted version (for expected disassembler output) as the second | |
214 | one. */ | |
215 | int | |
216 | literal_q (func_arg *arg, insn_data *data) | |
217 | #define literal_q(s,q) { literal_q, { p1: (s), p2: (q) } } | |
218 | { | |
219 | data->as_in = strdup ((char *) arg->p1); | |
220 | data->dis_out = strdup ((char *) arg->p2); | |
221 | return 0; | |
222 | } | |
223 | ||
224 | /* Given an insn name, check whether it should be skipped or not, | |
225 | depending on skip_list. Return non-zero if the insn is to be | |
226 | skipped. */ | |
227 | int | |
228 | skip_insn (char *name) | |
229 | { | |
230 | char **test; | |
231 | ||
232 | if (! skip_list) | |
233 | return 0; | |
234 | ||
235 | for (test = skip_list; * test; ++ test) | |
236 | if (strcmp (name, * test) == 0) | |
237 | return 0; | |
238 | ||
239 | return 1; | |
240 | } | |
241 | ||
242 | /* Use this to emit the actual insn name, with its opcode, in | |
243 | architectures with fixed-length instructions. */ | |
244 | int | |
245 | insn_bits (func_arg *arg, insn_data *data) | |
246 | #define insn_bits(name,bits) \ | |
247 | { insn_bits, { p1: # name, w: bits } } | |
248 | { | |
249 | if (skip_insn ((char *) arg->p1)) | |
250 | return 1; | |
251 | data->as_in = data->dis_out = strdup ((char *) arg->p1); | |
252 | data->bits = arg->w; | |
253 | return 0; | |
254 | } | |
255 | ||
256 | /* Use this to emit the insn name and its opcode in architectures | |
257 | without a variable instruction length. */ | |
258 | int | |
259 | insn_size_bits (func_arg *arg, insn_data *data) | |
260 | #define insn_size_bits(name,size,bits) \ | |
261 | { insn_size_bits, { p1: # name, i1: size, w: bits } } | |
262 | { | |
263 | if (skip_insn ((char *) arg->p1)) | |
264 | return 1; | |
265 | data->as_in = data->dis_out = strdup ((char *) arg->p1); | |
266 | data->bits = arg->w; | |
267 | insn_size = arg->i1; | |
268 | return 0; | |
269 | } | |
270 | ||
271 | /* Use this to advance the random generator by one, in case it is | |
272 | generating repetitive patterns. It is usually good to arrange that | |
273 | each insn consumes a prime number of ``random'' numbers, or, at | |
274 | least, that it does not consume an exact power of two ``random'' | |
275 | numbers. */ | |
276 | int | |
277 | tick_random (func_arg *arg, insn_data *data) | |
278 | #define tick_random { tick_random } | |
279 | { | |
280 | ++ randomization_counter; | |
281 | return 0; | |
282 | } | |
283 | ||
284 | /* Select the next ``random'' number from the array V of size S, and | |
285 | advance the counter. */ | |
286 | #define get_bits_from_size(V,S) \ | |
287 | ((V)[randomization_counter ++ % (S)]) | |
288 | ||
289 | /* Utility macros. `_get_bits_var', used in some macros below, assume | |
290 | the names of the arrays used to define the ``random'' orders start | |
291 | with `random_order_'. */ | |
292 | #define _get_bits_var(N) (random_order_ ## N) | |
293 | #define _get_bits_size(V) (sizeof (V) / sizeof * (V)) | |
294 | ||
295 | /* Use this within a `func_arg' to select one of the arrays below (or | |
296 | any other array that starts with random_order_N. */ | |
297 | #define mk_get_bits(N) \ | |
298 | p2: _get_bits_var (N), i3: _get_bits_size (_get_bits_var (N)) | |
299 | ||
300 | /* Simplified versions of get_bits_from_size for when you have access | |
301 | to the array, so that its size can be implicitly calculated. */ | |
302 | #define get_bits_from(V) get_bits_from_size ((V),_get_bits_size ((V))) | |
303 | #define get_bits(N) get_bits_from (_get_bits_var (N)) | |
304 | ||
305 | ||
306 | /* Use `2u' to generate 2-bit unsigned values. Good for selecting | |
307 | registers randomly from a set of 4 registers. */ | |
308 | unsigned random_order_2u[] = | |
309 | { | |
310 | /* This sequence was generated by hand so that no digit appers more | |
311 | than once in any horizontal or vertical line. */ | |
312 | 0, 1, 3, 2, | |
313 | 2, 0, 1, 3, | |
314 | 1, 3, 2, 0, | |
315 | 3, 2, 0, 1 | |
316 | }; | |
317 | ||
318 | /* Use `3u' to generate 3-bit unsigned values. Good for selecting | |
319 | registers randomly from a set of 8 registers. */ | |
320 | unsigned random_order_3u[] = | |
321 | { | |
322 | /* This sequence was generated by: | |
323 | f(k) = 3k mod 8 | |
324 | except that the middle pairs were swapped. */ | |
325 | 0, 6, 3, 1, 4, 2, 7, 5, | |
326 | /* This sequence was generated by: | |
327 | f(k) = 5k mod 8 | |
328 | except that the middle pairs were swapped. */ | |
329 | 0, 2, 5, 7, 4, 6, 1, 3, | |
330 | }; | |
331 | ||
332 | /* Use `4u' to generate 4-bit unsigned values. Good for selecting | |
333 | registers randomly from a set of 16 registers. */ | |
334 | unsigned random_order_4u[] = | |
335 | { | |
336 | /* This sequence was generated by: | |
337 | f(k) = 5k mod 16 | |
338 | except that the middle pairs were swapped. */ | |
339 | 0, 5, 15, 10, 9, 4, 14, 3, | |
340 | 8, 13, 7, 2, 1, 12, 6, 11, | |
341 | /* This sequence was generated by: | |
342 | f(k) = 7k mod 16 | |
343 | except that the middle pairs were swapped. */ | |
344 | 0, 7, 5, 14, 3, 12, 10, 1, | |
345 | 8, 15, 13, 6, 11, 4, 2, 9, | |
346 | }; | |
347 | ||
348 | /* Use `5u' to generate 5-bit unsigned values. Good for selecting | |
349 | registers randomly from a set of 32 registers. */ | |
350 | unsigned random_order_5u[] = | |
351 | { | |
352 | /* This sequence was generated by: | |
353 | f(k) = (13k) mod 32 | |
354 | except that the middle pairs were swapped. */ | |
355 | 0, 26, 13, 7, 20, 14, 1, 27, | |
356 | 8, 2, 21, 15, 28, 22, 9, 3, | |
357 | 16, 10, 29, 23, 4, 30, 17, 11, | |
358 | 24, 18, 5, 31, 12, 6, 25, 19 | |
359 | }; | |
360 | ||
361 | /* Use `7s' to generate 7-bit signed values. Good for selecting | |
362 | ``interesting'' constants from -64 to +63. */ | |
363 | int random_order_7s[] = | |
364 | { | |
365 | /* Sequence generated by hand, to explore limit values and a few | |
366 | intermediate values selected by chance. Keep the number of | |
367 | intermediate values low, to ensure that the limit values are | |
368 | generated often enough. */ | |
369 | 0, -1, -64, 63, -32, 32, 24, -20, | |
370 | 9, -27, -31, 33, 40, -2, -5, 1 | |
371 | }; | |
372 | ||
373 | /* Use `8s' to generate 8-bit signed values. Good for selecting | |
374 | ``interesting'' constants from -128 to +127. */ | |
375 | int random_order_8s[] = | |
376 | { | |
377 | /* Sequence generated by hand, to explore limit values and a few | |
378 | intermediate values selected by chance. Keep the number of | |
379 | intermediate values low, to ensure that the limit values are | |
380 | generated often enough. */ | |
381 | 0, -1, -128, 127, -32, 32, 24, -20, | |
382 | 73, -27, -95, 33, 104, -2, -69, 1 | |
383 | }; | |
384 | ||
385 | /* Use `9s' to generate 9-bit signed values. Good for selecting | |
386 | ``interesting'' constants from -256 to +255. */ | |
387 | int random_order_9s[] = | |
388 | { | |
389 | /* Sequence generated by hand, to explore limit values and a few | |
390 | intermediate values selected by chance. Keep the number of | |
391 | intermediate values low, to ensure that the limit values are | |
392 | generated often enough. */ | |
393 | 0, -1, -256, 255, -64, 64, 72, -40, | |
394 | 73, -137, -158, 37, 104, -240, -69, 1 | |
395 | }; | |
396 | ||
397 | /* Use `16s' to generate 16-bit signed values. Good for selecting | |
398 | ``interesting'' constants from -32768 to +32767. */ | |
399 | int random_order_16s[] = | |
400 | { | |
401 | /* Sequence generated by hand, to explore limit values and a few | |
402 | intermediate values selected by chance. Keep the number of | |
403 | intermediate values low, to ensure that the limit values are | |
404 | generated often enough. */ | |
405 | -32768, | |
406 | 32767, | |
407 | (-1 << 15) | (64 << 8) | 32, | |
408 | (64 << 8) | 32, | |
409 | 0x1234, | |
410 | (-1 << 15) | 0x8765, | |
411 | 0x0180, | |
412 | (-1 << 15) | 0x8001 | |
413 | }; | |
414 | ||
415 | /* Use `24s' to generate 24-bit signed values. Good for selecting | |
416 | ``interesting'' constants from -2^23 to 2^23-1. */ | |
417 | int random_order_24s[] = | |
418 | { | |
419 | /* Sequence generated by hand, to explore limit values and a few | |
420 | intermediate values selected by chance. Keep the number of | |
421 | intermediate values low, to ensure that the limit values are | |
422 | generated often enough. */ | |
423 | -1 << 23, | |
424 | 1 << 23 -1, | |
425 | (-1 << 23) | (((64 << 8) | 32) << 8) | 16, | |
426 | (((64 << 8) | 32) << 8) | 16, | |
427 | 0x123456, | |
428 | (-1 << 23) | 0x876543, | |
429 | 0x01ff80, | |
430 | (-1 << 23) | 0x80ff01 | |
431 | }; | |
432 | ||
433 | /* Use `32s' to generate 32-bit signed values. Good for selecting | |
434 | ``interesting'' constants from -2^31 to 2^31-1. */ | |
435 | int random_order_32s[] = | |
436 | { | |
437 | /* Sequence generated by hand, to explore limit values and a few | |
438 | intermediate values selected by chance. Keep the number of | |
439 | intermediate values low, to ensure that the limit values are | |
440 | generated often enough. */ | |
441 | -1 << 31, | |
442 | 1 << 31 - 1, | |
443 | (-1 << 31) | (((((64 << 8) | 32) << 8) | 16) << 8) | 8, | |
444 | (((((64 << 8) | 32) << 8) | 16) << 8) | 8, | |
445 | 0x12345678, | |
446 | (-1 << 31) | 0x87654321, | |
447 | 0x01ffff80, | |
448 | (-1 << 31) | 0x80ffff01 | |
449 | }; | |
450 | ||
451 | /* This function computes the number of digits needed to represent a | |
452 | given number. */ | |
453 | unsigned long | |
454 | ulen (unsigned long i, unsigned base) | |
455 | { | |
456 | int count = 0; | |
457 | ||
458 | if (i == 0) | |
459 | return 1; | |
460 | for (; i > 0; ++ count) | |
461 | i /= base; | |
462 | return count; | |
463 | } | |
464 | ||
465 | /* Use this to generate a signed constant of the given size, shifted | |
466 | by the given amount, with the specified endianness. */ | |
467 | int | |
468 | signed_constant (func_arg * arg, insn_data * data) | |
469 | #define signed_constant(bits, shift, revert) \ | |
470 | { signed_constant, { i1: shift, i2: bits * (revert ? -1 : 1), \ | |
471 | mk_get_bits (bits ## s) } } | |
472 | { | |
473 | long val = get_bits_from_size ((unsigned *) arg->p2, arg->i3); | |
474 | int len = (val >= 0 ? ulen (val, 10) : (1 + ulen (-val, 10))); | |
475 | int nbits = (arg->i2 >= 0 ? arg->i2 : -arg->i2); | |
476 | word bits = ((word) val) & (((((word) 1) << (nbits - 1)) << 1) - 1); | |
477 | ||
478 | data->as_in = data->dis_out = malloc (len + 1); | |
479 | sprintf (data->as_in, "%ld", val); | |
480 | if (arg->i2 < 0) | |
481 | { | |
482 | word rbits = 0; | |
483 | ||
484 | do | |
485 | { | |
486 | rbits <<= 8; | |
487 | rbits |= bits & 0xff; | |
488 | bits >>= 8; | |
489 | nbits -= 8; | |
490 | } | |
491 | while (nbits > 0); | |
492 | ||
493 | bits = rbits; | |
494 | } | |
495 | data->bits = bits << arg->i1; | |
496 | ||
497 | return 0; | |
498 | } | |
499 | ||
500 | /* Use this to generate a unsigned constant of the given size, shifted | |
501 | by the given amount, with the specified endianness. */ | |
502 | int | |
503 | unsigned_constant (func_arg * arg, insn_data * data) | |
504 | #define unsigned_constant(bits, shift, revert) \ | |
505 | { unsigned_constant, { i1: shift, i2: bits * (revert ? -1 : 1), \ | |
506 | mk_get_bits (bits ## s) } } | |
507 | { | |
508 | int nbits = (arg->i2 >= 0 ? arg->i2 : -arg->i2); | |
509 | unsigned long val = | |
510 | get_bits_from_size ((unsigned *) arg->p2, arg->i3) | |
511 | & (((((word) 1) << (nbits - 1)) << 1) - 1); | |
512 | int len = ulen (val, 10); | |
513 | word bits = val; | |
514 | ||
515 | data->as_in = data->dis_out = malloc (len + 1); | |
516 | sprintf (data->as_in, "%lu", val); | |
517 | if (arg->i2 < 0) | |
518 | { | |
519 | word rbits = 0; | |
520 | ||
521 | do | |
522 | { | |
523 | rbits <<= 8; | |
524 | rbits |= bits & 0xff; | |
525 | bits >>= 8; | |
526 | nbits -= 8; | |
527 | } | |
528 | while (nbits > 0); | |
529 | ||
530 | bits = rbits; | |
531 | } | |
532 | data->bits = bits << arg->i1; | |
533 | ||
534 | return 0; | |
535 | } | |
536 | ||
537 | /* Use this to generate an absolute address of the given size, shifted | |
538 | by the given amount, with the specified endianness. */ | |
539 | int | |
540 | absolute_address (func_arg *arg, insn_data *data) | |
541 | #define absolute_address (bits, shift, revert) \ | |
542 | { absolute_address, { i1: shift, i2: bits * (revert ? -1 : 1), \ | |
543 | mk_get_bits (bits ## s) } } | |
544 | { | |
545 | int nbits = (arg->i2 >= 0 ? arg->i2 : -arg->i2); | |
546 | unsigned long val = | |
547 | get_bits_from_size ((unsigned *) arg->p2, arg->i3) | |
548 | & (((((word) 1) << (nbits - 1)) << 1) - 1); | |
549 | word bits = val; | |
550 | ||
551 | data->as_in = malloc (ulen (val, 10) + 1); | |
552 | sprintf (data->as_in, "%lu", val); | |
553 | data->dis_out = malloc (nbits / 4 + 11); | |
554 | sprintf (data->dis_out, "0*%0*lx <[^>]*>", nbits / 4, val); | |
555 | if (arg->i2 < 0) | |
556 | { | |
557 | word rbits = 0; | |
558 | ||
559 | do | |
560 | { | |
561 | rbits <<= 8; | |
562 | rbits |= bits & 0xff; | |
563 | bits >>= 8; | |
564 | nbits -= 8; | |
565 | } | |
566 | while (nbits > 0); | |
567 | ||
568 | bits = rbits; | |
569 | } | |
570 | data->bits = bits << arg->i1; | |
571 | ||
572 | return 0; | |
573 | } | |
574 | ||
575 | /* Use this to generate a register name that starts with a given | |
576 | prefix, and is followed by a number generated by `gen' (see | |
577 | mk_get_bits below). The register number is shifted `shift' bits | |
578 | left before being stored in the binary insn. */ | |
579 | int | |
580 | reg_p (func_arg *arg, insn_data *data) | |
581 | #define reg_p(prefix,shift,gen) \ | |
582 | { reg_p, { i1: (shift), p1: (prefix), gen } } | |
583 | { | |
584 | unsigned reg = get_bits_from_size ((unsigned *) arg->p2, arg->i3); | |
585 | char *regname = (char *) arg->p1; | |
586 | ||
587 | data->as_in = data->dis_out = malloc (strlen (regname) + ulen (reg, 10) + 1); | |
588 | sprintf (data->as_in, "%s%u", regname, reg); | |
589 | data->bits = reg; | |
590 | data->bits <<= arg->i1; | |
591 | return 0; | |
592 | } | |
593 | ||
594 | /* Use this to generate a register name taken from an array. The | |
595 | index into the array `names' is to be produced by `gen', but `mask' | |
596 | may be used to filter out some of the bits before choosing the | |
597 | disassembler output and the bits for the binary insn, shifted left | |
598 | by `shift'. For example, if registers have canonical names, but | |
599 | can also be referred to by aliases, the array can be n times larger | |
600 | than the actual number of registers, and the mask is then used to | |
601 | pick the canonical name for the disassembler output, and to | |
602 | eliminate the extra bits from the binary output. */ | |
603 | int | |
604 | reg_r (func_arg *arg, insn_data *data) | |
605 | #define reg_r(names,shift,mask,gen) \ | |
606 | { reg_r, { i1: (shift), i2: (mask), p1: (names), gen } } | |
607 | { | |
608 | unsigned reg = get_bits_from_size ((unsigned *) arg->p2, arg->i3); | |
609 | ||
610 | data->as_in = strdup (((const char **) arg->p1)[reg]); | |
611 | reg &= arg->i2; | |
612 | data->dis_out = strdup (((const char **) arg->p1)[reg]); | |
613 | data->bits = reg; | |
614 | data->bits <<= arg->i1; | |
615 | return 0; | |
616 | } | |
617 | ||
618 | /* Given a NULL-terminated array of insns-definitions (pointers to | |
619 | arrays of funcs), output test code for the insns to as_in (assembly | |
620 | input) and dis_out (expected disassembler output). */ | |
621 | void | |
622 | output_insns (func **insn, FILE *as_in, FILE *dis_out) | |
623 | { | |
624 | for (; *insn; ++insn) | |
625 | { | |
626 | insn_data *data; | |
627 | func *parts = *insn; | |
628 | int part_count = 0, r; | |
629 | ||
630 | /* Figure out how many funcs have to be called. */ | |
631 | while (parts[part_count].func) | |
632 | ++part_count; | |
633 | ||
634 | /* Allocate storage for the output area of each func. */ | |
635 | data = (insn_data*) malloc (part_count * sizeof (insn_data)); | |
636 | ||
637 | #if SIMPLIFY_OUTPUT | |
638 | randomization_counter = 0; | |
639 | #else | |
640 | /* Repeat each insn several times. */ | |
641 | for (r = 0; r < INSN_REPEAT; ++r) | |
642 | #endif | |
643 | { | |
644 | unsigned saved_rc = randomization_counter; | |
645 | int part; | |
646 | word bits = 0; | |
647 | ||
648 | for (part = 0; part < part_count; ++part) | |
649 | { | |
650 | /* Zero-initialize the storage. */ | |
651 | data[part].as_in = data[part].dis_out = 0; | |
652 | data[part].bits = 0; | |
653 | /* If a func returns non-zero, skip this line. */ | |
654 | if (parts[part].func (&parts[part].arg, &data[part])) | |
655 | goto skip; | |
656 | /* Otherwise, get its output bit pattern into the total | |
657 | bit pattern. */ | |
658 | bits |= data[part].bits; | |
659 | } | |
660 | ||
661 | if (as_in) | |
662 | { | |
663 | /* Output the whole assembly line. */ | |
664 | fputc ('\t', as_in); | |
665 | for (part = 0; part < part_count; ++part) | |
666 | if (data[part].as_in) | |
667 | fputs (data[part].as_in, as_in); | |
668 | fputc ('\n', as_in); | |
669 | } | |
670 | ||
671 | if (dis_out) | |
672 | { | |
673 | /* Output the disassembler expected output line, | |
674 | starting with the offset and the insn binary pattern, | |
675 | just like objdump outputs. Because objdump sometimes | |
676 | inserts spaces between each byte in the insn binary | |
677 | pattern, make the space optional. */ | |
678 | fprintf (dis_out, "0*%x <", current_offset); | |
679 | if (last_label_name) | |
680 | if (current_offset == last_label_offset) | |
681 | fputs (last_label_name, dis_out); | |
682 | else | |
683 | fprintf (dis_out, "%s\\+0x%x", last_label_name, | |
684 | current_offset - last_label_offset); | |
685 | else | |
686 | fputs ("[^>]*", dis_out); | |
687 | fputs ("> ", dis_out); | |
688 | for (part = insn_size; part-- > 0; ) | |
689 | fprintf (dis_out, "%02x ?", (int)(bits >> (part * 8)) & 0xff); | |
690 | fputs (" *\t", dis_out); | |
691 | ||
692 | #if DISASSEMBLER_TEST | |
693 | for (part = 0; part < part_count; ++part) | |
694 | if (data[part].dis_out) | |
695 | fputs (data[part].dis_out, dis_out); | |
696 | #else | |
697 | /* If we're not testing the DISASSEMBLER, just match | |
698 | anything. */ | |
699 | fputs (".*", dis_out); | |
700 | #endif | |
701 | fputc ('\n', dis_out); | |
702 | #if OUTPUT_RANDOMIZATION_COUNTER | |
703 | fprintf (dis_out, "# %i\n", randomization_counter); | |
704 | #endif | |
705 | } | |
706 | ||
707 | /* Account for the insn_size bytes we've just output. */ | |
708 | current_offset += insn_size; | |
709 | ||
710 | /* Release the memory that each func may have allocated. */ | |
711 | for (; part-- > 0;) | |
712 | { | |
713 | skip: | |
714 | if (data[part].as_in) | |
715 | free (data[part].as_in); | |
716 | if (data[part].dis_out | |
717 | && data[part].dis_out != data[part].as_in) | |
718 | free (data[part].dis_out); | |
719 | } | |
720 | ||
721 | /* There's nothing random here, don't repeat this insn. */ | |
722 | if (randomization_counter == saved_rc) | |
723 | break; | |
724 | } | |
725 | ||
726 | free (data); | |
727 | } | |
728 | } | |
729 | ||
730 | /* For each group, output an asm label and the insns of the group. */ | |
731 | void | |
732 | output_groups (group_t group[], FILE *as_in, FILE *dis_out) | |
733 | { | |
734 | for (; group->name; ++group) | |
735 | { | |
736 | fprintf (as_in, "%s:\n", group->name); | |
737 | fprintf (dis_out, "# %s:\n", group->name); | |
738 | last_label_offset = current_offset; | |
739 | last_label_name = group->name; | |
740 | output_insns (group->insns, as_in, dis_out); | |
741 | } | |
742 | } | |
743 | ||
744 | #endif |