]> Git Repo - binutils.git/blob - sim/mips/gencode.c
* gencode.c (process_instructions): Call build_endian_shift when
[binutils.git] / sim / mips / gencode.c
1 /*> gencode.c <*/
2 /* Instruction handling support for the MIPS architecture simulator.
3
4    This file is part of the MIPS sim
5
6                 THIS SOFTWARE IS NOT COPYRIGHTED
7
8    Cygnus offers the following for use in the public domain.  Cygnus
9    makes no warranty with regard to the software or it's performance
10    and the user accepts the software "AS IS" with all faults.
11
12    CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13    THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
16    $Revision$
17      $Author$
18        $Date$
19 */
20
21 #if 0
22 #define DEBUG (1) /* Just for testing */
23 #endif
24
25 /* The Makefile currently defines "INSIDE_SIMULATOR" as part of the
26    build. It is not currently used by the MIPS simulator world
27    though. */
28
29 /* All output sent to stdout is for the simulator engine. All program
30    related warnings and errors should be sent to stderr. */
31
32 /* The simulator decode table is constructed this way to allow the
33    minimal code required for a particular instruction type to be
34    coded.  This avoids a large simulator source file, with lots of
35    build-time conditionals controlling what code is included.  However
36    this two-stage process does mean that care must be taken to ensure
37    that the correct decoding source is generated for a particular MIPS
38    simulator. */
39
40 /* Notes:
41
42    We could provide pipeline modelling by splitting the simulation of
43    instructions into seperate bytecodes for each pipeline
44    stage. e.g. for the VR4300 each instruction would generate 5
45    bytecodes, one for each pipeline stage. The simulator control would
46    then insert these into the relevant pipeline slots, and execute a
47    complete slots worth of bytecodes. However, the shape of the
48    pipeline, and what parts of each instruction are executed in each
49    pipeline stage, are different between MIPS implementations. If we
50    were to construct a simulator for a particular MIPS architecture
51    this would be a good solution.
52
53    To avoid having to provide multiple different pipeline models, a
54    simple approach for dealing with the delay slots, and register
55    dependencies has been used. The "MIPS IV Instruction Set" document
56    (Revision 3.1 - January 1995) details the standard MIPS instruction
57    set, and it defines operations in instruction (not pipe-line)
58    cycles. This means we only need to worry about a few cases where
59    the result is not available until after the next instruction, or
60    where registers in the previous two instruction cycles may be
61    corrupted. The case for corruption only occurs with HI or LO
62    register access, so we can just keep a count within the engine for
63    upto two cycles before marking the register as safe. We then only
64    need to check the safety flag when performing an update that
65    involves the HI or LO register. The only other case is the
66    BC1F/BC1T instructions in the FP unit. For ISAs I, II and III there
67    must be an instruction between the FP CMP and the BC1[FT]. We can
68    perform the same instruction cycle count scheme, so we can raise a
69    warning if an attempt is made to access the condition code early
70    (NOTE: The hardware does not interlock on this operation, so the
71    simulator should just raise a warning).
72
73    For the situations where a result is not available until later, we
74    implent a slot to hold pending values. After the PC is incremented,
75    and before the instruction is decoded we can execute the required
76    register update (or remainder of instruction processing). */
77
78 /* The FP instruction decoding is also provided by this code.  The
79    instructions are marked as "FP" ones so that we can construct a
80    simulator without an FPU if required.  Similarly we mark
81    instructions as Single or Double precision, since some MIPS
82    processors only have single precision FP hardware. */
83
84 /* NOTE: Ideally all state should be passed as parameters. This allows
85    a single simulator engine to be used for multiple concurrent
86    simulations. More importantly, if a suitably powerful control is in
87    place it will allow speculative simulation, since the context can
88    be saved easily, and then restored after performing some
89    simulation. The down-side is that for certain host architectures it
90    can slow the simulator down (e.g. if globals can be accessed faster
91    than local structures). However, this is not actually the case at
92    the moment. The constructed engine uses direct names (that can be
93    macro definitions). This keeps the engine source smalled (using
94    short-hands), and it also allows the user to control whether they
95    want to use global, or indirected memory locations. i.e. whether
96    they want a single- or multi-threaded simulator engine. */
97
98 /* The constructed simulator engine contains manifests for each of the
99    features supported. The code that includes the engine can then
100    discover the available features during its build. This information
101    can be used to control run-time features provided by the final
102    simulator. */
103
104 /*---------------------------------------------------------------------------*/
105
106 /* Program defaults */
107 #define DEF_ISA      (3)
108 #define DEF_PROC64   (1 == 1)
109 #define DEF_FP       (1 == 1)
110 #define DEF_FPSINGLE (1 == 0)
111
112 #define FEATURE_PROC32      (1 << 0)    /* 0 = 64bit; 1 = 32bit */
113 #define FEATURE_HASFPU      (1 << 1)    /* 0 = no FPU; 1 = include FPU */
114 #define FEATURE_FPSINGLE    (1 << 1)    /* 0 = double; 1 = single (only used if FEATURE_HASFPU defined) */
115 #define FEATURE_GP64        (1 << 2)    /* 0 = GPRLEN 32; 1 = GPRLEN 64 */
116 #define FEATURE_FAST        (1 << 17)   /* 0 = normal;  1 = disable features that slow performance */
117 #define FEATURE_WARN_STALL  (1 << 24)   /* 0 = nothing; 1 = generate warnings when pipeline would stall */
118 #define FEATURE_WARN_LOHI   (1 << 25)   /* 0 = nothing; 1 = generate warnings when LO/HI corrupted */
119 #define FEATURE_WARN_ZERO   (1 << 26)   /* 0 = nothing; 1 = generate warnings if attempt to write register zero */ 
120 #define FEATURE_WARN_MEM    (1 << 27)   /* 0 = nothing; 1 = generate warnings when memory problems are noticed */
121 #define FEATURE_WARN_R31    (1 << 28)   /* 0 = nothing; 1 = generate warnings if r31 used dangerously */
122 #define FEATURE_WARN_RESULT (1 << 29)   /* 0 = nothing; 1 = generate warnings when undefined results may occur */
123
124 #if 1
125 #define FEATURE_WARNINGS  (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_ZERO | FEATURE_WARN_R31)
126 #else
127 #define FEATURE_WARNINGS  (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_ZERO | FEATURE_WARN_R31 | FEATURE_WARN_RESULT)
128 #endif
129
130 /* FEATURE_WARN_STALL */
131 /* If MIPS I we want to raise a warning if an attempt is made to
132    access Rn in an instruction immediately following an Rn update
133    "WARNING : Invalid value read". The simulator engine is designed
134    that the previous value is read in such cases, to allow programs
135    that make use of this feature to execute. *
136 /* If MIPS II or later, attempting to read a register before the
137    update has completed will generate a "WARNING : Processor stall"
138    message (since the processor will lock the pipeline until the value
139    becomes available). */
140
141 /* FEATURE_WARN_LOHI */
142 /* Warn if an attempt is made to read the HI/LO registers before the
143    update has completed, or if an attempt is made to update the
144    registers whilst an update is occurring. */
145
146 /* FEATURE_WARN_ZERO */
147 /* Notify the user if an attempt is made to use GPR 0 as a destination. */
148
149 /* FEATURE_WARN_R31 */
150 /* Notify the user if register r31 (the default procedure call return
151    address) is used unwisely. e.g. If r31 is used as the source in a
152    branch-and-link instruction, it would mean that an exception in the
153    delay slot instruction would not allow the branch to be re-started
154    (since r31 will have been overwritten by the link operation during
155    the first execution of the branch). */
156
157 /* FEATURE_WARN_RESULT */
158 /* Certain instructions do not raise exceptions when invalid operands
159    are given, they will just result in undefined values being
160    generated. This option controls whether the simulator flags such
161    events. */
162
163 /*---------------------------------------------------------------------------*/
164
165 #include <stdio.h>
166 #include <getopt.h>
167 #include <limits.h>
168 #include <errno.h>
169 #include <ctype.h>
170 #include "ansidecl.h"
171 #include "opcode/mips.h"
172
173 /* FIXME: ansidecl.h defines AND.  */
174 #undef AND
175
176 #ifndef ULONG_MAX
177 #define ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
178 #endif
179
180 static unsigned long my_strtoul ();
181
182 #if 0
183 #ifndef TRUE
184 #define TRUE  (1 == 1)
185 #define FALSE (1 == 0)
186 #endif
187 #endif
188
189 /*---------------------------------------------------------------------------*/
190
191 /* Holding the instruction table this way makes it easier to check the
192    instruction values defined, and to add instructions to the
193    system. However, it makes the process of constructing the simulator
194    a bit more complicated: */
195
196 /* The "bitmap" is encoded as follows (NOTE: Only lower-case
197    alphabetic characters should be used, since the letter ordinal is
198    used as a bit position): */
199
200 typedef struct operand_encoding {
201  char id; /* character identifier */
202  int fpos; /* first bit position */
203  int flen; /* field length in bits */
204  char * const type;
205  char * const name;
206  unsigned int flags;
207 } operand_encoding;
208
209 /* Values for the "flags" field: */
210 #define OP_NONE   (0 << 0)      /* To keep the source tidy */
211 #define OP_GPR    (1 << 0)      /* Get operand from integer register bank */
212 #define OP_SIGNX  (1 << 1)      /* Sign-extend the operand */
213 #define OP_SHIFT2 (1 << 2)      /* Shift field left by 2 */
214 #define OP_BITS5  (1 << 3)      /* Only take the lo 5-bits of the operand */
215
216 struct operand_encoding opfields[] = {
217  {'0',-1,-1,"",      "",              (OP_NONE)},  /* special case for explicit zero */
218  {'1',-1,-1,"",      "",              (OP_NONE)},  /* special case for explicit one */
219  {'?',-1,-1,"",      "",              (OP_NONE)},  /* undefined (do not care at this level) */
220  /* The rest are the explicit operand fields: */
221  {'a', 6, 5,"int",   "op1",           (OP_NONE)},  /* shift amount (or hint) */
222  {'b',21, 5,"int",   "fr",            (OP_NONE)},   /* fr register */
223  {'c',16, 1,"int",   "boolean",       (OP_NONE)},  /* TRUE or FALSE boolean */
224  {'d',11, 5,"int",   "destreg",       (OP_NONE)},  /* integer destination/rd register */
225  {'e', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-3bits must be zero) */
226  {'f',17, 1,"int",   "likely",        (OP_NONE)},  /* set if branch LIKELY */
227  {'g',16, 5,"t_reg", "op2",           (OP_GPR)},   /* integer source rt register */
228  {'h', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-1bit must be zero) */
229  {'i', 0,16,"t_reg", "op2",           (OP_SIGNX)}, /* signed immediate (op2) */
230  {'j', 0,26,"ut_reg","op1",           (OP_SHIFT2)},/* shifted left 2 bits and combined with hi-order bits of address in the delay slot */
231  {'k',16, 5,"int",   "ft",            (OP_NONE)},
232  {'l', 0,16,"t_reg", "offset",        (OP_SIGNX | OP_SHIFT2)}, /* signed offset shifted left 2 to make 18bit signed offset */
233  {'m',21, 3,"int",   "format",        (OP_NONE)},  /* FP format field */
234  {'n',16, 5,"int",   "hint",          (OP_NONE)},  /* hint */
235  {'o',21, 5,"t_reg", "op1",           (OP_GPR | OP_BITS5)},  /* integer source/rs register (but never treated as 32bit word) */
236  {'p', 8, 3,"int",   "condition_code",(OP_NONE)},  /* FP condition code field */
237  {'q',18, 3,"int",   "condition_code",(OP_NONE)},  /* FP condition code field */
238  {'r', 6, 5,"int",   "destreg",       (OP_NONE)},  /* FP fd register */
239  {'s',21, 5,"t_reg", "op1",           (OP_GPR)},   /* integer source/rs register */
240  {'t',16, 5,"int",   "destreg",       (OP_NONE)},  /* integer target rt (destination) register */
241  {'u', 0, 4,"int",   "cmpflags",      (OP_NONE)},  /* FP comparison control flags */
242  {'v',11, 5,"int",   "fs",            (OP_NONE)},  /* FP fs register (or PREFX hint) */
243  {'w', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-2bits must be zero) */
244  {'x',23, 1,"int",   "to",            (OP_NONE)},  /* TRUE if move To; FALSE if move From */
245  {'y', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset */
246  {'z', 0,16,"ut_reg","op2",           (OP_NONE)},  /* unsigned immediate (zero extended) */
247 };
248
249 /* Main instruction encoding types: */
250 typedef enum {
251  NORMAL,
252  SPECIAL,
253  REGIMM,
254  COP1,
255  COP1X,
256  COP1S, /* These instructions live in the reserved FP format values: 0..15,18-19,22-31 */
257  UNKNOWN
258 } inst_type;
259
260 /* Main instruction families: */
261 typedef enum {
262  ADD,                   /* res = operand1 + operand2 */
263  SUB,                   /* res = operand1 - operand2 */
264  MUL,                   /* res = operand1 * operand2 */
265  DIV,                   /* res = operand1 / operand2 */
266  AND,                   /* res = operand1 & operand2 */
267  OR,                    /* res = operand1 | operand2 */
268  XOR,                   /* res = operand1 ^ operand2 */
269  MOVE,                  /* res = operand1 */
270  BRANCH,                /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
271  JUMP,                  /* execute delay slot instruction before jump */
272  LOAD,                  /* load from memory */
273  STORE,                 /* store to memory */
274  PREFETCH,              /* prefetch data into cache */
275  SET,                   /* set register on result of condition code */
276  SHIFT,                 /* perform a logical or arithmetic shift */
277  TRAP,                  /* system exception generation */
278  BREAK,                 /* system breakpoint exception generation */
279  SYSCALL,               /* system exception generation */
280  SYNC,                  /* system cache control */
281  DECODE,                /* co-processor instruction */
282  CACHE,                 /* co-processor 0 CACHE instruction */
283  MADD16,                /* VR4100 specific multiply-add extensions */
284  FPMOVE,
285  FPMOVEC,
286  FPFLOOR,               
287  FPCEIL,
288  FPTRUNC,
289  FPROUND,
290  FPNEG,
291  FPABS,
292  FPDIV,
293  FPMUL,
294  FPSUB,
295  FPADD,
296  FPPREFX,
297  FPRECIP,
298  FPSQRT,
299  FPCONVERT,
300  FPCOMPARE,
301  RSVD                   /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "Reserved Instruction" */
302 } opcode_type;
303
304 /* Flags field: */
305 #define NONE            (0 << 0)        /* Zero value (used to keep source tidy) */
306 #define SIM_SH_SIZE     (0)
307 #define SIM_MASK_SIZE   (0x7)
308 #define BYTE            (0)     /*  8bit */
309 #define HALFWORD        (1)     /* 16bit */
310 #define WORD            (2)     /* 32bit */
311 #define DOUBLEWORD      (3)     /* 64bit */
312 #define SINGLE          (4)     /* single precision FP */
313 #define DOUBLE          (5)     /* double precision FP */
314
315 /* Shorthand to get the size field from the flags value: */
316 #define GETDATASIZE()   ((MIPS_DECODE[loop].flags >> SIM_SH_SIZE) & SIM_MASK_SIZE)
317
318 /* The rest are single bit flags: */
319 #define MULTIPLY        (1 << 3)        /* actually FP multiply ADD/SUB modifier */
320 #define EQ              (1 << 4)
321 #define GT              (1 << 5)
322 #define LT              (1 << 6)
323 #define NOT             (1 << 7)
324 #define LIKELY          (1 << 8)
325 #define SIGNEXTEND      (1 << 9)
326 #define OVERFLOW        (1 << 10)
327 #define LINK            (1 << 11)
328 #define ATOMIC          (1 << 12)
329 #define SHIFT16         (1 << 13)
330 #define REG             (1 << 14)
331 #define LEFT            (1 << 15)       /* Deliberate explicit encodings to allow check for neither, or both */
332 #define RIGHT           (1 << 16)       /* Mutually exclusive with "LEFT" */
333 #define LOGICAL         (1 << 17)
334 #define ARITHMETIC      (1 << 18)
335 #define UNSIGNED        (1 << 19)
336 #define HI32            (1 << 20)
337 #define HI              (1 << 21)       /* accesses or updates the HI register */
338 #define LO              (1 << 22)       /* accesses or updates the LO register */
339 #define WORD32          (1 << 23)
340 #define FP              (1 << 24)       /* Floating Point operation */
341 #define FIXED           (1 << 25)       /* fixed point arithmetic */
342 #define COPROC          (1 << 26)
343 #define INTEGER         (1 << 27)
344 #define CONDITIONAL     (1 << 28)
345 #define RECIP           (1 << 29)
346 #define CONTROL         (1 << 30)
347 #define NOARG           (1 << 31)       /* Instruction has no (defined) operands */
348 /* NOTE: We can overload the use of certain of these flags, since not
349    all options are applicable to all instruction types. This will free
350    up more space for new flags. */
351
352 typedef struct instruction {
353  char         *name;   /* ASCII mnemonic name */
354  unsigned int  isa;    /* MIPS ISA number where instruction introduced */
355  char         *bitmap; /* 32character string describing instruction operands */
356  inst_type     mark;   /* type of MIPS instruction encoding */
357  opcode_type   type;   /* main instruction family */
358  unsigned int  flags;  /* flags describing instruction features */
359 } instruction;
360 /* The number of pipeline cycles taken by an instruction varies
361    between MIPS processors. This means that the information must be
362    encoded elsewhere, in a CPU specific structure. */
363
364 /* NOTE: Undefined instructions cause "Reserved Instruction"
365    exceptions. i.e. if there is no bit-mapping defined then the
366    instruction is deemed to be undefined. */
367
368 /* NOTE: The "isa" field is also used to encode flags for particular
369    chip architecture extensions. e.g. the NEC VR4100 specific
370    instructions. Normally chip extensions are added via the COP0
371    space. However, the VR4100 (and possibly other devices) also use
372    the normal instruction space. */
373 #define MASK_ISA (0x000000FF) /* Start by leaving 8bits for the ISA ID */
374 /* The other bits are allocated downwards, to avoid renumbering if we
375    have to extend the bits allocated to the pure ISA number. */
376 #define ARCH_VR4100       ((unsigned)1 << 31) /* NEC VR4100 extension instructions */
377
378 /* The HIBERNATE, STANDBY and SUSPEND instructions are encoded in the
379    COP0 space. This means that an external decoder should be added
380    when constructing a full VR4100 simulator. However some arithmetic
381    instructions are encoded in the normal instruction space. */
382
383 struct instruction MIPS_DECODE[] = {
384  /* The instructions are alphabetical, and not in instruction bit-order: */
385  {"ABS",     1,"01000110mmm00000vvvvvrrrrr000101",COP1,   FPABS,    (FP)},
386  {"ADD",     1,"000000sssssgggggddddd00000100000",SPECIAL,ADD,      (WORD | WORD32 | OVERFLOW)}, /* rd = rs + rt */
387  {"ADD",     1,"01000110mmmkkkkkvvvvvrrrrr000000",COP1,   FPADD,    (FP)},
388  {"ADDI",    1,"001000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (WORD | WORD32 | OVERFLOW)},
389  {"ADDU",    1,"000000sssssgggggddddd00000100001",SPECIAL,ADD,      (WORD | WORD32)}, /* rd = rs + rt */
390  {"ADDIU",   1,"001001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (WORD | WORD32)},
391  {"AND",     1,"000000sssssgggggddddd00000100100",SPECIAL,AND,      (NONE)}, /* rd = rs AND rt */
392  {"ANDI",    1,"001100ssssstttttzzzzzzzzzzzzzzzz",NORMAL, AND,      (NONE)},
393  {"BC1",     1,"01000101000qqqfcllllllllllllllll",COP1S,  BRANCH,   (FP)},
394  {"BEQ",     1,"000100sssssgggggllllllllllllllll",NORMAL, BRANCH,   (EQ)},
395  {"BEQL",    2,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH,   (EQ | LIKELY)},
396  {"BGEZ",    1,"000001sssss00001llllllllllllllll",REGIMM, BRANCH,   (GT | EQ)},
397  {"BGEZAL",  1,"000001sssss10001llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LINK)},
398  {"BGEZALL", 2,"000001sssss10011llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LINK)},
399  {"BGEZL",   2,"000001sssss00011llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LIKELY)},
400  {"BGTZ",    1,"000111sssss00000llllllllllllllll",NORMAL, BRANCH,   (GT)},
401  {"BGTZL",   2,"010111sssss00000llllllllllllllll",NORMAL, BRANCH,   (GT | LIKELY)},
402  {"BLEZ",    1,"000110sssss00000llllllllllllllll",NORMAL, BRANCH,   (LT | EQ)},
403  {"BLEZL",   2,"010110sssss00000llllllllllllllll",NORMAL, BRANCH,   (LT | EQ | LIKELY)},
404  {"BLTZ",    1,"000001sssss00000llllllllllllllll",REGIMM, BRANCH,   (LT)},
405  {"BLTZAL",  1,"000001sssss10000llllllllllllllll",REGIMM, BRANCH,   (LT | LINK)},
406  {"BLTZALL", 2,"000001sssss10010llllllllllllllll",REGIMM, BRANCH,   (LT | LINK | LIKELY)},
407  {"BLTZL",   2,"000001sssss00010llllllllllllllll",REGIMM, BRANCH,   (LT | LIKELY)},
408  {"BNE",     1,"000101sssssgggggllllllllllllllll",NORMAL, BRANCH,   (NOT | EQ)},
409  {"BNEL",    2,"010101sssssgggggllllllllllllllll",NORMAL, BRANCH,   (NOT | EQ | LIKELY)},
410  {"BREAK",   1,"000000????????????????????001101",SPECIAL,BREAK,    (NOARG)},
411  {"CEIL.L",  3,"01000110mmm00000vvvvvrrrrr001010",COP1,   FPCEIL,   (FP | FIXED | DOUBLEWORD)},
412  {"CEIL.W",  2,"01000110mmm00000vvvvvrrrrr001110",COP1,   FPCEIL,   (FP | FIXED | WORD)},
413  {"COP0",    1,"010000??????????????????????????",NORMAL, DECODE,   (NOARG)},
414  {"COP2",    1,"010010??????????????????????????",NORMAL, DECODE,   (NOARG)},
415  {"CVT.D",   1,"01000110mmm00000vvvvvrrrrr100001",COP1,   FPCONVERT,(FP | DOUBLE)},
416  {"CVT.L",   3,"01000110mmm00000vvvvvrrrrr100101",COP1,   FPCONVERT,(FP | FIXED | DOUBLEWORD)},
417  {"CVT.S",   1,"01000110mmm00000vvvvvrrrrr100000",COP1,   FPCONVERT,(FP | SINGLE)},
418  {"CVT.W",   1,"01000110mmm00000vvvvvrrrrr100100",COP1,   FPCONVERT,(FP | FIXED | WORD)},
419  {"C.%s",    1,"01000110mmmkkkkkvvvvvppp0011uuuu",COP1,   FPCOMPARE,(FP)},
420  {"CxC1",    1,"01000100x10kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | WORD | CONTROL)},
421  {"DADD",    3,"000000sssssgggggddddd00000101100",SPECIAL,ADD,      (DOUBLEWORD | OVERFLOW)},
422  {"DADDI",   3,"011000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (DOUBLEWORD | OVERFLOW)},
423  {"DADDU",   3,"000000sssssgggggddddd00000101101",SPECIAL,ADD,      (DOUBLEWORD | UNSIGNED)},
424  {"DADDIU",  3,"011001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (DOUBLEWORD | UNSIGNED)},
425  {"DDIV",    3,"000000sssssggggg0000000000011110",SPECIAL,DIV,      (DOUBLEWORD | HI | LO)},
426  {"DDIVU",   3,"000000sssssggggg0000000000011111",SPECIAL,DIV,      (DOUBLEWORD | UNSIGNED | HI | LO)},
427  {"DIV",     1,"000000sssssggggg0000000000011010",SPECIAL,DIV,      (WORD | WORD32 | SIGNEXTEND | HI | LO)},
428  {"DIV",     1,"01000110mmmkkkkkvvvvvrrrrr000011",COP1,   FPDIV,    (FP | WORD | HI | LO)},
429  {"DIVU",    1,"000000sssssggggg0000000000011011",SPECIAL,DIV,      (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO)},
430  {"DMADD16", (ARCH_VR4100 | 3),"000000sssssggggg0000000000101001",SPECIAL,MADD16,   (DOUBLEWORD | HI | LO)},
431  {"DMULT",   3,"000000sssssggggg0000000000011100",SPECIAL,MUL,      (DOUBLEWORD | HI | LO)},
432  {"DMULTU",  3,"000000sssssggggg0000000000011101",SPECIAL,MUL,      (DOUBLEWORD | UNSIGNED | HI | LO)},
433  {"DMxC1",   3,"01000100x01kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | DOUBLEWORD)},
434  {"DSLL",    3,"00000000000gggggdddddaaaaa111000",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL)},
435  {"DSLLV",   3,"000000sssssgggggddddd00000010100",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL)},
436  {"DSLL32",  3,"00000000000gggggdddddaaaaa111100",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL | HI32)}, /* rd = rt << (sa + 32) */
437  {"DSRA",    3,"00000000000gggggdddddaaaaa111011",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC)},
438  {"DSRAV",   3,"000000sssssgggggddddd00000010111",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC)},
439  {"DSRA32",  3,"00000000000gggggdddddaaaaa111111",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC | HI32)}, /* rd = rt >> (sa + 32) */
440  {"DSRL",    3,"00000000000gggggdddddaaaaa111010",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL)},
441  {"DSRLV",   3,"000000sssssgggggddddd00000010110",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL)},
442  {"DSRL32",  3,"00000000000gggggdddddaaaaa111110",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL | HI32)},
443  {"DSUB",    3,"000000sssssgggggddddd00000101110",SPECIAL,SUB,      (DOUBLEWORD)},
444  {"DSUBU",   3,"000000sssssgggggddddd00000101111",SPECIAL,SUB,      (DOUBLEWORD | UNSIGNED)},
445  {"FLOOR.L", 3,"01000110mmm00000vvvvvrrrrr001011",COP1,   FPFLOOR,  (FP | FIXED | DOUBLEWORD)},
446  {"FLOOR.W", 2,"01000110mmm00000vvvvvrrrrr001111",COP1,   FPFLOOR,  (FP | FIXED | WORD)},
447  {"J",       1,"000010jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (NONE)},                    /* NOTE: boundary case due to delay slot address being used */
448  {"JAL",     1,"000011jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (LINK)},                    /* NOTE: boundary case due to delay slot address being used */
449  {"JALR",    1,"000000sssss00000ddddd00000001001",SPECIAL,JUMP,     (LINK | REG)},
450  {"JR",      1,"000000sssss000000000000000001000",SPECIAL,JUMP,     (NONE)}, /* need to check PC as part of instruction fetch */
451  {"LB",      1,"100000ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (BYTE | SIGNEXTEND)},       /* NOTE: "i" rather than "o" because BYTE addressing is allowed */
452  {"LBU",     1,"100100ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (BYTE)},                    /* NOTE: See "LB" comment */
453  {"LD",      3,"110111sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD)},
454  {"LDC1",    2,"110101sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | COPROC)},
455  {"LDC2",    2,"110110sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | COPROC)},
456  {"LDL",     3,"011010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (DOUBLEWORD | LEFT)},       /* NOTE: See "LB" comment */
457  {"LDR",     3,"011011ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (DOUBLEWORD | RIGHT)},      /* NOTE: See "LB" comment */
458  {"LDXC1",   4,"010011sssssggggg00000rrrrr000001",COP1X,  LOAD,     (FP | DOUBLEWORD | COPROC | REG)},
459  {"LH",      1,"100001sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD,     (HALFWORD | SIGNEXTEND)},
460  {"LHU",     1,"100101sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD,     (HALFWORD)},
461  {"LL",      2,"110000ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | ATOMIC | SIGNEXTEND)},
462  {"LLD",     3,"110100sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | ATOMIC)},
463  {"LUI",     1,"00111100000tttttiiiiiiiiiiiiiiii",NORMAL, MOVE,     (SHIFT16)}, /* Cheat and specify sign-extension of immediate field */
464  {"LW",      1,"100011ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | SIGNEXTEND)},
465  {"LWC1",    1,"110001ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | COPROC)},
466  {"LWC2",    1,"110010ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | COPROC)},
467  {"LWL",     1,"100010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (WORD | LEFT)},
468  {"LWR",     1,"100110ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (WORD | RIGHT)},
469  {"LWU",     3,"100111ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD)},
470  {"LWXC1",   4,"010011sssssggggg00000rrrrr000000",COP1X,  LOAD,     (FP | WORD | COPROC | REG)},
471  {"MADD16",  (ARCH_VR4100 | 3),"000000sssssggggg0000000000101000",SPECIAL,MADD16,   (WORD | HI | LO)},
472  {"MADD.D",  4,"010011bbbbbkkkkkvvvvvrrrrr100001",COP1X,  FPADD,    (FP | MULTIPLY | DOUBLE)},
473  {"MADD.S",  4,"010011bbbbbkkkkkvvvvvrrrrr100000",COP1X,  FPADD,    (FP | MULTIPLY | SINGLE)},
474  {"MFHI",    1,"0000000000000000ddddd00000010000",SPECIAL,MOVE,     (HI)},    /* with following, from and to denoted by usage of "s" or "d" */
475  {"MFLO",    1,"0000000000000000ddddd00000010010",SPECIAL,MOVE,     (LO)},
476  {"MTHI",    1,"000000sssss000000000000000010001",SPECIAL,MOVE,     (HI)},
477  {"MTLO",    1,"000000sssss000000000000000010011",SPECIAL,MOVE,     (LO)},
478  {"MOV",     1,"01000110mmm00000vvvvvrrrrr000110",COP1,   FPMOVE,   (FP)},
479  {"MOVN",    4,"000000sssssgggggddddd00000001011",SPECIAL,MOVE,     (NOT | EQ)},
480  {"MOVN",    4,"01000110mmmgggggvvvvvrrrrr010011",COP1,   FPMOVE,   (FP | NOT | EQ)},
481  {"MOV%c",   4,"000000sssssqqq0cddddd00000000001",SPECIAL,FPMOVE,   (FP | CONDITIONAL | INTEGER)},
482  {"MOV%c",   4,"01000110mmmqqq0cvvvvvrrrrr010001",COP1,   FPMOVE,   (FP | CONDITIONAL)},
483  {"MOVZ",    4,"000000sssssgggggddddd00000001010",SPECIAL,MOVE,     (EQ)},
484  {"MOVZ",    4,"01000110mmmgggggvvvvvrrrrr010010",COP1,   FPMOVE,   (FP | EQ)},
485  {"MSUB.D",  4,"010011bbbbbkkkkkvvvvvrrrrr101001",COP1X,  FPSUB,    (FP | MULTIPLY | DOUBLE)},
486  {"MSUB.S",  4,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X,  FPSUB,    (FP | MULTIPLY | SINGLE)},
487  {"MUL",     1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1,   FPMUL,    (FP | HI | LO)},
488  {"MULT",    1,"000000sssssggggg0000000000011000",SPECIAL,MUL,      (WORD | WORD32 | HI | LO)},
489  {"MULTU",   1,"000000sssssggggg0000000000011001",SPECIAL,MUL,      (WORD | WORD32 | UNSIGNED | HI | LO)},
490  {"MxC1",    1,"01000100x00kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | WORD)},
491  {"NEG",     1,"01000110mmm00000vvvvvrrrrr000111",COP1,   FPNEG,    (FP)},
492  {"NMADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr110001",COP1X,  FPADD,    (FP | NOT | MULTIPLY | DOUBLE)},
493  {"NMADD.S", 4,"010011bbbbbkkkkkvvvvvrrrrr110000",COP1X,  FPADD,    (FP | NOT | MULTIPLY | SINGLE)},
494  {"NMSUB.D", 4,"010011bbbbbkkkkkvvvvvrrrrr111001",COP1X,  FPSUB,    (FP | NOT | MULTIPLY | DOUBLE)},
495  {"NMSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr111000",COP1X,  FPSUB,    (FP | NOT | MULTIPLY | SINGLE)},
496  {"NOR",     1,"000000sssssgggggddddd00000100111",SPECIAL,OR,       (NOT)},
497  {"OR",      1,"000000sssssgggggddddd00000100101",SPECIAL,OR,       (NONE)},
498  {"ORI",     1,"001101ssssstttttzzzzzzzzzzzzzzzz",NORMAL, OR,       (NONE)},
499  {"PREF",    4,"110011sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, PREFETCH, (NONE)},
500  {"PREFX",   4,"010011sssssgggggvvvvv00000001111",COP1X,  FPPREFX,  (FP)},
501  {"RECIP",   4,"01000110mmm00000vvvvvrrrrr010101",COP1,   FPRECIP,  (FP)},
502  {"ROUND.L", 3,"01000110mmm00000vvvvvrrrrr001000",COP1,   FPROUND,  (FP | FIXED | DOUBLEWORD)},
503  {"ROUND.W", 2,"01000110mmm00000vvvvvrrrrr001100",COP1,   FPROUND,  (FP | FIXED | WORD)},
504  {"RSQRT",   4,"01000110mmm00000vvvvvrrrrr010110",COP1,   FPSQRT,   (FP | RECIP)},
505  {"SB",      1,"101000sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (BYTE)},
506  {"SC",      2,"111000sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | ATOMIC)},
507  {"SCD",     3,"111100sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | ATOMIC)},
508  {"SD",      3,"111111sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD)},
509  {"SDC1",    2,"111101sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | COPROC)},
510  {"SDC2",    2,"111110sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | COPROC)},
511  {"SDL",     3,"101100sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (DOUBLEWORD | LEFT)},
512  {"SDR",     3,"101101sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (DOUBLEWORD | RIGHT)},
513  {"SDXC1",   4,"010011sssssgggggvvvvv00000001001",COP1X,  STORE,    (FP | DOUBLEWORD | COPROC | REG)},
514  {"SH",      1,"101001sssssggggghhhhhhhhhhhhhhhh",NORMAL, STORE,    (HALFWORD)},
515  {"SLL",     1,"00000000000gggggdddddaaaaa000000",SPECIAL,SHIFT,    (WORD | LEFT | LOGICAL)}, /* rd = rt << sa */
516  {"SLLV",    1,"000000ooooogggggddddd00000000100",SPECIAL,SHIFT,    (WORD | LEFT | LOGICAL)}, /* rd = rt << rs - with "SLL" depends on "s" and "a" field values */
517  {"SLT",     1,"000000sssssgggggddddd00000101010",SPECIAL,SET,      (LT)},
518  {"SLTI",    1,"001010ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET,      (LT)},
519  {"SLTU",    1,"000000sssssgggggddddd00000101011",SPECIAL,SET,      (LT | UNSIGNED)},
520  {"SLTIU",   1,"001011ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET,      (LT | UNSIGNED)},
521  {"SQRT",    2,"01000110mmm00000vvvvvrrrrr000100",COP1,   FPSQRT,   (FP)},
522  {"SRA",     1,"00000000000gggggdddddaaaaa000011",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | ARITHMETIC)},
523  {"SRAV",    1,"000000ooooogggggddddd00000000111",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | ARITHMETIC)},
524  {"SRL",     1,"00000000000gggggdddddaaaaa000010",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | LOGICAL)},
525  {"SRLV",    1,"000000ooooogggggddddd00000000110",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | LOGICAL)},
526  {"SUB",     1,"000000sssssgggggddddd00000100010",SPECIAL,SUB,      (WORD | WORD32 | OVERFLOW)},
527  {"SUB",     1,"01000110mmmkkkkkvvvvvrrrrr000001",COP1,   FPSUB,    (FP)},
528  {"SUBU",    1,"000000sssssgggggddddd00000100011",SPECIAL,SUB,      (WORD | WORD32)},
529  {"SW",      1,"101011sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD)},
530  {"SWC1",    1,"111001ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | COPROC)},
531  {"SWC2",    1,"111010ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | COPROC)},
532  {"SWL",     1,"101010sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (WORD | LEFT)},
533  {"SWR",     1,"101110sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (WORD | RIGHT)},
534  {"SWXC1",   4,"010011sssssgggggvvvvv00000001000",COP1X,  STORE,    (FP | WORD | COPROC | REG)},
535  {"SYNC",    2,"000000000000000000000aaaaa001111",SPECIAL,SYNC,     (NONE)}, /* z = 5bit stype field */
536  {"SYSCALL", 1,"000000????????????????????001100",SPECIAL,SYSCALL,  (NOARG)},
537  {"TEQ",     2,"000000sssssggggg??????????110100",SPECIAL,TRAP,     (EQ)},
538  {"TEQI",    2,"000001sssss01100iiiiiiiiiiiiiiii",REGIMM, TRAP,     (EQ)},
539  {"TGE",     2,"000000sssssggggg??????????110000",SPECIAL,TRAP,     (GT | EQ)},
540  {"TGEI",    2,"000001sssss01000iiiiiiiiiiiiiiii",REGIMM, TRAP,     (GT | EQ)},
541  {"TGEIU",   2,"000001sssss01001iiiiiiiiiiiiiiii",REGIMM, TRAP,     (GT | EQ | UNSIGNED)},
542  {"TGEU",    2,"000000sssssggggg??????????110001",SPECIAL,TRAP,     (GT | EQ | UNSIGNED)},
543  {"TLT",     2,"000000sssssggggg??????????110010",SPECIAL,TRAP,     (LT)},
544  {"TLTI",    2,"000001sssss01010iiiiiiiiiiiiiiii",REGIMM, TRAP,     (LT)},
545  {"TLTIU",   2,"000001sssss01011iiiiiiiiiiiiiiii",REGIMM, TRAP,     (LT | UNSIGNED)},
546  {"TLTU",    2,"000000sssssggggg??????????110011",SPECIAL,TRAP,     (LT | UNSIGNED)},
547  {"TNE",     2,"000000sssssggggg??????????110110",SPECIAL,TRAP,     (NOT | EQ)},
548  {"TNEI",    2,"000001sssss01110iiiiiiiiiiiiiiii",REGIMM, TRAP,     (NOT | EQ)},
549  {"TRUNC.L", 3,"01000110mmm00000vvvvvrrrrr001001",COP1,   FPTRUNC,  (FP | FIXED | DOUBLEWORD)},
550  {"TRUNC.W", 2,"01000110mmm00000vvvvvrrrrr001101",COP1,   FPTRUNC,  (FP | FIXED | WORD)},
551  {"XOR",     1,"000000sssssgggggddddd00000100110",SPECIAL,XOR,      (NONE)},
552  {"XORI",    1,"001110ssssstttttzzzzzzzzzzzzzzzz",NORMAL, XOR,      (NONE)},
553  {"CACHE",   3,"101111sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, CACHE,    (NONE)},
554  {"<INT>",   1,"111011sssssgggggyyyyyyyyyyyyyyyy",NORMAL, RSVD,     (NONE)},
555 };
556
557 /*---------------------------------------------------------------------------*/
558
559 /* We use the letter ordinal as the bit-position in our flags field: */
560 #define fieldval(l)     (1 << ((l) - 'a'))
561
562 unsigned int
563 convert_bitmap(bitmap,onemask,zeromask,dontmask)
564      char *bitmap;
565      unsigned int *onemask, *zeromask, *dontmask;
566 {
567   unsigned int flags = 0x00000000;
568   int loop; /* current bitmap position */
569   int lastsp = -1; /* last bitmap field starting position */
570   int lastoe = -1; /* last bitmap field encoding */
571
572   *onemask = 0x00000000;
573   *zeromask = 0x00000000;
574   *dontmask = 0x00000000;
575
576   if (strlen(bitmap) != 32) {
577     fprintf(stderr,"Invalid bitmap string - not 32 characters long \"%s\"\n",bitmap);
578     exit(3);
579   }
580
581   for (loop = 0; (loop < 32); loop++) {
582     int oefield ;
583     for (oefield = 0; (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))); oefield++)
584      if (bitmap[31 - loop] == opfields[oefield].id)
585       break;
586     if (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))) {
587       if ((lastoe != -1) && (lastoe != oefield))
588        if ((loop - lastsp) != (opfields[lastoe].flen)) {
589          fprintf(stderr,"Invalid field length %d for bitmap field '%c' (0x%02X) (should be %d) : bitmap = \"%s\"\n",(loop - lastsp),(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],opfields[lastoe].flen,bitmap);
590          exit(4);
591        }
592          
593       switch (bitmap[31 - loop]) {
594         case '0' : /* fixed value */
595          *zeromask |= (1 << loop);
596          lastsp = loop;
597          lastoe = -1;
598          break;
599
600         case '1' : /* fixed value */
601          *onemask |= (1 << loop);
602          lastsp = loop;
603          lastoe = -1;
604          break;
605
606         case '?' : /* fixed value */
607          *dontmask |= (1 << loop);
608          lastsp = loop;
609          lastoe = -1;
610          break;
611
612         default : /* check character encoding */
613          {
614            if (opfields[oefield].fpos != -1) {
615              /* If flag not set, then check starting position: */
616              if (!(flags & fieldval(bitmap[31 - loop]))) {
617                if (loop != opfields[oefield].fpos) {
618                  fprintf(stderr,"Bitmap field '%c' (0x%02X) at wrong offset %d in bitmap \"%s\"\n",(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],loop,bitmap);
619                  exit(4);
620                }
621                flags |= fieldval(bitmap[31 - loop]);
622                lastsp = loop;
623                lastoe = oefield;
624              }
625            }
626            *dontmask |= (1 << loop);
627          }
628          break;
629        }
630     } else {
631       fprintf(stderr,"Unrecognised bitmap character '%c' (0x%02X) at offset %d in bitmap \"%s\"\n",(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],loop,bitmap);
632       exit(4);
633     }
634   }
635
636  /* NOTE: Since we check for the position and size of fields when
637     parsing the "bitmap" above, we do *NOT* need to check that invalid
638     field combinations have been used. */
639
640  return(flags);
641 }
642
643 /*---------------------------------------------------------------------------*/
644
645 static void
646 build_operands(flags)
647      unsigned int flags;
648 {
649   int loop;
650   for (loop = 0; (loop < (sizeof(opfields) / sizeof(operand_encoding))); loop++)
651    if ((opfields[loop].fpos != -1) && (flags & fieldval(opfields[loop].id))) {
652      printf("  %s %s = ",opfields[loop].type,opfields[loop].name);
653
654      if (opfields[loop].flags & OP_SIGNX)
655       printf("SIGNEXTEND((%s)",opfields[loop].type);
656
657      if (opfields[loop].flags & OP_GPR)
658       printf("GPR[");
659
660      if (opfields[loop].flags & OP_SHIFT2)
661       printf("(");
662
663      printf("((instruction >> %d) & 0x%08X)",opfields[loop].fpos,((1 << opfields[loop].flen) - 1));
664
665      if (opfields[loop].flags & OP_SHIFT2)
666       printf(" << 2)");
667
668      if (opfields[loop].flags & OP_GPR)
669       printf("]");
670
671      if (opfields[loop].flags & OP_BITS5)
672       printf("&0x1F");
673
674      if (opfields[loop].flags & OP_SIGNX)
675       printf(",%d)",(opfields[loop].flen + ((opfields[loop].flags & OP_SHIFT2) ? 2 : 0)));
676
677      printf(";\n");
678    }
679
680  return;
681 }
682
683 /*---------------------------------------------------------------------------*/
684
685 typedef enum {
686   s_left,
687   s_right
688 } e_endshift;
689
690 static void
691 build_endian_shift(proc64,datalen,endbit,direction,shift)
692      int proc64;
693      int datalen;
694      int endbit;
695      e_endshift direction;
696      int shift;
697 {
698   if (proc64 && (datalen == 4)) {
699     printf("    if ((vaddr & (1 << %d)) ^ (BigEndianCPU << %d)) {\n",endbit,endbit);
700     printf("     memval %s= %d;\n",direction == s_left ? "<<" : ">>",shift);
701     printf("    }\n");
702   }
703
704   return;
705 }
706
707 /*---------------------------------------------------------------------------*/
708 /* doisa = number of MIPS ISA simulator table is being constructed for.
709  * proc64 = TRUE if constructing 64bit processor world.
710  * dofp = boolean, TRUE if FP instructions are to be included.
711  * fpsingle = boolean, TRUE if only single precision FP instructions to be included.
712  */
713
714 void
715 process_instructions(doarch,features)
716      unsigned int doarch;
717      unsigned int features;
718 {
719   int doisa = (doarch & MASK_ISA);
720   int limit = (sizeof(MIPS_DECODE) / sizeof(instruction));
721   int gprlen=((features & FEATURE_GP64) ? 64 : 32);
722   int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
723   int dofp = (features & FEATURE_HASFPU);
724   int fpsingle = (features & FEATURE_FPSINGLE);
725   int maxisa;
726   int loop;
727
728   if (limit < 1) {
729     fprintf(stderr,"process_instructions: invalid structure length\n");
730     exit(1);
731   }
732
733   if (proc64 && (gprlen != 64)) {
734     fprintf(stderr,"Error: 64bit processor build specified, with MIPS ISA I or II\n");
735     exit(3);
736   }
737
738   /* NOTE: "proc64" also differentiates between 32- and 64-bit wide memory */
739
740   maxisa = 0;
741   for (loop = 0; (loop < limit); loop++)
742    if ((MIPS_DECODE[loop].isa & MASK_ISA) > maxisa)
743     maxisa = (MIPS_DECODE[loop].isa & MASK_ISA);
744
745   if (doisa == 0)
746    doisa = maxisa;
747
748   printf("#if defined(SIM_MANIFESTS)\n");
749   printf("#define MIPSISA (%d)\n",doisa);
750   if (proc64)
751    printf("#define PROCESSOR_64BIT (1 == 1)\n");
752   else
753    printf("#define PROCESSOR_64BIT (1 == 0)\n");
754 #if 1 /* cheat: We only have a 64bit LoadMemory and StoreMemory routines at the moment */
755   printf("#define LOADDRMASK (0x%08X)\n",0x7);
756 #else
757   printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
758 #endif
759   /* The FP registers are the same width as the CPU registers: */
760   printf("#define GPRLEN (%d)\n",gprlen);
761   printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
762   printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
763   printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
764   if (dofp)
765    printf("#define HASFPU (1 == 1)\n");
766   if (features & FEATURE_FAST)
767    printf("#define FASTSIM (1 == 1)\n");
768   if (features & FEATURE_WARN_STALL)
769    printf("#define WARN_STALL (1 == 1)\n");
770   if (features & FEATURE_WARN_LOHI)
771    printf("#define WARN_LOHI (1 == 1)\n");
772   if (features & FEATURE_WARN_ZERO)
773    printf("#define WARN_ZERO (1 == 1)\n");
774   if (features & FEATURE_WARN_MEM)
775    printf("#define WARN_MEM (1 == 1)\n");
776   if (features & FEATURE_WARN_R31)
777    printf("#define WARN_R31 (1 == 1)\n");
778   if (features & FEATURE_WARN_RESULT)
779    printf("#define WARN_RESULT (1 == 1)\n");
780
781   printf("#else /* simulator engine */\n");
782
783   printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
784   printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
785   if (dofp)
786    printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
787   printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
788
789  if (proc64) {
790    printf("#if !defined(PROCESSOR_64BIT)\n");
791    printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
792    printf("#endif\n");
793  }
794
795  printf("/* Actual instruction decoding block */\n");
796  printf("{\n");
797   {
798     int limit;
799     printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
800     limit = (OP_MASK_OP + 1);
801     printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
802     limit += (OP_MASK_SPEC + 1);
803     printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
804     limit += (OP_MASK_RT + 1);
805     printf("else if (num == 0x11) {\n");
806     printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
807     printf("  if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
808     printf("   num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
809     printf("  else\n");
810     printf("   num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
811     limit += (OP_MASK_SPEC + 1);
812     printf(" else\n");
813     /* To keep this code quick, we just clear out the "to" bit
814        here. The proper (though slower) code would be to have another
815        conditional, checking whether this instruction is a branch or
816        not, before limiting the range to the bottom two bits of the
817        move operation. */
818     printf("  num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
819     limit += (OP_MASK_COP1SPEC + 1);
820     printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
821     limit += (OP_MASK_SPEC + 1);
822     printf("/* Total possible switch entries: %d */\n",limit) ;
823   }
824  printf("switch (num)\n") ;
825  printf("{\n");
826
827  for (loop = 0; (loop < limit); loop++) {
828    /* First check that the ISA number we are constructing for is
829       valid, before checking if the instruction matches any of the
830       architecture specific flags. NOTE: We allow a selected ISA of
831       zero to be used to match all standard instructions. */
832    if ((((MIPS_DECODE[loop].isa & MASK_ISA) <= doisa) && (((MIPS_DECODE[loop].isa & ~MASK_ISA) == 0) || ((MIPS_DECODE[loop].isa & ~MASK_ISA) & doarch) != 0)) && (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))) {
833      unsigned int onemask;
834      unsigned int zeromask;
835      unsigned int dontmask;
836      unsigned int mask;
837      unsigned int number;
838      unsigned int flags = convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
839      char *regtype = ((gprlen == 64) ? "uword64" : "unsigned int");
840
841      if (!(MIPS_DECODE[loop].flags & COPROC) && ((GETDATASIZE() == DOUBLEWORD) && !proc64)) {
842        fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
843        exit(4);
844      }
845
846 #if defined(DEBUG)
847      printf("/* DEBUG: onemask  0x%08X */\n",onemask) ;
848      printf("/* DEBUG: zeromask 0x%08X */\n",zeromask) ;
849      printf("/* DEBUG: dontmask 0x%08X */\n",dontmask) ;
850 #endif
851
852      switch (MIPS_DECODE[loop].mark) {
853        case NORMAL :
854         mask = (OP_MASK_OP << OP_SH_OP) ;
855         number = ((onemask >> OP_SH_OP) & OP_MASK_OP) ;
856         break ;
857
858        case SPECIAL :
859         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
860         number = ((OP_MASK_OP + 1) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
861         break ;
862
863        case REGIMM :
864         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_RT << OP_SH_RT)) ;
865         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_RT) & OP_MASK_RT)) ;
866         break ;
867
868        case COP1 :
869         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
870         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
871         break ;
872
873        case COP1S :
874         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_COP1SPEC << OP_SH_COP1SPEC)) ;
875         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_COP1SPEC) & OP_MASK_COP1SPEC)) ;
876         break;
877
878        case COP1X :
879         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
880         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
881         break ;
882
883        default :
884         fprintf(stderr,"Unrecognised opcode mark %d in table slot %d \"%s\"\n",MIPS_DECODE[loop].mark,loop,MIPS_DECODE[loop].name) ;
885         exit(5) ;
886       }
887
888      printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
889
890 #if defined(DEBUG)
891      printf("/* DEBUG: mask 0x%08X */\n",mask) ;
892      printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
893 #endif
894
895      /* Check if there are any other explicit bits in the instruction: */
896      if ((~mask & (onemask | zeromask)) != 0x00000000) {
897        printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
898        printf(" {\n") ;
899        printf("  SignalException(ReservedInstruction,instruction);\n") ;
900        printf(" }\n") ;
901        printf(" else\n") ;
902      }
903
904      if ((flags == 0) && !(MIPS_DECODE[loop].flags & NOARG)) {
905        fprintf(stderr,"Bitmap error: Instruction with no operand fields \"%s\"\n",MIPS_DECODE[loop].name) ;
906        exit(5) ;
907      }
908
909      printf(" {\n") ;
910
911      /* Get hold of the operands */
912      /* NOTE: If we wanted to make the simulator code smaller, we
913       * could pull these into a common sequence before we perform
914       * the instruction decoding. However, this would affect the
915       * performance since unnecessary field extraction would be
916       * occurring for certain instructions.
917       *
918       * Also we do not perform checking for multiple definitions of a
919       * particular operand here, since they are caught by the
920       * compilation of the produced code.
921       */
922      build_operands(flags);
923
924      /* Finish constructing the jump address if required: */
925      if (flags & fieldval('j'))
926       printf("  op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */\n");
927
928      /* Now perform required operand checks: */
929
930 /* The following code has been removed, since it seems perfectly
931    reasonable to have a non-aligned offset that is added to another
932    non-aligned base to create an aligned address. Some more
933    information on exactly what the MIPS IV specification requires is
934    needed before deciding on the best strategy. Experimentation with a
935    VR4300 suggests that we do not need to raise the warning. */
936 #if 0
937      /* For MIPS IV (and onwards), certain instruction operand values
938         will give undefined results. For the simulator we could
939         generate explicit exceptions (i.e. ReservedInstruction) to
940         make it easier to spot invalid use. However, for the moment we
941         just raise a warning. NOTE: This is a different check to the
942         later decoding, which checks for the final address being
943         valid. */
944      if ((flags & (fieldval('e') | fieldval('w') | fieldval('h'))) && (doisa >= 4)) {
945        printf("  if (instruction & 0x%1X)\n",((flags & fieldval('e')) ? 0x7 : ((flags & fieldval('w')) ? 0x3 : 0x1)));
946        printf("  {\n");
947        /* NOTE: If we change this to a SignalException(), we must
948           ensure that the following opcode processing is not
949           executed. i.e. the code falls straight out to the simulator
950           control loop. */
951        printf("   sim_warning(\"Instruction has lo-order offset bits set in instruction\");\n");
952        printf("  }\n");
953      }
954 #endif
955
956      /* The extended condition codes only appeared in ISA IV */
957      if ((flags & fieldval('p')) && (doisa < 4)) {
958        printf("  if (condition_code != 0)\n");
959        printf("  {\n");
960        printf("   SignalException(ReservedInstruction,instruction);\n");
961        printf("  }\n");
962        printf("  else\n");
963      }
964
965      if ((MIPS_DECODE[loop].flags & WORD32) && (GETDATASIZE() != WORD)) {
966        fprintf(stderr,"Error in opcode table: WORD32 set for non-WORD opcode\n");
967        exit(1);
968      }
969
970 #if 1
971      /* The R4000 book differs slightly from the MIPS IV ISA
972         manual. An example is the sign-extension of a 64-bit processor
973         SUBU operation, and what is meant by an Undefined Result. This
974         is now provided purely as a warning. After examining a HW
975         implementation, this is now purely a warning... and the actual
976         operation is performed, with possibly undefined results. */
977      if (((MIPS_DECODE[loop].flags & WORD32) && proc64) && (features & FEATURE_WARN_RESULT)) {
978        /* The compiler should optimise out an OR with zero */
979        printf("  if (%s | %s)\n",((flags & fieldval('s')) ? "NOTWORDVALUE(op1)" : "0"),((flags & fieldval('g')) ? "NOTWORDVALUE(op2)" : "0"));
980        printf("   UndefinedResult();\n") ;
981      }
982 #else
983      /* Check that the source is a 32bit value */
984      if ((MIPS_DECODE[loop].flags & WORD32) && proc64) {
985        /* The compiler should optimise out an OR with zero */
986        printf("  if (%s | %s)\n",((flags & fieldval('s')) ? "NOTWORDVALUE(op1)" : "0"),((flags & fieldval('g')) ? "NOTWORDVALUE(op2)" : "0"));
987        printf("   UndefinedResult();\n") ;
988        printf("  else\n") ;
989      }
990 #endif
991
992      printf("  {\n") ;
993
994      switch (MIPS_DECODE[loop].type) {
995        /* TODO: To make these easier to edit and maintain, they should
996           actually be provided as source macros (or inline functions)
997           OUTSIDE this main switch statement. The PPC simulator has a
998           neater scheme for describing the instruction sequences. */
999
1000        case ADD:
1001        case SUB:
1002         {
1003           char *signed_basetype = "unknown";
1004           char *unsigned_basetype = "unknown";
1005
1006           switch (GETDATASIZE()) {
1007             case WORD :
1008              signed_basetype = "signed int";
1009              unsigned_basetype = "unsigned int";
1010              break;
1011             case DOUBLEWORD :
1012              signed_basetype = "word64";
1013              unsigned_basetype = "uword64";
1014              break;
1015             default :
1016              fprintf(stderr,"Opcode table error: size of ADD/SUB operands not known (%d)\n",GETDATASIZE());
1017              exit(1);
1018           }
1019
1020           if ((MIPS_DECODE[loop].type) == ADD) {
1021             printf("   %s temp = (%s)(op1 + op2);\n", unsigned_basetype, unsigned_basetype);
1022             printf("   %s tempS = (%s)temp;\n", signed_basetype, signed_basetype);
1023             if (MIPS_DECODE[loop].flags & OVERFLOW) {
1024               printf("   if (((op1 < 0) == (op2 < 0)) && ((tempS < 0) != (op1 < 0)))\n");
1025               printf("    SignalException(IntegerOverflow);\n");
1026               printf("   else\n");
1027             }
1028             if (!proc64 || (MIPS_DECODE[loop].flags & UNSIGNED) || (GETDATASIZE() == DOUBLEWORD))
1029              printf("   GPR[destreg] = (%s)temp;\n",regtype);
1030             else /* only sign-extend when placing 32bit result in 64bit processor */
1031              printf("   GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
1032           } else { /* SUB */
1033             printf("   %s temp = (%s)(op1 - op2);\n", unsigned_basetype, unsigned_basetype);
1034             printf("   %s tempS = (%s)temp;\n", signed_basetype, signed_basetype);
1035             if (MIPS_DECODE[loop].flags & OVERFLOW) { /* different signs => overflow if result_sign != arg_sign */
1036               printf("   if (((op1 < 0) != (op2 < 0)) && ((tempS < 0) == (op1 < 0)))\n");
1037               printf("    SignalException(IntegerOverflow);\n");
1038               printf("   else\n");
1039             }
1040             /* UNSIGNED 32bit operations on a 64bit processor should
1041                *STILL* be sign-extended. We have cheated in the
1042                data-structure, by not marking it with UNSIGNED, and not
1043                setting OVERFLOW. */
1044             if (!proc64 || (MIPS_DECODE[loop].flags & UNSIGNED) || (GETDATASIZE() == DOUBLEWORD))
1045              printf("   GPR[destreg] = (%s)temp;\n",regtype);
1046             else /* only sign-extend when placing 32bit result in 64bit processor */
1047              printf("   GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
1048           }
1049         }
1050         break ;
1051
1052        case MUL:
1053         if (features & FEATURE_WARN_LOHI) {
1054           printf("   CHECKHILO(\"Multiplication\");\n");
1055         }
1056         printf("   {\n");
1057         if (GETDATASIZE() == DOUBLEWORD) {
1058           printf("   uword64 mid;\n");
1059           printf("   uword64 midhi;\n");
1060           printf("   uword64 temp;\n");
1061           if ((MIPS_DECODE[loop].flags & UNSIGNED) == 0)
1062             {
1063               printf("   int sign = 0;\n");
1064               printf("   if (op1 < 0) { op1 = - op1; ++sign; }\n");
1065               printf("   if (op2 < 0) { op2 = - op2; ++sign; }\n");
1066             }
1067           printf("   LO = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n");
1068           printf("   HI = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n");
1069           printf("   mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
1070           printf("   midhi = SET64HI(WORD64LO(mid));\n");
1071           printf("   temp = (LO + midhi);\n");
1072           printf("   if ((temp == midhi) ? (LO != 0) : (temp < midhi))\n");
1073           printf("    HI += 1;\n");
1074           printf("   HI += WORD64HI(mid);\n");
1075           printf("   mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
1076           printf("   midhi = SET64HI(WORD64LO(mid));\n");
1077           printf("   LO = (temp + midhi);\n");
1078           printf("   if ((LO == midhi) ? (temp != 0) : (LO < midhi))\n");
1079           printf("    HI += 1;\n");
1080           printf("   HI += WORD64HI(mid);\n");
1081           if ((MIPS_DECODE[loop].flags & UNSIGNED) == 0)
1082             printf("   if (sign & 1) { LO = - LO; HI = (LO == 0 ? 0 : -1) - HI; }\n");
1083         } else {
1084           if (MIPS_DECODE[loop].flags & UNSIGNED)
1085             printf("   uword64 temp = ((uword64)(op1 & 0xffffffff) * (uword64)(op2 & 0xffffffff));\n");
1086           else
1087             printf("   uword64 temp = (op1 * op2);\n");
1088           printf("   LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
1089           printf("   HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
1090         }
1091         printf("   }\n");
1092         break ;
1093
1094        case DIV:
1095         {
1096          int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1097
1098          if (features & FEATURE_WARN_LOHI) {
1099            printf("   CHECKHILO(\"Division\");\n");
1100          }
1101          printf("   {\n");
1102          if (GETDATASIZE() == DOUBLEWORD) {
1103            printf("   LO = ((%sword64)op1 / (%sword64)op2);\n",(boolU ? "u" : ""),(boolU ? "u" : ""));
1104            printf("   HI = ((%sword64)op1 %c (%sword64)op2);\n",(boolU ? "u" : ""),'%',(boolU ? "u" : ""));
1105          } else {
1106            printf("   LO = SIGNEXTEND(((%sint)op1 / (%sint)op2),32);\n",(boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
1107            printf("   HI = SIGNEXTEND(((%sint)op1 %c (%sint)op2),32);\n",(boolU ? "unsigned " : ""),'%',(boolU ? "unsigned " : ""));
1108          }
1109          printf("   }\n");
1110         }
1111         break ;
1112
1113        case SHIFT:
1114         {
1115          int datalen = GETDATASIZE();
1116          int bits = ((datalen == WORD) ? 32 : 64);
1117          char *ltype = ((datalen == WORD) ? "unsigned int" : "uword64");
1118
1119          /* Check that the specified SHIFT is valid: */
1120          if ((datalen == BYTE) || (datalen == HALFWORD)) {
1121            fprintf(stderr,"Shift \"%s\" specified with BYTE or HALFWORD\n",MIPS_DECODE[loop].name);
1122            exit(9);
1123          }
1124          if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & RIGHT)) {
1125            fprintf(stderr,"Shift \"%s\" specified with both LEFT and RIGHT\n",MIPS_DECODE[loop].name);
1126            exit(9);
1127          }
1128          if (!(MIPS_DECODE[loop].flags & LEFT) && !(MIPS_DECODE[loop].flags & RIGHT)) {
1129            fprintf(stderr,"Shift \"%s\" specified with neither LEFT or RIGHT\n",MIPS_DECODE[loop].name);
1130            exit(9);
1131          }
1132          if ((MIPS_DECODE[loop].flags & LOGICAL) && (MIPS_DECODE[loop].flags & ARITHMETIC)) {
1133            fprintf(stderr,"Shift \"%s\" specified with both LOGICAL and ARITHMETIC\n",MIPS_DECODE[loop].name);
1134            exit(9);
1135          }
1136          if (!(MIPS_DECODE[loop].flags & LOGICAL) && !(MIPS_DECODE[loop].flags & ARITHMETIC)) {
1137            fprintf(stderr,"Shift \"%s\" specified with neither LOGICAL or ARITHMETIC\n",MIPS_DECODE[loop].name);
1138            exit(9);
1139          }
1140          if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & ARITHMETIC)) {
1141            fprintf(stderr,"Arithmetic LEFT shift \"%s\" specified\n",MIPS_DECODE[loop].name);
1142            exit(9);
1143          }
1144
1145          /* If register specified shift, then extract the relevant shift amount: */
1146          if (flags & fieldval('s'))
1147           printf("   op1 &= 0x%02X;\n",(bits - 1));
1148
1149          /* If HI32 specified, then shift range is 32..63 */
1150          if (MIPS_DECODE[loop].flags & HI32)
1151           printf("   op1 |= (1 << 5);\n");
1152
1153          /* We do not need to perform pre-masking with 0xFFFFFFFF when
1154             dealing with 32bit shift lefts, since the sign-extension
1155             code will replace any remaining hi-bits: */
1156          if (MIPS_DECODE[loop].flags & LEFT)
1157           printf("   GPR[destreg] = ((uword64)op2 << op1);\n");
1158          else
1159           printf("   GPR[destreg] = ((uword64)(op2%s) >> op1);\n",((bits == 32) ? " & 0xFFFFFFFF" : ""));
1160
1161          /* For ARITHMETIC shifts, we must duplicate the sign-bit.  We
1162             don't do this if op1 is zero, since it is not needed and
1163             since that would cause an undefined shift of the number of
1164             bits in the type.  */
1165          if (MIPS_DECODE[loop].flags & ARITHMETIC)
1166           printf("   GPR[destreg] |= (op1 != 0 && (op2 & ((%s)1 << %d)) ? ((((%s)1 << op1) - 1) << (%d - op1)) : 0);\n",ltype,(bits - 1),ltype,bits);
1167
1168          /* Ensure WORD values are sign-extended into 64bit registers */
1169          if ((bits == 32) && (gprlen == 64))
1170           printf("   GPR[destreg] = SIGNEXTEND(GPR[destreg],%d);\n",bits);
1171         }
1172         break ;
1173
1174        case MOVE:
1175         if (MIPS_DECODE[loop].flags & (HI | LO)) {
1176           char *regname = ((MIPS_DECODE[loop].flags & LO) ? "LO" : "HI");
1177           if (flags & fieldval('d'))
1178            printf("   GPR[destreg] = %s;\n",regname);
1179           else {
1180             if (features & FEATURE_WARN_LOHI) {
1181               printf("   if (%sACCESS != 0)\n",regname);
1182               printf("     sim_warning(\"MT (move-to) over-writing %s register value\");\n",regname);
1183             }
1184             printf("   %s = op1;\n",regname);
1185           }
1186           if (features & FEATURE_WARN_LOHI)
1187            printf("   %sACCESS = 3; /* 3rd instruction will be safe */\n",regname);
1188         } else
1189          if (MIPS_DECODE[loop].flags & SHIFT16)
1190           printf("   GPR[destreg] = (op2 << 16);\n");
1191          else {
1192            /* perform conditional move */
1193            if (!(MIPS_DECODE[loop].flags & EQ)) {
1194              fprintf(stderr,"Standard conditional %s does not have the equality flag\n",MIPS_DECODE[loop].name);
1195              exit(8);
1196            }
1197            printf("   if (op2 %c= 0)\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1198            printf("    GPR[destreg] = op1;\n");
1199          }
1200         break ;
1201
1202        case SYNC:
1203         printf("   SyncOperation(op1);\n");
1204         break ;
1205
1206        case SYSCALL:
1207         printf("   SignalException(SystemCall);\n");
1208         break ;
1209
1210        case BREAK:
1211         printf("   SignalException(BreakPoint);\n");
1212         break ;
1213
1214        case TRAP:
1215         {
1216          int boolNOT = (MIPS_DECODE[loop].flags & NOT);
1217          int boolEQ  = (MIPS_DECODE[loop].flags & EQ);
1218          int boolGT  = (MIPS_DECODE[loop].flags & GT);
1219          int boolLT  = (MIPS_DECODE[loop].flags & LT);
1220          int boolU   = (MIPS_DECODE[loop].flags & UNSIGNED);
1221
1222          if (boolGT && boolLT) {
1223            fprintf(stderr,"GT and LT specified for \"%s\"\n",MIPS_DECODE[loop].name);
1224            exit(8);
1225          }
1226
1227          if (boolNOT && (boolGT || boolLT)) {
1228            fprintf(stderr,"NOT specified with GT or LT specified for \"%s\"\n",MIPS_DECODE[loop].name);
1229            exit(8);
1230          }
1231
1232          printf("  if ((%sword64)op1 ",(boolU ? "u" : ""));
1233          printf("%c%s",(boolNOT ? '!' : (boolLT ? '<' : (boolGT ? '>' : '='))),(boolEQ ? "=" : ""));
1234          printf(" (%sword64)op2)\n",(boolU ? "u" : ""));
1235          printf("   SignalException(Trap);\n");
1236         }
1237         break ;
1238
1239        case SET:
1240         {
1241          int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1242
1243          if (!(MIPS_DECODE[loop].flags & LT)) {
1244            fprintf(stderr,"Set instruction without LT specified \"%s\"\n",MIPS_DECODE[loop].name);
1245            exit(8);
1246          }
1247
1248          printf("   if ((%sword64)op1 < (%sword64)op2)\n",(boolU ? "u" : ""),(boolU ? "u" : ""));
1249          printf("    GPR[destreg] = 1;\n");
1250          printf("   else\n");
1251          printf("    GPR[destreg] = 0;\n");
1252         }
1253         break ;
1254
1255        case AND:
1256         printf("   GPR[destreg] = (op1 & op2);\n");
1257         break ;
1258
1259        case OR:
1260         printf("   GPR[destreg] = %s(op1 | op2);\n",((MIPS_DECODE[loop].flags & NOT) ? "~" : ""));
1261         break ;
1262
1263        case XOR:
1264         printf("   GPR[destreg] = (op1 ^ op2);\n");
1265         break ;
1266
1267        case DECODE:
1268         printf("   decode_coproc(instruction);\n");
1269         break ;
1270
1271        case CACHE:
1272         /* 16-bit offset is sign-extended and added to the base register to make a virtual address */
1273         /* The virtual address is translated to a physical address using the TLB */
1274         /* The hint specifies a cache operation for that address */
1275         printf("    uword64 vaddr = (op1 + offset);\n");
1276         printf("    uword64 paddr;\n");
1277         printf("    int uncached;\n");
1278         /* NOTE: We are assuming that the AddressTranslation is a load: */
1279         printf("    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
1280         printf("      CacheOp(hint,vaddr,paddr,instruction);\n");
1281         break;
1282
1283        case MADD16: /* VR4100 specific multiply-add instructions */
1284         /* Some of this code is shared with the standard multiply
1285            routines, so an effort should be made to merge where
1286            possible. */
1287         if (features & FEATURE_WARN_LOHI) {
1288           printf("   CHECKHILO(\"Multiply-Add\");\n");
1289         }
1290         if (features & FEATURE_WARN_RESULT) {
1291           /* Give user a warning if either op1 or op2 are not 16bit signed integers */
1292           printf("   if (NOTHALFWORDVALUE(op1) || NOTHALFWORDVALUE(op2))\n");
1293           printf("     sim_warning(\"MADD16 operation with non-16bit operands\");\n");
1294         }
1295         printf("   {\n");
1296         printf("    uword64 temp = (op1 * op2);\n"); /* 16x16 multiply */
1297         if (GETDATASIZE() == DOUBLEWORD) {
1298           printf("   LO = LO + temp;\n");
1299         } else { /* WORD */
1300           printf("   temp += (SET64HI(WORD64LO(HI)) | WORD64LO(LO));\n");
1301           printf("   LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
1302           printf("   HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
1303         }
1304         printf("   }\n");
1305         break;
1306
1307        case RSVD: /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "CoProcessorUnusable" */
1308         if (doisa < 4) {
1309           printf("   if (CoProcPresent(3))\n");
1310           printf("    SignalException(CoProcessorUnusable);\n");
1311           printf("   else\n");
1312         }
1313         printf("   SignalException(ReservedInstruction,instruction);\n");
1314         break ;
1315
1316        case JUMP:
1317         if (MIPS_DECODE[loop].flags & LINK) {
1318           if (!(MIPS_DECODE[loop].flags & REG))
1319            printf("   int destreg = 31;\n");
1320           printf("   GPR[destreg] = (PC + 4); /* NOTE: The PC is already 4 ahead within the simulator */\n");
1321         }
1322
1323         printf("   /* NOTE: The jump occurs AFTER the next instruction has been executed */\n");
1324         printf("   DSPC = op1;\n");
1325         printf("   DELAYSLOT();\n");
1326         break ;
1327
1328        case BRANCH: /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
1329         if (MIPS_DECODE[loop].flags & FP) {
1330           if (doisa < 4) {
1331             printf("  if (condition_code != 0)\n");
1332             printf("   SignalException(ReservedInstruction,instruction);\n");
1333             printf("  else {\n");
1334           }
1335           /* "PREVCOC1()" should be the COC1 value at the start of the preceding instruction */
1336           printf("   int condition = (%s == boolean);\n",((doisa < 4) ? "PREVCOC1()" : "GETFCC(condition_code)"));
1337         } else {
1338           if ((MIPS_DECODE[loop].flags & NOT) && !(MIPS_DECODE[loop].flags & EQ)) {
1339             fprintf(stderr,"NOT specified when not EQ in \"%s\"\n",MIPS_DECODE[loop].name);
1340             exit(7);
1341           }
1342           if ((MIPS_DECODE[loop].flags & NOT) && (MIPS_DECODE[loop].flags & (GT | LT))) {
1343             fprintf(stderr,"NOT specified with GT or LT in \"%s\"\n",MIPS_DECODE[loop].name);
1344             exit(7);
1345           }            
1346           /* GT  LT */
1347           if (MIPS_DECODE[loop].flags & GT)
1348            printf("   int condition = (op1 >%s 0);\n",((MIPS_DECODE[loop].flags & EQ) ? "=" : ""));
1349           else
1350            if (MIPS_DECODE[loop].flags & LT)
1351             printf("   int condition = (op1 <%s 0);\n",((MIPS_DECODE[loop].flags & EQ) ? "=" : ""));
1352            else
1353             if (MIPS_DECODE[loop].flags & EQ)
1354              printf("   int condition = (op1 %c= op2);\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1355         }
1356
1357         if (MIPS_DECODE[loop].flags & LINK) {
1358           if (features & FEATURE_WARN_R31) {
1359             printf("   if (((instruction >> %d) & 0x%08X) == 31)\n",OP_SH_RS,OP_MASK_RS);
1360             printf("    sim_warning(\"Branch with link using r31 as source operand\");\n");
1361           }
1362           printf("   GPR[31] = (PC + 4); /* NOTE: PC is already 8 ahead */\n");
1363         }
1364
1365         printf("   /* NOTE: The branch occurs AFTER the next instruction has been executed */\n");
1366         printf("   if (condition) {\n");
1367         printf("    DSPC = (PC + offset);\n");
1368         printf("    DELAYSLOT();\n");
1369         printf("   }\n");
1370         if ((MIPS_DECODE[loop].flags & FP) && (doisa != 1)) {
1371           printf("   else if (likely) {\n");
1372           printf("    NULLIFY();\n");
1373           printf("   }\n");
1374         } else if (MIPS_DECODE[loop].flags & LIKELY) {
1375           printf("   else\n");
1376           printf("    NULLIFY();\n");
1377         }
1378         if ((MIPS_DECODE[loop].flags & FP) && (doisa < 4))
1379          printf("   }\n");
1380         break ;
1381
1382        case PREFETCH: /* The beginning is shared with normal load operations */
1383        case LOAD:
1384        case STORE:
1385         {
1386          int isload = ((MIPS_DECODE[loop].type == LOAD) || (MIPS_DECODE[loop].type == PREFETCH));
1387          int datalen;
1388          char *accesslength = "<UNKNOWN>";
1389
1390          switch (GETDATASIZE()) {
1391            case BYTE :
1392             datalen = 1;
1393             accesslength = "AccessLength_BYTE";
1394             break ;
1395
1396            case HALFWORD :
1397             datalen = 2;
1398             accesslength = "AccessLength_HALFWORD";
1399             break ;
1400
1401            case WORD :
1402             datalen = 4;
1403             accesslength = "AccessLength_WORD";
1404             break ;
1405
1406            case DOUBLEWORD :
1407             datalen = 8;
1408             accesslength = "AccessLength_DOUBLEWORD";
1409             break ;
1410          }
1411
1412          if (MIPS_DECODE[loop].flags & REG)
1413           printf("   uword64 vaddr = ((uword64)op1 + op2);\n");
1414          else
1415           printf("   uword64 vaddr = ((uword64)op1 + offset);\n");
1416          printf("   uword64 paddr;\n");
1417          printf("   int uncached;\n");
1418
1419          /* The following check should only occur on normal (non-shifted) memory loads */
1420          if ((datalen != 1) && !(MIPS_DECODE[loop].flags & (LEFT | RIGHT))) {
1421            printf("   if ((vaddr & %d) != 0)\n",(datalen - 1));
1422            printf("    SignalException(%s);\n",(isload ? "AddressLoad" : "AddressStore"));
1423            printf("   else\n") ;
1424          }
1425
1426          printf("   {\n");
1427          printf("    if (AddressTranslation(vaddr,isDATA,%s,&paddr,&uncached,isTARGET,isREAL))\n",(isload ? "isLOAD" : "isSTORE"));
1428
1429          if (MIPS_DECODE[loop].type == PREFETCH)
1430           printf("     Prefetch(uncached,paddr,vaddr,isDATA,hint);\n");
1431          else {
1432            printf("    {\n");
1433            printf("     %s memval;\n",(proc64 ? "uword64" : "unsigned int"));
1434
1435            if ((MIPS_DECODE[loop].flags & COPROC) && ((datalen != 4) && (datalen != 8))) {
1436              fprintf(stderr,"Co-processor transfer operation not WORD or DOUBLEWORD in length \"%s\"\n",MIPS_DECODE[loop].name);
1437              exit(6);
1438            }
1439
1440            if (MIPS_DECODE[loop].flags & (LEFT | RIGHT)) {
1441              if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & RIGHT)) {
1442                fprintf(stderr,"Memory transfer with both LEFT and RIGHT specified \"%s\"\n",MIPS_DECODE[loop].name);
1443                exit(4);
1444              }
1445
1446              switch (datalen) {
1447               case 8:
1448                if (!proc64) {
1449                  fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",MIPS_DECODE[loop].name);
1450                  exit(4);
1451                }
1452                /* fall through to... */
1453               case 4:
1454                {
1455                  char *maskstr = ((datalen == 8) ? "((uword64)-1)" : "0xFFFFFFFF");
1456
1457                  printf("     uword64 mask = %d;\n",((datalen == 8) ? 0x7 : 0x3));
1458                  printf("     unsigned int reverse = (ReverseEndian ? mask : 0);\n");
1459                  printf("     unsigned int bigend = (BigEndianCPU ? mask : 0);\n");
1460                  printf("     int byte;\n");
1461                  printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));\n");
1462                  printf("     byte = ((vaddr & mask) ^ bigend);\n");
1463                  printf("     if (%sBigEndianMem)\n",((MIPS_DECODE[loop].flags & LEFT) ? "!" : ""));
1464                  printf("      paddr &= ~mask;\n");
1465
1466                  if (isload) {
1467                    if (MIPS_DECODE[loop].flags & LEFT)
1468                     printf("     memval = LoadMemory(uncached,byte,paddr,vaddr,isDATA,isREAL);\n");
1469                    else
1470                     printf("     memval = LoadMemory(uncached,(%d - byte),paddr,vaddr,isDATA,isREAL);\n",(datalen - 1));
1471                  }
1472
1473                  if (MIPS_DECODE[loop].flags & LEFT) {
1474                    if (isload) {
1475                      /* For WORD transfers work out if the value will
1476                         be in the top or bottom of the DOUBLEWORD
1477                         returned: */
1478 #if 1
1479                      build_endian_shift(proc64,datalen,2,s_right,32);
1480 #else
1481                      if (proc64 && (datalen == 4)) {
1482                        printf("     if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1483                        printf("      memval >>= 32;\n");
1484                        printf("     }\n");
1485                      }
1486 #endif
1487                      printf("     GPR[destreg] = ((memval << ((%d - byte) * 8)) | (GPR[destreg] & (((uword64)1 << ((%d - byte) * 8)) - 1)));\n",(datalen - 1),(datalen - 1));
1488                      if (proc64 && (datalen == 4))
1489                       printf("     GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
1490                    } else { /* store */
1491                      printf("     memval = (op2 >> (8 * (%d - byte)));\n",(datalen - 1));
1492 #if 1
1493                      build_endian_shift(proc64,datalen,2,s_left,32);
1494 #else
1495                      /* TODO: This is duplicated in the LOAD code
1496                         above - and the RIGHT LOAD and STORE code
1497                         below. It should be merged if possible. */
1498                      if (proc64 && (datalen == 4)) {
1499                        printf("    if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1500                        printf("     memval <<= 32;\n");
1501                        printf("    }\n");
1502                      }
1503 #endif
1504                      printf("     StoreMemory(uncached,byte,memval,paddr,vaddr,isREAL);\n");
1505                    }
1506                  } else { /* RIGHT */
1507                    if (isload) {
1508 #if 1
1509                      build_endian_shift(proc64,datalen,2,s_right,32);
1510 #else
1511                      if (proc64 && (datalen == 4)) {
1512                        printf("     if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1513                        printf("      memval >>= 32;\n");
1514                        printf("     }\n");
1515                      }
1516 #endif
1517                      printf("     {\n");
1518                      printf("      uword64 srcmask;\n");
1519                      /* All of this extra code is just a bodge
1520                         required because some hosts don't allow
1521                         ((v) << 64). The SPARC just leaves the (v)
1522                         value un-touched. */
1523                      printf("      if (byte == 0)\n");
1524                      printf("       srcmask = 0;\n");
1525                      printf("      else\n");
1526                      printf("       srcmask = ((uword64)-1 << (8 * (%d - byte)));\n",datalen);
1527                      printf("      GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));\n",datalen);
1528                      printf("     }\n");
1529                      if (proc64 && (datalen == 4))
1530                       printf("     GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
1531                    } else { /* store */
1532                      printf("     memval = (op2 << (byte * 8));\n");
1533                      build_endian_shift(proc64,datalen,2,s_left,32);
1534                      printf("     StoreMemory(uncached,(%s - byte),memval,paddr,vaddr,isREAL);\n",accesslength);
1535                    }
1536                  }
1537                }
1538                break;
1539
1540               default:
1541                fprintf(stderr,"Shifted memory transfer not WORD or DOUBLEWORD in length \"%s\"\n",MIPS_DECODE[loop].name);
1542                exit(6);
1543              }
1544            } else { /* normal memory transfer */
1545              if (!(MIPS_DECODE[loop].flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (MIPS_DECODE[loop].flags & UNSIGNED))) && !proc64) {
1546                fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",MIPS_DECODE[loop].name);
1547                exit(4);
1548                /* TODO: The R4000 documentation states that a LWU
1549                   instruction executed when in a 32bit processor mode
1550                   should cause a ReservedInstruction exception. This
1551                   will mean adding a run-time check into the code
1552                   sequence. */
1553              }
1554
1555              if (isload) {
1556 #if 1 /* see the comments attached to LOADDRMASK above */
1557                printf("     uword64 mask = 0x7;\n");
1558 #else
1559                printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
1560 #endif
1561                printf("     unsigned int shift = %d;\n",(datalen >> 1));
1562                printf("     unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
1563                printf("     unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
1564                printf("     unsigned int byte;\n");
1565
1566 /* TODO: This should really also check for 32bit world performing 32bit access */
1567                if (datalen != 8) /* not for DOUBLEWORD */
1568                 printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
1569
1570                printf("     memval = LoadMemory(uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
1571
1572                /* The following will only make sense if the
1573                   "LoadMemory" above returns a DOUBLEWORD entity */
1574                if (datalen != 8) { /* not for DOUBLEWORD */
1575                  int valmask;
1576                  switch (datalen) {
1577                   case 1:
1578                    valmask = 0xFF;
1579                    break;
1580
1581                   case 2:
1582                    valmask = 0xFFFF;
1583                    break;
1584
1585                   case 4:
1586                    valmask = 0xFFFFFFFF;
1587                    break;
1588
1589                   default:
1590                    fprintf(stderr,"Unrecognised datalen (%d) when processing \"%s\"\n",datalen,MIPS_DECODE[loop].name);
1591                    exit(4);
1592                  }
1593                  printf("     byte = ((vaddr & mask) ^ (bigend << shift));\n");
1594                  /* NOTE: The R4000 user manual has the COP_LW
1595                     occuring in the same cycle as the rest of the
1596                     instruction, yet the MIPS IV shows the operation
1597                     happening on the next cycle. To keep the simulator
1598                     simple, this code follows the R4000
1599                     manual. Experimentation with a silicon
1600                     implementation will be needed to ascertain the
1601                     correct operation. */
1602                  if (MIPS_DECODE[loop].flags & COPROC)
1603                   printf("     COP_LW(%s,destreg,(unsigned int)",
1604                          ((MIPS_DECODE[loop].flags & REG)
1605                           ? "1"
1606                           : "((instruction >> 26) & 0x3)"));
1607                  else
1608                   printf("     GPR[destreg] = (");
1609
1610                  if (MIPS_DECODE[loop].flags & SIGNEXTEND)
1611                   printf("SIGNEXTEND(");
1612                  printf("((memval >> (8 * byte)) & 0x%08X)",valmask);
1613                  if (MIPS_DECODE[loop].flags & SIGNEXTEND)
1614                   printf(",%d)",(datalen * 8));
1615                  printf(");\n");
1616                } else {
1617                  if (MIPS_DECODE[loop].flags & COPROC)
1618                   printf("     COP_LD(%s,destreg,memval);;\n",
1619                          ((MIPS_DECODE[loop].flags & REG)
1620                           ? "1"
1621                           : "((instruction >> 26) & 0x3)"));
1622                  else
1623                   printf("     GPR[destreg] = memval;\n");
1624                }
1625              } else { /* store operation */
1626                if ((datalen == 1) || (datalen == 2)) {
1627                  /* SH and SB */
1628 #if 1 /* see the comments attached to LOADDRMASK above */
1629                  printf("     uword64 mask = 0x7;\n");
1630 #else
1631                  printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
1632 #endif
1633                  printf("     unsigned int shift = %d;\n",(datalen >> 1));
1634                  printf("     unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
1635                  printf("     unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
1636                  printf("     unsigned int byte;\n");
1637
1638                  printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
1639                  printf("     byte = ((vaddr & mask) ^ (bigend << shift));\n");
1640                  printf("     memval = (op2 << (8 * byte));\n");
1641                } else
1642                 if (proc64 && (datalen == 4)) { /* proc64 SC and SW */
1643 #if 1 /* see the comments attached to LOADDRMASK above */
1644                   printf("     uword64 mask = 0x7;\n");
1645 #else
1646                   printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
1647 #endif
1648                   printf("     unsigned int byte;\n");
1649                   printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));\n");
1650                   printf("     byte = ((vaddr & mask) ^ (BigEndianCPU << 2));\n");
1651                   if (MIPS_DECODE[loop].flags & COPROC)
1652                    printf("     memval = (((uword64)COP_SW(%s,%s)) << (8 * byte));\n",
1653                           ((MIPS_DECODE[loop].flags & REG)
1654                            ? "1"
1655                            : "((instruction >> 26) & 0x3)"),
1656                           ((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
1657                   else
1658                    printf("     memval = (op2 << (8 * byte));\n");
1659                 } else { /* !proc64 SC and SW, plus proc64 SD and SCD */
1660                   if (MIPS_DECODE[loop].flags & COPROC)
1661                    printf("     memval = (uword64)COP_S%c(%s,%s);\n",
1662                           ((datalen == 8) ? 'D' : 'W'),
1663                           ((MIPS_DECODE[loop].flags & REG)
1664                            ? "1"
1665                            : "((instruction >> 26) & 0x3)"),
1666                           ((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
1667                   else
1668                    printf("     memval = op2;\n");
1669                 }
1670
1671                if (MIPS_DECODE[loop].flags & ATOMIC)
1672                 printf("      if (LLBIT)\n");
1673
1674                printf("      {\n");
1675                printf("       StoreMemory(uncached,%s,memval,paddr,vaddr,isREAL);\n",accesslength);
1676                printf("      }\n");
1677              }
1678
1679              if (MIPS_DECODE[loop].flags & ATOMIC) {
1680                if ((datalen != 4) && (datalen != 8)) {
1681                  fprintf(stderr,"ATOMIC can only be applied to WORD and DOUBLEWORD instructions \"%s\"\n",MIPS_DECODE[loop].name);
1682                  exit(4);
1683                } else
1684                 if (isload)
1685                  printf("     LLBIT = 1;\n");
1686                 else {
1687                   /* The documentation states that:
1688
1689                      SC *WILL* fail if coherent store into the same
1690                      block occurs, or if an exception occurs between
1691                      the LL and SC instructions.
1692
1693                      SC *MAY* fail if a load, store or prefetch is
1694                      executed on the processor (VR4300 doesn't seem
1695                      to), or if the instructions between the LL and
1696                      SC are not in a 2048byte contiguous VM range.
1697
1698                      SC *MUST* have been preceded by an LL
1699                      (i.e. LLBIT will be set), and it must use the
1700                      same Vaddr, Paddr and cache-coherence algorithm
1701                      as the LL (which means we should store this
1702                      information from the load-conditional).
1703                      */
1704                   printf("     GPR[(instruction >> %d) & 0x%08X] = LLBIT;\n",OP_SH_RT,OP_MASK_RT);
1705                 }
1706              }
1707            }
1708            printf("    }\n");
1709          }
1710          printf("   }\n");
1711         }
1712         break ;
1713
1714        case FPPREFX:
1715         /* This code could be merged with the PREFIX generation above: */
1716         printf("   uword64 vaddr = ((uword64)op1 + (uword64)op2);\n");
1717         printf("   uword64 paddr;\n");
1718         printf("   int uncached;\n");
1719         printf("   if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
1720         printf("    Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
1721         break ;
1722
1723        case FPMOVEC:
1724         if (MIPS_DECODE[loop].flags & CONTROL) {
1725           /* The following "magic" of interpreting the FP
1726              control-register number would not be needed if we were not
1727              trying to match our internal register numbers with those
1728              used by GDB. */
1729           printf("    if (to) {\n");
1730           if (doisa < 4) {
1731             printf("     if (fs == 0) {\n");
1732             printf("      PENDING_FILL((fs + FCR0IDX),WORD64LO(GPR[ft]));\n");
1733             printf("     } else if (fs == 31) {\n");
1734             printf("      PENDING_FILL((fs + FCR31IDX),WORD64LO(GPR[ft]));\n");
1735             printf("     } /* else NOP */\n");
1736             printf("     PENDING_FILL(COCIDX,0); /* special case */\n");
1737           } else {
1738             printf("     if (fs == 0) {\n");
1739             printf("      FCR0 = WORD64LO(GPR[ft]);\n");
1740             printf("     } else if (fs == 31) {\n");
1741             printf("      FCR31 = WORD64LO(GPR[ft]);\n");
1742             printf("     } /* else NOP */\n");
1743             printf("     SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0)); /* COC[1] */\n");
1744           }
1745           printf("    } else { /* control from */\n");
1746           if (doisa < 4) {
1747             printf("     if (fs == 0) {\n");
1748             printf("      PENDING_FILL(ft,SIGNEXTEND(FCR0,32));\n");
1749             printf("     } else if (fs == 31) {\n");
1750             printf("      PENDING_FILL(ft,SIGNEXTEND(FCR31,32));\n");
1751             printf("     } /* else NOP */\n");
1752           } else {
1753             printf("     if (fs == 0) {\n");
1754             printf("      GPR[ft] = SIGNEXTEND(FCR0,32);\n");
1755             printf("     } else if (fs == 31) {\n");
1756             printf("      GPR[ft] = SIGNEXTEND(FCR31,32);\n");
1757             printf("     } /* else NOP */\n");
1758           }
1759           printf("    }\n");
1760         } else {
1761           printf("    if (to) {\n");
1762           if (GETDATASIZE() == WORD) {
1763             if (doisa < 4) { 
1764               printf("     if (SizeFGR() == 64) {\n");
1765               printf("      PENDING_FILL((fs + FGRIDX),(SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft])));\n");
1766               printf("     } else { \n");
1767               printf("      PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
1768               printf("     }\n");
1769             } else {
1770               printf("     if (SizeFGR() == 64)\n");
1771               printf("      FGR[fs] = (SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft]));\n");
1772               printf("     else\n");
1773               printf("      FGR[fs] = WORD64LO(GPR[ft]);\n");
1774               printf("     fpr_state[fs] = fmt_uninterpreted;\n");
1775             }
1776           } else if (GETDATASIZE() == DOUBLEWORD) {
1777             if (doisa < 4) {
1778               printf("     if (SizeFGR() == 64) {\n");
1779               printf("      PENDING_FILL((fs + FGRIDX),GPR[ft]);\n");
1780               printf("     } else\n");
1781               printf("      if ((fs & 0x1) == 0)\n");
1782               printf("       {\n");
1783               printf("        PENDING_FILL(((fs + 1) + FGRIDX),WORD64HI(GPR[ft]));\n");
1784               printf("        PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
1785               printf("       }\n");
1786               if (features & FEATURE_WARN_RESULT) {
1787                 printf("      else\n");
1788                 printf("       UndefinedResult();\n");
1789               }
1790             } else {
1791               printf("     if (SizeFGR() == 64) {\n");
1792               printf("      FGR[fs] = GPR[ft];\n");
1793               printf("      fpr_state[fs] = fmt_uninterpreted;\n");
1794               printf("     } else\n");
1795               printf("      if ((fs & 0x1) == 0)\n");
1796               printf("       {\n");
1797               printf("        FGR[fs + 1] = WORD64HI(GPR[ft]);\n");
1798               printf("        FGR[fs] = WORD64LO(GPR[ft]);\n");
1799               printf("        fpr_state[fs + 1] = fmt_uninterpreted;\n");
1800               printf("        fpr_state[fs] = fmt_uninterpreted;\n");
1801               printf("       }\n");
1802               if (features & FEATURE_WARN_RESULT) {
1803                 printf("      else\n");
1804                 printf("       UndefinedResult();\n");
1805               }
1806             }
1807           } else {
1808             fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
1809             exit(1);
1810           }
1811           printf("    } else {\n");
1812           if (GETDATASIZE() == WORD) {
1813             if (doisa < 4) /* write-back occurs in next cycle */
1814              printf("     PENDING_FILL(ft,SIGNEXTEND(FGR[fs],32));\n");
1815             else /* in this cycle */
1816              printf("     GPR[ft] = SIGNEXTEND(FGR[fs],32);\n");
1817           } else if (GETDATASIZE() == DOUBLEWORD) {
1818             if (doisa < 4) { 
1819               printf("     if (SizeFGR() == 64) {\n");
1820               printf("      PENDING_FILL(ft,FGR[fs]);\n");
1821               printf("     } else\n");
1822               printf("      if ((fs & 0x1) == 0) {\n");
1823               printf("       PENDING_FILL(ft,(SET64HI(FGR[fs+1]) | FGR[fs]));\n");
1824               printf("      } else {\n");
1825               printf("       PENDING_FILL(ft,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
1826               if (features & FEATURE_WARN_RESULT)
1827               printf("        UndefinedResult();\n");
1828               printf("      }\n");
1829             } else {
1830               printf("     if (SizeFGR() == 64)\n");
1831               printf("      GPR[ft] = FGR[fs];\n");
1832               printf("     else\n");
1833               printf("      if ((fs & 0x1) == 0)\n");
1834               printf("       GPR[ft] = (SET64HI(FGR[fs + 1]) | FGR[fs]);\n");
1835               printf("      else {\n");
1836               printf("       GPR[ft] = (SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
1837               if (features & FEATURE_WARN_RESULT)
1838               printf("       UndefinedResult();\n");
1839               printf("      }\n");
1840             }
1841           } else {
1842             fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
1843             exit(1);
1844           }
1845           printf("    }\n");
1846         }
1847         break ;
1848
1849        case FPMOVE:
1850         if (MIPS_DECODE[loop].flags & CONDITIONAL) {
1851           if (MIPS_DECODE[loop].flags & INTEGER) { /* moving GPR - testing FGR */
1852             printf("   if (GETFCC(condition_code) == boolean)\n");
1853             printf("    GPR[destreg] = op1;\n");
1854           } else {
1855             if (MIPS_DECODE[loop].flags & EQ) /* moving FGR - testing GPR */
1856              printf("   if (op2 %c= 0)\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1857             else
1858              printf("   if (GETFCC(condition_code) == boolean)\n");
1859             printf("    StoreFPR(destreg,format,ValueFPR(fs,format));\n");
1860             printf("   else\n");
1861             printf("    StoreFPR(destreg,format,ValueFPR(destreg,format));\n");
1862           }
1863         } else { /* simple MOVE */
1864           printf("   StoreFPR(destreg,format,ValueFPR(fs,format));\n");
1865         }
1866         break ;
1867
1868        case FPNEG:
1869         printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1870         printf("   SignalException(ReservedInstruction,instruction);\n");
1871         printf("  else\n");
1872         printf("   StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));\n");
1873         break ;
1874
1875        case FPABS:
1876         printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1877         printf("   SignalException(ReservedInstruction,instruction);\n");
1878         printf("  else\n");
1879         printf("   StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));\n");
1880         break ;
1881
1882        case FPDIV:
1883         printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1884         printf("   SignalException(ReservedInstruction,instruction);\n");
1885         printf("  else\n");
1886         printf("   StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
1887         break ;
1888
1889        case FPMUL:
1890         printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1891         printf("   SignalException(ReservedInstruction,instruction);\n");
1892         printf("  else\n");
1893         printf("   StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
1894         break ;
1895
1896        case FPRECIP:
1897         printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1898         printf("   SignalException(ReservedInstruction,instruction);\n");
1899         printf("  else\n");
1900         printf("   StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));\n");
1901         break ;
1902
1903        case FPSQRT:
1904         printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1905         printf("   SignalException(ReservedInstruction,instruction);\n");
1906         printf("  else\n");
1907         printf("   StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)));\n",((MIPS_DECODE[loop].flags & RECIP) ? "Recip" : ""));
1908         break ;
1909
1910        case FPCEIL:
1911        case FPFLOOR:
1912        case FPTRUNC:
1913        case FPROUND:
1914         {
1915           char *op = "";
1916           char *type = "";
1917
1918           switch (MIPS_DECODE[loop].type) {
1919             case FPCEIL:
1920              op = "FP_RM_TOPINF";
1921              break;
1922             case FPFLOOR:
1923              op = "FP_RM_TOMINF";
1924              break;
1925             case FPTRUNC:
1926              op = "FP_RM_TOZERO";
1927              break;
1928             case FPROUND:
1929              op = "FP_RM_NEAREST";
1930              break;
1931             default:
1932              fprintf(stderr,"Error: Handled missing for FP reason code %d\n",MIPS_DECODE[loop].type);
1933              exit(1);
1934           }
1935
1936           switch (GETDATASIZE()) {
1937             case WORD :
1938              type = "fmt_word";
1939              break;
1940             case DOUBLEWORD :
1941              type = "fmt_long";
1942              break;
1943             default:
1944              fprintf(stderr,"Error in instruction encoding table for FP %s operation (not WORD or DOUBLEWORD)\n",op);
1945              exit(1);
1946           }
1947           printf("  if ((format != fmt_single) && (format != fmt_double))\n");
1948           printf("   SignalException(ReservedInstruction,instruction);\n");
1949           printf("  else\n");
1950           printf("   StoreFPR(destreg,%s,Convert(%s,ValueFPR(fs,format),format,%s));\n",type,op,type);
1951         }
1952         break ;
1953
1954        case FPCONVERT:
1955         {
1956           char *type = "";
1957           switch (GETDATASIZE()) {
1958             case SINGLE:
1959              type = "fmt_single";
1960              break;
1961             case DOUBLE:
1962              type = "fmt_double";
1963              break;
1964             case WORD:
1965              type = "fmt_word";
1966              break;
1967             case DOUBLEWORD:
1968              type = "fmt_long";
1969              break;
1970             default :
1971              fprintf(stderr,"Error: Unknown data size %d in FPCONVERT instruction\n",GETDATASIZE());
1972              exit(1);
1973            }
1974
1975           /* Not all combinations of conversion are valid at the
1976              moment: When converting to a fixed-point format, only
1977              floating-point sources are allowed. */
1978           printf("   if ((format == %s) | %s)\n",type,((MIPS_DECODE[loop].flags & FIXED) ? "((format == fmt_long) || (format == fmt_word))": "0"));
1979           printf("    SignalException(ReservedInstruction,instruction);\n");
1980           printf("   else\n");
1981           printf("    StoreFPR(destreg,%s,Convert(GETRM(),ValueFPR(fs,format),format,%s));\n",type,type);
1982         }
1983         break ;
1984
1985        case FPSUB:
1986         if (MIPS_DECODE[loop].flags & MULTIPLY) {
1987           char *type = "";
1988           switch (GETDATASIZE()) {
1989             case SINGLE:
1990              type = "fmt_single";
1991              break;
1992             case DOUBLE:
1993              type = "fmt_double";
1994              break;
1995             default:
1996              fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZE());
1997              exit(1);
1998           }
1999           printf("   StoreFPR(destreg,%s,%s(Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",type,((MIPS_DECODE[loop].flags & NOT) ? "Negate" : ""),type,type,type,type,type,type);
2000         } else {
2001           printf("  if ((format != fmt_single) && (format != fmt_double))\n");
2002           printf("   SignalException(ReservedInstruction,instruction);\n");
2003           printf("  else\n");
2004           printf("   StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
2005         }
2006         break ;
2007
2008        case FPADD:
2009         if (MIPS_DECODE[loop].flags & MULTIPLY) {
2010           char *type = "";
2011           switch (GETDATASIZE()) {
2012             case SINGLE:
2013              type = "fmt_single";
2014              break;
2015             case DOUBLE:
2016              type = "fmt_double";
2017              break;
2018             default:
2019              fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZE());
2020              exit(1);
2021           }
2022           if (MIPS_DECODE[loop].flags & NOT)
2023             printf ("   StoreFPR(destreg,%s,Negate(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
2024                     type, type, type, type, type, type, type);
2025           else
2026             printf ("   StoreFPR(destreg,%s,Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
2027                     type, type, type, type, type, type);
2028         } else {
2029           printf("  if ((format != fmt_single) && (format != fmt_double))\n");
2030           printf("   SignalException(ReservedInstruction,instruction);\n");
2031           printf("  else\n");
2032           printf("   StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
2033         }
2034         break ;
2035
2036        case FPCOMPARE:
2037         /* For the MIPS I,II or III there *MUST* be at least one
2038            instruction between the compare that sets a condition code
2039            and the branch that tests it. NOTE: However the hardware
2040            does not detect this condition. */
2041         /* Explicitly limit the operation to S and D formats: */
2042         printf("   if ((format != fmt_single) && (format != fmt_double))\n");
2043         printf("    SignalException(ReservedInstruction,instruction);\n") ;
2044         printf("   else {\n");
2045         if (doisa < 4) {
2046           printf("    if ((cmpflags & (1 << 3)) || (condition_code != 0))\n");
2047           printf("     SignalException(ReservedInstruction,instruction);\n") ;
2048           printf("    else\n");
2049         }
2050         printf("     {\n");
2051         printf("      int ignore = 0;\n");
2052         printf("      int less = 0;\n");
2053         printf("      int equal = 0;\n");
2054         printf("      int unordered = 1;\n");
2055         printf("      uword64 ofs = ValueFPR(fs,format);\n");
2056         printf("      uword64 oft = ValueFPR(ft,format);\n");
2057         printf("      if (NaN(ofs,format) || NaN(oft,format)) {\n");
2058         printf("      if (FCSR & FP_ENABLE(IO)) {\n");
2059         printf("       FCSR |= FP_CAUSE(IO);\n");
2060         printf("       SignalException(FPE);\n");
2061         printf("       ignore = 1;\n");
2062         printf("      }\n");
2063         printf("     } else {\n");
2064         printf("      less = Less(ofs,oft,format);\n");
2065         printf("      equal = Equal(ofs,oft,format);\n");
2066         printf("      unordered = 0;\n");
2067         printf("     }\n");
2068         printf("     if (!ignore) {\n");
2069         printf("      int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered));\n");
2070         printf("      SETFCC(condition_code,condition);\n");
2071         printf("     }\n");
2072         printf("    }\n");
2073         printf("   }\n");
2074         break ;
2075
2076        default:
2077         fprintf(stderr,"Unrecognised opcode type %d\n",MIPS_DECODE[loop].type) ;
2078         exit(6) ;
2079       }
2080      printf("  }\n") ;
2081      printf(" }\n") ;
2082      printf(" break ;\n") ;
2083     }
2084   }
2085
2086  printf("default : /* Unrecognised instruction */\n") ;
2087  printf(" SignalException(ReservedInstruction,instruction);\n") ;
2088  printf(" break ;\n") ;
2089  printf("}\n}\n") ;
2090  printf("#endif /* simulator engine */\n");
2091
2092  return ;
2093 }
2094
2095 /*---------------------------------------------------------------------------*/
2096
2097 /* The command-line feature controls are presented in a similar style
2098    to those offered by GCC, in the aim of providing a consistent
2099    interface to the user. */
2100 typedef enum {
2101   T_NONE,  /* no argument - mask and value fields control "feature" definition */
2102   T_NUM,   /* numeric argument - optionally preceded by '=' - mask field defines maximum value */
2103   T_STRING /* string argument - optionally prcededed by '=' */
2104 } mactypes;
2105
2106 struct {
2107   char *name;
2108   mactypes type;
2109   unsigned int mask;
2110   unsigned int value;
2111   char *desc;
2112 } machine_options[] = {
2113   {"ips",         T_NUM,   MASK_ISA,0,"\tSelect MIPS ISA version"},
2114   {"cpu",         T_STRING,0,0,"\t\tSelect particular MIPS architecture"},
2115   {"gp64",        T_NONE,  FEATURE_GP64,FEATURE_GP64,"\t\t\tSelect 64bit GP registers"},
2116   {"gp32",        T_NONE,  FEATURE_GP64,0,"\t\t\tSelect 32bit GP registers"},
2117   {"no-fp",       T_NONE,  FEATURE_HASFPU,0,"\t\tDisable FP simulation"},
2118   {"single-float",T_NONE,  (FEATURE_FPSINGLE | FEATURE_HASFPU),(FEATURE_FPSINGLE | FEATURE_HASFPU),"\t\tSelect single precision only FPU"},
2119   {"double-float",T_NONE,  (FEATURE_FPSINGLE | FEATURE_HASFPU),FEATURE_HASFPU,"\t\tSelect double precision FPU"},
2120   {0,             T_NONE,  0,0}
2121 };
2122
2123 /* The following architecture identies are those accepted by the "-mcpu" option: */
2124 struct architectures {
2125  const char *name;    /* ASCII string identifier for command-line, no white-space allowed */
2126  unsigned int idflag; /* or-ed into "isa" value */
2127 };
2128
2129 static const struct architectures available_architectures[] = {
2130   {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
2131   {0,     0}            /* terminator */
2132 };
2133
2134 /*---------------------------------------------------------------------------*/
2135
2136 static void
2137 usage(name)
2138      char *name;
2139 {
2140  int loop;
2141
2142  fprintf(stderr,"%s: Construct a MIPS simulator engine.\n",name);
2143
2144  fprintf(stderr,"\
2145 The output of this program is a block of 'C' code designed to be\n\
2146 included into the main simulation control loop of a device specific\n\
2147 simulator.\n");
2148
2149  fprintf(stderr,"\nOptions:\n");
2150  fprintf(stderr," -h --help\t\tProvide this help text\n");
2151  fprintf(stderr," -f --fast\t\tProvide the fastest possible engine (i.e. no statistics)\n");
2152  fprintf(stderr," -w --warnings\t\tEnable all the simulator engine warnings\n");
2153
2154  for (loop = 0; (machine_options[loop].name != 0); loop++) {
2155    fprintf(stderr," -m%s",machine_options[loop].name);
2156    switch (machine_options[loop].type) {
2157      case T_NUM :
2158        fprintf(stderr,"N (range 0..%d)",machine_options[loop].mask);
2159      case T_NONE :
2160        break;
2161
2162      case T_STRING :
2163        fprintf(stderr,"=name");
2164        break;
2165
2166      default :
2167        fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",machine_options[loop].type);
2168        exit(1);
2169    }
2170    fprintf(stderr,"%s\n",machine_options[loop].desc);
2171  }
2172
2173  fprintf(stderr,"\nAvailable \"-mcpu\" architectures: ");
2174  for (loop = 0; (available_architectures[loop].name != 0); loop++)
2175    fprintf(stderr,"%s ",available_architectures[loop].name);
2176  fprintf(stderr,"\n\n");
2177
2178  fprintf(stderr,"\
2179 The \"trace\" and \"warnings\" options do not define the output stream.\n\
2180 They only inform the code that includes the constructed engine to provide\n\
2181 the required features.\n\n\
2182 The \"-mips0\" option forces the construction of a simulator supporting\n\
2183 the highest available MIPS ISA supported.\n");
2184
2185  return;
2186 }
2187
2188 /*---------------------------------------------------------------------------*/
2189
2190 int
2191 main(argc,argv)
2192      int argc;
2193      char **argv;
2194 {
2195   int c;
2196   char *progname = argv[0];
2197   unsigned int doarch = DEF_ISA;
2198   unsigned int features = 0; /* default state */
2199
2200   if (DEF_FP)
2201    features |= FEATURE_HASFPU;
2202   if (!DEF_PROC64)
2203    features |= FEATURE_PROC32;
2204   if (DEF_FPSINGLE)
2205    features |= FEATURE_FPSINGLE;
2206
2207   if (features & FEATURE_PROC32)
2208    features &= ~FEATURE_GP64;
2209   else
2210    features |= FEATURE_GP64;
2211
2212   while (1) {
2213     int this_option_optind = (optind ? optind : 1);
2214     int option_index = 0;
2215     static struct option cmdline[] = {
2216       {"fast",    0,0,'f'},
2217       {"help",    0,0,'h'},
2218       {"warnings",0,0,'w'},
2219       {0,         0,0,0}
2220     };
2221    
2222     c = getopt_long(argc,argv,"hm:tw",cmdline,&option_index);
2223     if (c == -1)
2224      break ; /* out of the while loop */
2225
2226     switch (c) {
2227       case 'h' : /* help */
2228        usage(progname);
2229        exit(0);
2230
2231       case 'f' : /* fast */
2232        features |= FEATURE_FAST;
2233        break;
2234
2235       case 'w' : /* warnings */
2236        features |= FEATURE_WARNINGS;
2237        /* TODO: Future extension: Allow better control over the warnings generated:
2238         disable warnings                -wnone                                  ~FEATURE_WARNINGS
2239         all possible warnings           -wall                                   FEATURE_WARNINGS
2240         pipeline stall occuring         -wstall                                 FEATURE_WARN_STALL
2241         LO/HI corruption                -wlo or -whi or -wlohi or -whilo        FEATURE_WARN_HILO
2242         write to zero                   -wzero                                  FEATURE_WARN_ZERO       actually performed in external code - though we should set a manifest
2243         bad r31 use                     -wr31                                   FEATURE_WARN_R31
2244         undefined results               -wresult                                FEATURE_WARN_RESULT
2245        */
2246        break;
2247
2248       case 'm' : /* machine options */
2249        {
2250          int loop;
2251
2252          for (loop = 0; (machine_options[loop].name != 0); loop++)
2253           if (strncmp(machine_options[loop].name,optarg,strlen(machine_options[loop].name)) == 0) {
2254             char *loptarg = (optarg + strlen(machine_options[loop].name));
2255             switch (machine_options[loop].type) {
2256               case T_NONE :
2257                if (*loptarg) {
2258                  fprintf(stderr,"%s: Spurious characters \"%s\" at end of -m%s option\n",progname,loptarg,machine_options[loop].name);
2259                  exit(1);
2260                }
2261                features &= ~(machine_options[loop].mask);
2262                features |= machine_options[loop].value;
2263                break;
2264
2265               case T_NUM :
2266                if (*loptarg && *loptarg == '=')
2267                 loptarg++;
2268
2269                if (strcmp(machine_options[loop].name,"ips") == 0) {
2270                  unsigned int num;
2271
2272                  if (!*loptarg) {
2273                    fprintf(stderr,"%s: ISA number expected after -mips\n",progname);
2274                    exit(1);
2275                  }
2276
2277                  num = my_strtoul(loptarg,&loptarg,10);
2278
2279                  if ((num == ULONG_MAX) && (errno = ERANGE)) {
2280                    fprintf(stderr,"%s: Invalid number given to -mips option\n",progname);
2281                    exit(1);
2282                  }
2283
2284                  if (*loptarg) {
2285                    fprintf(stderr,"%s: Spurious trailing characters after ISA number \"%s\"\n",progname,loptarg);
2286                    exit(1);
2287                  }
2288
2289                  if (num > MASK_ISA) {
2290                    fprintf(stderr,"%s: ISA number %d outside acceptable range (0..%d)\n",progname,num,MASK_ISA);
2291                    exit(1);
2292                  }
2293
2294                  doarch = ((doarch & ~MASK_ISA) | num);
2295                  if ((num == 0) || (num > 2)) {
2296                    if ((features & FEATURE_PROC32) || !(features & FEATURE_GP64))
2297                     fprintf(stderr,"%s: Warning: -mips%d forcing -mgp64\n",progname,num);
2298                    features |= FEATURE_GP64;
2299                    features &= ~FEATURE_PROC32;
2300                  } else {
2301                    if (!(features & FEATURE_PROC32) || (features & FEATURE_GP64))
2302                     fprintf(stderr,"%s: Warning: -mips%d forcing -mgp32\n",progname,num);
2303                    features &= ~FEATURE_GP64;
2304                    features |= FEATURE_PROC32;
2305                  }
2306                } else {
2307                  fprintf(stderr,"%s: FATAL: Unrecognised (numeric) machine option -m%s\n",progname,optarg);
2308                  exit(1);
2309                }
2310                break;
2311
2312               case T_STRING :
2313                if (*loptarg && *loptarg == '=')
2314                 loptarg++;
2315
2316                if (strcmp(machine_options[loop].name,"cpu") == 0) {
2317                  int archloop;
2318
2319                  if (!*loptarg) {
2320                    fprintf(stderr,"%s: Architecture identifier expected after -mcpu\n",progname);
2321                    exit(1);
2322                  }
2323
2324                  for (archloop = 0; (available_architectures[archloop].name != 0); archloop++) {
2325                    if ((*loptarg == 'v') || (*loptarg == 'V'))
2326                     *loptarg++;
2327
2328                    if (*loptarg && (*loptarg == 'r') || (*loptarg == 'R'))
2329                     *loptarg++;
2330
2331                    if (strcmp(available_architectures[archloop].name,loptarg) == 0) {
2332                      doarch |= available_architectures[archloop].idflag;
2333                      break;
2334                    }
2335                  }
2336
2337                  if (available_architectures[archloop].name == 0) {
2338                    fprintf(stderr,"%s: Unrecognised MIPS architecture \"%s\"\n",progname,loptarg);
2339                    exit(1);
2340                  }
2341                } else {
2342                  fprintf(stderr,"%s: FATAL: Unrecognised (string) machine option -m%s\n",progname,optarg);
2343                  exit(1);
2344                }
2345                break;
2346
2347               default :
2348                fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",progname,machine_options[loop].type);
2349                exit(1);
2350             }
2351             break;
2352           }
2353
2354          if (machine_options[loop].name == 0) {
2355            fprintf(stderr,"%s: Unrecognised option: -m%s\n",progname,optarg);
2356            exit(1);
2357          }
2358        }
2359        break;
2360
2361       case '?' :
2362        /* An error message should already have been displayed */
2363        exit(1);
2364
2365       default :
2366        fprintf(stderr,"%s: FATAL: getopt returned unrecognised code 0x%08X\n",progname,c);
2367        exit(1);
2368     }
2369   }
2370
2371   if (optind < argc) {
2372     fprintf(stderr,"%s: Spurios non-option arguments ",progname);
2373     while (optind < argc)
2374      fprintf(stderr,"\"%s\" ",argv[optind++]);
2375     fprintf(stderr,"\n");
2376     exit(1);
2377   }
2378
2379   if ((features & FEATURE_FAST) && (features & FEATURE_WARNINGS))
2380    fprintf(stderr,"Warning: Fast model generation selected, along with trace or warnings.\n");
2381
2382   process_instructions(doarch,features) ;
2383   return(0) ;
2384 }
2385
2386 /*---------------------------------------------------------------------------*/
2387
2388 /* We can't assume that the compiler for the build system has strtoul,
2389    so we provide our own copy.  */
2390
2391 /*
2392  * Copyright (c) 1990 Regents of the University of California.
2393  * All rights reserved.
2394  *
2395  * Redistribution and use in source and binary forms, with or without
2396  * modification, are permitted provided that the following conditions
2397  * are met:
2398  * 1. Redistributions of source code must retain the above copyright
2399  *    notice, this list of conditions and the following disclaimer.
2400  * 2. Redistributions in binary form must reproduce the above copyright
2401  *    notice, this list of conditions and the following disclaimer in the
2402  *    documentation and/or other materials provided with the distribution.
2403  * 3. All advertising materials mentioning features or use of this software
2404  *    must display the following acknowledgement:
2405  *      This product includes software developed by the University of
2406  *      California, Berkeley and its contributors.
2407  * 4. Neither the name of the University nor the names of its contributors
2408  *    may be used to endorse or promote products derived from this software
2409  *    without specific prior written permission.
2410  *
2411  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2412  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2413  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2414  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2415  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2416  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2417  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2418  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2419  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2420  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2421  * SUCH DAMAGE.
2422  */
2423
2424 /*
2425  * Convert a string to an unsigned long integer.
2426  *
2427  * Ignores `locale' stuff.  Assumes that the upper and lower case
2428  * alphabets and digits are each contiguous.
2429  */
2430 static unsigned long
2431 my_strtoul(nptr, endptr, base)
2432         const char *nptr;
2433         char **endptr;
2434         register int base;
2435 {
2436         register const char *s = nptr;
2437         register unsigned long acc;
2438         register int c;
2439         register unsigned long cutoff;
2440         register int neg = 0, any, cutlim;
2441
2442         /*
2443          * See strtol for comments as to the logic used.
2444          */
2445         do {
2446                 c = *s++;
2447         } while (isspace(c));
2448         if (c == '-') {
2449                 neg = 1;
2450                 c = *s++;
2451         } else if (c == '+')
2452                 c = *s++;
2453         if ((base == 0 || base == 16) &&
2454             c == '0' && (*s == 'x' || *s == 'X')) {
2455                 c = s[1];
2456                 s += 2;
2457                 base = 16;
2458         }
2459         if (base == 0)
2460                 base = c == '0' ? 8 : 10;
2461         cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
2462         cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
2463         for (acc = 0, any = 0;; c = *s++) {
2464                 if (isdigit(c))
2465                         c -= '0';
2466                 else if (isalpha(c))
2467                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
2468                 else
2469                         break;
2470                 if (c >= base)
2471                         break;
2472                 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
2473                         any = -1;
2474                 else {
2475                         any = 1;
2476                         acc *= base;
2477                         acc += c;
2478                 }
2479         }
2480         if (any < 0) {
2481                 acc = ULONG_MAX;
2482                 errno = ERANGE;
2483         } else if (neg)
2484                 acc = -acc;
2485         if (endptr != 0)
2486                 *endptr = (char *) (any ? s - 1 : nptr);
2487         return (acc);
2488 }
2489
2490 /*---------------------------------------------------------------------------*/
2491
2492 /*> EOF gencode.c <*/
This page took 0.170547 seconds and 4 git commands to generate.