1 #ifndef TEST_GEN_C 2 #define TEST_GEN_C 1 3 4 /* Copyright (C) 2000-2016 Free Software Foundation, Inc. 5 Contributed by Alexandre Oliva <aoliva (at) 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 3 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 19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 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 745