OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [testsuite/] [gas/] [all/] [test-gen.c] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
#ifndef TEST_GEN_C
2
#define TEST_GEN_C 1
3
 
4
/* Copyright (C) 2000, 2003, 2005, 2007 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 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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.