Add r5900
[external/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 /* All output sent to stdout is for the simulator engine. All program
26    related warnings and errors should be sent to stderr. */
27
28 /* The simulator decode table is constructed this way to allow the
29    minimal code required for a particular instruction type to be
30    coded.  This avoids a large simulator source file, with lots of
31    build-time conditionals controlling what code is included.  However
32    this two-stage process does mean that care must be taken to ensure
33    that the correct decoding source is generated for a particular MIPS
34    simulator. */
35
36 /* Notes:
37
38    We could provide pipeline modelling by splitting the simulation of
39    instructions into seperate bytecodes for each pipeline
40    stage. e.g. for the VR4300 each instruction would generate 5
41    bytecodes, one for each pipeline stage. The simulator control would
42    then insert these into the relevant pipeline slots, and execute a
43    complete slots worth of bytecodes. However, the shape of the
44    pipeline, and what parts of each instruction are executed in each
45    pipeline stage, are different between MIPS implementations. If we
46    were to construct a simulator for a particular MIPS architecture
47    this would be a good solution.
48
49    To avoid having to provide multiple different pipeline models, a
50    simple approach for dealing with the delay slots, and register
51    dependencies has been used. The "MIPS IV Instruction Set" document
52    (Revision 3.1 - January 1995) details the standard MIPS instruction
53    set, and it defines operations in instruction (not pipe-line)
54    cycles. This means we only need to worry about a few cases where
55    the result is not available until after the next instruction, or
56    where registers in the previous two instruction cycles may be
57    corrupted. The case for corruption only occurs with HI or LO
58    register access, so we can just keep a count within the engine for
59    upto two cycles before marking the register as safe. We then only
60    need to check the safety flag when performing an update that
61    involves the HI or LO register. The only other case is the
62    BC1F/BC1T instructions in the FP unit. For ISAs I, II and III there
63    must be an instruction between the FP CMP and the BC1[FT]. We can
64    perform the same instruction cycle count scheme, so we can raise a
65    warning if an attempt is made to access the condition code early
66    (NOTE: The hardware does not interlock on this operation, so the
67    simulator should just raise a warning).
68
69    For the situations where a result is not available until later, we
70    implent a slot to hold pending values. After the PC is incremented,
71    and before the instruction is decoded we can execute the required
72    register update (or remainder of instruction processing). */
73
74 /* The FP instruction decoding is also provided by this code.  The
75    instructions are marked as "FP" ones so that we can construct a
76    simulator without an FPU if required.  Similarly we mark
77    instructions as Single or Double precision, since some MIPS
78    processors only have single precision FP hardware. */
79
80 /* NOTE: Ideally all state should be passed as parameters. This allows
81    a single simulator engine to be used for multiple concurrent
82    simulations. More importantly, if a suitably powerful control is in
83    place it will allow speculative simulation, since the context can
84    be saved easily, and then restored after performing some
85    simulation. The down-side is that for certain host architectures it
86    can slow the simulator down (e.g. if globals can be accessed faster
87    than local structures). However, this is not actually the case at
88    the moment. The constructed engine uses direct names (that can be
89    macro definitions). This keeps the engine source smalled (using
90    short-hands), and it also allows the user to control whether they
91    want to use global, or indirected memory locations. i.e. whether
92    they want a single- or multi-threaded simulator engine. */
93
94 /* The constructed simulator engine contains manifests for each of the
95    features supported. The code that includes the engine can then
96    discover the available features during its build. This information
97    can be used to control run-time features provided by the final
98    simulator. */
99
100 /*---------------------------------------------------------------------------*/
101
102 /* Program defaults */
103 #define DEF_ISA      (3)
104 #define DEF_PROC64   (1 == 1)
105 #define DEF_FP       (1 == 1)
106 #define DEF_FPSINGLE (1 == 0)
107
108 #define FEATURE_PROC32      (1 << 0)    /* 0 = 64bit; 1 = 32bit */
109 #define FEATURE_HASFPU      (1 << 1)    /* 0 = no FPU; 1 = include FPU */
110 #define FEATURE_FPSINGLE    (1 << 1)    /* 0 = double; 1 = single (only used if FEATURE_HASFPU defined) */
111 #define FEATURE_GP64        (1 << 2)    /* 0 = GPRLEN 32; 1 = GPRLEN 64 */
112 #define FEATURE_FAST        (1 << 17)   /* 0 = normal;  1 = disable features that slow performance */
113 #define FEATURE_WARN_STALL  (1 << 24)   /* 0 = nothing; 1 = generate warnings when pipeline would stall */
114 #define FEATURE_WARN_LOHI   (1 << 25)   /* 0 = nothing; 1 = generate warnings when LO/HI corrupted */
115 #define FEATURE_WARN_ZERO   (1 << 26)   /* 0 = nothing; 1 = generate warnings if attempt to write register zero */ 
116 #define FEATURE_WARN_MEM    (1 << 27)   /* 0 = nothing; 1 = generate warnings when memory problems are noticed */
117 #define FEATURE_WARN_R31    (1 << 28)   /* 0 = nothing; 1 = generate warnings if r31 used dangerously */
118 #define FEATURE_WARN_RESULT (1 << 29)   /* 0 = nothing; 1 = generate warnings when undefined results may occur */
119
120 #if 1
121 #define FEATURE_WARNINGS  (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_ZERO | FEATURE_WARN_R31)
122 #else
123 #define FEATURE_WARNINGS  (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_ZERO | FEATURE_WARN_R31 | FEATURE_WARN_RESULT)
124 #endif
125
126 /* FEATURE_WARN_STALL */
127 /* If MIPS I we want to raise a warning if an attempt is made to
128    access Rn in an instruction immediately following an Rn update
129    "WARNING : Invalid value read". The simulator engine is designed
130    that the previous value is read in such cases, to allow programs
131    that make use of this feature to execute. */
132 /* If MIPS II or later, attempting to read a register before the
133    update has completed will generate a "WARNING : Processor stall"
134    message (since the processor will lock the pipeline until the value
135    becomes available). */
136
137 /* FEATURE_WARN_LOHI */
138 /* Warn if an attempt is made to read the HI/LO registers before the
139    update has completed, or if an attempt is made to update the
140    registers whilst an update is occurring. */
141
142 /* FEATURE_WARN_ZERO */
143 /* Notify the user if an attempt is made to use GPR 0 as a destination. */
144
145 /* FEATURE_WARN_R31 */
146 /* Notify the user if register r31 (the default procedure call return
147    address) is used unwisely. e.g. If r31 is used as the source in a
148    branch-and-link instruction, it would mean that an exception in the
149    delay slot instruction would not allow the branch to be re-started
150    (since r31 will have been overwritten by the link operation during
151    the first execution of the branch). */
152
153 /* FEATURE_WARN_RESULT */
154 /* Certain instructions do not raise exceptions when invalid operands
155    are given, they will just result in undefined values being
156    generated. This option controls whether the simulator flags such
157    events. */
158
159 /*---------------------------------------------------------------------------*/
160
161 #include <stdio.h>
162 #include <getopt.h>
163 #include <limits.h>
164 #include <errno.h>
165 #include <ctype.h>
166 #include "ansidecl.h"
167 #include "opcode/mips.h"
168
169 /* FIXME: ansidecl.h defines AND.  */
170 #undef AND
171
172 #ifndef ULONG_MAX
173 #define ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
174 #endif
175
176 static unsigned long my_strtoul ();
177
178 #if 0
179 #ifndef TRUE
180 #define TRUE  (1 == 1)
181 #define FALSE (1 == 0)
182 #endif
183 #endif
184
185 /*---------------------------------------------------------------------------*/
186
187 /* Holding the instruction table this way makes it easier to check the
188    instruction values defined, and to add instructions to the
189    system. However, it makes the process of constructing the simulator
190    a bit more complicated: */
191
192 /* The "bitmap" is encoded as follows (NOTE: Only lower-case
193    alphabetic characters should be used, since the letter ordinal is
194    used as a bit position): */
195
196 typedef struct operand_encoding {
197  char id; /* character identifier */
198  int fpos; /* first bit position */
199  int flen; /* field length in bits */
200  char * const type;
201  char * const name;
202  unsigned int flags;
203 } operand_encoding;
204
205 /* Values for the "flags" field: */
206 #define OP_NONE   (0 << 0)      /* To keep the source tidy */
207 #define OP_GPR    (1 << 0)      /* Get operand from integer register bank */
208 #define OP_SIGNX  (1 << 1)      /* Sign-extend the operand */
209 #define OP_SHIFT2 (1 << 2)      /* Shift field left by 2 */
210 #define OP_BITS5  (1 << 3)      /* Only take the lo 5-bits of the operand */
211 #define OP_GPR1   (1 << 4)      /* fetch from the GPR1 registers */
212
213 struct operand_encoding opfields[] = {
214  {'0',-1,-1,"",      "",              (OP_NONE)},  /* special case for explicit zero */
215  {'1',-1,-1,"",      "",              (OP_NONE)},  /* special case for explicit one */
216  {'?',-1,-1,"",      "",              (OP_NONE)},  /* undefined (do not care at this level) */
217  /* The rest are the explicit operand fields: */
218  {'a', 6, 5,"int",   "op1",           (OP_NONE)},  /* shift amount (or hint) */
219  {'b',21, 5,"int",   "fr",            (OP_NONE)},   /* fr register */
220  {'c',16, 1,"int",   "boolean",       (OP_NONE)},  /* TRUE or FALSE boolean */
221  {'d',11, 5,"int",   "destreg",       (OP_NONE)},  /* integer destination/rd register */
222  {'e', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-3bits must be zero) */
223  {'f',17, 1,"int",   "likely",        (OP_NONE)},  /* set if branch LIKELY */
224  {'g',16, 5,"t_reg", "op2",           (OP_GPR)},   /* integer source rt register */
225  {'h', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-1bit must be zero) */
226  {'i', 0,16,"t_reg", "op2",           (OP_SIGNX)}, /* signed immediate (op2) */
227  {'j', 0,26,"ut_reg","op1",           (OP_SHIFT2)},/* shifted left 2 bits and combined with hi-order bits of address in the delay slot */
228  {'k',16, 5,"int",   "ft",            (OP_NONE)},
229  {'l', 0,16,"t_reg", "offset",        (OP_SIGNX | OP_SHIFT2)}, /* signed offset shifted left 2 to make 18bit signed offset */
230  {'m',21, 3,"int",   "format",        (OP_NONE)},  /* FP format field */
231  {'n',16, 5,"int",   "hint",          (OP_NONE)},  /* hint */
232  {'o',21, 5,"t_reg", "op1",           (OP_GPR | OP_BITS5)},  /* integer source/rs register (but never treated as 32bit word) */
233  {'p', 8, 3,"int",   "condition_code",(OP_NONE)},  /* FP condition code field */
234  {'q',18, 3,"int",   "condition_code",(OP_NONE)},  /* FP condition code field */
235  {'r', 6, 5,"int",   "destreg",       (OP_NONE)},  /* FP fd register */
236  {'s',21, 5,"t_reg", "op1",           (OP_GPR)},   /* integer source/rs register */
237  {'t',16, 5,"int",   "destreg",       (OP_NONE)},  /* integer target rt (destination) register */
238  {'u', 0, 4,"int",   "cmpflags",      (OP_NONE)},  /* FP comparison control flags */
239  {'v',11, 5,"int",   "fs",            (OP_NONE)},  /* FP fs register (or PREFX hint) */
240  {'w', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset (lo-2bits must be zero) */
241  {'x',23, 1,"int",   "to",            (OP_NONE)},  /* TRUE if move To; FALSE if move From */
242  {'y', 0,16,"t_reg", "offset",        (OP_SIGNX)}, /* signed offset */
243  {'z', 0,16,"ut_reg","op2",           (OP_NONE)},  /* unsigned immediate (zero extended) */
244  {'S',21, 5,"t_reg", "rs_reg",  (OP_GPR|OP_GPR1)}, /* rs field, GPR[rs] and GPR1[rs] as source */
245  {'T',16, 5,"t_reg", "rt_reg",  (OP_GPR|OP_GPR1)}, /* rt field, GPR[rt] and GPR1[rt] as source */
246 };
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
258  MMINORM,
259  MMI0,
260  MMI1,
261  MMI2,
262  MMI3,
263
264  /* mips16 encoding types.  */
265  I, RI, RR, RRI, RRR, RRI_A, ISHIFT, I8, I8_MOVR32, I8_MOV32R, I64, RI64
266 } inst_type;
267
268 /* Main instruction families: */
269 typedef enum {
270  ADD,                   /* res = operand1 + operand2 */
271  SUB,                   /* res = operand1 - operand2 */
272  MUL,                   /* res = operand1 * operand2 */
273  DIV,                   /* res = operand1 / operand2 */
274  AND,                   /* res = operand1 & operand2 */
275  OR,                    /* res = operand1 | operand2 */
276  XOR,                   /* res = operand1 ^ operand2 */
277  MOVE,                  /* res = operand1 */
278  BRANCH,                /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
279  JUMP,                  /* execute delay slot instruction before jump */
280  LOAD,                  /* load from memory */
281  STORE,                 /* store to memory */
282  PREFETCH,              /* prefetch data into cache */
283  SET,                   /* set register on result of condition code */
284  SHIFT,                 /* perform a logical or arithmetic shift */
285  TRAP,                  /* system exception generation */
286  BREAK,                 /* system breakpoint exception generation */
287  SYSCALL,               /* system exception generation */
288  SYNC,                  /* system cache control */
289  DECODE,                /* co-processor instruction */
290  CACHE,                 /* co-processor 0 CACHE instruction */
291  MADD16,                /* VR4100 specific multiply-add extensions */
292  FPMOVE,
293  FPMOVEC,
294  FPFLOOR,               
295  FPCEIL,
296  FPTRUNC,
297  FPROUND,
298  FPNEG,
299  FPABS,
300  FPDIV,
301  FPMUL,
302  FPSUB,
303  FPADD,
304  FPPREFX,
305  FPRECIP,
306  FPSQRT,
307  FPCONVERT,
308  FPCOMPARE,
309  /* start-sanitize-r5900 */
310  MADD,
311  PABS,
312  PADD,
313  PADSBH,
314  POP,
315  PCMP,
316  PCPYH,
317  PCPYLD,
318  PCPYUD,
319  PEXCH,
320  PEXCW,
321  PEXOH,
322  PEXOW,
323  PEXTLB,
324  PEXTLH,
325  PEXTLW,
326  PEXTUB,
327  PEXTUH,
328  PEXTUW,
329  PPACB,
330  PPACH,
331  PPACW,
332  PREVH,
333  PROT3W,
334  PINTH,
335  PINTOH,
336  PMXX,
337  PMFHL,
338  PMTHL,
339  PMAXMIN,
340  QFSRV,
341  MxSA,
342  MTSAB,
343  MTSAH,
344  PSHIFT,
345  PSLLVW,
346  PSRLVW,
347  PSRAVW,
348  PLZCW,
349  PHMADDH,
350  PMULTH,
351  PMULTW,
352  PDIVBW,
353  PDIVW,
354  PEXT5,
355  PPAC5,
356  /* end-sanitize-r5900 */
357  NYI,                   /* Not Yet Implemented, placeholder, errors if used */
358  RSVD                   /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "Reserved Instruction" */
359 } opcode_type;
360
361 /* Flags field: */
362 #define NONE            (0 << 0)        /* Zero value (used to keep source tidy) */
363 #define SIM_SH_SIZE     (0)
364 #define SIM_MASK_SIZE   (0x7)
365 #define BYTE            (0)     /*  8bit */
366 #define HALFWORD        (1)     /* 16bit */
367 #define WORD            (2)     /* 32bit */
368 #define DOUBLEWORD      (3)     /* 64bit */
369 #define SINGLE          (4)     /* single precision FP */
370 #define DOUBLE          (5)     /* double precision FP */
371 #define QUADWORD        (6)     /* 128bit */
372
373 /* Shorthand to get the size field from the flags value: */
374 #define GETDATASIZEINSN(i) (((i)->flags >> SIM_SH_SIZE) & SIM_MASK_SIZE)
375
376 /* The rest are single bit flags: */
377 #define MULTIPLY        (1 << 3)        /* actually FP multiply ADD/SUB modifier */
378 #define EQ              (1 << 4)
379 #define GT              (1 << 5)
380 #define LT              (1 << 6)
381 #define NOT             (1 << 7)
382 #define LIKELY          (1 << 8)
383 #define SIGNEXTEND      (1 << 9)
384 #define OVERFLOW        (1 << 10)
385 #define LINK            (1 << 11)
386 #define ATOMIC          (1 << 12)
387 #define SHIFT16         (1 << 13)
388 #define REG             (1 << 14)
389 #define LEFT            (1 << 15)       /* Deliberate explicit encodings to allow check for neither, or both */
390 #define RIGHT           (1 << 16)       /* Mutually exclusive with "LEFT" */
391 #define LOGICAL         (1 << 17)
392 #define ARITHMETIC      (1 << 18)
393 #define UNSIGNED        (1 << 19)
394 #define HI32            (1 << 20)
395 #define HI              (1 << 21)       /* accesses or updates the HI register */
396 #define LO              (1 << 22)       /* accesses or updates the LO register */
397 #define WORD32          (1 << 23)
398 #define FP              (1 << 24)       /* Floating Point operation */
399 #define FIXED           (1 << 25)       /* fixed point arithmetic */
400 #define COPROC          (1 << 26)
401 #define INTEGER         (1 << 27)
402 #define CONDITIONAL     (1 << 28)
403 #define RECIP           (1 << 29)
404 #define CONTROL         (1 << 30)
405 #define NOARG           (1 << 31)       /* Instruction has no (defined) operands */
406 /* NOTE: We can overload the use of certain of these flags, since not
407    all options are applicable to all instruction types. This will free
408    up more space for new flags. */
409
410 /* Overloadings of above bits */
411 #define PIPE1        LIKELY      /* Using pipeline 1 (DIV,MUL) */
412 #define OP3          EQ          /* 3 operand version of operation  (MUL)     */
413
414 #define SATURATE     OVERFLOW    /* for PADD, saturate for overflow           */
415
416 #define SUBTRACT     LEFT        /* for PMULT, PMULT becomes PMSUB            */
417 #define ADDITION     RIGHT       /* for PMULT, PMULT becomes PMADD            */
418
419 #define FROM         LEFT        /* move from special register                */
420 #define TO           RIGHT       /* move to special register                  */
421
422 /* For bitwise parallel operations */ 
423 #define POP_AND      BYTE        /* for POP, op = &                           */
424 #define POP_OR       HALFWORD    /* for POP, op = |                           */
425 #define POP_NOR      WORD        /* for POP, op = ~(x | y)                    */
426 #define POP_XOR      DOUBLEWORD  /* for POP, op = ^                           */
427
428 #define GET_OP_FROM_INSN(insn) GETDATASIZEINSN(insn)
429    
430 typedef struct instruction {
431  char         *name;   /* ASCII mnemonic name */
432  unsigned int  isa;    /* MIPS ISA number where instruction introduced */
433  char         *bitmap; /* 32character string describing instruction operands */
434  inst_type     mark;   /* type of MIPS instruction encoding */
435  opcode_type   type;   /* main instruction family */
436  unsigned int  flags;  /* flags describing instruction features */
437 } instruction;
438 /* The number of pipeline cycles taken by an instruction varies
439    between MIPS processors. This means that the information must be
440    encoded elsewhere, in a CPU specific structure. */
441
442 /* NOTE: Undefined instructions cause "Reserved Instruction"
443    exceptions. i.e. if there is no bit-mapping defined then the
444    instruction is deemed to be undefined. */
445
446 /* NOTE: The "isa" field is also used to encode flags for particular
447    chip architecture extensions. e.g. the NEC VR4100 specific
448    instructions. Normally chip extensions are added via the COP0
449    space. However, the VR4100 (and possibly other devices) also use
450    the normal instruction space. */
451 #define MASK_ISA (0x000000FF) /* Start by leaving 8bits for the ISA ID */
452 /* The other bits are allocated downwards, to avoid renumbering if we
453    have to extend the bits allocated to the pure ISA number. */
454 #define ARCH_VR4100       ((unsigned)1 << 31) /* NEC VR4100 extension instructions */
455 /* start-sanitize-r5900 */
456 #define ARCH_R5900        ((unsigned)1 << 30) /* Toshiba r5900 extension instructions */
457 /* end-sanitize-r5900 */
458
459 /* A list (or'ed) of extension insn sets that can be requested independant of the ISA# */
460 #define MASK_ISA_INDEP  (0                                             \
461                          /* start-sanitize-r5900 */                    \
462                          | ARCH_R5900                                  \
463                          /* end-sanitize-r5900 */                      \
464                          | 0)
465
466
467
468
469 /* Very short names for use in the table below to keep it neet. */
470 #define G1 (3 | ARCH_VR4100)
471
472 #define G2 (4                                        \
473             /* start-sanitize-r5900 */               \
474             | ARCH_R5900                             \
475             /* end-sanitize-r5900 */                 \
476             | 0)
477
478 #define G3 (4                                                           \
479             /* start-sanitize-r5900 */                                  \
480             /* insn that are not really 5900 insn but were left in */   \
481             /* until we can rewrite the code-gen and libs          */   \
482             | ARCH_R5900                                                \
483             /* end-sanitize-r5900 */                                    \
484             | 0)
485
486
487
488 /* start-sanitize-r5900 */
489 #define T5 ARCH_R5900       
490 /* end-sanitize-r5900 */
491
492
493 /* The HIBERNATE, STANDBY and SUSPEND instructions are encoded in the
494    COP0 space. This means that an external decoder should be added
495    when constructing a full VR4100 simulator. However some arithmetic
496    instructions are encoded in the normal instruction space. */
497
498 struct instruction MIPS_DECODE[] = {
499  /* The instructions are alphabetical, and not in instruction bit-order: */
500  {"ABS",     1,"01000110mmm00000vvvvvrrrrr000101",COP1,   FPABS,    (FP)},
501  {"ADD",     1,"000000sssssgggggddddd00000100000",SPECIAL,ADD,      (WORD | WORD32 | OVERFLOW)}, /* rd = rs + rt */
502  {"ADD",     1,"01000110mmmkkkkkvvvvvrrrrr000000",COP1,   FPADD,    (FP)},
503  {"ADDI",    1,"001000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (WORD | WORD32 | OVERFLOW)},
504  {"ADDU",    1,"000000sssssgggggddddd00000100001",SPECIAL,ADD,      (WORD | WORD32)}, /* rd = rs + rt */
505  {"ADDIU",   1,"001001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (WORD | WORD32)},
506  {"AND",     1,"000000sssssgggggddddd00000100100",SPECIAL,AND,      (NONE)}, /* rd = rs AND rt */
507  {"ANDI",    1,"001100ssssstttttzzzzzzzzzzzzzzzz",NORMAL, AND,      (NONE)},
508  {"BC1",     1,"01000101000qqqfcllllllllllllllll",COP1S,  BRANCH,   (FP)},
509  {"BEQ",     1,"000100sssssgggggllllllllllllllll",NORMAL, BRANCH,   (EQ)},
510  {"BEQL",    2,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH,   (EQ | LIKELY)},
511  {"BGEZ",    1,"000001sssss00001llllllllllllllll",REGIMM, BRANCH,   (GT | EQ)},
512  {"BGEZAL",  1,"000001sssss10001llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LINK)},
513  {"BGEZALL", 2,"000001sssss10011llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LINK)},
514  {"BGEZL",   2,"000001sssss00011llllllllllllllll",REGIMM, BRANCH,   (GT | EQ | LIKELY)},
515  {"BGTZ",    1,"000111sssss00000llllllllllllllll",NORMAL, BRANCH,   (GT)},
516  {"BGTZL",   2,"010111sssss00000llllllllllllllll",NORMAL, BRANCH,   (GT | LIKELY)},
517  {"BLEZ",    1,"000110sssss00000llllllllllllllll",NORMAL, BRANCH,   (LT | EQ)},
518  {"BLEZL",   2,"010110sssss00000llllllllllllllll",NORMAL, BRANCH,   (LT | EQ | LIKELY)},
519  {"BLTZ",    1,"000001sssss00000llllllllllllllll",REGIMM, BRANCH,   (LT)},
520  {"BLTZAL",  1,"000001sssss10000llllllllllllllll",REGIMM, BRANCH,   (LT | LINK)},
521  {"BLTZALL", 2,"000001sssss10010llllllllllllllll",REGIMM, BRANCH,   (LT | LINK | LIKELY)},
522  {"BLTZL",   2,"000001sssss00010llllllllllllllll",REGIMM, BRANCH,   (LT | LIKELY)},
523  {"BNE",     1,"000101sssssgggggllllllllllllllll",NORMAL, BRANCH,   (NOT | EQ)},
524  {"BNEL",    2,"010101sssssgggggllllllllllllllll",NORMAL, BRANCH,   (NOT | EQ | LIKELY)},
525  {"BREAK",   1,"000000????????????????????001101",SPECIAL,BREAK,    (NOARG)},
526  {"CEIL.L",  3,"01000110mmm00000vvvvvrrrrr001010",COP1,   FPCEIL,   (FP | FIXED | DOUBLEWORD)},
527  {"CEIL.W",  2,"01000110mmm00000vvvvvrrrrr001110",COP1,   FPCEIL,   (FP | FIXED | WORD)},
528  {"COP0",    1,"010000??????????????????????????",NORMAL, DECODE,   (NOARG)},
529  {"COP2",    1,"010010??????????????????????????",NORMAL, DECODE,   (NOARG)},
530  {"CVT.D",   1,"01000110mmm00000vvvvvrrrrr100001",COP1,   FPCONVERT,(FP | DOUBLE)},
531  {"CVT.L",   3,"01000110mmm00000vvvvvrrrrr100101",COP1,   FPCONVERT,(FP | FIXED | DOUBLEWORD)},
532  {"CVT.S",   1,"01000110mmm00000vvvvvrrrrr100000",COP1,   FPCONVERT,(FP | SINGLE)},
533  {"CVT.W",   1,"01000110mmm00000vvvvvrrrrr100100",COP1,   FPCONVERT,(FP | FIXED | WORD)},
534  {"C.%s",    1,"01000110mmmkkkkkvvvvvppp0011uuuu",COP1,   FPCOMPARE,(FP)},
535  {"CxC1",    1,"01000100x10kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | WORD | CONTROL)},
536  {"DADD",    3,"000000sssssgggggddddd00000101100",SPECIAL,ADD,      (DOUBLEWORD | OVERFLOW)},
537  {"DADDI",   3,"011000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (DOUBLEWORD | OVERFLOW)},
538  {"DADDU",   3,"000000sssssgggggddddd00000101101",SPECIAL,ADD,      (DOUBLEWORD | UNSIGNED)},
539  {"DADDIU",  3,"011001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD,      (DOUBLEWORD | UNSIGNED)},
540  {"DDIV",    3,"000000sssssggggg0000000000011110",SPECIAL,DIV,      (DOUBLEWORD | HI | LO)},
541  {"DDIVU",   3,"000000sssssggggg0000000000011111",SPECIAL,DIV,      (DOUBLEWORD | UNSIGNED | HI | LO)},
542  {"DIV",     1,"000000sssssggggg0000000000011010",SPECIAL,DIV,      (WORD | WORD32 | SIGNEXTEND | HI | LO)},
543  {"DIV",     1,"01000110mmmkkkkkvvvvvrrrrr000011",COP1,   FPDIV,    (FP | WORD | HI | LO)},
544  /* start-sanitize-r5900 */
545  {"DIV1",   T5,"011100sssssggggg0000000000011010",MMINORM,DIV,      (WORD | WORD32 | SIGNEXTEND | HI | LO | PIPE1)},
546  /* end-sanitize-r5900 */
547  {"DIVU",    1,"000000sssssggggg0000000000011011",SPECIAL,DIV,      (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO)},
548  /* start-sanitize-r5900 */
549  {"DIVU1",  T5,"011100sssssggggg0000000000011011",MMINORM,DIV,      (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO | PIPE1)},
550  /* end-sanitize-r5900 */
551  {"DMADD16",G1,"000000sssssggggg0000000000101001",SPECIAL,MADD16,   (DOUBLEWORD | HI | LO)},
552  {"DMULT",   3,"000000sssssggggg0000000000011100",SPECIAL,MUL,      (DOUBLEWORD | HI | LO)},
553  {"DMULTU",  3,"000000sssssggggg0000000000011101",SPECIAL,MUL,      (DOUBLEWORD | UNSIGNED | HI | LO)},
554  {"DMxC1",   3,"01000100x01kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | DOUBLEWORD)},
555  {"DSLL",    3,"00000000000gggggdddddaaaaa111000",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL)},
556  {"DSLLV",   3,"000000sssssgggggddddd00000010100",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL | REG)},
557  {"DSLL32",  3,"00000000000gggggdddddaaaaa111100",SPECIAL,SHIFT,    (DOUBLEWORD | LEFT | LOGICAL | HI32)}, /* rd = rt << (sa + 32) */
558  {"DSRA",    3,"00000000000gggggdddddaaaaa111011",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC)},
559  {"DSRAV",   3,"000000sssssgggggddddd00000010111",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC | REG)},
560  {"DSRA32",  3,"00000000000gggggdddddaaaaa111111",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | ARITHMETIC | HI32)}, /* rd = rt >> (sa + 32) */
561  {"DSRL",    3,"00000000000gggggdddddaaaaa111010",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL)},
562  {"DSRLV",   3,"000000sssssgggggddddd00000010110",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL | REG)},
563  {"DSRL32",  3,"00000000000gggggdddddaaaaa111110",SPECIAL,SHIFT,    (DOUBLEWORD | RIGHT | LOGICAL | HI32)},
564  {"DSUB",    3,"000000sssssgggggddddd00000101110",SPECIAL,SUB,      (DOUBLEWORD)},
565  {"DSUBU",   3,"000000sssssgggggddddd00000101111",SPECIAL,SUB,      (DOUBLEWORD | UNSIGNED)},
566  {"FLOOR.L", 3,"01000110mmm00000vvvvvrrrrr001011",COP1,   FPFLOOR,  (FP | FIXED | DOUBLEWORD)},
567  {"FLOOR.W", 2,"01000110mmm00000vvvvvrrrrr001111",COP1,   FPFLOOR,  (FP | FIXED | WORD)},
568  {"J",       1,"000010jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (NONE)},                    /* NOTE: boundary case due to delay slot address being used */
569  {"JAL",     1,"000011jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (LINK)},                    /* NOTE: boundary case due to delay slot address being used */
570  {"JALR",    1,"000000sssss00000ddddd00000001001",SPECIAL,JUMP,     (LINK | REG)},
571  {"JALX",    1,"011101jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP,     (LINK | NOT)},
572  {"JR",      1,"000000sssss000000000000000001000",SPECIAL,JUMP,     (NONE)}, /* need to check PC as part of instruction fetch */
573  {"LB",      1,"100000ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (BYTE | SIGNEXTEND)},       /* NOTE: "i" rather than "o" because BYTE addressing is allowed */
574  {"LBU",     1,"100100ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (BYTE)},                    /* NOTE: See "LB" comment */
575  {"LD",      3,"110111sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD)},
576  {"LDC1",    2,"110101sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | COPROC)},
577  {"LDC2",    2,"110110sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | COPROC)},
578  {"LDL",     3,"011010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (DOUBLEWORD | LEFT)},       /* NOTE: See "LB" comment */
579  {"LDR",     3,"011011ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (DOUBLEWORD | RIGHT)},      /* NOTE: See "LB" comment */
580  {"LDXC1",  G3,"010011sssssggggg00000rrrrr000001",COP1X,  LOAD,     (FP | DOUBLEWORD | COPROC | REG)},
581  {"LH",      1,"100001sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD,     (HALFWORD | SIGNEXTEND)},
582  {"LHU",     1,"100101sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD,     (HALFWORD)},
583  {"LL",      2,"110000ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | ATOMIC | SIGNEXTEND)},
584  {"LLD",     3,"110100sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (DOUBLEWORD | ATOMIC)},
585  {"LUI",     1,"00111100000tttttiiiiiiiiiiiiiiii",NORMAL, MOVE,     (SHIFT16)}, /* Cheat and specify sign-extension of immediate field */
586  /* start-sanitize-r5900 */
587  {"LQ",     T5,"011110sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD,     (QUADWORD)},
588  /* end-sanitize-r5900 */
589  {"LW",      1,"100011ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | SIGNEXTEND)},
590  {"LWC1",    1,"110001ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | COPROC)},
591  {"LWC2",    1,"110010ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD | COPROC)},
592  {"LWL",     1,"100010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (WORD | LEFT)},
593  {"LWR",     1,"100110ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD,     (WORD | RIGHT)},
594  {"LWU",     3,"100111ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD,     (WORD)},
595  {"LWXC1",  G3,"010011sssssggggg00000rrrrr000000",COP1X,  LOAD,     (FP | WORD | COPROC | REG)},
596  /* start-sanitize-r5900 */
597  {"MADD",   T5,"011100sssssgggggddddd00000000000",MMINORM,MADD,     (NONE)},
598  {"MADD1",  T5,"011100sssssgggggddddd00000100000",MMINORM,MADD,     (PIPE1)},
599  {"MADDU",  T5,"011100sssssgggggddddd00000000001",MMINORM,MADD,     (UNSIGNED)},
600  {"MADDU1", T5,"011100sssssgggggddddd00000100001",MMINORM,MADD,     (UNSIGNED | PIPE1)},
601  /* end-sanitize-r5900 */
602  {"MADD16", G1,"000000sssssggggg0000000000101000",SPECIAL,MADD16,   (WORD | HI | LO)},
603  {"MADD.D", G3,"010011bbbbbkkkkkvvvvvrrrrr100001",COP1X,  FPADD,    (FP | MULTIPLY | DOUBLE)},
604  {"MADD.S", G3,"010011bbbbbkkkkkvvvvvrrrrr100000",COP1X,  FPADD,    (FP | MULTIPLY | SINGLE)},
605  {"MFHI",    1,"0000000000000000ddddd00000010000",SPECIAL,MOVE,     (HI | LEFT)},    /* with following, from and to denoted by usage of LEFT or RIGHT */
606  /* start-sanitize-r5900 */
607  {"MFHI1",  T5,"0111000000000000ddddd00000010000",MMINORM,MOVE,     (HI | LEFT | PIPE1)},
608  /* end-sanitize-r5900 */
609  {"MFLO",    1,"0000000000000000ddddd00000010010",SPECIAL,MOVE,     (LO | LEFT)},
610  /* start-sanitize-r5900 */
611  {"MFLO1",  T5,"0111000000000000ddddd00000010010",MMINORM,MOVE,     (LO | LEFT | PIPE1)},
612  {"MFSA",   T5,"0000000000000000ddddd00000101000",SPECIAL,MxSA,     (FROM)},
613  /* end-sanitize-r5900 */
614  {"MTHI",    1,"000000sssss000000000000000010001",SPECIAL,MOVE,     (HI | RIGHT)},
615  /* start-sanitize-r5900 */
616  {"MTHI1",  T5,"011100sssss000000000000000010001",MMINORM,MOVE,     (HI | RIGHT | PIPE1)},
617  /* end-sanitize-r5900 */
618  {"MTLO",    1,"000000sssss000000000000000010011",SPECIAL,MOVE,     (LO | RIGHT)},
619  /* start-sanitize-r5900 */
620  {"MTLO1",  T5,"011100sssss000000000000000010011",MMINORM,MOVE,     (LO | RIGHT | PIPE1)},
621  {"MTSA",   T5,"000000sssss000000000000000101001",SPECIAL,MxSA,     (TO)},
622  {"MTSAB",  T5,"000001sssss11000iiiiiiiiiiiiiiii",REGIMM, MTSAB,    (NONE)},
623  {"MTSAH",  T5,"000001sssss11001iiiiiiiiiiiiiiii",REGIMM, MTSAH,    (NONE)},
624  /* end-sanitize-r5900 */
625  {"MOV",     1,"01000110mmm00000vvvvvrrrrr000110",COP1,   FPMOVE,   (FP)},
626  {"MOVN",   G2,"000000sssssgggggddddd00000001011",SPECIAL,MOVE,     (NOT | EQ)},
627  {"MOVN",   G2,"01000110mmmgggggvvvvvrrrrr010011",COP1,   FPMOVE,   (FP | NOT | EQ)},
628  {"MOV%c",  G3,"000000sssssqqq0cddddd00000000001",SPECIAL,FPMOVE,   (FP | CONDITIONAL | INTEGER)},
629  {"MOV%c",  G3,"01000110mmmqqq0cvvvvvrrrrr010001",COP1,   FPMOVE,   (FP | CONDITIONAL)},
630  {"MOVZ",   G2,"000000sssssgggggddddd00000001010",SPECIAL,MOVE,     (EQ)},
631  {"MOVZ",   G2,"01000110mmmgggggvvvvvrrrrr010010",COP1,   FPMOVE,   (FP | EQ)},
632  {"MSUB.D", G3,"010011bbbbbkkkkkvvvvvrrrrr101001",COP1X,  FPSUB,    (FP | MULTIPLY | DOUBLE)},
633  {"MSUB.S", G3,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X,  FPSUB,    (FP | MULTIPLY | SINGLE)},
634  {"MUL",     1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1,   FPMUL,    (FP | HI | LO)},
635  {"MULT",    1,"000000sssssgggggddddd00000011000",SPECIAL,MUL,      (OP3 | WORD | WORD32 | HI | LO)},
636  /* start-sanitize-r5900 */
637  {"MULT1",  T5,"011100sssssgggggddddd00000011000",MMINORM,MUL,      (OP3 | WORD | WORD32 | HI | LO | PIPE1)},
638  /* end-sanitize-r5900 */
639  {"MULTU",   1,"000000sssssgggggddddd00000011001",SPECIAL,MUL,      (OP3 | WORD | WORD32 | UNSIGNED | HI | LO)},
640  /* start-sanitize-r5900 */
641  {"MULTU1", T5,"011100sssssgggggddddd00000011001",MMINORM,MUL,      (OP3 | WORD | WORD32 | UNSIGNED | HI | LO | PIPE1)},
642  /* end-sanitize-r5900 */
643  {"MxC1",    1,"01000100x00kkkkkvvvvv00000000000",COP1S,  FPMOVEC,  (FP | WORD)},
644  {"NEG",     1,"01000110mmm00000vvvvvrrrrr000111",COP1,   FPNEG,    (FP)},
645  {"NMADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr110001",COP1X,  FPADD,    (FP | NOT | MULTIPLY | DOUBLE)},
646  {"NMADD.S", 4,"010011bbbbbkkkkkvvvvvrrrrr110000",COP1X,  FPADD,    (FP | NOT | MULTIPLY | SINGLE)},
647  {"NMSUB.D", 4,"010011bbbbbkkkkkvvvvvrrrrr111001",COP1X,  FPSUB,    (FP | NOT | MULTIPLY | DOUBLE)},
648  {"NMSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr111000",COP1X,  FPSUB,    (FP | NOT | MULTIPLY | SINGLE)},
649  {"NOR",     1,"000000sssssgggggddddd00000100111",SPECIAL,OR,       (NOT)},
650  {"OR",      1,"000000sssssgggggddddd00000100101",SPECIAL,OR,       (NONE)},
651  {"ORI",     1,"001101ssssstttttzzzzzzzzzzzzzzzz",NORMAL, OR,       (NONE)},
652
653  /* start-sanitize-r5900 */
654  {"PABSH",  T5,"01110000000TTTTTddddd00101101000",MMI1,   PABS,     (HALFWORD)},
655  {"PABSW",  T5,"01110000000TTTTTddddd00001101000",MMI1,   PABS,     (WORD)},
656
657  {"PADDB",  T5,"011100SSSSSTTTTTddddd01000001000",MMI0,   PADD,     (BYTE)},
658  {"PADDH",  T5,"011100SSSSSTTTTTddddd00100001000",MMI0,   PADD,     (HALFWORD)},
659  {"PADDW",  T5,"011100SSSSSTTTTTddddd00000001000",MMI0,   PADD,     (WORD)},
660
661  {"PADDSB", T5,"011100SSSSSTTTTTddddd11000001000",MMI0,   PADD,     (BYTE | SATURATE)},
662  {"PADDSH", T5,"011100SSSSSTTTTTddddd10100001000",MMI0,   PADD,     (HALFWORD | SATURATE)},
663  {"PADDSW", T5,"011100SSSSSTTTTTddddd10000001000",MMI0,   PADD,     (WORD | SATURATE)},
664
665  {"PADDUB", T5,"011100SSSSSTTTTTddddd11000101000",MMI1,   PADD,     (BYTE | UNSIGNED)},
666  {"PADDUH", T5,"011100SSSSSTTTTTddddd10100101000",MMI1,   PADD,     (HALFWORD | UNSIGNED)},
667  {"PADDUW", T5,"011100SSSSSTTTTTddddd10000101000",MMI1,   PADD,     (WORD | UNSIGNED)},
668
669  {"PADSBH", T5,"011100SSSSSTTTTTddddd00100101000",MMI1,   PADSBH,   (NONE)},
670
671  {"PAND",   T5,"011100SSSSSTTTTTddddd10010001001",MMI2,   POP,      (POP_AND)},
672
673  {"PCEQB",  T5,"011100SSSSSTTTTTddddd01010101000",MMI1,   PCMP,     (EQ | BYTE)},
674  {"PCEQH",  T5,"011100SSSSSTTTTTddddd00110101000",MMI1,   PCMP,     (EQ | HALFWORD)},
675  {"PCEQW",  T5,"011100SSSSSTTTTTddddd00010101000",MMI1,   PCMP,     (EQ | WORD)},
676
677  {"PCGTB",  T5,"011100SSSSSTTTTTddddd01010001000",MMI0,   PCMP,     (GT | BYTE)},
678  {"PCGTH",  T5,"011100SSSSSTTTTTddddd00110001000",MMI0,   PCMP,     (GT | HALFWORD)},
679  {"PCGTW",  T5,"011100SSSSSTTTTTddddd00010001000",MMI0,   PCMP,     (GT | WORD)},
680
681  {"PCPYH",  T5,"01110000000TTTTTddddd11011101001",MMI3,   PCPYH,    (NONE)},
682  {"PCPYLD", T5,"011100SSSSSTTTTTddddd01110001001",MMI2,   PCPYLD,   (NONE)},
683  {"PCPYUD", T5,"011100SSSSSTTTTTddddd01110101001",MMI3,   PCPYUD,   (NONE)},
684
685  {"PDIVBW", T5,"011100SSSSSTTTTT0000011101001001",MMI2,   PDIVBW,   (NONE)},
686  {"PDIVUW", T5,"011100SSSSSTTTTT0000001101101001",MMI3,   PDIVW,    (UNSIGNED)},
687  {"PDIVW",  T5,"011100SSSSSTTTTT0000001101001001",MMI2,   PDIVW,    (NONE)},
688  
689  {"PEXCH",  T5,"01110000000TTTTTddddd11010101001",MMI3,   PEXCH,    (NONE)},
690  {"PEXCW",  T5,"01110000000TTTTTddddd11110101001",MMI3,   PEXCW,    (NONE)},
691  {"PEXOH",  T5,"01110000000TTTTTddddd11010001001",MMI2,   PEXOH,    (NONE)},
692  {"PEXOW",  T5,"01110000000TTTTTddddd11110001001",MMI2,   PEXOW,    (NONE)},
693
694  {"PEXT5",  T5,"01110000000TTTTTddddd11110001000",MMI0,   PEXT5,    (NONE)},
695
696  {"PEXTLB", T5,"011100SSSSSTTTTTddddd11010001000",MMI0,   PEXTLB,   (NONE)},
697  {"PEXTLH", T5,"011100SSSSSTTTTTddddd10110001000",MMI0,   PEXTLH,   (NONE)},
698  {"PEXTLW", T5,"011100SSSSSTTTTTddddd10010001000",MMI0,   PEXTLW,   (NONE)},
699  {"PEXTUB", T5,"011100SSSSSTTTTTddddd11010101000",MMI1,   PEXTUB,   (NONE)},
700  {"PEXTUH", T5,"011100SSSSSTTTTTddddd10110101000",MMI1,   PEXTUH,   (NONE)},
701  {"PEXTUW", T5,"011100SSSSSTTTTTddddd10010101000",MMI1,   PEXTUW,   (NONE)},
702
703  {"PHMADDH",T5,"011100SSSSSTTTTTddddd10001001001",MMI2,   PHMADDH,  (NONE)},
704  {"PHMSUBH",T5,"011100SSSSSTTTTTddddd10101001001",MMI2,   PHMADDH,  (SUBTRACT)},
705
706  {"PINTH",  T5,"011100SSSSSTTTTTddddd01010001001",MMI2,   PINTH,    (NONE)},
707  {"PINTOH", T5,"011100SSSSSTTTTTddddd01010101001",MMI3,   PINTOH,   (NONE)},
708
709  {"PLZCW",  T5,"011100SSSSS00000ddddd00000000100",MMINORM,PLZCW,    (NONE)},
710
711  {"PMADDH", T5,"011100SSSSSTTTTTddddd10000001001",MMI2,   PMULTH,   (ADDITION)},
712  {"PMADDUW",T5,"011100SSSSSTTTTTddddd00000101001",MMI3,   PMULTW,   (UNSIGNED)},
713  {"PMADDW", T5,"011100SSSSSTTTTTddddd00000001001",MMI2,   PMULTW,   (ADDITION)},
714
715  {"PMAXH",  T5,"011100SSSSSTTTTTddddd00111001000",MMI0,   PMAXMIN,  (GT | HALFWORD)},
716  {"PMAXW",  T5,"011100SSSSSTTTTTddddd00011001000",MMI0,   PMAXMIN,  (GT | WORD)},
717
718  {"PMFHI",  T5,"0111000000000000ddddd01000001001",MMI2,   PMXX,     (HI|FROM)},
719  {"PMFLO",  T5,"0111000000000000ddddd01001001001",MMI2,   PMXX,     (LO|FROM)},
720
721  {"PMFHL",  T5,"0111000000000000dddddaaaaa110000",MMINORM,PMFHL,    (NONE)},
722
723  {"PMINH",  T5,"011100SSSSSTTTTTddddd00111101000",MMI1,   PMAXMIN,  (LT | HALFWORD)},
724  {"PMINW",  T5,"011100SSSSSTTTTTddddd00011101000",MMI1,   PMAXMIN,  (LT | WORD)},
725
726  {"PMSUBH", T5,"011100SSSSSTTTTTddddd10100001001",MMI2,   PMULTH,   (SUBTRACT)},
727  {"PMSUBW", T5,"011100SSSSSTTTTTddddd00100001001",MMI2,   PMULTW,   (SUBTRACT)},
728
729  {"PMTHI",  T5,"011100SSSSS000000000001000101001",MMI3,   PMXX,     (HI|TO)},
730  {"PMTLO",  T5,"011100SSSSS000000000001001101001",MMI3,   PMXX,     (LO|TO)},
731
732 {"PMTHL.LW",T5,"011100SSSSS000000000000000110001",MMINORM,PMTHL,    (NONE)},
733
734  {"PMULTH", T5,"011100SSSSSTTTTTddddd11100001001",MMI2,   PMULTH,   (NONE)},
735  {"PMULTUW",T5,"011100SSSSSTTTTTddddd01100101001",MMI3,   PMULTW,   (UNSIGNED)},
736  {"PMULTW", T5,"011100SSSSSTTTTTddddd01100001001",MMI2,   PMULTW,   (NONE)},
737
738  {"PNOR",   T5,"011100SSSSSTTTTTddddd10011101001",MMI3,   POP,      (POP_NOR)},
739  {"POR",    T5,"011100SSSSSTTTTTddddd10010101001",MMI3,   POP,      (POP_OR)},
740
741  {"PPAC5",  T5,"01110000000TTTTTddddd11111001000",MMI0,   PPAC5,    (NONE)},
742
743  {"PPACB",  T5,"011100SSSSSTTTTTddddd11011001000",MMI0,   PPACB,    (NONE)},
744  {"PPACH",  T5,"011100SSSSSTTTTTddddd10111001000",MMI0,   PPACH,    (NONE)},
745  {"PPACW",  T5,"011100SSSSSTTTTTddddd10011001000",MMI0,   PPACW,    (NONE)},
746
747  {"PREVH",  T5,"01110000000TTTTTddddd11011001001",MMI2,   PREVH,    (NONE)},
748  {"PROT3W", T5,"01110000000TTTTTddddd11111001001",MMI2,   PROT3W,   (NONE)},
749
750  {"PSLLH",  T5,"01110000000TTTTTdddddaaaaa110100",MMINORM,PSHIFT,   (LEFT | LOGICAL | HALFWORD)},
751  {"PSLLVW", T5,"011100SSSSSTTTTTddddd00010001001",MMI2,   PSLLVW,   (NONE)},
752  {"PSLLW",  T5,"01110000000TTTTTdddddaaaaa111100",MMINORM,PSHIFT,   (LEFT | LOGICAL | WORD)},
753
754  {"PSRAH",  T5,"01110000000TTTTTdddddaaaaa110111",MMINORM,PSHIFT,   (RIGHT | ARITHMETIC | HALFWORD)},
755  {"PSRAVW", T5,"011100SSSSSTTTTTddddd00011101001",MMI3,   PSRAVW,   (NONE)},
756  {"PSRAW",  T5,"01110000000TTTTTdddddaaaaa111111",MMINORM,PSHIFT,   (RIGHT | ARITHMETIC | WORD)},
757
758  {"PSRLH",  T5,"01110000000TTTTTdddddaaaaa110110",MMINORM,PSHIFT,   (RIGHT | LOGICAL | HALFWORD)},
759  {"PSRLVW", T5,"011100SSSSSTTTTTddddd00011001001",MMI2,   PSRLVW,   (NONE)},
760  {"PSRLW",  T5,"01110000000TTTTTdddddaaaaa111110",MMINORM,PSHIFT,   (RIGHT | LOGICAL | WORD)},
761
762  {"PSUBB",  T5,"011100SSSSSTTTTTddddd01001001000",MMI0,   PADD,     (SUBTRACT | BYTE)},
763  {"PSUBH",  T5,"011100SSSSSTTTTTddddd00101001000",MMI0,   PADD,     (SUBTRACT | HALFWORD)},
764  {"PSUBSB", T5,"011100SSSSSTTTTTddddd11001001000",MMI0,   PADD,     (SUBTRACT | SATURATE | BYTE )},
765  {"PSUBSH", T5,"011100SSSSSTTTTTddddd10101001000",MMI0,   PADD,     (SUBTRACT | SATURATE | HALFWORD)},
766  {"PSUBSW", T5,"011100SSSSSTTTTTddddd10001001000",MMI0,   PADD,     (SUBTRACT | SATURATE | WORD)},
767  {"PSUBUB", T5,"011100SSSSSTTTTTddddd11001101000",MMI1,   PADD,     (SUBTRACT | UNSIGNED | BYTE)},
768  {"PSUBUH", T5,"011100SSSSSTTTTTddddd10101101000",MMI1,   PADD,     (SUBTRACT | UNSIGNED | HALFWORD)},
769  {"PSUBUW", T5,"011100SSSSSTTTTTddddd10001101000",MMI1,   PADD,     (SUBTRACT | UNSIGNED | WORD)},
770  {"PSUBW",  T5,"011100SSSSSTTTTTddddd00001001000",MMI0,   PADD,     (SUBTRACT | WORD)},
771
772  {"PXOR",   T5,"011100SSSSSTTTTTddddd10011001001",MMI2,   POP,      (POP_XOR)},
773  /* end-sanitize-r5900 */
774
775  {"PREF",   G2,"110011sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, PREFETCH, (NONE)},
776  {"PREFX",   4,"010011sssssgggggvvvvv00000001111",COP1X,  FPPREFX,  (FP)},
777
778  /* start-sanitize-r5900 */
779  {"QFSRV",  T5,"011100SSSSSTTTTTddddd11011101000",MMI1,   QFSRV,    (NONE)},
780  /* end-sanitize-r5900 */
781
782  {"RECIP",   4,"01000110mmm00000vvvvvrrrrr010101",COP1,   FPRECIP,  (FP)},
783  {"ROUND.L", 3,"01000110mmm00000vvvvvrrrrr001000",COP1,   FPROUND,  (FP | FIXED | DOUBLEWORD)},
784  {"ROUND.W", 2,"01000110mmm00000vvvvvrrrrr001100",COP1,   FPROUND,  (FP | FIXED | WORD)},
785  {"RSQRT",   4,"01000110mmm00000vvvvvrrrrr010110",COP1,   FPSQRT,   (FP | RECIP)},
786  {"SB",      1,"101000sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (BYTE)},
787  {"SC",      2,"111000sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | ATOMIC)},
788  {"SCD",     3,"111100sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | ATOMIC)},
789  {"SD",      3,"111111sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD)},
790  {"SDC1",    2,"111101sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | COPROC)},
791  {"SDC2",    2,"111110sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE,    (DOUBLEWORD | COPROC)},
792  {"SDL",     3,"101100sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (DOUBLEWORD | LEFT)},
793  {"SDR",     3,"101101sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (DOUBLEWORD | RIGHT)},
794  {"SDXC1",  G3,"010011sssssgggggvvvvv00000001001",COP1X,  STORE,    (FP | DOUBLEWORD | COPROC | REG)},
795  {"SH",      1,"101001sssssggggghhhhhhhhhhhhhhhh",NORMAL, STORE,    (HALFWORD)},
796  {"SLL",     1,"00000000000gggggdddddaaaaa000000",SPECIAL,SHIFT,    (WORD | LEFT | LOGICAL)}, /* rd = rt << sa */
797  {"SLLV",    1,"000000ooooogggggddddd00000000100",SPECIAL,SHIFT,    (WORD | LEFT | LOGICAL)}, /* rd = rt << rs - with "SLL" depends on "s" and "a" field values */
798  {"SLT",     1,"000000sssssgggggddddd00000101010",SPECIAL,SET,      (LT)},
799  {"SLTI",    1,"001010ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET,      (LT)},
800  {"SLTU",    1,"000000sssssgggggddddd00000101011",SPECIAL,SET,      (LT | UNSIGNED)},
801  {"SLTIU",   1,"001011ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET,      (LT | UNSIGNED)},
802  /* start-sanitize-r5900 */
803  {"SQ",     T5,"011111sssssTTTTTeeeeeeeeeeeeeeee",NORMAL, STORE,    (QUADWORD)},
804  /* end-sanitize-r5900 */
805  {"SQRT",    2,"01000110mmm00000vvvvvrrrrr000100",COP1,   FPSQRT,   (FP)},
806  {"SRA",     1,"00000000000gggggdddddaaaaa000011",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | ARITHMETIC)},
807  {"SRAV",    1,"000000ooooogggggddddd00000000111",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | ARITHMETIC)},
808  {"SRL",     1,"00000000000gggggdddddaaaaa000010",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | LOGICAL)},
809  {"SRLV",    1,"000000ooooogggggddddd00000000110",SPECIAL,SHIFT,    (WORD | WORD32 | RIGHT | LOGICAL)},
810  {"SUB",     1,"000000sssssgggggddddd00000100010",SPECIAL,SUB,      (WORD | WORD32 | OVERFLOW)},
811  {"SUB",     1,"01000110mmmkkkkkvvvvvrrrrr000001",COP1,   FPSUB,    (FP)},
812  {"SUBU",    1,"000000sssssgggggddddd00000100011",SPECIAL,SUB,      (WORD | WORD32)},
813  {"SW",      1,"101011sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD)},
814  {"SWC1",    1,"111001ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | COPROC)},
815  {"SWC2",    1,"111010ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE,    (WORD | COPROC)},
816  {"SWL",     1,"101010sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (WORD | LEFT)},
817  {"SWR",     1,"101110sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE,    (WORD | RIGHT)},
818  {"SWXC1",  G3,"010011sssssgggggvvvvv00000001000",COP1X,  STORE,    (FP | WORD | COPROC | REG)},
819  {"SYNC",    2,"000000000000000000000aaaaa001111",SPECIAL,SYNC,     (NONE)}, /* z = 5bit stype field */
820  {"SYSCALL", 1,"000000????????????????????001100",SPECIAL,SYSCALL,  (NOARG)},
821  {"TEQ",     2,"000000sssssggggg??????????110100",SPECIAL,TRAP,     (EQ)},
822  {"TEQI",    2,"000001sssss01100iiiiiiiiiiiiiiii",REGIMM, TRAP,     (EQ)},
823  {"TGE",     2,"000000sssssggggg??????????110000",SPECIAL,TRAP,     (GT | EQ)},
824  {"TGEI",    2,"000001sssss01000iiiiiiiiiiiiiiii",REGIMM, TRAP,     (GT | EQ)},
825  {"TGEIU",   2,"000001sssss01001iiiiiiiiiiiiiiii",REGIMM, TRAP,     (GT | EQ | UNSIGNED)},
826  {"TGEU",    2,"000000sssssggggg??????????110001",SPECIAL,TRAP,     (GT | EQ | UNSIGNED)},
827  {"TLT",     2,"000000sssssggggg??????????110010",SPECIAL,TRAP,     (LT)},
828  {"TLTI",    2,"000001sssss01010iiiiiiiiiiiiiiii",REGIMM, TRAP,     (LT)},
829  {"TLTIU",   2,"000001sssss01011iiiiiiiiiiiiiiii",REGIMM, TRAP,     (LT | UNSIGNED)},
830  {"TLTU",    2,"000000sssssggggg??????????110011",SPECIAL,TRAP,     (LT | UNSIGNED)},
831  {"TNE",     2,"000000sssssggggg??????????110110",SPECIAL,TRAP,     (NOT | EQ)},
832  {"TNEI",    2,"000001sssss01110iiiiiiiiiiiiiiii",REGIMM, TRAP,     (NOT | EQ)},
833  {"TRUNC.L", 3,"01000110mmm00000vvvvvrrrrr001001",COP1,   FPTRUNC,  (FP | FIXED | DOUBLEWORD)},
834  {"TRUNC.W", 2,"01000110mmm00000vvvvvrrrrr001101",COP1,   FPTRUNC,  (FP | FIXED | WORD)},
835  {"XOR",     1,"000000sssssgggggddddd00000100110",SPECIAL,XOR,      (NONE)},
836  {"XORI",    1,"001110ssssstttttzzzzzzzzzzzzzzzz",NORMAL, XOR,      (NONE)},
837  {"CACHE",   3,"101111sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, CACHE,    (NONE)},
838  {"<INT>",   1,"111011sssssgggggyyyyyyyyyyyyyyyy",NORMAL, RSVD,     (NONE)},
839 };
840
841 static const struct instruction MIPS16_DECODE[] = {
842 {"ADDIU",   1, "01000xxxddd04444",  RRI_A,   ADD,     WORD | WORD32 },
843 {"ADDIU8",  1, "01001wwwkkkkkkkk",  RI,      ADD,     WORD | WORD32 },
844 {"ADJSP",   1, "01100011KKKKKKKKS", I8,      ADD,     WORD | WORD32 },
845 {"ADDIUPC", 1, "00001dddAAAAAAAAP", RI,      ADD,     WORD | WORD32 },
846 {"ADDIUSP", 1, "00000dddAAAAAAAAs", RI,      ADD,     WORD | WORD32 },
847 {"ADDU",    1, "11100xxxyyyddd01",  RRR,     ADD,     WORD | WORD32 },
848 {"AND",     1, "11101wwwyyy01100",  RR,      AND,     NONE },
849 {"B",       1, "00010qqqqqqqqqqqzZ", I,      BRANCH,  EQ },
850 {"BEQZ",    1, "00100xxxppppppppz", RI,      BRANCH,  EQ },
851 {"BNEZ",    1, "00101xxxppppppppz", RI,      BRANCH,  NOT | EQ },
852 {"BREAK",   1, "01100??????00101",  RR,      BREAK,   NOARG },
853 {"BTEQZ",   1, "01100000pppppppptz", I8,     BRANCH,  EQ },
854 {"BTNEZ",   1, "01100001pppppppptz", I8,     BRANCH,  NOT | EQ },
855 {"CMP",     1, "11101xxxyyy01010T", RR,      XOR,     NONE },
856 {"CMPI",    1, "01110xxxUUUUUUUUT", RI,      XOR,     NONE },
857 {"DADDIU",  3, "01000xxxddd14444",  RRI_A,   ADD,     DOUBLEWORD },
858 {"DADDIU5", 3, "11111101wwwjjjjj",  RI64,    ADD,     DOUBLEWORD },
859 {"DADJSP",  3, "11111011KKKKKKKKS", I64,     ADD,     DOUBLEWORD },
860 {"DADIUPC", 3, "11111110dddEEEEEP", RI64,    ADD,     DOUBLEWORD },
861 {"DADIUSP", 3, "11111111dddEEEEEs", RI64,    ADD,     DOUBLEWORD },
862 {"DADDU",   3, "11100xxxyyyddd00",  RRR,     ADD,     DOUBLEWORD },
863 {"DDIV",    3, "11101xxxyyy11110",  RR,      DIV,     DOUBLEWORD | HI | LO },
864 {"DDIVU",   3, "11101xxxyyy11111",  RR,      DIV,     DOUBLEWORD | UNSIGNED | HI | LO },
865 {"DIV",     1, "11101xxxyyy11010",  RR,      DIV,     WORD | WORD32 | SIGNEXTEND | HI | LO },
866 {"DIVU",    1, "11101xxxyyy11011",  RR,      DIV,     WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO },
867 {"DMULT",   3, "11101xxxyyy11100",  RR,      MUL,     DOUBLEWORD | HI | LO },
868 {"DMULTU",  3, "11101xxxyyy11101",  RR,      MUL,     DOUBLEWORD | UNSIGNED | HI | LO },
869 {"DSLL",    3, "00110dddyyy[[[01",  ISHIFT,  SHIFT,   DOUBLEWORD | LEFT | LOGICAL },
870 {"DSLLV",   3, "11101xxxvvv10100",  RR,      SHIFT,   DOUBLEWORD | LEFT | LOGICAL | REG },
871 {"DSRA",    3, "11101]]]vvv10011",  RR,      SHIFT,   DOUBLEWORD | RIGHT | ARITHMETIC },
872 {"DSRAV",   3, "11101xxxvvv10111",  RR,      SHIFT,   DOUBLEWORD | RIGHT | ARITHMETIC | REG},
873 {"DSRL",    3, "11101]]]vvv01000",  RR,      SHIFT,   DOUBLEWORD | RIGHT | LOGICAL },
874 {"DSRLV",   3, "11101xxxvvv10110",  RR,      SHIFT,   DOUBLEWORD | RIGHT | LOGICAL | REG},
875 {"DSUBU",   3, "11100xxxyyyddd10",  RRR,     SUB,     DOUBLEWORD | UNSIGNED},
876 #if 0
877   /* FIXME: Should we handle these ourselves, or should we require an
878      emulation routine?  */
879 {"EXIT",    1, "1110111100001000",  RR,      BREAK,   EXIT },
880 {"ENTRY",   1, "11101??????01000",  RR,      BREAK,   ENTRY },
881 #endif
882 {"EXTEND",  1, "11110eeeeeeeeeee",  I,       RSVD,    NOARG },
883 {"JALR",    1, "11101xxx01000000R", RR,      JUMP,    LINK | REG },
884 {"JAL",     1, "00011aaaaaaaaaaa",  I,       JUMP,    LINK },
885 {"JR",      1, "11101xxx00000000",  RR,      JUMP,    NONE },
886 {"JRRA",    1, "1110100000100000r", RR,      JUMP,    NONE },
887 {"LB",      1, "10000xxxddd55555",  RRI,     LOAD,    BYTE | SIGNEXTEND },
888 {"LBU",     1, "10100xxxddd55555",  RRI,     LOAD,    BYTE },
889 {"LD",      3, "00111xxxdddDDDDD",  RRI,     LOAD,    DOUBLEWORD },
890 {"LDPC",    3, "11111100dddDDDDDP", RI64,    LOAD,    DOUBLEWORD },
891 {"LDSP",    3, "11111000dddDDDDDs", RI64,    LOAD,    DOUBLEWORD },
892 {"LH",      1, "10001xxxdddHHHHH",  RRI,     LOAD,    HALFWORD | SIGNEXTEND },
893 {"LHU",     1, "10101xxxdddHHHHH",  RRI,     LOAD,    HALFWORD },
894 {"LI",      1, "01101dddUUUUUUUUZ", RI,      OR,      NONE },
895 {"LW",      1, "10011xxxdddWWWWW",  RRI,     LOAD,    WORD | SIGNEXTEND },
896 {"LWPC",    1, "10110dddVVVVVVVVP", RI,      LOAD,    WORD | SIGNEXTEND },
897 {"LWSP",    1, "10010dddVVVVVVVVs", RI,      LOAD,    WORD | SIGNEXTEND },
898 {"LWU",     1, "10111xxxdddWWWWW",  RRI,     LOAD,    WORD },
899 {"MFHI",    1, "11101ddd00010000",  RR,      MOVE,    HI | LEFT },
900 {"MFLO",    1, "11101ddd00010010",  RR,      MOVE,    LO | LEFT },
901 {"MOVR32",  1, "01100111dddXXXXXz", I8_MOVR32, OR,    NONE },
902 {"MOV32R",  1, "01100101YYYYYxxxz", I8_MOV32R, OR,    NONE },
903 {"MULT",    1, "11101xxxyyy11000",  RR,      MUL,     WORD | WORD32 | HI | LO},
904 {"MULTU",   1, "11101xxxyyy11001",  RR,      MUL,     WORD | WORD32 | UNSIGNED | HI | LO },
905 {"NEG",     1, "11101dddyyy01011Z", RR,      SUB,     WORD },
906 {"NOT",     1, "11101dddyyy01111Z", RR,      OR,      NOT },
907 {"OR",      1, "11101wwwyyy01101",  RR,      OR,      NONE },
908 {"SB",      1, "11000xxxyyy55555",  RRI,     STORE,   BYTE },
909 {"SD",      3, "01111xxxyyyDDDDD",  RRI,     STORE,   DOUBLEWORD },
910 {"SDSP",    3, "11111001yyyDDDDDs", RI64,    STORE,   DOUBLEWORD },
911 {"SDRASP",  3, "11111010CCCCCCCCsQ", I64,    STORE,   DOUBLEWORD },
912 {"SH",      1, "11001xxxyyyHHHHH",  RRI,     STORE,   HALFWORD },
913 {"SLL",     1, "00110dddyyy<<<00",  ISHIFT,  SHIFT,   WORD | LEFT | LOGICAL },
914 {"SLLV",    1, "11101xxxvvv00100",  RR,      SHIFT,   WORD | LEFT | LOGICAL | REG},
915 {"SLT",     1, "11101xxxyyy00010T", RR,      SET,     LT },
916 {"SLTI",    1, "01010xxx88888888T", RI,      SET,     LT },
917 {"SLTU",    1, "11101xxxyyy00011T", RR,      SET,     LT | UNSIGNED },
918 {"SLTIU",   1, "01011xxx88888888T", RI,      SET,     LT | UNSIGNED },
919 {"SRA",     1, "00110dddyyy<<<11",  ISHIFT,  SHIFT,   WORD | WORD32 | RIGHT | ARITHMETIC },
920 {"SRAV",    1, "11101xxxvvv00111",  RR,      SHIFT,   WORD | WORD32 | RIGHT | ARITHMETIC | REG },
921 {"SRL",     1, "00110dddyyy<<<10",  ISHIFT,  SHIFT,   WORD | WORD32 | RIGHT | LOGICAL },
922 {"SRLV",    1, "11101xxxvvv00110",  RR,      SHIFT,   WORD | WORD32 | RIGHT | LOGICAL | REG },
923 {"SUBU",    1, "11100xxxyyyddd11",  RRR,     SUB,     WORD | WORD32 },
924 {"SW",      1, "11011xxxyyyWWWWW",  RRI,     STORE,   WORD },
925 {"SWSP",    1, "11010yyyVVVVVVVVs", RI,      STORE,   WORD },
926 {"SWRASP",  1, "01100010VVVVVVVVQs", I8,     STORE,   WORD },
927 {"XOR",     1, "11101wwwyyy01110",  RR,      XOR,     NONE }
928 };
929
930 static int bitmap_val PARAMS ((const char *, int, int));
931 static void build_mips16_operands PARAMS ((const char *));
932 static void build_instruction
933   PARAMS ((int, unsigned int, int, const struct instruction *));
934
935 /*---------------------------------------------------------------------------*/
936
937 static char* 
938 name_for_data_len( insn )
939      struct instruction* insn;
940   {
941     if (GETDATASIZEINSN(insn) == BYTE)
942       return "BYTE";
943
944     else if (GETDATASIZEINSN(insn) == HALFWORD)
945       return "HALFWORD";
946
947     else if (GETDATASIZEINSN(insn) == WORD)
948       return "WORD";
949
950     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
951       return "DOUBLEWORD";
952
953     else if (GETDATASIZEINSN(insn) == QUADWORD)
954       return "QUADWORD";
955
956     else
957       return 0;
958   }
959
960 static char* 
961 letter_for_data_len( insn )
962      struct instruction* insn;
963   {
964     if (GETDATASIZEINSN(insn) == BYTE)
965       return "B";
966
967     else if (GETDATASIZEINSN(insn) == HALFWORD)
968       return "H";
969
970     else if (GETDATASIZEINSN(insn) == WORD)
971       return "W";
972
973     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
974       return "D";
975
976     else if (GETDATASIZEINSN(insn) == QUADWORD)
977       return "Q";
978
979     else
980       return 0;
981   }
982
983 static char* 
984 type_for_data_len( insn )
985      struct instruction* insn;
986   {
987     if (GETDATASIZEINSN(insn) == BYTE)
988       return "int";
989
990     else if (GETDATASIZEINSN(insn) == HALFWORD)
991       return "int";
992
993     else if (GETDATASIZEINSN(insn) == WORD)
994       return "long";
995
996     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
997       return "long long";
998
999     else if (GETDATASIZEINSN(insn) == QUADWORD)
1000       return 0;
1001
1002     else
1003       return 0;
1004   }
1005
1006 static char* 
1007 max_for_data_len( insn )
1008      struct instruction* insn;
1009   {
1010     if (GETDATASIZEINSN(insn) == BYTE)
1011       return "127";
1012
1013     else if (GETDATASIZEINSN(insn) == HALFWORD)
1014       return "32767";
1015
1016     else if (GETDATASIZEINSN(insn) == WORD)
1017       return "(int)0x7FFFFFFF";
1018
1019     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
1020       return 0;
1021
1022     else if (GETDATASIZEINSN(insn) == QUADWORD)
1023       return 0;
1024
1025     else
1026       return 0;
1027   }
1028
1029 static char* 
1030 min_for_data_len( insn )
1031      struct instruction* insn;
1032   {
1033     if (GETDATASIZEINSN(insn) == BYTE)
1034       return "-128";
1035
1036     else if (GETDATASIZEINSN(insn) == HALFWORD)
1037       return "-32768";
1038
1039     else if (GETDATASIZEINSN(insn) == WORD)
1040       return "(int)0x80000000";
1041
1042     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
1043       return 0;
1044
1045     else if (GETDATASIZEINSN(insn) == QUADWORD)
1046       return 0;
1047
1048     else
1049       return 0;
1050   }
1051
1052 static char* 
1053 umax_for_data_len( insn )
1054      struct instruction* insn;
1055   {
1056     if (GETDATASIZEINSN(insn) == BYTE)
1057       return "0xFF";
1058
1059     else if (GETDATASIZEINSN(insn) == HALFWORD)
1060       return "0xFFFF";
1061
1062     else if (GETDATASIZEINSN(insn) == WORD)
1063       return "0xFFFFFFFF";
1064
1065     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
1066       return 0;
1067
1068     else if (GETDATASIZEINSN(insn) == QUADWORD)
1069       return 0;
1070
1071     else
1072       return 0;
1073   }
1074
1075 static char* 
1076 bits_for_data_len( insn )
1077      struct instruction* insn;
1078   {
1079     if (GETDATASIZEINSN(insn) == BYTE)
1080       return "8";
1081
1082     else if (GETDATASIZEINSN(insn) == HALFWORD)
1083       return "16";
1084
1085     else if (GETDATASIZEINSN(insn) == WORD)
1086       return "32";
1087
1088     else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
1089       return "64";
1090
1091     else if (GETDATASIZEINSN(insn) == QUADWORD)
1092       return "128";
1093
1094     else
1095       return 0;
1096   }
1097
1098 /*---------------------------------------------------------------------------*/
1099
1100
1101 void
1102 convert_bitmap(bitmap,onemask,zeromask,dontmask)
1103      char *bitmap;
1104      unsigned int *onemask, *zeromask, *dontmask;
1105 {
1106   int loop; /* current bitmap position */
1107   int lastsp = -1; /* last bitmap field starting position */
1108   int lastoe = -1; /* last bitmap field encoding */
1109
1110   *onemask = 0x00000000;
1111   *zeromask = 0x00000000;
1112   *dontmask = 0x00000000;
1113
1114   if (strlen(bitmap) != 32) {
1115     fprintf(stderr,"Invalid bitmap string - not 32 characters long \"%s\"\n",bitmap);
1116     exit(3);
1117   }
1118
1119   for (loop = 0; (loop < 32); loop++) {
1120     int oefield ;
1121     for (oefield = 0; (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))); oefield++)
1122      if (bitmap[31 - loop] == opfields[oefield].id)
1123       break;
1124     if (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))) {
1125       if ((lastoe != -1) && (lastoe != oefield))
1126        if ((loop - lastsp) != (opfields[lastoe].flen)) {
1127          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);
1128          exit(4);
1129        }
1130          
1131       switch (bitmap[31 - loop]) {
1132         case '0' : /* fixed value */
1133          *zeromask |= (1 << loop);
1134          lastsp = loop;
1135          lastoe = -1;
1136          break;
1137
1138         case '1' : /* fixed value */
1139          *onemask |= (1 << loop);
1140          lastsp = loop;
1141          lastoe = -1;
1142          break;
1143
1144         case '?' : /* fixed value */
1145          *dontmask |= (1 << loop);
1146          lastsp = loop;
1147          lastoe = -1;
1148          break;
1149
1150         default : /* check character encoding */
1151          {
1152            if (opfields[oefield].fpos != -1) {
1153              /* If flag not set, then check starting position: */
1154              if (lastoe != oefield) {
1155                if (loop != opfields[oefield].fpos) {
1156                  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);
1157                  exit(4);
1158                }
1159                lastsp = loop;
1160                lastoe = oefield;
1161              }
1162            }
1163            *dontmask |= (1 << loop);
1164          }
1165          break;
1166        }
1167     } else {
1168       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);
1169       exit(4);
1170     }
1171   }
1172
1173  /* NOTE: Since we check for the position and size of fields when
1174     parsing the "bitmap" above, we do *NOT* need to check that invalid
1175     field combinations have been used. */
1176 }
1177
1178 /* Get the value of a 16 bit bitstring for a given shift count and
1179    number of bits.  */
1180
1181 static int
1182 bitmap_val (bitmap, shift, bits)
1183      const char *bitmap;
1184      int shift;
1185      int bits;
1186 {
1187   const char *s;
1188   int ret;
1189
1190   ret = 0;
1191   s = bitmap + 16 - shift - bits;
1192   for (; bits > 0; --bits)
1193     {
1194       ret <<= 1;
1195       if (*s == '0')
1196         ;
1197       else if (*s == '1')
1198         ret |= 1;
1199       else
1200         abort ();
1201       ++s;
1202     }
1203
1204   return ret;
1205 }
1206
1207 /*---------------------------------------------------------------------------*/
1208
1209 static void
1210 build_operands(doisa,features,insn)
1211      int doisa;
1212      unsigned int features;
1213      instruction* insn;
1214 {
1215   int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
1216   int finish_jump_flag = 0;
1217   int check_mult = 0;
1218   int check_condition_code = 0;
1219   int sfield_used = 0;
1220   int gfield_used = 0;
1221   int any_operand = 0;
1222
1223   int current_field_id = -1;
1224   int bitpos;
1225
1226   for (bitpos=0; bitpos<32; bitpos++) {
1227     if (insn->bitmap[31-bitpos] != current_field_id)
1228       {
1229         int opindex;
1230
1231         current_field_id = insn->bitmap[31-bitpos];
1232
1233         for (opindex = 0; (opindex < (sizeof(opfields) / sizeof(operand_encoding))); opindex++)
1234           if ((opfields[opindex].fpos != -1) && (opfields[opindex].id == insn->bitmap[31-bitpos])) {
1235
1236             any_operand = 1;
1237
1238             printf("  %s %s = ",opfields[opindex].type,opfields[opindex].name);
1239
1240             if (opfields[opindex].flags & OP_SIGNX)
1241               printf("SIGNEXTEND((%s)",opfields[opindex].type);
1242
1243             if (opfields[opindex].flags & OP_GPR)
1244               printf("GPR[");
1245
1246             if (opfields[opindex].flags & OP_SHIFT2)
1247               printf("(");
1248
1249             printf("((instruction >> %d) & 0x%08X)",opfields[opindex].fpos,((1 << opfields[opindex].flen) - 1));
1250
1251             if (opfields[opindex].flags & OP_SHIFT2)
1252               printf(" << 2)");
1253
1254             if (opfields[opindex].flags & OP_GPR)
1255               printf("]");
1256
1257             if (opfields[opindex].flags & OP_BITS5)
1258               printf("&0x1F");
1259
1260             if (opfields[opindex].flags & OP_SIGNX)
1261               printf(",%d)",(opfields[opindex].flen + ((opfields[opindex].flags & OP_SHIFT2) ? 2 : 0)));
1262
1263             printf(";\n");
1264
1265             if (opfields[opindex].flags & OP_GPR1)
1266               {
1267                 printf("  %s %s1 = GPR1[",opfields[opindex].type,opfields[opindex].name);
1268                 printf("((instruction >> %d) & 0x%08X)",
1269                        opfields[opindex].fpos,
1270                        ((1 << opfields[opindex].flen) - 1));
1271               printf("];\n");
1272               }
1273
1274             if (opfields[opindex].id == 'j')
1275               finish_jump_flag = 1;
1276
1277             if (opfields[opindex].id == 'e')
1278               check_mult = 8;
1279             
1280             if (opfields[opindex].id == 'w')
1281               check_mult = 4;
1282
1283             if (opfields[opindex].id == 'w')
1284               check_mult = 2;
1285
1286             if (opfields[opindex].id == 'p')
1287               check_condition_code = 1;
1288
1289             if (opfields[opindex].id == 's')
1290               sfield_used = 1;
1291
1292             if (opfields[opindex].id == 'g')
1293               gfield_used = 1;
1294           }
1295       }
1296   }
1297
1298   if ( !any_operand && !(insn->flags & NOARG)) {
1299     fprintf(stderr,"Bitmap error: Instruction with no operand fields \"%s\"\n",insn->name) ;
1300     exit(5) ;
1301   }
1302
1303   /* Finish constructing the jump address if required: */
1304   if (finish_jump_flag)
1305     printf("  op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */\n");
1306
1307   /* Now perform required operand checks: */
1308
1309   /* The following code has been removed, since it seems perfectly
1310      reasonable to have a non-aligned offset that is added to another
1311      non-aligned base to create an aligned address. Some more
1312      information on exactly what the MIPS IV specification requires is
1313      needed before deciding on the best strategy. Experimentation with a
1314      VR4300 suggests that we do not need to raise the warning. */
1315 #if 0
1316   /* For MIPS IV (and onwards), certain instruction operand values
1317      will give undefined results. For the simulator we could
1318      generate explicit exceptions (i.e. ReservedInstruction) to
1319      make it easier to spot invalid use. However, for the moment we
1320      just raise a warning. NOTE: This is a different check to the
1321      later decoding, which checks for the final address being
1322      valid. */
1323      
1324   if (check_mult != 0 && check_mult != 1) {
1325     printf("  if (instruction & 0x%1X)\n", check_mult);
1326     printf("  {\n");
1327     /* NOTE: If we change this to a SignalException(), we must
1328        ensure that the following opcode processing is not
1329        executed. i.e. the code falls straight out to the simulator
1330        control loop. */
1331     printf("   sim_warning(\"Instruction has lo-order offset bits set in instruction\");\n");
1332     printf("  }\n");
1333   }
1334 #endif
1335
1336   /* The extended condition codes only appeared in ISA IV */
1337   if (check_condition_code && (doisa < 4)) {
1338     printf("  if (condition_code != 0)\n");
1339     printf("  {\n");
1340     printf("   SignalException(ReservedInstruction,instruction);\n");
1341     printf("  }\n");
1342     printf("  else\n");
1343   }
1344   
1345   if ((insn->flags & WORD32) && (GETDATASIZEINSN(insn) != WORD)) {
1346     fprintf(stderr,"Error in opcode table: WORD32 set for non-WORD opcode\n");
1347     exit(1);
1348   }
1349   
1350 #if 1
1351   /* The R4000 book differs slightly from the MIPS IV ISA
1352      manual. An example is the sign-extension of a 64-bit processor
1353      SUBU operation, and what is meant by an Undefined Result. This
1354      is now provided purely as a warning. After examining a HW
1355      implementation, this is now purely a warning... and the actual
1356      operation is performed, with possibly undefined results. */
1357   if (((insn->flags & WORD32) && proc64) && (features & FEATURE_WARN_RESULT)) {
1358     /* The compiler should optimise out an OR with zero */
1359     printf("  if (%s | %s)\n",(sfield_used ? "NOTWORDVALUE(op1)" : "0"),(gfield_used ? "NOTWORDVALUE(op2)" : "0"));
1360     printf("   UndefinedResult();\n") ;
1361   }
1362 #else
1363   /* Check that the source is a 32bit value */
1364   if ((insn->flags & WORD32) && proc64) {
1365     /* The compiler should optimise out an OR with zero */
1366     printf("  if (%s | %s)\n",(sfield_used ? "NOTWORDVALUE(op1)" : "0"),(gfield_used ? "NOTWORDVALUE(op2)" : "0"));
1367     printf("   UndefinedResult();\n") ;
1368     printf("  else\n") ;
1369   }
1370 #endif
1371
1372   return;
1373 }
1374
1375 /* The mips16 operand table.  */
1376
1377 struct mips16_op
1378 {
1379   /* The character which appears in the bitmap string.  */
1380   int type;
1381   /* The type of the variable in the simulator.  */
1382   const char *vartype;
1383   /* The name of the variable in the simulator.  */
1384   const char *name;
1385   /* The number of bits.  */
1386   int nbits;
1387   /* The number of bits when extended (zero if can not be extended).  */
1388   int extbits;
1389   /* The amount by which the short form is shifted when it is used;
1390      for example, the sw instruction has a shift count of 2.  */
1391   int shift;
1392   /* Flags.  */
1393   int flags;
1394 };
1395
1396 /* Flags which appears in the mips16 operand table.  */
1397
1398 /* Whether this is a mips16 register index.  */
1399 #define MIPS16_REG16 (0x1)
1400 /* Whether this is a register value.  */
1401 #define MIPS16_REGVAL (0x2)
1402 /* Whether this is a swapped mips32 register index (MOV32R) */
1403 #define MIPS16_REG32_SWAPPED (0x4)
1404 /* Whether this index is also the destination register.  */
1405 #define MIPS16_DESTREG (0x8)
1406 /* Whether the short form is unsigned.  */
1407 #define MIPS16_UNSP (0x10)
1408 /* Whether the extended form is unsigned.  */
1409 #define MIPS16_EXTU (0x20)
1410 /* Implicit stack pointer.  */
1411 #define MIPS16_SP (0x40)
1412 /* Implicit program counter.  */
1413 #define MIPS16_PC (0x80)
1414 /* Implicit $0.  */
1415 #define MIPS16_ZERO (0x100)
1416 /* Implicit $24.  */
1417 #define MIPS16_TREG (0x200)
1418 /* Implicit $31.  */
1419 #define MIPS16_RA (0x400)
1420 /* Jump address.  */
1421 #define MIPS16_JUMP_ADDR (0x800)
1422 /* Branch offset.  */
1423 #define MIPS16_BRANCH (0x1000)
1424
1425 /* The mips16 operand table.  */
1426
1427 static const struct mips16_op mips16_op_table[] =
1428 {
1429   { 'd', "int", "destreg", 3,  0, 0, MIPS16_REG16 },
1430   { 'x', "t_reg", "op1",  3,  0, 0, MIPS16_REG16 | MIPS16_REGVAL },
1431   { 'w', "t_reg", "op1",  3,  0, 0, MIPS16_REG16|MIPS16_REGVAL|MIPS16_DESTREG},
1432   { 'y', "t_reg", "op2", 3,  0, 0, MIPS16_REG16 | MIPS16_REGVAL },
1433   { 'v', "t_reg", "op2", 3,  0, 0, MIPS16_REG16|MIPS16_REGVAL|MIPS16_DESTREG },
1434   { 'X', "t_reg", "op1", 5,  0, 0, MIPS16_REGVAL },
1435   { 'Y', "int", "destreg", 5,  0, 0, MIPS16_REG32_SWAPPED },
1436   { 'a', "ut_reg", "op1", 11,  0, 0, MIPS16_JUMP_ADDR },
1437   { 'e', "int", "ext", 11,  0, 0, 0 },
1438   { '<', "int", "op1",  3,  5, 0, MIPS16_UNSP | MIPS16_EXTU },
1439   { '>', "int", "op1",  3,  5, 0, MIPS16_UNSP | MIPS16_EXTU },
1440   { '[', "int", "op1",  3,  6, 0, MIPS16_UNSP | MIPS16_EXTU },
1441   { ']', "int", "op1",  3,  6, 0, MIPS16_UNSP | MIPS16_EXTU },
1442   { '4', "int", "op2",  4, 15, 0, 0 },
1443   { '5', "int", "offset",  5, 16, 0, MIPS16_UNSP },
1444   { 'H', "int", "offset",  5, 16, 1, MIPS16_UNSP },
1445   { 'W', "int", "offset",  5, 16, 2, MIPS16_UNSP },
1446   { 'D', "int", "offset",  5, 16, 3, MIPS16_UNSP },
1447   { 'j', "int", "op2",  5, 16, 0, 0 },
1448   { '8', "int", "op2",  8, 16, 0, MIPS16_UNSP },
1449   { 'V', "int", "offset",  8, 16, 2, MIPS16_UNSP },
1450   { 'C', "int", "offset",  8, 16, 3, MIPS16_UNSP },
1451   { 'U', "int", "op2",  8, 16, 0, MIPS16_UNSP | MIPS16_EXTU },
1452   { 'k', "int", "op2",  8, 16, 0, 0 },
1453   { 'K', "int", "op2",  8, 16, 3, 0 },
1454   { 'p', "int", "offset",  8, 16, 0, MIPS16_BRANCH },
1455   { 'q', "int", "offset", 11, 16, 0, MIPS16_BRANCH },
1456   { 'A', "int", "op2",  8, 16, 2, MIPS16_UNSP },
1457   { 'B', "int", "op2",  5, 16, 3, MIPS16_UNSP },
1458   { 'E', "int", "op2",  5, 16, 2, MIPS16_UNSP },
1459
1460   /* The remaining operands are special operands which encode implied
1461      arguments.  These only appear at the end of a bitmap string, and
1462      do not represent actual bits.  */
1463   { 's', "t_reg", "op1",  0,  0, 0, MIPS16_SP | MIPS16_REGVAL  },
1464   { 'S', "t_reg", "op1",  0,  0, 0, MIPS16_SP|MIPS16_REGVAL|MIPS16_DESTREG },
1465   { 'P', "t_reg", "op1",  0,  0, 0, MIPS16_PC },
1466   { 'z', "t_reg", "op2",  0,  0, 0, MIPS16_ZERO },
1467   { 'Z', "t_reg", "op1",  0,  0, 0, MIPS16_ZERO },
1468   { 't', "t_reg", "op1",  0,  0, 0, MIPS16_TREG | MIPS16_REGVAL },
1469   { 'T', "int",   "destreg",  0,  0, 0, MIPS16_TREG },
1470   { 'r', "t_reg", "op1",  0,  0, 0, MIPS16_RA | MIPS16_REGVAL },
1471   { 'R', "int",   "destreg",  0,  0, 0, MIPS16_RA },
1472   { 'Q', "t_reg", "op2",  0,  0, 0, MIPS16_RA | MIPS16_REGVAL },
1473
1474   { '\0', NULL,  NULL,     0, 0,  0, 0 }
1475 };
1476
1477 /* Build mips16 operands.  */
1478
1479 static void
1480 build_mips16_operands (bitmap)
1481      const char *bitmap;
1482 {
1483   const char *s;
1484   int start = -1;
1485   const struct mips16_op *op = NULL;
1486   const struct mips16_op *ops[3];
1487   int opindex = 0;
1488   int i;
1489
1490   for (s = bitmap; *s != '\0'; s++)
1491     {
1492       if (op != NULL)
1493         {
1494           if (op->type == *s)
1495             continue;
1496
1497           /* Make sure we saw the right number of bits for that
1498              operand.  */
1499           if (op->nbits != 0 && (s - bitmap) - op->nbits != start)
1500             abort ();
1501           op = NULL;
1502         }
1503
1504       if (*s == '0' || *s == '1' || *s == '?')
1505         continue;
1506
1507       start = s - bitmap;
1508
1509       for (op = mips16_op_table; op->type != *s; ++op)
1510         if (op->type == '\0')
1511           abort ();
1512
1513       printf ("  %s %s = ", op->vartype, op->name);
1514       if (op->nbits != 0)
1515         printf ("(instruction >> %d) & 0x%x",
1516                 16 - (s - bitmap) - op->nbits,
1517                 (1 << op->nbits) - 1);
1518       else
1519         {
1520           if ((op->flags & MIPS16_SP) != 0)
1521             printf ("29");
1522           else if ((op->flags & MIPS16_PC) != 0)
1523             {
1524               int j;
1525
1526               printf ("((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : IPC) & ~ (uword64) 1)");
1527               for (j = 0; j < opindex; j++)
1528                 if (ops[j]->shift != 0)
1529                   printf (" & ~ (uword64) 0x%x", (1 << ops[j]->shift) - 1);
1530             }
1531           else if ((op->flags & MIPS16_ZERO) != 0)
1532             printf ("0");
1533           else if ((op->flags & MIPS16_TREG) != 0)
1534             printf ("24");
1535           else if ((op->flags & MIPS16_RA) != 0)
1536             printf ("31");
1537           else
1538             abort ();
1539         }
1540       printf (";\n");
1541
1542       if ((op->flags & MIPS16_DESTREG) != 0)
1543         printf ("  int destreg;\n");
1544
1545       if (opindex > 2)
1546         abort ();
1547       ops[opindex] = op;
1548       ++opindex;
1549     }
1550
1551   if (op != NULL)
1552     {
1553       /* Make sure we saw the right number of bits for that
1554          operand.  */
1555       if (op->nbits != 0 && 16 - op->nbits != start)
1556         abort ();
1557     }
1558
1559   for (i = 0; i < opindex; i++)
1560     {
1561       op = ops[i];
1562       if ((op->flags & MIPS16_REG16) != 0)
1563         {
1564           printf ("  if (%s < 2)\n", op->name);
1565           printf ("    %s += 16;\n", op->name);
1566         }
1567       if ((op->flags & MIPS16_REG32_SWAPPED) != 0)
1568         printf ("  %s = (%s >> 2) | ((%s & 3) << 3);\n",
1569                 op->name, op->name, op->name);
1570       if ((op->flags & MIPS16_DESTREG) != 0)
1571         printf ("  destreg = %s;\n", op->name);
1572       if ((op->flags & MIPS16_REGVAL) != 0)
1573         printf ("  %s = GPR[%s];\n", op->name, op->name);
1574
1575       if (op->extbits != 0)
1576         {
1577           printf ("  if (have_extendval)\n");
1578           printf ("    {\n");
1579           if (op->extbits == 16)
1580             printf ("      %s |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0);\n",
1581                     op->name);
1582           else if (op->extbits == 15)
1583             printf ("      %s |= ((extendval & 0xf) << 11) | (extendval & 0x7f0);\n",
1584                     op->name);
1585           else if (op->extbits == 6)
1586             printf ("      %s = ((extendval >> 6) & 0x1f) | (extendval & 0x20);\n",
1587                     op->name);
1588           else
1589             printf ("      %s = (extendval >> 6) & 0x1f;\n",
1590                     op->name);
1591           if ((op->flags & MIPS16_EXTU) == 0)
1592             {
1593               printf ("      if (%s >= 0x%x)\n",
1594                       op->name, 1 << (op->extbits - 1));
1595               printf ("        %s -= 0x%x;\n",
1596                       op->name, 1 << op->extbits);
1597             }
1598           printf ("      have_extendval = 0;\n");
1599           printf ("    }\n");
1600           printf ("  else\n");
1601           printf ("    {\n");
1602           if ((op->flags & MIPS16_UNSP) == 0)
1603             {
1604               printf ("      if (%s >= 0x%x)\n",
1605                       op->name, 1 << (op->nbits - 1));
1606               printf ("        %s -= 0x%x;\n",
1607                       op->name, 1 << op->nbits);
1608             }
1609           if (op->shift != 0)
1610             printf ("      %s <<= %d;\n", op->name, op->shift);
1611           if (op->type == '<' || op->type == '>'
1612               || op->type == '[' || op->type == ']')
1613             {
1614               printf ("      if (%s == 0)\n", op->name);
1615               printf ("        %s = 8;\n", op->name);
1616             }
1617           printf ("    }\n");
1618         }
1619
1620       if ((op->flags & MIPS16_BRANCH) != 0)
1621         printf ("  %s *= 2;\n", op->name);
1622
1623       if ((op->flags & MIPS16_JUMP_ADDR) != 0)
1624         {
1625           printf ("  {\n");
1626           printf ("    uword64 paddr;\n");
1627           printf ("    int uncached;\n");
1628           printf ("    if (AddressTranslation (PC &~ (uword64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL))\n");
1629           printf ("      {\n");
1630           printf ("        uword64 memval;\n");
1631           printf ("        unsigned int reverse = (ReverseEndian ? 3 : 0);\n");
1632           printf ("        unsigned int bigend = (BigEndianCPU ? 3 : 0);\n");
1633           printf ("        unsigned int byte;\n");
1634           printf ("        paddr = ((paddr & ~0x7) | ((paddr & 0x7) ^ (reverse << 1)));\n");
1635           printf ("        LoadMemory (&memval,0,uncached, AccessLength_HALFWORD, paddr, PC, isINSTRUCTION, isREAL);\n");
1636           printf ("        byte = (((PC &~ (uword64) 1) & 0x7) ^ (bigend << 1));\n");
1637           printf ("        memval = (memval >> (8 * byte)) & 0xffff;\n");
1638           printf ("        %s = (((%s & 0x1f) << 23)\n", op->name, op->name);
1639           printf ("              | ((%s & 0x3e0) << 13)\n", op->name);
1640           printf ("              | (memval << 2));\n");
1641           printf ("        if ((instruction & 0x400) == 0)\n");
1642           printf ("          %s |= 1;\n", op->name);
1643           printf ("        PC += 2;\n");
1644           printf ("      }\n");
1645           printf ("  }\n");
1646           printf ("  %s |= PC & ~ (uword64) 0x0fffffff;\n", op->name);
1647         }
1648     }
1649
1650   /* FIXME: Is this the way to detect an unused extend opcode?  */
1651   printf ("  if (have_extendval)\n");
1652   printf ("    SignalException (ReservedInstruction, instruction);\n");
1653 }
1654
1655 /*---------------------------------------------------------------------------*/
1656
1657 typedef enum {
1658   s_left,
1659   s_right
1660 } e_endshift;
1661
1662 static void
1663 build_endian_shift(proc64,datalen,endbit,direction,shift)
1664      int proc64;
1665      int datalen;
1666      int endbit;
1667      e_endshift direction;
1668      int shift;
1669 {
1670   if (datalen == 4) {
1671     printf("    if ((vaddr & (1 << %d)) ^ (BigEndianCPU << %d)) {\n",endbit,endbit);
1672     printf("     memval %s= %d;\n",direction == s_left ? "<<" : ">>",shift);
1673     printf("    }\n");
1674   }
1675
1676   return;
1677 }
1678
1679 /*---------------------------------------------------------------------------*/
1680 /* doisa = number of MIPS ISA simulator table is being constructed for.
1681  * proc64 = TRUE if constructing 64bit processor world.
1682  * dofp = boolean, TRUE if FP instructions are to be included.
1683  * fpsingle = boolean, TRUE if only single precision FP instructions to be included.
1684  */
1685
1686 void
1687 process_instructions(doarch,features)
1688      unsigned int doarch;
1689      unsigned int features;
1690 {
1691   int doisa = (doarch & MASK_ISA);
1692   int limit = (sizeof(MIPS_DECODE) / sizeof(instruction));
1693   int gprlen=((features & FEATURE_GP64) ? 64 : 32);
1694   int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
1695   int dofp = (features & FEATURE_HASFPU);
1696   int fpsingle = (features & FEATURE_FPSINGLE);
1697   int maxisa;
1698   int loop;
1699
1700   if (limit < 1) {
1701     fprintf(stderr,"process_instructions: invalid structure length\n");
1702     exit(1);
1703   }
1704
1705   if (proc64 && (gprlen != 64)) {
1706     fprintf(stderr,"Error: 64bit processor build specified, with MIPS ISA I or II\n");
1707     exit(3);
1708   }
1709
1710   /* NOTE: "proc64" also differentiates between 32- and 64-bit wide memory */
1711
1712   maxisa = 0;
1713   for (loop = 0; (loop < limit); loop++)
1714    if ((MIPS_DECODE[loop].isa & MASK_ISA) > maxisa)
1715     maxisa = (MIPS_DECODE[loop].isa & MASK_ISA);
1716
1717   if (doisa == 0)
1718    doisa = maxisa;
1719
1720   printf("#if defined(SIM_MANIFESTS)\n");
1721   printf("#define MIPSISA (%d)\n",doisa);
1722   if (proc64)
1723    printf("#define PROCESSOR_64BIT (1 == 1)\n");
1724   else
1725    printf("#define PROCESSOR_64BIT (1 == 0)\n");
1726 #if 1 /* cheat: We only have a 64bit LoadMemory and StoreMemory routines at the moment */
1727   printf("#define LOADDRMASK (0x%08X)\n",0x7);
1728 #else
1729   printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
1730 #endif
1731   /* The FP registers are the same width as the CPU registers: */
1732   printf("#define GPRLEN (%d)\n",gprlen);
1733   printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
1734   printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
1735   printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
1736   if (dofp)
1737    printf("#define HASFPU (1 == 1)\n");
1738   if (features & FEATURE_FAST)
1739    printf("#define FASTSIM (1 == 1)\n");
1740   if (features & FEATURE_WARN_STALL)
1741    printf("#define WARN_STALL (1 == 1)\n");
1742   if (features & FEATURE_WARN_LOHI)
1743    printf("#define WARN_LOHI (1 == 1)\n");
1744   if (features & FEATURE_WARN_ZERO)
1745    printf("#define WARN_ZERO (1 == 1)\n");
1746   if (features & FEATURE_WARN_MEM)
1747    printf("#define WARN_MEM (1 == 1)\n");
1748   if (features & FEATURE_WARN_R31)
1749    printf("#define WARN_R31 (1 == 1)\n");
1750   if (features & FEATURE_WARN_RESULT)
1751    printf("#define WARN_RESULT (1 == 1)\n");
1752
1753   printf("#else /* simulator engine */\n");
1754
1755   printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
1756   printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
1757   if (dofp)
1758    printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
1759   printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
1760
1761  if (proc64) {
1762    printf("#if !defined(PROCESSOR_64BIT)\n");
1763    printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
1764    printf("#endif\n");
1765  }
1766
1767  printf("/* Actual instruction decoding block */\n");
1768  printf("if ((vaddr & 1) == 0){\n");
1769   {
1770     int limit;
1771     printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
1772     limit = (OP_MASK_OP + 1);
1773
1774     printf("#ifdef DEBUG\n");
1775     printf("printf(\"DBG: instruction = 0x%%08X\\n\",instruction);\n");
1776     printf("#endif\n");
1777
1778     printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
1779     limit += (OP_MASK_SPEC + 1);
1780
1781     printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
1782     limit += (OP_MASK_RT + 1);
1783
1784     printf("else if (num == 0x11) {\n");
1785     printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
1786     printf("  if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
1787     printf("   num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
1788     printf("  else\n");
1789     printf("   num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
1790     limit += (OP_MASK_SPEC + 1);
1791
1792     printf(" else\n");
1793     /* To keep this code quick, we just clear out the "to" bit
1794        here. The proper (though slower) code would be to have another
1795        conditional, checking whether this instruction is a branch or
1796        not, before limiting the range to the bottom two bits of the
1797        move operation. */
1798     printf("  num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
1799     limit += (OP_MASK_COP1SPEC + 1);
1800
1801     printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
1802     limit += (OP_MASK_SPEC + 1);
1803
1804     printf("else if (num == 0x1C) {\n");
1805     printf("  int mmi_func = ((instruction >> %d) & 0x%08X);\n",OP_SH_MMI,OP_MASK_MMI);
1806
1807     printf("  if (mmi_func == 0x08) \n");
1808     printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
1809     limit += (OP_MASK_MMISUB + 1);
1810
1811     printf("  else if (mmi_func == 0x28) \n");
1812     printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
1813     limit += (OP_MASK_MMISUB + 1);
1814
1815     printf("  else if (mmi_func == 0x09) \n");
1816     printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
1817     limit += (OP_MASK_MMISUB + 1);
1818
1819     printf("  else if (mmi_func == 0x29) \n");
1820     printf("    num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
1821     limit += (OP_MASK_MMISUB + 1);
1822
1823     printf("  else \n");
1824     printf("    num = (%d + mmi_func);\n",limit);
1825     limit += (OP_MASK_MMI + 1);
1826
1827     printf("}\n");
1828
1829     printf("/* Total possible switch entries: %d */\n",limit) ;
1830   }
1831
1832  printf("#ifdef DEBUG\n");
1833  printf("printf(\"DBG: num = %%d\\n\",num);\n");
1834  printf("#endif\n");
1835
1836  printf("switch (num)\n") ;
1837  printf("{\n");
1838
1839  for (loop = 0; (loop < limit); loop++) {
1840    /* First check if the insn is in a requested isa# independent set,
1841       then check that the ISA number we are constructing for is
1842       valid, then if the instruction matches any of the
1843       architecture specific flags. NOTE: We allow a selected ISA of
1844       zero to be used to match all standard instructions. */
1845    if (((MIPS_DECODE[loop].isa & doarch & MASK_ISA_INDEP)
1846         || (((MIPS_DECODE[loop].isa & MASK_ISA) <= doisa) 
1847             && (((MIPS_DECODE[loop].isa & ~MASK_ISA) == 0) 
1848                 || ((MIPS_DECODE[loop].isa & ~MASK_ISA) & doarch) != 0)))
1849        && (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))) {
1850      unsigned int onemask;
1851      unsigned int zeromask;
1852      unsigned int dontmask;
1853      unsigned int mask;
1854      unsigned int number;
1855
1856      convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
1857
1858      if (!(MIPS_DECODE[loop].flags & COPROC) 
1859          && ((GETDATASIZEINSN(&MIPS_DECODE[loop]) == DOUBLEWORD) && !proc64)) {
1860        fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
1861        exit(4);
1862      }
1863
1864 #if defined(DEBUG)
1865      printf("/* DEBUG: onemask  0x%08X */\n",onemask) ;
1866      printf("/* DEBUG: zeromask 0x%08X */\n",zeromask) ;
1867      printf("/* DEBUG: dontmask 0x%08X */\n",dontmask) ;
1868 #endif
1869
1870      switch (MIPS_DECODE[loop].mark) {
1871        case NORMAL :
1872         mask = (OP_MASK_OP << OP_SH_OP) ;
1873         number = ((onemask >> OP_SH_OP) & OP_MASK_OP) ;
1874         break ;
1875
1876        case SPECIAL :
1877         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
1878         number = ((OP_MASK_OP + 1) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
1879         break ;
1880
1881        case REGIMM :
1882         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_RT << OP_SH_RT)) ;
1883         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_RT) & OP_MASK_RT)) ;
1884         break ;
1885
1886        case COP1 :
1887         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
1888         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
1889         break ;
1890
1891        case COP1S :
1892         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_COP1SPEC << OP_SH_COP1SPEC)) ;
1893         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_COP1SPEC) & OP_MASK_COP1SPEC)) ;
1894         break;
1895
1896        case COP1X :
1897         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
1898         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)) ;
1899         break ;
1900
1901        case MMI0 :
1902         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
1903                 | (OP_MASK_MMISUB << OP_SH_MMISUB));
1904         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
1905            + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
1906            + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
1907         break ;
1908
1909        case MMI1 :
1910         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
1911                 | (OP_MASK_MMISUB << OP_SH_MMISUB));
1912         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
1913            + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
1914            + (OP_MASK_MMISUB + 1)
1915            + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
1916         break ;
1917
1918        case MMI2 :
1919         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
1920                 | (OP_MASK_MMISUB << OP_SH_MMISUB));
1921         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
1922            + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
1923            + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1)
1924            + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
1925         break ;
1926
1927        case MMI3 :
1928         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)
1929                 | (OP_MASK_MMISUB << OP_SH_MMISUB));
1930         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
1931            + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
1932            + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1)
1933            + ((onemask >> OP_SH_MMISUB) & OP_MASK_MMISUB)) ;
1934         break ;
1935
1936        case MMINORM :
1937         mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_MMI << OP_SH_MMI)) ;
1938         number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) 
1939            + (OP_MASK_SPEC + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1))
1940            + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1) + (OP_MASK_MMISUB + 1)
1941            + (OP_MASK_MMISUB + 1) 
1942            + ((onemask >> OP_SH_MMI) & OP_MASK_MMI)) ;
1943         break ;
1944
1945        default :
1946         fprintf(stderr,"Unrecognised opcode mark %d in table slot %d \"%s\"\n",MIPS_DECODE[loop].mark,loop,MIPS_DECODE[loop].name) ;
1947         exit(5) ;
1948       }
1949
1950      printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
1951
1952 #if defined(DEBUG)
1953      printf("/* DEBUG: mask 0x%08X */\n",mask) ;
1954      printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
1955 #endif
1956
1957      /* Check if there are any other explicit bits in the instruction: */
1958      if ((~mask & (onemask | zeromask)) != 0x00000000) {
1959        printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
1960        printf(" {\n") ;
1961        printf("  SignalException(ReservedInstruction,instruction);\n") ;
1962        printf(" }\n") ;
1963        printf(" else\n") ;
1964      }
1965
1966      printf(" {\n") ;
1967
1968      /* Get hold of the operands */
1969      /* NOTE: If we wanted to make the simulator code smaller, we
1970       * could pull these into a common sequence before we perform
1971       * the instruction decoding. However, this would affect the
1972       * performance since unnecessary field extraction would be
1973       * occurring for certain instructions.
1974       *
1975       * Also we do not perform checking for multiple definitions of a
1976       * particular operand here, since they are caught by the
1977       * compilation of the produced code.
1978       */
1979      build_operands(doisa, features, &MIPS_DECODE[loop]);
1980
1981      printf("  {\n") ;
1982
1983      build_instruction (doisa, features, 0, &MIPS_DECODE[loop]);
1984
1985      printf("  }\n") ;
1986      printf(" }\n") ;
1987      printf(" break ;\n") ;
1988    }
1989   }
1990
1991  printf("default : /* Unrecognised instruction */\n") ;
1992  printf(" SignalException(ReservedInstruction,instruction);\n") ;
1993  printf(" break ;\n") ;
1994  printf("}\n}\n") ;
1995
1996  /* Handle mips16 instructions.  The switch table looks like this:
1997      0 - 31: I, RI, and RRI instructions by major.
1998     32 - 35: ISHIFT instructions by function + 32
1999     36 - 37: RRI_A instructions by function + 36
2000     38 - 45: I8, I8_MOV32R, and I8_MOVR32 instructions by function + 38
2001     46 - 49: RRR instructions by function + 46
2002     50 - 81: RR instructions by minor + 50 (except for minor == 0)
2003     82 - 89: I64 and RI64 instructions by funct + 82
2004     90 - 97: jalr (RR minor 0) by y + 90
2005     */
2006  printf ("else {\n");
2007  printf ("static int extendval;\n");
2008  printf ("static int have_extendval;\n");
2009  printf ("int num = ((instruction >> %d) & 0x%08X);\n",
2010          MIPS16OP_SH_OP, MIPS16OP_MASK_OP);
2011  printf ("switch (num)\n{\n");
2012  printf ("case 0x6: num = 32 + (instruction & 3); break;\n");
2013  printf ("case 0x8: num = 36 + ((instruction & 0x10) >> 4); break;\n");
2014  printf ("case 0xc: num = 38 + ((instruction & 0x700) >> 8); break;\n");
2015  printf ("case 0x1c: num = 46 + (instruction & 3); break;\n");
2016  printf ("case 0x1d: num = 50 + (instruction & 0x1f);\n");
2017  printf ("           if (num == 50) num = 90 + ((instruction & 0xe0) >> 5);\n");
2018  printf ("           break;\n");
2019  printf ("case 0x1f: num = 82 + ((instruction & 0x700) >> 8); break;\n");
2020  printf ("default: break;\n}\n");
2021  printf ("switch (num)\n{\n");
2022
2023  for (loop = 0; loop < sizeof MIPS16_DECODE / sizeof MIPS16_DECODE[0]; loop++)
2024    {
2025      const char *bitmap;
2026      int num;
2027
2028      if (! proc64 && GETDATASIZEINSN (&MIPS16_DECODE[loop]) == DOUBLEWORD)
2029        continue;
2030
2031      bitmap = MIPS16_DECODE[loop].bitmap;
2032      switch (MIPS16_DECODE[loop].mark)
2033        {
2034        case I:
2035        case RI:
2036        case RRI:
2037          num = bitmap_val (bitmap, 11, 5);
2038          break;
2039        case ISHIFT:
2040          num = 32 + bitmap_val (bitmap, 0, 2);
2041          break;
2042        case RRI_A:
2043          num = 36 + bitmap_val (bitmap, 4, 1);
2044          break;
2045        case I8:
2046        case I8_MOV32R:
2047        case I8_MOVR32:
2048          num = 38 + bitmap_val (bitmap, 8, 3);
2049          break;
2050        case RRR:
2051          num = 46 + bitmap_val (bitmap, 0, 2);
2052          break;
2053        case RR:
2054          {
2055            int minor;
2056
2057            minor = bitmap_val (bitmap, 0, 5);
2058            if (minor != 0)
2059              num = 50 + minor;
2060            else
2061              num = 90 + bitmap_val (bitmap, 5, 3);
2062          }
2063          break;
2064        case I64:
2065        case RI64:
2066          num = 82 + bitmap_val (bitmap, 8, 3);
2067          break;
2068        default:
2069          abort ();
2070        }
2071
2072      printf ("case %d: /* \"%s\" %s */\n", num, MIPS16_DECODE[loop].name,
2073              bitmap);
2074
2075      printf (" {\n");
2076
2077      build_mips16_operands (bitmap);
2078
2079      printf ("  {\n") ;
2080
2081      /* build_instruction doesn't know about extend.  */
2082      if (num != 30)
2083        build_instruction (doisa, features, 1, &MIPS16_DECODE[loop]);
2084      else
2085        {
2086          printf ("    extendval = ext;\n");
2087          printf ("    have_extendval = 1;\n");
2088        }
2089
2090      printf ("  }\n");
2091      printf (" }\n") ;
2092      printf (" break ;\n") ;
2093    }
2094
2095  printf ("default : /* Unrecognised instruction */\n") ;
2096  printf (" SignalException(ReservedInstruction,instruction);\n") ;
2097  printf (" break ;\n") ;
2098  printf ("}\n}\n") ;
2099
2100  printf("#endif /* simulator engine */\n");
2101
2102  return ;
2103 }
2104
2105 /* Output the code to execute an instruction, assuming the operands
2106    have already been extracted.  */
2107
2108 static void 
2109 build_instruction (doisa, features, mips16, insn)
2110      int doisa;
2111      unsigned int features;
2112      int mips16;
2113      const struct instruction *insn;
2114 {
2115   int gprlen=((features & FEATURE_GP64) ? 64 : 32);
2116   int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
2117   char *regtype = ((gprlen == 64) ? "uword64" : "unsigned int");
2118
2119   switch (insn->type) {
2120       /* TODO: To make these easier to edit and maintain, they should
2121          actually be provided as source macros (or inline functions)
2122          OUTSIDE this main switch statement. The PPC simulator has a
2123          neater scheme for describing the instruction sequences. */
2124
2125     case ADD:
2126     case SUB:
2127      {
2128        char *signed_basetype = "unknown";
2129        char *unsigned_basetype = "unknown";
2130
2131        switch (GETDATASIZEINSN(insn)) {
2132          case WORD :
2133           signed_basetype = "signed int";
2134           unsigned_basetype = "unsigned int";
2135           break;
2136          case DOUBLEWORD :
2137           signed_basetype = "word64";
2138           unsigned_basetype = "uword64";
2139           break;
2140          default :
2141           fprintf(stderr,"Opcode table error: size of ADD/SUB operands not known (%d)\n",GETDATASIZEINSN(insn));
2142           exit(1);
2143        }
2144
2145        if ((insn->type) == ADD) {
2146          printf("   %s temp = (%s)(op1 + op2);\n", unsigned_basetype, unsigned_basetype);
2147          printf("   %s tempS = (%s)temp;\n", signed_basetype, signed_basetype);
2148          if (insn->flags & OVERFLOW) {
2149            printf("   if (((op1 < 0) == (op2 < 0)) && ((tempS < 0) != (op1 < 0)))\n");
2150            printf("    SignalException(IntegerOverflow);\n");
2151            printf("   else\n");
2152          }
2153          if (!proc64 || (insn->flags & UNSIGNED) || (GETDATASIZEINSN(insn) == DOUBLEWORD))
2154           printf("   GPR[destreg] = (%s)temp;\n",regtype);
2155          else /* only sign-extend when placing 32bit result in 64bit processor */
2156           printf("   GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
2157        } else { /* SUB */
2158          printf("   %s temp = (%s)(op1 - op2);\n", unsigned_basetype, unsigned_basetype);
2159          printf("   %s tempS = (%s)temp;\n", signed_basetype, signed_basetype);
2160          if (insn->flags & OVERFLOW) { /* different signs => overflow if result_sign != arg_sign */
2161            printf("   if (((op1 < 0) != (op2 < 0)) && ((tempS < 0) == (op1 < 0)))\n");
2162            printf("    SignalException(IntegerOverflow);\n");
2163            printf("   else\n");
2164          }
2165          /* UNSIGNED 32bit operations on a 64bit processor should
2166             *STILL* be sign-extended. We have cheated in the
2167             data-structure, by not marking it with UNSIGNED, and not
2168             setting OVERFLOW. */
2169          if (!proc64 || (insn->flags & UNSIGNED) || (GETDATASIZEINSN(insn) == DOUBLEWORD))
2170           printf("   GPR[destreg] = (%s)temp;\n",regtype);
2171          else /* only sign-extend when placing 32bit result in 64bit processor */
2172           printf("   GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
2173        }
2174      }
2175      break ;
2176
2177     case MUL:
2178      {
2179      char* pipe = (insn->flags & PIPE1) ? "1" : "";
2180
2181      if (features & FEATURE_WARN_LOHI) {
2182        printf("   CHECKHILO(\"Multiplication\");\n");
2183      }
2184      printf("   {\n");
2185      if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
2186        printf("   uword64 mid;\n");
2187        printf("   uword64 midhi;\n");
2188        printf("   uword64 temp;\n");
2189        if ((insn->flags & UNSIGNED) == 0)
2190          {
2191            printf("   int sign = 0;\n");
2192            printf("   if (op1 < 0) { op1 = - op1; ++sign; }\n");
2193            printf("   if (op2 < 0) { op2 = - op2; ++sign; }\n");
2194          }
2195        printf("   LO%s = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n",pipe);
2196        printf("   HI%s = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n",pipe);
2197        printf("   mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
2198        printf("   midhi = SET64HI(WORD64LO(mid));\n");
2199        printf("   temp = (LO%s + midhi);\n",pipe);
2200        printf("   if ((temp == midhi) ? (LO%s != 0) : (temp < midhi))\n",pipe);
2201        printf("     HI%s += 1;\n",pipe);
2202        printf("   HI%s += WORD64HI(mid);\n",pipe);
2203        printf("   mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
2204        printf("   midhi = SET64HI(WORD64LO(mid));\n");
2205        printf("   LO%s = (temp + midhi);\n",pipe);
2206        printf("   if ((LO%s == midhi) ? (temp != 0) : (LO%s < midhi))\n",pipe,pipe);
2207        printf("     HI%s += 1;\n",pipe);
2208        printf("   HI%s += WORD64HI(mid);\n",pipe);
2209        if ((insn->flags & UNSIGNED) == 0)
2210          printf("   if (sign & 1) { LO%s = - LO%s; HI%s = (LO%s == 0 ? 0 : -1) - HI%s; }\n",pipe,pipe,pipe,pipe,pipe);
2211      } else {
2212        if (insn->flags & UNSIGNED)
2213          printf("   uword64 temp = ((uword64)(op1 & 0xffffffff) * (uword64)(op2 & 0xffffffff));\n");
2214        else
2215          printf("   uword64 temp = ((word64) op1 * (word64) op2);\n");
2216        printf("   LO%s = SIGNEXTEND((%s)WORD64LO(temp),32);\n",pipe,regtype);
2217        printf("   HI%s = SIGNEXTEND((%s)WORD64HI(temp),32);\n",pipe,regtype);
2218      }
2219      if (insn->flags & OP3)
2220        {
2221          printf("     if ( destreg != 0 )\n");
2222          printf("         GPR[destreg] = LO%s;\n",pipe);
2223        }
2224      printf("   }\n");
2225      break ;
2226      }
2227     case DIV:
2228      {
2229       int boolU = (insn->flags & UNSIGNED);
2230       int pipe1 = (insn->flags & PIPE1);
2231
2232       if (features & FEATURE_WARN_LOHI) {
2233         printf("   CHECKHILO(\"Division\");\n");
2234       }
2235       printf("   {\n");
2236       if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
2237         printf("   LO%s = ((%sword64)op1 / (%sword64)op2);\n",
2238                (pipe1 ? "1" : ""),
2239                (boolU ? "u" : ""),(boolU ? "u" : ""));
2240         printf("   HI%s = ((%sword64)op1 %c (%sword64)op2);\n",
2241                (pipe1 ? "1" : ""),
2242                (boolU ? "u" : ""),'%',(boolU ? "u" : ""));
2243       } else {
2244         printf("   LO%s = SIGNEXTEND(((%sint)op1 / (%sint)op2),32);\n",
2245                (pipe1 ? "1" : ""),
2246                (boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
2247         printf("   HI%s = SIGNEXTEND(((%sint)op1 %c (%sint)op2),32);\n",
2248                (pipe1 ? "1" : ""),
2249                (boolU ? "unsigned " : ""),'%',(boolU ? "unsigned " : ""));
2250       }
2251       printf("   }\n");
2252      }
2253      break ;
2254
2255     case SHIFT:
2256      {
2257       int datalen = GETDATASIZEINSN(insn);
2258       int bits = ((datalen == WORD) ? 32 : 64);
2259       char *ltype = ((datalen == WORD) ? "unsigned int" : "uword64");
2260
2261       /* Check that the specified SHIFT is valid: */
2262       if ((datalen == BYTE) || (datalen == HALFWORD)) {
2263         fprintf(stderr,"Shift \"%s\" specified with BYTE or HALFWORD\n",insn->name);
2264         exit(9);
2265       }
2266       if ((insn->flags & LEFT) && (insn->flags & RIGHT)) {
2267         fprintf(stderr,"Shift \"%s\" specified with both LEFT and RIGHT\n",insn->name);
2268         exit(9);
2269       }
2270       if (!(insn->flags & LEFT) && !(insn->flags & RIGHT)) {
2271         fprintf(stderr,"Shift \"%s\" specified with neither LEFT or RIGHT\n",insn->name);
2272         exit(9);
2273       }
2274       if ((insn->flags & LOGICAL) && (insn->flags & ARITHMETIC)) {
2275         fprintf(stderr,"Shift \"%s\" specified with both LOGICAL and ARITHMETIC\n",insn->name);
2276         exit(9);
2277       }
2278       if (!(insn->flags & LOGICAL) && !(insn->flags & ARITHMETIC)) {
2279         fprintf(stderr,"Shift \"%s\" specified with neither LOGICAL or ARITHMETIC\n",insn->name);
2280         exit(9);
2281       }
2282       if ((insn->flags & LEFT) && (insn->flags & ARITHMETIC)) {
2283         fprintf(stderr,"Arithmetic LEFT shift \"%s\" specified\n",insn->name);
2284         exit(9);
2285       }
2286
2287       /* Work around an MSC code generation bug by precomputing a value
2288        * with the sign bit set.  */
2289       if (insn->flags & ARITHMETIC)
2290        printf("   %s highbit = (%s)1 << %d;\n", ltype, ltype, bits - 1);
2291
2292       /* If register specified shift, then extract the relevant shift amount: */
2293       if (insn->flags & REG)
2294        printf("   op1 &= 0x%02X;\n",(bits - 1));
2295
2296       /* If HI32 specified, then shift range is 32..63 */
2297       if (insn->flags & HI32)
2298        printf("   op1 |= (1 << 5);\n");
2299
2300       /* We do not need to perform pre-masking with 0xFFFFFFFF when
2301          dealing with 32bit shift lefts, since the sign-extension
2302          code will replace any remaining hi-bits: */
2303       if (insn->flags & LEFT)
2304        printf("   GPR[destreg] = ((uword64)op2 << op1);\n");
2305       else
2306        printf("   GPR[destreg] = ((uword64)(op2%s) >> op1);\n",((bits == 32) ? " & 0xFFFFFFFF" : ""));
2307
2308       /* For ARITHMETIC shifts, we must duplicate the sign-bit.  We
2309          don't do this if op1 is zero, since it is not needed and
2310          since that would cause an undefined shift of the number of
2311          bits in the type.  */
2312       if (insn->flags & ARITHMETIC)
2313        printf("   GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((%s)1 << op1) - 1) << (%d - op1)) : 0);\n",ltype,bits);
2314
2315       /* Ensure WORD values are sign-extended into 64bit registers */
2316       if ((bits == 32) && (gprlen == 64))
2317        printf("   GPR[destreg] = SIGNEXTEND(GPR[destreg],%d);\n",bits);
2318      }
2319      break ;
2320
2321     case MOVE:
2322      if (insn->flags & (HI | LO)) {
2323        char *regname = ((insn->flags & LO) ? "LO" : "HI");
2324        int pipe1 = (insn->flags & PIPE1);
2325        if (insn->flags & LEFT)
2326         printf("   GPR[destreg] = %s%s;\n",regname,(pipe1 ? "1" : ""));
2327        else {
2328          if (features & FEATURE_WARN_LOHI) {
2329            printf("   if (%s%sACCESS != 0)\n",regname,(pipe1 ? "1" : ""));
2330            printf("     sim_warning(\"MT (move-to) over-writing %s register value\");\n",regname);
2331          }
2332          printf("   %s%s = op1;\n",regname,(pipe1 ? "1" : ""));
2333        }
2334        if (features & FEATURE_WARN_LOHI)
2335         printf("   %s%sACCESS = 3; /* 3rd instruction will be safe */\n",regname,(pipe1 ? "1" : ""));
2336      } else
2337       if (insn->flags & SHIFT16)
2338        printf("   GPR[destreg] = (op2 << 16);\n");
2339       else {
2340         /* perform conditional move */
2341         if (!(insn->flags & EQ)) {
2342           fprintf(stderr,"Standard conditional %s does not have the equality flag\n",insn->name);
2343           exit(8);
2344         }
2345         printf("   if (op2 %c= 0)\n",((insn->flags & NOT) ? '!' : '='));
2346         printf("    GPR[destreg] = op1;\n");
2347       }
2348      break ;
2349
2350     case SYNC:
2351      printf("   SyncOperation(op1);\n");
2352      break ;
2353
2354     case SYSCALL:
2355      printf("   SignalException(SystemCall,instruction);\n");
2356      break ;
2357
2358     case BREAK:
2359      printf("   SignalException(BreakPoint,instruction);\n");
2360      break ;
2361
2362     case TRAP:
2363      {
2364       int boolNOT = (insn->flags & NOT);
2365       int boolEQ  = (insn->flags & EQ);
2366       int boolGT  = (insn->flags & GT);
2367       int boolLT  = (insn->flags & LT);
2368       int boolU   = (insn->flags & UNSIGNED);
2369
2370       if (boolGT && boolLT) {
2371         fprintf(stderr,"GT and LT specified for \"%s\"\n",insn->name);
2372         exit(8);
2373       }
2374
2375       if (boolNOT && (boolGT || boolLT)) {
2376         fprintf(stderr,"NOT specified with GT or LT specified for \"%s\"\n",insn->name);
2377         exit(8);
2378       }
2379
2380       printf("  if ((%sword64)op1 ",(boolU ? "u" : ""));
2381       printf("%c%s",(boolNOT ? '!' : (boolLT ? '<' : (boolGT ? '>' : '='))),(boolEQ ? "=" : ""));
2382       printf(" (%sword64)op2)\n",(boolU ? "u" : ""));
2383       printf("   SignalException(Trap,instruction);\n");
2384      }
2385      break ;
2386
2387     case SET:
2388      {
2389       int boolU = (insn->flags & UNSIGNED);
2390
2391       if (!(insn->flags & LT)) {
2392         fprintf(stderr,"Set instruction without LT specified \"%s\"\n",insn->name);
2393         exit(8);
2394       }
2395
2396       printf("   if ((%sword64)op1 < (%sword64)op2)\n",(boolU ? "u" : ""),(boolU ? "u" : ""));
2397       printf("    GPR[destreg] = 1;\n");
2398       printf("   else\n");
2399       printf("    GPR[destreg] = 0;\n");
2400      }
2401      break ;
2402
2403     case AND:
2404      printf("   GPR[destreg] = (op1 & op2);\n");
2405      break ;
2406
2407     case OR:
2408      /* The default mips16 nop instruction does an or to register
2409         zero; catch that case, so that we don't get useless warnings
2410         from the simulator.  */
2411      if (mips16)
2412        printf ("   if (destreg != 0)\n");
2413      printf("   GPR[destreg] = %s(op1 | op2);\n",((insn->flags & NOT) ? "~" : ""));
2414      break ;
2415
2416     case XOR:
2417      printf("   GPR[destreg] = (op1 ^ op2);\n");
2418      break ;
2419
2420     case DECODE:
2421      printf("   decode_coproc(instruction);\n");
2422      break ;
2423
2424     case CACHE:
2425      /* 16-bit offset is sign-extended and added to the base register to make a virtual address */
2426      /* The virtual address is translated to a physical address using the TLB */
2427      /* The hint specifies a cache operation for that address */
2428      printf("    uword64 vaddr = (op1 + offset);\n");
2429      printf("    uword64 paddr;\n");
2430      printf("    int uncached;\n");
2431      /* NOTE: We are assuming that the AddressTranslation is a load: */
2432      printf("    if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
2433      printf("      CacheOp(hint,vaddr,paddr,instruction);\n");
2434      break;
2435
2436     case MADD16: /* VR4100 specific multiply-add instructions */
2437      /* Some of this code is shared with the standard multiply
2438         routines, so an effort should be made to merge where
2439         possible. */
2440      if (features & FEATURE_WARN_LOHI) {
2441        printf("   CHECKHILO(\"Multiply-Add\");\n");
2442      }
2443      if (features & FEATURE_WARN_RESULT) {
2444        /* Give user a warning if either op1 or op2 are not 16bit signed integers */
2445        printf("   if (NOTHALFWORDVALUE(op1) || NOTHALFWORDVALUE(op2))\n");
2446        printf("     sim_warning(\"MADD16 operation with non-16bit operands\");\n");
2447      }
2448      printf("   {\n");
2449      printf("    uword64 temp = (op1 * op2);\n"); /* 16x16 multiply */
2450      if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
2451        printf("   LO = LO + temp;\n");
2452      } else { /* WORD */
2453        printf("   temp += (SET64HI(WORD64LO(HI)) | WORD64LO(LO));\n");
2454        printf("   LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
2455        printf("   HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
2456      }
2457      printf("   }\n");
2458      break;
2459
2460     case RSVD: /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "CoProcessorUnusable" */
2461      if (doisa < 4) {
2462        printf("   if (CoProcPresent(3))\n");
2463        printf("    SignalException(CoProcessorUnusable);\n");
2464        printf("   else\n");
2465      }
2466      printf("   SignalException(ReservedInstruction,instruction);\n");
2467      break ;
2468
2469     case JUMP:
2470      if (insn->flags & LINK) {
2471        if (!(insn->flags & REG))
2472         printf("   int destreg = 31;\n");
2473        printf("   GPR[destreg] = (PC + %d); /* NOTE: The PC is already %d ahead within the simulator */\n",
2474               mips16 ? 2 : 4, mips16 ? 2 : 4);
2475      }
2476
2477      if (insn->flags & NOT)
2478        printf("   op1 ^= 1;\n");
2479
2480      printf("   /* NOTE: ??? Gdb gets confused if the PC is sign-extended,\n");
2481      printf("            so we just truncate it to 32 bits here.  */\n");
2482      printf("   op1 = WORD64LO(op1);\n");
2483      printf("   /* NOTE: The jump occurs AFTER the next instruction has been executed */\n");
2484      printf("   DSPC = op1;\n");
2485      if (insn->flags & LINK)
2486        printf("   JALDELAYSLOT();\n");
2487      else
2488        printf("   DELAYSLOT();\n");
2489      break ;
2490
2491     case BRANCH: /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
2492      if (insn->flags & FP) {
2493        if (doisa < 4) {
2494          printf("  if (condition_code != 0)\n");
2495          printf("   SignalException(ReservedInstruction,instruction);\n");
2496          printf("  else {\n");
2497        }
2498        /* "PREVCOC1()" should be the COC1 value at the start of the preceding instruction */
2499        printf("   int condition = (%s == boolean);\n",((doisa < 4) ? "PREVCOC1()" : "GETFCC(condition_code)"));
2500      } else {
2501        if ((insn->flags & NOT) && !(insn->flags & EQ)) {
2502          fprintf(stderr,"NOT specified when not EQ in \"%s\"\n",insn->name);
2503          exit(7);
2504        }
2505        if ((insn->flags & NOT) && (insn->flags & (GT | LT))) {
2506          fprintf(stderr,"NOT specified with GT or LT in \"%s\"\n",insn->name);
2507          exit(7);
2508        }            
2509        /* GT  LT */
2510        if (insn->flags & GT)
2511         printf("   int condition = (op1 >%s 0);\n",((insn->flags & EQ) ? "=" : ""));
2512        else
2513         if (insn->flags & LT)
2514          printf("   int condition = (op1 <%s 0);\n",((insn->flags & EQ) ? "=" : ""));
2515         else
2516          if (insn->flags & EQ)
2517           printf("   int condition = (op1 %c= op2);\n",((insn->flags & NOT) ? '!' : '='));
2518      }
2519
2520      if (insn->flags & LINK) {
2521        if (features & FEATURE_WARN_R31) {
2522          printf("   if (((instruction >> %d) & 0x%08X) == 31)\n",OP_SH_RS,OP_MASK_RS);
2523          printf("    sim_warning(\"Branch with link using r31 as source operand\");\n");
2524        }
2525        printf("   GPR[31] = (PC + 4); /* NOTE: PC is already 8 ahead */\n");
2526      }
2527
2528      if (! mips16) {
2529        printf("   /* NOTE: The branch occurs AFTER the next instruction has been executed */\n");
2530        printf("   if (condition) {\n");
2531        printf("    DSPC = (PC + offset);\n");
2532        printf("    DELAYSLOT();\n");
2533        printf("   }\n");
2534      } else {
2535        /* No delayed slots for mips16 branches.  */
2536        printf("   if (condition)\n");
2537        printf("    PC = PC + offset;\n");
2538      }
2539      if ((insn->flags & FP) && (doisa != 1)) {
2540        printf("   else if (likely) {\n");
2541        printf("    NULLIFY();\n");
2542        printf("   }\n");
2543      } else if (insn->flags & LIKELY) {
2544        printf("   else\n");
2545        printf("    NULLIFY();\n");
2546      }
2547      if ((insn->flags & FP) && (doisa < 4))
2548       printf("   }\n");
2549      break ;
2550
2551     case PREFETCH: /* The beginning is shared with normal load operations */
2552     case LOAD:
2553     case STORE:
2554      {
2555       int isload = ((insn->type == LOAD) || (insn->type == PREFETCH));
2556       int datalen;
2557       char *accesslength = "<UNKNOWN>";
2558
2559       switch (GETDATASIZEINSN(insn)) {
2560         case BYTE :
2561          datalen = 1;
2562          accesslength = "AccessLength_BYTE";
2563          break ;
2564
2565         case HALFWORD :
2566          datalen = 2;
2567          accesslength = "AccessLength_HALFWORD";
2568          break ;
2569
2570         case WORD :
2571          datalen = 4;
2572          accesslength = "AccessLength_WORD";
2573          break ;
2574
2575         case DOUBLEWORD :
2576          datalen = 8;
2577          accesslength = "AccessLength_DOUBLEWORD";
2578          break ;
2579
2580         case QUADWORD :
2581          datalen = 16;
2582          accesslength = "AccessLength_QUADWORD";
2583          break ;
2584       }
2585
2586       if (insn->flags & REG)
2587        printf("   uword64 vaddr = ((uword64)op1 + op2);\n");
2588       else
2589        printf("   uword64 vaddr = ((uword64)op1 + offset);\n");
2590       printf("   uword64 paddr;\n");
2591       printf("   int uncached;\n");
2592
2593       /* The following check should only occur on normal (non-shifted) memory loads */
2594       if ((datalen != 1) && !(insn->flags & (LEFT | RIGHT))) {
2595         printf("   if ((vaddr & %d) != 0)\n",(datalen - 1));
2596         printf("    SignalException(%s);\n",(isload ? "AddressLoad" : "AddressStore"));
2597         printf("   else\n") ;
2598       }
2599
2600       printf("   {\n");
2601       printf("    if (AddressTranslation(vaddr,isDATA,%s,&paddr,&uncached,isTARGET,isREAL))\n",(isload ? "isLOAD" : "isSTORE"));
2602
2603       if (insn->type == PREFETCH)
2604        printf("     Prefetch(uncached,paddr,vaddr,isDATA,hint);\n");
2605       else {
2606         printf("    {\n");
2607         printf("     uword64 memval;\n");
2608         printf("     uword64 memval1;\n");
2609
2610         if ((insn->flags & COPROC) && ((datalen != 4) && (datalen != 8))) {
2611           fprintf(stderr,"Co-processor transfer operation not WORD or DOUBLEWORD in length \"%s\"\n",insn->name);
2612           exit(6);
2613         }
2614
2615         if (insn->flags & (LEFT | RIGHT)) {
2616           if ((insn->flags & LEFT) && (insn->flags & RIGHT)) {
2617             fprintf(stderr,"Memory transfer with both LEFT and RIGHT specified \"%s\"\n",insn->name);
2618             exit(4);
2619           }
2620
2621           switch (datalen) {
2622            case 8:
2623             if (!proc64) {
2624               fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",insn->name);
2625               exit(4);
2626             }
2627             /* fall through to... */
2628            case 4:
2629             {
2630               printf("     uword64 mask = %d;\n",((datalen == 8) ? 0x7 : 0x3));
2631               printf("     unsigned int reverse = (ReverseEndian ? mask : 0);\n");
2632               printf("     unsigned int bigend = (BigEndianCPU ? mask : 0);\n");
2633               printf("     int byte;\n");
2634               printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));\n");
2635               printf("     byte = ((vaddr & mask) ^ bigend);\n");
2636               printf("     if (%s!ByteSwapMem)\n",((insn->flags & LEFT) ? "!" : ""));
2637               printf("      paddr &= ~mask;\n");
2638
2639               if (isload) {
2640                 if (insn->flags & LEFT)
2641                   {
2642                     printf("     LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL);\n");
2643                   }
2644                 else
2645                   {
2646                     printf("     LoadMemory(&memval,&memval1,uncached,(%d - byte),paddr,vaddr,isDATA,isREAL);\n",(datalen - 1));
2647                   }
2648               }
2649
2650               if (insn->flags & LEFT) {
2651                 if (isload) {
2652                   /* For WORD transfers work out if the value will
2653                      be in the top or bottom of the DOUBLEWORD
2654                      returned: */
2655 #if 1
2656                   build_endian_shift(proc64,datalen,2,s_right,32);
2657 #else
2658                   if (proc64 && (datalen == 4)) {
2659                     printf("     if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
2660                     printf("      memval >>= 32;\n");
2661                     printf("     }\n");
2662                   }
2663 #endif
2664                   printf("     GPR[destreg] = ((memval << ((%d - byte) * 8)) | (GPR[destreg] & (((uword64)1 << ((%d - byte) * 8)) - 1)));\n",(datalen - 1),(datalen - 1));
2665                   if (proc64 && (datalen == 4))
2666                    printf("     GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
2667                 } else { /* store */
2668                   printf("     memval = (op2 >> (8 * (%d - byte)));\n",(datalen - 1));
2669 #if 1
2670                   build_endian_shift(proc64,datalen,2,s_left,32);
2671 #else
2672                   /* TODO: This is duplicated in the LOAD code
2673                      above - and the RIGHT LOAD and STORE code
2674                      below. It should be merged if possible. */
2675                   if (proc64 && (datalen == 4)) {
2676                     printf("    if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
2677                     printf("     memval <<= 32;\n");
2678                     printf("    }\n");
2679                   }
2680 #endif
2681                   printf("     StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL);\n");
2682                 }
2683               } else { /* RIGHT */
2684                 if (isload) {
2685 #if 1
2686                   build_endian_shift(proc64,datalen,2,s_right,32);
2687 #else
2688                   if (proc64 && (datalen == 4)) {
2689                     printf("     if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
2690                     printf("      memval >>= 32;\n");
2691                     printf("     }\n");
2692                   }
2693 #endif
2694                   printf("     {\n");
2695                   printf("      uword64 srcmask;\n");
2696                   /* All of this extra code is just a bodge
2697                      required because some hosts don't allow
2698                      ((v) << 64). The SPARC just leaves the (v)
2699                      value un-touched. */
2700                   printf("      if (byte == 0)\n");
2701                   printf("       srcmask = 0;\n");
2702                   printf("      else\n");
2703                   printf("       srcmask = ((uword64)-1 << (8 * (%d - byte)));\n",datalen);
2704                   printf("      GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));\n");
2705                   printf("     }\n");
2706                   if (proc64 && (datalen == 4))
2707                    printf("     GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
2708                 } else { /* store */
2709                   printf("     memval = ((uword64) op2 << (byte * 8));\n");
2710                   build_endian_shift(proc64,datalen,2,s_left,32);
2711                   printf("     StoreMemory(uncached,(%s - byte),memval,memval1,paddr,vaddr,isREAL);\n",accesslength);
2712                 }
2713               }
2714             }
2715             break;
2716
2717            default:
2718             fprintf(stderr,"Shifted memory transfer not WORD or DOUBLEWORD in length \"%s\"\n",insn->name);
2719             exit(6);
2720           }
2721         } else { /* normal memory transfer */
2722           if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
2723             fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
2724             exit(4);
2725             /* TODO: The R4000 documentation states that a LWU
2726                instruction executed when in a 32bit processor mode
2727                should cause a ReservedInstruction exception. This
2728                will mean adding a run-time check into the code
2729                sequence. */
2730           }
2731
2732           if (isload) {
2733 #if 1 /* see the comments attached to LOADDRMASK above */
2734             printf("     uword64 mask = 0x7;\n");
2735 #else
2736             printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
2737 #endif
2738             printf("     unsigned int shift = %d;\n",(datalen >> 1));
2739             printf("     unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
2740             printf("     unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
2741             printf("     unsigned int byte;\n");
2742
2743 /* TODO: This should really also check for 32bit world performing 32bit access */
2744             if (datalen < 8) /* not for DOUBLEWORD or QUADWORD*/
2745              printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
2746
2747             printf("     LoadMemory(&memval,&memval1,uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
2748               
2749             /* The following will only make sense if the
2750                "LoadMemory" above returns a DOUBLEWORD entity */
2751             if (datalen < 8) { /* not for DOUBLEWORD or QUADWORD*/
2752               int valmask;
2753               switch (datalen) {
2754                case 1:
2755                 valmask = 0xFF;
2756                 break;
2757
2758                case 2:
2759                 valmask = 0xFFFF;
2760                 break;
2761
2762                case 4:
2763                 valmask = 0xFFFFFFFF;
2764                 break;
2765
2766                default:
2767                 fprintf(stderr,"Unrecognised datalen (%d) when processing \"%s\"\n",datalen,insn->name);
2768                 exit(4);
2769               }
2770               printf("     byte = ((vaddr & mask) ^ (bigend << shift));\n");
2771               /* NOTE: The R4000 user manual has the COP_LW
2772                  occuring in the same cycle as the rest of the
2773                  instruction, yet the MIPS IV shows the operation
2774                  happening on the next cycle. To keep the simulator
2775                  simple, this code follows the R4000
2776                  manual. Experimentation with a silicon
2777                  implementation will be needed to ascertain the
2778                  correct operation. */
2779               if (insn->flags & COPROC)
2780                printf("     COP_LW(%s,destreg,(unsigned int)",
2781                       ((insn->flags & REG)
2782                        ? "1"
2783                        : "((instruction >> 26) & 0x3)"));
2784               else
2785                printf("     GPR[destreg] = (");
2786
2787               if (insn->flags & SIGNEXTEND)
2788                printf("SIGNEXTEND(");
2789               printf("((memval >> (8 * byte)) & 0x%08X)",valmask);
2790               if (insn->flags & SIGNEXTEND)
2791                printf(",%d)",(datalen * 8));
2792               printf(");\n");
2793             } else {
2794               if (insn->flags & COPROC)
2795                printf("     COP_LD(%s,destreg,memval);;\n",
2796                       ((insn->flags & REG)
2797                        ? "1"
2798                        : "((instruction >> 26) & 0x3)"));
2799               else
2800                 {
2801                   printf("     GPR[destreg] = memval;\n");
2802                   if (datalen > 8)
2803                     printf("     GPR1[destreg] = memval1;\n");
2804                 }
2805             }
2806           } else { /* store operation */
2807             if ((datalen == 1) || (datalen == 2)) {
2808               /* SH and SB */
2809 #if 1 /* see the comments attached to LOADDRMASK above */
2810               printf("     uword64 mask = 0x7;\n");
2811 #else
2812               printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
2813 #endif
2814               printf("     unsigned int shift = %d;\n",(datalen >> 1));
2815               printf("     unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
2816               printf("     unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
2817               printf("     unsigned int byte;\n");
2818
2819               printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
2820               printf("     byte = ((vaddr & mask) ^ (bigend << shift));\n");
2821               printf("     memval = ((uword64) op2 << (8 * byte));\n");
2822             } else
2823              if (datalen == 4) { /* SC and SW */
2824 #if 1 /* see the comments attached to LOADDRMASK above */
2825                printf("     uword64 mask = 0x7;\n");
2826 #else
2827                printf("     uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
2828 #endif
2829                printf("     unsigned int byte;\n");
2830                printf("     paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));\n");
2831                printf("     byte = ((vaddr & mask) ^ (BigEndianCPU << 2));\n");
2832                if (insn->flags & COPROC)
2833                 printf("     memval = (((uword64)COP_SW(%s,%s)) << (8 * byte));\n",
2834                        ((insn->flags & REG)
2835                         ? "1"
2836                         : "((instruction >> 26) & 0x3)"),
2837                        ((insn->flags & FP) ? "fs" : "destreg"));
2838                else
2839                 printf("     memval = ((uword64) op2 << (8 * byte));\n");
2840              } else if (datalen <= 8) { /* SD and SCD */
2841                if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
2842                  fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
2843                  exit(4);
2844                }
2845                if (insn->flags & COPROC)
2846                 printf("     memval = (uword64)COP_SD(%s,%s);\n",
2847                        ((insn->flags & REG)
2848                         ? "1"
2849                         : "((instruction >> 26) & 0x3)"),
2850                        ((insn->flags & FP) ? "fs" : "destreg"));
2851                else
2852                 printf("     memval = op2;\n");
2853              } else { /* wider than 8 */
2854                if (insn->flags & COPROC) {
2855                  fprintf(stderr,"COPROC not available for 128 bit operations \"%s\"\n",insn->name);
2856                  exit(4);
2857                }
2858                printf("     memval  = rt_reg;\n");
2859                printf("     memval1 = rt_reg1;\n");
2860              }
2861
2862             if (insn->flags & ATOMIC)
2863              printf("      if (LLBIT)\n");
2864
2865             printf("      {\n");
2866             printf("       StoreMemory(uncached,%s,memval,memval1,paddr,vaddr,isREAL);\n",accesslength);
2867             printf("      }\n");
2868           }
2869
2870           if (insn->flags & ATOMIC) {
2871             if ((datalen != 4) && (datalen != 8)) {
2872               fprintf(stderr,"ATOMIC can only be applied to WORD and DOUBLEWORD instructions \"%s\"\n",insn->name);
2873               exit(4);
2874             } else
2875              if (isload)
2876               printf("     LLBIT = 1;\n");
2877              else {
2878                /* The documentation states that:
2879
2880                   SC *WILL* fail if coherent store into the same
2881                   block occurs, or if an exception occurs between
2882                   the LL and SC instructions.
2883
2884                   SC *MAY* fail if a load, store or prefetch is
2885                   executed on the processor (VR4300 doesn't seem
2886                   to), or if the instructions between the LL and
2887                   SC are not in a 2048byte contiguous VM range.
2888
2889                   SC *MUST* have been preceded by an LL
2890                   (i.e. LLBIT will be set), and it must use the
2891                   same Vaddr, Paddr and cache-coherence algorithm
2892                   as the LL (which means we should store this
2893                   information from the load-conditional).
2894                   */
2895                printf("     GPR[(instruction >> %d) & 0x%08X] = LLBIT;\n",OP_SH_RT,OP_MASK_RT);
2896              }
2897           }
2898         }
2899         printf("    }\n");
2900       }
2901       printf("   }\n");
2902      }
2903      break ;
2904
2905     case FPPREFX:
2906      /* This code could be merged with the PREFIX generation above: */
2907      printf("   uword64 vaddr = ((uword64)op1 + (uword64)op2);\n");
2908      printf("   uword64 paddr;\n");
2909      printf("   int uncached;\n");
2910      printf("   if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
2911      printf("    Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
2912      break ;
2913
2914     case FPMOVEC:
2915      if (insn->flags & CONTROL) {
2916        /* The following "magic" of interpreting the FP
2917           control-register number would not be needed if we were not
2918           trying to match our internal register numbers with those
2919           used by GDB. */
2920        printf("    if (to) {\n");
2921        if (doisa < 4) {
2922          printf("     if (fs == 0) {\n");
2923          printf("      PENDING_FILL((fs + FCR0IDX),WORD64LO(GPR[ft]));\n");
2924          printf("     } else if (fs == 31) {\n");
2925          printf("      PENDING_FILL((fs + FCR31IDX),WORD64LO(GPR[ft]));\n");
2926          printf("     } /* else NOP */\n");
2927          printf("     PENDING_FILL(COCIDX,0); /* special case */\n");
2928        } else {
2929          printf("     if (fs == 0) {\n");
2930          printf("      FCR0 = WORD64LO(GPR[ft]);\n");
2931          printf("     } else if (fs == 31) {\n");
2932          printf("      FCR31 = WORD64LO(GPR[ft]);\n");
2933          printf("     } /* else NOP */\n");
2934          printf("     SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0)); /* COC[1] */\n");
2935        }
2936        printf("    } else { /* control from */\n");
2937        if (doisa < 4) {
2938          printf("     if (fs == 0) {\n");
2939          printf("      PENDING_FILL(ft,SIGNEXTEND(FCR0,32));\n");
2940          printf("     } else if (fs == 31) {\n");
2941          printf("      PENDING_FILL(ft,SIGNEXTEND(FCR31,32));\n");
2942          printf("     } /* else NOP */\n");
2943        } else {
2944          printf("     if (fs == 0) {\n");
2945          printf("      GPR[ft] = SIGNEXTEND(FCR0,32);\n");
2946          printf("     } else if (fs == 31) {\n");
2947          printf("      GPR[ft] = SIGNEXTEND(FCR31,32);\n");
2948          printf("     } /* else NOP */\n");
2949        }
2950        printf("    }\n");
2951      } else {
2952        printf("    if (to) {\n");
2953        if (GETDATASIZEINSN(insn) == WORD) {
2954          if (doisa < 4) { 
2955            printf("     if (SizeFGR() == 64) {\n");
2956            printf("      PENDING_FILL((fs + FGRIDX),(SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft])));\n");
2957            printf("     } else { \n");
2958            printf("      PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
2959            printf("     }\n");
2960          } else {
2961            printf("     if (SizeFGR() == 64)\n");
2962            printf("      FGR[fs] = (SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft]));\n");
2963            printf("     else\n");
2964            printf("      FGR[fs] = WORD64LO(GPR[ft]);\n");
2965            printf("     fpr_state[fs] = fmt_uninterpreted;\n");
2966          }
2967        } else if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
2968          if (doisa < 4) {
2969            printf("     if (SizeFGR() == 64) {\n");
2970            printf("      PENDING_FILL((fs + FGRIDX),GPR[ft]);\n");
2971            printf("     } else\n");
2972            printf("      if ((fs & 0x1) == 0)\n");
2973            printf("       {\n");
2974            printf("        PENDING_FILL(((fs + 1) + FGRIDX),WORD64HI(GPR[ft]));\n");
2975            printf("        PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
2976            printf("       }\n");
2977            if (features & FEATURE_WARN_RESULT) {
2978              printf("      else\n");
2979              printf("       UndefinedResult();\n");
2980            }
2981          } else {
2982            printf("     if (SizeFGR() == 64) {\n");
2983            printf("      FGR[fs] = GPR[ft];\n");
2984            printf("      fpr_state[fs] = fmt_uninterpreted;\n");
2985            printf("     } else\n");
2986            printf("      if ((fs & 0x1) == 0)\n");
2987            printf("       {\n");
2988            printf("        FGR[fs + 1] = WORD64HI(GPR[ft]);\n");
2989            printf("        FGR[fs] = WORD64LO(GPR[ft]);\n");
2990            printf("        fpr_state[fs + 1] = fmt_uninterpreted;\n");
2991            printf("        fpr_state[fs] = fmt_uninterpreted;\n");
2992            printf("       }\n");
2993            if (features & FEATURE_WARN_RESULT) {
2994              printf("      else\n");
2995              printf("       UndefinedResult();\n");
2996            }
2997          }
2998        } else {
2999          fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
3000          exit(1);
3001        }
3002        printf("    } else {\n");
3003        if (GETDATASIZEINSN(insn) == WORD) {
3004          if (doisa < 4) /* write-back occurs in next cycle */
3005           printf("     PENDING_FILL(ft,SIGNEXTEND(FGR[fs],32));\n");
3006          else /* in this cycle */
3007           printf("     GPR[ft] = SIGNEXTEND(FGR[fs],32);\n");
3008        } else if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
3009          if (doisa < 4) { 
3010            printf("     if (SizeFGR() == 64) {\n");
3011            printf("      PENDING_FILL(ft,FGR[fs]);\n");
3012            printf("     } else\n");
3013            printf("      if ((fs & 0x1) == 0) {\n");
3014            printf("       PENDING_FILL(ft,(SET64HI(FGR[fs+1]) | FGR[fs]));\n");
3015            printf("      } else {\n");
3016            printf("       PENDING_FILL(ft,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
3017            if (features & FEATURE_WARN_RESULT)
3018            printf("        UndefinedResult();\n");
3019            printf("      }\n");
3020          } else {
3021            printf("     if (SizeFGR() == 64)\n");
3022            printf("      GPR[ft] = FGR[fs];\n");
3023            printf("     else\n");
3024            printf("      if ((fs & 0x1) == 0)\n");
3025            printf("       GPR[ft] = (SET64HI(FGR[fs + 1]) | FGR[fs]);\n");
3026            printf("      else {\n");
3027            printf("       GPR[ft] = (SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
3028            if (features & FEATURE_WARN_RESULT)
3029            printf("       UndefinedResult();\n");
3030            printf("      }\n");
3031          }
3032        } else {
3033          fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
3034          exit(1);
3035        }
3036        printf("    }\n");
3037      }
3038      break ;
3039
3040     case FPMOVE:
3041      if (insn->flags & CONDITIONAL) {
3042        if (insn->flags & INTEGER) { /* moving GPR - testing FGR */
3043          printf("   if (GETFCC(condition_code) == boolean)\n");
3044          printf("    GPR[destreg] = op1;\n");
3045        } else {
3046          if (insn->flags & EQ) /* moving FGR - testing GPR */
3047           printf("   if (op2 %c= 0)\n",((insn->flags & NOT) ? '!' : '='));
3048          else
3049           printf("   if (GETFCC(condition_code) == boolean)\n");
3050          printf("    StoreFPR(destreg,format,ValueFPR(fs,format));\n");
3051          printf("   else\n");
3052          printf("    StoreFPR(destreg,format,ValueFPR(destreg,format));\n");
3053        }
3054      } else { /* simple MOVE */
3055        printf("   StoreFPR(destreg,format,ValueFPR(fs,format));\n");
3056      }
3057      break ;
3058
3059     case FPNEG:
3060      printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3061      printf("   SignalException(ReservedInstruction,instruction);\n");
3062      printf("  else\n");
3063      printf("   StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));\n");
3064      break ;
3065
3066     case FPABS:
3067      printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3068      printf("   SignalException(ReservedInstruction,instruction);\n");
3069      printf("  else\n");
3070      printf("   StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));\n");
3071      break ;
3072
3073     case FPDIV:
3074      printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3075      printf("   SignalException(ReservedInstruction,instruction);\n");
3076      printf("  else\n");
3077      printf("   StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
3078      break ;
3079
3080     case FPMUL:
3081      printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3082      printf("   SignalException(ReservedInstruction,instruction);\n");
3083      printf("  else\n");
3084      printf("   StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
3085      break ;
3086
3087     case FPRECIP:
3088      printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3089      printf("   SignalException(ReservedInstruction,instruction);\n");
3090      printf("  else\n");
3091      printf("   StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));\n");
3092      break ;
3093
3094     case FPSQRT:
3095      printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3096      printf("   SignalException(ReservedInstruction,instruction);\n");
3097      printf("  else\n");
3098      printf("   StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)));\n",((insn->flags & RECIP) ? "Recip" : ""));
3099      break ;
3100
3101     case FPCEIL:
3102     case FPFLOOR:
3103     case FPTRUNC:
3104     case FPROUND:
3105      {
3106        char *op = "";
3107        char *type = "";
3108
3109        switch (insn->type) {
3110          case FPCEIL:
3111           op = "FP_RM_TOPINF";
3112           break;
3113          case FPFLOOR:
3114           op = "FP_RM_TOMINF";
3115           break;
3116          case FPTRUNC:
3117           op = "FP_RM_TOZERO";
3118           break;
3119          case FPROUND:
3120           op = "FP_RM_NEAREST";
3121           break;
3122          default:
3123           fprintf(stderr,"Error: Handled missing for FP reason code %d\n",insn->type);
3124           exit(1);
3125        }
3126
3127        switch (GETDATASIZEINSN(insn)) {
3128          case WORD :
3129           type = "fmt_word";
3130           break;
3131          case DOUBLEWORD :
3132           type = "fmt_long";
3133           break;
3134          default:
3135           fprintf(stderr,"Error in instruction encoding table for FP %s operation (not WORD or DOUBLEWORD)\n",op);
3136           exit(1);
3137        }
3138        printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3139        printf("   SignalException(ReservedInstruction,instruction);\n");
3140        printf("  else\n");
3141        printf("   StoreFPR(destreg,%s,Convert(%s,ValueFPR(fs,format),format,%s));\n",type,op,type);
3142      }
3143      break ;
3144
3145     case FPCONVERT:
3146      {
3147        char *type = "";
3148        switch (GETDATASIZEINSN(insn)) {
3149          case SINGLE:
3150           type = "fmt_single";
3151           break;
3152          case DOUBLE:
3153           type = "fmt_double";
3154           break;
3155          case WORD:
3156           type = "fmt_word";
3157           break;
3158          case DOUBLEWORD:
3159           type = "fmt_long";
3160           break;
3161          default :
3162           fprintf(stderr,"Error: Unknown data size %d in FPCONVERT instruction\n",GETDATASIZEINSN(insn));
3163           exit(1);
3164         }
3165
3166        /* Not all combinations of conversion are valid at the
3167           moment: When converting to a fixed-point format, only
3168           floating-point sources are allowed. */
3169        printf("   if ((format == %s) | %s)\n",type,((insn->flags & FIXED) ? "((format == fmt_long) || (format == fmt_word))": "0"));
3170        printf("    SignalException(ReservedInstruction,instruction);\n");
3171        printf("   else\n");
3172        printf("    StoreFPR(destreg,%s,Convert(GETRM(),ValueFPR(fs,format),format,%s));\n",type,type);
3173      }
3174      break ;
3175
3176     case FPSUB:
3177      if (insn->flags & MULTIPLY) {
3178        char *type = "";
3179        switch (GETDATASIZEINSN(insn)) {
3180          case SINGLE:
3181           type = "fmt_single";
3182           break;
3183          case DOUBLE:
3184           type = "fmt_double";
3185           break;
3186          default:
3187           fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZEINSN(insn));
3188           exit(1);
3189        }
3190        printf("   StoreFPR(destreg,%s,%s(Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",type,((insn->flags & NOT) ? "Negate" : ""),type,type,type,type,type,type);
3191      } else {
3192        printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3193        printf("   SignalException(ReservedInstruction,instruction);\n");
3194        printf("  else\n");
3195        printf("   StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
3196      }
3197      break ;
3198
3199     case FPADD:
3200      if (insn->flags & MULTIPLY) {
3201        char *type = "";
3202        switch (GETDATASIZEINSN(insn)) {
3203          case SINGLE:
3204           type = "fmt_single";
3205           break;
3206          case DOUBLE:
3207           type = "fmt_double";
3208           break;
3209          default:
3210           fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZEINSN(insn));
3211           exit(1);
3212        }
3213        if (insn->flags & NOT)
3214          printf ("   StoreFPR(destreg,%s,Negate(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
3215                  type, type, type, type, type, type, type);
3216        else
3217          printf ("   StoreFPR(destreg,%s,Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
3218                  type, type, type, type, type, type);
3219      } else {
3220        printf("  if ((format != fmt_single) && (format != fmt_double))\n");
3221        printf("   SignalException(ReservedInstruction,instruction);\n");
3222        printf("  else\n");
3223        printf("   StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
3224      }
3225      break ;
3226
3227     case FPCOMPARE:
3228      /* For the MIPS I,II or III there *MUST* be at least one
3229         instruction between the compare that sets a condition code
3230         and the branch that tests it. NOTE: However the hardware
3231         does not detect this condition. */
3232      /* Explicitly limit the operation to S and D formats: */
3233      printf("   if ((format != fmt_single) && (format != fmt_double))\n");
3234      printf("    SignalException(ReservedInstruction,instruction);\n") ;
3235      printf("   else {\n");
3236      if (doisa < 4) {
3237        printf("    if (condition_code != 0)\n");
3238        printf("     SignalException(ReservedInstruction,instruction);\n") ;
3239        printf("    else\n");
3240      }
3241      printf("     {\n");
3242      printf("      int ignore = 0;\n");
3243      printf("      int less = 0;\n");
3244      printf("      int equal = 0;\n");
3245      printf("      int unordered = 1;\n");
3246      printf("      uword64 ofs = ValueFPR(fs,format);\n");
3247      printf("      uword64 oft = ValueFPR(ft,format);\n");
3248      printf("      if (NaN(ofs,format) || NaN(oft,format)) {\n");
3249      printf("      if (FCSR & FP_ENABLE(IO)) {\n");
3250      printf("       FCSR |= FP_CAUSE(IO);\n");
3251      printf("       SignalException(FPE);\n");
3252      printf("       ignore = 1;\n");
3253      printf("      }\n");
3254      printf("     } else {\n");
3255      printf("      less = Less(ofs,oft,format);\n");
3256      printf("      equal = Equal(ofs,oft,format);\n");
3257      printf("      unordered = 0;\n");
3258      printf("     }\n");
3259      printf("     if (!ignore) {\n");
3260      printf("      int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered));\n");
3261      printf("      SETFCC(condition_code,condition);\n");
3262      printf("     }\n");
3263      printf("    }\n");
3264      printf("   }\n");
3265      break ;
3266
3267 /* start-sanitize-r5900 */
3268     case MADD:
3269      {
3270        char* pipeline = (insn->flags & PIPE1) ? "1" : "";
3271        int notsigned = (insn->flags & UNSIGNED);
3272        char* prodtype = notsigned ? "uword64" : "word64";
3273
3274        printf("%s prod = (%s)WORD64(WORD64LO(HI%s),WORD64LO(LO%s)) + ((%s)%s(op1%s) * (%s)%s(op2%s));\n",
3275               prodtype, prodtype, pipeline, pipeline, 
3276               prodtype, (notsigned ? "WORD64LO" : "SIGNEXTEND"), (notsigned ? "" : ",32"),
3277               prodtype, (notsigned ? "WORD64LO" : "SIGNEXTEND"), (notsigned ? "" : ",32")
3278               );
3279        printf("GPR[destreg] = LO%s = SIGNEXTEND(prod,32);\n", pipeline );
3280        printf("HI%s = SIGNEXTEND( WORD64HI(prod), 32);\n", pipeline );
3281        break;
3282      }
3283
3284     case MxSA:
3285       {
3286         if (insn->flags & TO)
3287           printf("SA = op1;\n");
3288         else
3289           printf("GPR[destreg] = SA;\n");
3290         break;
3291       }
3292
3293     case MTSAB:
3294      printf("SA = ((op1 & 0xF) ^ (op2 & 0xF)) * 8;\n");
3295      break;
3296
3297     case MTSAH:
3298      printf("SA = ((op1 & 0x7) ^ (op2 & 0x7)) * 16;\n");
3299      break;
3300
3301     case QFSRV:
3302      printf("int bytes = (SA / 8) %% 16;\n");   /* mod 16 to avoid garbage */
3303      printf("if (SA %% 8)\n");
3304      printf("   SignalException(ReservedInstruction,instruction);\n");
3305      printf("else\n");
3306      printf("    {\n");
3307      printf("    int i;\n");
3308      printf("    for(i=0;i<(16-bytes);i++)\n");
3309      printf("        GPR_SB(destreg,i) = RT_SB(bytes+i);\n");
3310      printf("    for(;i<16;i++)\n");
3311      printf("        GPR_SB(destreg,i) = RS_SB(i-(16-bytes));\n");
3312      printf("    }\n");
3313      break;
3314
3315     case PADD:
3316      {
3317        char* op = (insn->flags & SUBTRACT) ? "-" : "+";
3318        char* name = name_for_data_len( insn );
3319        char* letter = letter_for_data_len( insn );
3320
3321        char* tmptype;
3322        char* maximum;
3323        char* minimum;
3324        char* signedness;
3325
3326        if ( insn->flags & UNSIGNED )
3327          {
3328            tmptype = type_for_data_len( insn );
3329            signedness = "unsigned";
3330            maximum = umax_for_data_len( insn );
3331            minimum = 0;
3332          }
3333        else if ( insn->flags & SATURATE )
3334          {
3335            tmptype = type_for_data_len( insn );
3336            signedness = "";
3337            maximum = 0;
3338            minimum = 0;
3339          }
3340        else
3341          {
3342            tmptype = type_for_data_len( insn );
3343            signedness = "";
3344            maximum = max_for_data_len( insn );
3345            minimum = min_for_data_len( insn );
3346          }
3347
3348        printf("int i;\n");
3349        printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3350        printf("     {\n");
3351        printf("     %s %s r = RS_S%s(i) %s RT_S%s(i);\n", signedness, tmptype, letter, op, letter );
3352        if ( maximum )
3353          {
3354            printf("     if (r > %s)      GPR_S%s(destreg,i) = %s;\n", maximum, letter, maximum );
3355            if ( minimum )
3356              printf("     else if (r < %s) GPR_S%s(destreg,i) = %s;\n", minimum, letter, minimum );
3357            printf("     else             ");
3358          }
3359        printf("GPR_S%s(destreg,i) = r;\n", letter );
3360        printf("     }\n");
3361        break;
3362      }
3363
3364     case PMULTH:
3365      {
3366        char* op;
3367        if ( insn->flags & SUBTRACT )
3368          op = "-";
3369        else if ( insn->flags & ADDITION )
3370          op = "+";
3371        else
3372          op = "";
3373
3374        printf("GPR_SW(destreg,0) = LO_SW(0) %s= (RS_SH(0) * RT_SH(0));\n", op);
3375        printf("                    LO_SW(1) %s= (RS_SH(1) * RT_SH(1));\n", op);
3376        printf("GPR_SW(destreg,1) = HI_SW(0) %s= (RS_SH(2) * RT_SH(2));\n", op);
3377        printf("                    HI_SW(1) %s= (RS_SH(3) * RT_SH(3));\n", op);
3378        printf("GPR_SW(destreg,2) = LO_SW(2) %s= (RS_SH(4) * RT_SH(4));\n", op);
3379        printf("                    LO_SW(3) %s= (RS_SH(5) * RT_SH(5));\n", op);
3380        printf("GPR_SW(destreg,3) = HI_SW(2) %s= (RS_SH(6) * RT_SH(6));\n", op);
3381        printf("                    HI_SW(3) %s= (RS_SH(7) * RT_SH(7));\n", op);
3382        break;
3383      }
3384
3385     case PMULTW:
3386      {
3387        char* op;
3388        char* sign  = (insn->flags & UNSIGNED) ? "U" : "S";
3389        char* prodtype = (insn->flags & UNSIGNED) ? "uword64" : "word64";
3390        char* constructor = (insn->flags & UNSIGNED) ? "UWORD64" : "WORD64";
3391
3392        printf("%s prod0;\n", prodtype );
3393        printf("%s prod1;\n", prodtype );
3394
3395        if ( insn->flags & SUBTRACT )
3396          {
3397            op = "-";
3398            printf("prod0 = %s( HI_SW(0), LO_SW(0) );\n", constructor );
3399            printf("prod1 = %s( HI_SW(2), LO_SW(2) );\n", constructor );
3400          }
3401        else if ( insn->flags & ADDITION )
3402          {
3403            op = "+";
3404            printf("prod0 = %s( HI_SW(0), LO_SW(0) );\n", constructor );
3405            printf("prod1 = %s( HI_SW(2), LO_SW(2) );\n", constructor );
3406          }
3407        else
3408          op = "";
3409
3410        printf("prod0 %s= (%s)RS_SW(0) * (%s)RT_SW(0);\n", op, prodtype, prodtype );
3411        printf("prod1 %s= (%s)RS_SW(2) * (%s)RT_SW(2);\n", op, prodtype, prodtype );
3412
3413        printf("GPR_%sD(destreg,0) = prod0;\n", sign );
3414        printf("GPR_%sD(destreg,1) = prod1;\n", sign );
3415
3416        printf("LO  = SIGNEXTEND( prod0, 32 );\n");
3417        printf("HI  = SIGNEXTEND( WORD64HI(prod0), 32 );\n");
3418        printf("LO1 = SIGNEXTEND( prod1, 32 );\n");
3419        printf("HI1 = SIGNEXTEND( WORD64HI(prod1), 32 );\n");
3420        break;
3421      }
3422
3423     case PDIVW:
3424       {
3425         char* sign = (insn->flags & UNSIGNED) ? "U" : "S";
3426
3427         printf("LO  = RS_%sW(0) / RT_%sW(0);\n", sign, sign );
3428         printf("HI  = RS_%sW(0) %% RT_%sW(0);\n", sign, sign );
3429         printf("LO1 = RS_%sW(2) / RT_%sW(2);\n", sign, sign );
3430         printf("HI1 = RS_%sW(2) %% RT_%sW(2);\n", sign, sign );
3431         break;
3432       }
3433
3434     case PDIVBW:
3435       printf("int devisor = RT_SH(0);\n");
3436       printf("LO_SW(0) = RS_SW(0) / devisor;\n");
3437       printf("HI_SW(0) = SIGNEXTEND( (RS_SW(0) %% devisor), 16 );\n");
3438       printf("LO_SW(1) = RS_SW(1) / devisor;\n");
3439       printf("HI_SW(1) = SIGNEXTEND( (RS_SW(1) %% devisor), 16 );\n");
3440       printf("LO_SW(2) = RS_SW(2) / devisor;\n");
3441       printf("HI_SW(2) = SIGNEXTEND( (RS_SW(2) %% devisor), 16 );\n");
3442       printf("LO_SW(3) = RS_SW(3) / devisor;\n");
3443       printf("HI_SW(3) = SIGNEXTEND( (RS_SW(3) %% devisor), 16 );\n");
3444       break;
3445
3446     case PADSBH:
3447      printf("int i;\n");
3448      printf("for(i=0;i<HALFWORDS_IN_MMI_REGS/2;i++)\n");
3449      printf("  GPR_SH(destreg,i) = RS_SH(i) - RT_SH(i);\n");
3450      printf("for(;i<HALFWORDS_IN_MMI_REGS;i++)\n");
3451      printf("  GPR_SH(destreg,i) = RS_SH(i) + RT_SH(i);\n");
3452      break;
3453
3454     case PHMADDH:
3455      {
3456        char* op = (insn->flags & SUBTRACT) ? "-" : "+";
3457        printf("GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) %s (RS_SH(0) * RT_SH(0));\n", op );
3458        printf("GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) %s (RS_SH(2) * RT_SH(2));\n", op );
3459        printf("GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) %s (RS_SH(4) * RT_SH(4));\n", op );
3460        printf("GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) %s (RS_SH(6) * RT_SH(6));\n", op );
3461      }
3462      break;
3463
3464     case PSHIFT:
3465      {
3466        char* name = name_for_data_len( insn );
3467        char* letter = letter_for_data_len( insn );
3468        char* bits = bits_for_data_len( insn );
3469        char* shift = (insn->flags & RIGHT) ? ">>" : "<<";
3470        char* sign = (insn->flags & ARITHMETIC) ? "S" : "U";
3471
3472        printf("int shift_by = op1 & (%s-1);\n", bits );
3473        printf("int i;\n");
3474        printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3475        printf("    GPR_%s%s(destreg,i) = ", sign, letter );
3476        if ( insn->flags & ARITHMETIC )
3477          printf("SIGNEXTEND( ");
3478        printf("(RT_%s%s(i) %s shift_by)", sign, letter, shift );
3479        if ( insn->flags & ARITHMETIC )
3480          printf(", (%s-shift_by) )", bits );
3481        printf(";\n");
3482        break;
3483      }
3484
3485     case PSLLVW:
3486      printf("GPR_UD(destreg,0) = RT_UW(0) << (RS_UB(0) & 0x1F);\n");
3487      printf("GPR_UD(destreg,1) = RT_UW(2) << (RS_UB(8) & 0x1F);\n");
3488      break;
3489
3490     case PSRLVW:
3491      printf("GPR_UD(destreg,0) = RT_UW(0) >> (RS_UB(0) & 0x1F);\n");
3492      printf("GPR_UD(destreg,1) = RT_UW(2) >> (RS_UB(8) & 0x1F);\n");
3493      break;
3494
3495     case PSRAVW:
3496      printf("GPR_SD(destreg,0) = SIGNEXTEND( (RT_SW (0) >> (RS_UB(0) & 0x1F)), 32-(RS_UB(0) & 0x1F) );\n");
3497      printf("GPR_SD(destreg,1) = SIGNEXTEND( (RT_SW (2) >> (RS_UB(8) & 0x1F)), 32-(RS_UB(8) & 0x1F) );\n");
3498      break;
3499
3500     case POP:
3501      {
3502        char* op1;
3503        char* op2;
3504        
3505        if ( GET_OP_FROM_INSN(insn) == POP_AND )
3506          {
3507            op1 = "&";
3508            op2 = "";
3509          }
3510        else if ( GET_OP_FROM_INSN(insn) == POP_OR )
3511          {
3512            op1 = "|";
3513            op2 = "";
3514          }
3515        else if ( GET_OP_FROM_INSN(insn) == POP_NOR )
3516          {
3517            op1 = "|";
3518            op2 = "~";
3519          }
3520        else if ( GET_OP_FROM_INSN(insn) == POP_XOR )
3521          {
3522            op1 = "^";
3523            op2 = "";
3524          }
3525        
3526        printf("int i;\n");
3527        printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
3528        printf("  GPR_UW(destreg,i) = %s(RS_UW(i) %s RT_UW(i));\n", op2, op1 );
3529        break;
3530      }
3531
3532     case PCMP:
3533      {
3534        char* name = name_for_data_len( insn );
3535        char* letter = letter_for_data_len( insn );
3536        char* maximum = umax_for_data_len( insn );
3537        char* op = (insn->flags & GT) ? ">" : "==";
3538
3539        printf("int i;\n");
3540        printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3541        printf("     {\n");
3542        printf("     if (RS_S%s(i) %s RT_S%s(i)) GPR_S%s(destreg,i) = %s;\n", 
3543               letter, op, letter, letter, maximum );
3544        printf("     else                        GPR_S%s(destreg,i) = 0;\n", letter );
3545        printf("     }\n");
3546        break;
3547      }
3548
3549     case PMAXMIN:
3550      {
3551        char* name = name_for_data_len( insn );
3552        char* letter = letter_for_data_len( insn );
3553        char* op = (insn->flags & GT) ? ">" : "<";
3554
3555        printf("int i;\n");
3556        printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3557        printf("     {\n");
3558        printf("     if (RS_S%s(i) %s RT_S%s(i)) GPR_S%s(destreg,i) = RS_S%s(i);\n", 
3559               letter, op, letter, letter, letter );
3560        printf("     else                        GPR_S%s(destreg,i) = RT_S%s(i);\n", letter, letter );
3561        printf("     }\n");
3562        break;
3563      }
3564
3565     case PABS:
3566      {
3567        char* name = name_for_data_len( insn );
3568        char* letter = letter_for_data_len( insn );
3569
3570        printf("int i;\n");
3571        printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3572        printf("  {\n");
3573        printf("  if (RT_S%s(i) < 0)\n", letter );
3574        printf("    GPR_S%s(destreg,i) = -RT_S%s(i);\n", letter, letter );
3575        printf("  else\n");
3576        printf("    GPR_S%s(destreg,i) =  RT_S%s(i);\n", letter, letter );
3577        printf("  }\n");
3578        break;
3579      }
3580
3581     case PCPYH:
3582      printf("GPR_UH(destreg,7) = GPR_UH(destreg,6) = GPR_UH(destreg,5) = GPR_UH(destreg,4) = RT_UH(4);\n");
3583      printf("GPR_UH(destreg,3) = GPR_UH(destreg,2) = GPR_UH(destreg,1) = GPR_UH(destreg,0) = RT_UH(0);\n");
3584      break;
3585
3586     case PCPYLD:
3587      printf("GPR_UD(destreg,0) = RT_UD(0);\n");
3588      printf("GPR_UD(destreg,1) = RS_UD(0);\n");
3589      break;
3590
3591     case PCPYUD:
3592      printf("GPR_UD(destreg,0) = RS_UD(1);\n");
3593      printf("GPR_UD(destreg,1) = RT_UD(1);\n");
3594      break;
3595
3596     case PEXCH:
3597      printf("GPR_UH(destreg,0) = RT_UH(0);\n");
3598      printf("GPR_UH(destreg,1) = RT_UH(2);\n");
3599      printf("GPR_UH(destreg,2) = RT_UH(1);\n");
3600      printf("GPR_UH(destreg,3) = RT_UH(3);\n");
3601      printf("GPR_UH(destreg,4) = RT_UH(4);\n");
3602      printf("GPR_UH(destreg,5) = RT_UH(6);\n");
3603      printf("GPR_UH(destreg,6) = RT_UH(5);\n");
3604      printf("GPR_UH(destreg,7) = RT_UH(7);\n");
3605      break;
3606
3607     case PEXCW:
3608      printf("GPR_UW(destreg,0) = RT_UW(0);\n");
3609      printf("GPR_UW(destreg,1) = RT_UW(2);\n");
3610      printf("GPR_UW(destreg,2) = RT_UW(1);\n");
3611      printf("GPR_UW(destreg,3) = RT_UW(3);\n");
3612      break;
3613
3614     case PEXOH:
3615      printf("GPR_UH(destreg,0) = RT_UH(2);\n");
3616      printf("GPR_UH(destreg,1) = RT_UH(1);\n");
3617      printf("GPR_UH(destreg,2) = RT_UH(0);\n");
3618      printf("GPR_UH(destreg,3) = RT_UH(3);\n");
3619      printf("GPR_UH(destreg,4) = RT_UH(6);\n");
3620      printf("GPR_UH(destreg,5) = RT_UH(5);\n");
3621      printf("GPR_UH(destreg,6) = RT_UH(4);\n");
3622      printf("GPR_UH(destreg,7) = RT_UH(7);\n");
3623      break;
3624
3625     case PEXOW:
3626      printf("GPR_UW(destreg,0) = RT_UW(2);\n");
3627      printf("GPR_UW(destreg,1) = RT_UW(1);\n");
3628      printf("GPR_UW(destreg,2) = RT_UW(0);\n");
3629      printf("GPR_UW(destreg,3) = RT_UW(3);\n");
3630      break;
3631
3632     case PEXTLB:
3633      printf("GPR_UB(destreg,0)  = RT_UB(0);\n");
3634      printf("GPR_UB(destreg,1)  = RS_UB(0);\n");
3635      printf("GPR_UB(destreg,2)  = RT_UB(1);\n");
3636      printf("GPR_UB(destreg,3)  = RS_UB(1);\n");
3637      printf("GPR_UB(destreg,4)  = RT_UB(2);\n");
3638      printf("GPR_UB(destreg,5)  = RS_UB(2);\n");
3639      printf("GPR_UB(destreg,6)  = RT_UB(3);\n");
3640      printf("GPR_UB(destreg,7)  = RS_UB(3);\n");
3641      printf("GPR_UB(destreg,8)  = RT_UB(4);\n");
3642      printf("GPR_UB(destreg,9)  = RS_UB(4);\n");
3643      printf("GPR_UB(destreg,10) = RT_UB(5);\n");
3644      printf("GPR_UB(destreg,11) = RS_UB(5);\n");
3645      printf("GPR_UB(destreg,12) = RT_UB(6);\n");
3646      printf("GPR_UB(destreg,13) = RS_UB(6);\n");
3647      printf("GPR_UB(destreg,14) = RT_UB(7);\n");
3648      printf("GPR_UB(destreg,15) = RS_UB(7);\n");
3649      break;
3650
3651     case PEXTLH:
3652      printf("GPR_UH(destreg,0)  = RT_UH(0);\n");
3653      printf("GPR_UH(destreg,1)  = RS_UH(0);\n");
3654      printf("GPR_UH(destreg,2)  = RT_UH(1);\n");
3655      printf("GPR_UH(destreg,3)  = RS_UH(1);\n");
3656      printf("GPR_UH(destreg,4)  = RT_UH(2);\n");
3657      printf("GPR_UH(destreg,5)  = RS_UH(2);\n");
3658      printf("GPR_UH(destreg,6)  = RT_UH(3);\n");
3659      printf("GPR_UH(destreg,7)  = RS_UH(3);\n");
3660      break;
3661
3662     case PEXTLW:
3663      printf("GPR_UW(destreg,0)  = RT_UW(0);\n");
3664      printf("GPR_UW(destreg,1)  = RS_UW(0);\n");
3665      printf("GPR_UW(destreg,2)  = RT_UW(1);\n");
3666      printf("GPR_UW(destreg,3)  = RS_UW(1);\n");
3667      break;
3668
3669     case PEXTUB:
3670      printf("GPR_UB(destreg,0)  = RT_UB(8);\n");
3671      printf("GPR_UB(destreg,1)  = RS_UB(8);\n");
3672      printf("GPR_UB(destreg,2)  = RT_UB(9);\n");
3673      printf("GPR_UB(destreg,3)  = RS_UB(9);\n");
3674      printf("GPR_UB(destreg,4)  = RT_UB(10);\n");
3675      printf("GPR_UB(destreg,5)  = RS_UB(10);\n");
3676      printf("GPR_UB(destreg,6)  = RT_UB(11);\n");
3677      printf("GPR_UB(destreg,7)  = RS_UB(11);\n");
3678      printf("GPR_UB(destreg,8)  = RT_UB(12);\n");
3679      printf("GPR_UB(destreg,9)  = RS_UB(12);\n");
3680      printf("GPR_UB(destreg,10) = RT_UB(13);\n");
3681      printf("GPR_UB(destreg,11) = RS_UB(13);\n");
3682      printf("GPR_UB(destreg,12) = RT_UB(14);\n");
3683      printf("GPR_UB(destreg,13) = RS_UB(14);\n");
3684      printf("GPR_UB(destreg,14) = RT_UB(15);\n");
3685      printf("GPR_UB(destreg,15) = RS_UB(15);\n");
3686      break;
3687
3688     case PEXTUH:
3689      printf("GPR_UH(destreg,0)  = RT_UH(4);\n");
3690      printf("GPR_UH(destreg,1)  = RS_UH(4);\n");
3691      printf("GPR_UH(destreg,2)  = RT_UH(5);\n");
3692      printf("GPR_UH(destreg,3)  = RS_UH(5);\n");
3693      printf("GPR_UH(destreg,4)  = RT_UH(6);\n");
3694      printf("GPR_UH(destreg,5)  = RS_UH(6);\n");
3695      printf("GPR_UH(destreg,6)  = RT_UH(7);\n");
3696      printf("GPR_UH(destreg,7)  = RS_UH(7);\n");
3697      break;
3698
3699     case PEXTUW:
3700      printf("GPR_UW(destreg,0)  = RT_UW(2);\n");
3701      printf("GPR_UW(destreg,1)  = RS_UW(2);\n");
3702      printf("GPR_UW(destreg,2)  = RT_UW(3);\n");
3703      printf("GPR_UW(destreg,3)  = RS_UW(3);\n");
3704      break;
3705
3706     case PPACB:
3707      printf("GPR_UB(destreg,0)  = RT_UB(0);\n");
3708      printf("GPR_UB(destreg,1)  = RT_UB(2);\n");
3709      printf("GPR_UB(destreg,2)  = RT_UB(4);\n");
3710      printf("GPR_UB(destreg,3)  = RT_UB(6);\n");
3711      printf("GPR_UB(destreg,4)  = RT_UB(8);\n");
3712      printf("GPR_UB(destreg,5)  = RT_UB(10);\n");
3713      printf("GPR_UB(destreg,6)  = RT_UB(12);\n");
3714      printf("GPR_UB(destreg,7)  = RT_UB(14);\n");
3715      printf("GPR_UB(destreg,8)  = RS_UB(0);\n");
3716      printf("GPR_UB(destreg,9)  = RS_UB(2);\n");
3717      printf("GPR_UB(destreg,10) = RS_UB(4);\n");
3718      printf("GPR_UB(destreg,11) = RS_UB(6);\n");
3719      printf("GPR_UB(destreg,12) = RS_UB(8);\n");
3720      printf("GPR_UB(destreg,13) = RS_UB(10);\n");
3721      printf("GPR_UB(destreg,14) = RS_UB(12);\n");
3722      printf("GPR_UB(destreg,15) = RS_UB(14);\n");
3723      break;
3724
3725     case PPACH:
3726      printf("GPR_UH(destreg,0)  = RT_UH(0);\n");
3727      printf("GPR_UH(destreg,1)  = RT_UH(2);\n");
3728      printf("GPR_UH(destreg,2)  = RT_UH(4);\n");
3729      printf("GPR_UH(destreg,3)  = RT_UH(6);\n");
3730      printf("GPR_UH(destreg,4)  = RS_UH(0);\n");
3731      printf("GPR_UH(destreg,5)  = RS_UH(2);\n");
3732      printf("GPR_UH(destreg,6)  = RS_UH(4);\n");
3733      printf("GPR_UH(destreg,7)  = RS_UH(6);\n");
3734      break;
3735
3736     case PPACW:
3737      printf("GPR_UW(destreg,0)  = RT_UW(0);\n");
3738      printf("GPR_UW(destreg,1)  = RT_UW(2);\n");
3739      printf("GPR_UW(destreg,2)  = RS_UW(0);\n");
3740      printf("GPR_UW(destreg,3)  = RS_UW(2);\n");
3741      break;
3742
3743     case PREVH:
3744      printf("GPR_UH(destreg,0)  = RT_UH(3);\n");
3745      printf("GPR_UH(destreg,1)  = RT_UH(2);\n");
3746      printf("GPR_UH(destreg,2)  = RT_UH(1);\n");
3747      printf("GPR_UH(destreg,3)  = RT_UH(0);\n");
3748      printf("GPR_UH(destreg,4)  = RT_UH(7);\n");
3749      printf("GPR_UH(destreg,5)  = RT_UH(6);\n");
3750      printf("GPR_UH(destreg,6)  = RT_UH(5);\n");
3751      printf("GPR_UH(destreg,7)  = RT_UH(4);\n");
3752      break;
3753
3754     case PROT3W:
3755      printf("GPR_UW(destreg,0)  = RT_UW(0);\n");
3756      printf("GPR_UW(destreg,1)  = RT_UW(3);\n");
3757      printf("GPR_UW(destreg,2)  = RT_UW(1);\n");
3758      printf("GPR_UW(destreg,3)  = RT_UW(2);\n");
3759      break;
3760
3761     case PINTH:
3762      printf("GPR_UH(destreg,0)  = RT_UH(0);\n");
3763      printf("GPR_UH(destreg,1)  = RS_UH(4);\n");
3764      printf("GPR_UH(destreg,2)  = RT_UH(1);\n");
3765      printf("GPR_UH(destreg,3)  = RS_UH(5);\n");
3766      printf("GPR_UH(destreg,4)  = RT_UH(2);\n");
3767      printf("GPR_UH(destreg,5)  = RS_UH(6);\n");
3768      printf("GPR_UH(destreg,6)  = RT_UH(3);\n");
3769      printf("GPR_UH(destreg,7)  = RS_UH(7);\n");
3770      break;
3771
3772     case PINTOH:
3773      printf("GPR_UH(destreg,0) = RT_UH(0);\n");
3774      printf("GPR_UH(destreg,1) = RS_UH(0);\n");
3775      printf("GPR_UH(destreg,2) = RT_UH(2);\n");
3776      printf("GPR_UH(destreg,3) = RS_UH(2);\n");
3777      printf("GPR_UH(destreg,4) = RT_UH(4);\n");
3778      printf("GPR_UH(destreg,5) = RS_UH(4);\n");
3779      printf("GPR_UH(destreg,6) = RT_UH(6);\n");
3780      printf("GPR_UH(destreg,7) = RS_UH(6);\n");
3781      break;
3782
3783     case PMXX:  /* Parallel move HI or LO / TO or FROM */
3784      {
3785        if ( (insn->flags & (HI|FROM)) == (HI|FROM) )
3786          {
3787            printf("GPR_SD(destreg,0) = HI;\n");
3788            printf("GPR_SD(destreg,1) = HI1;\n");
3789          }
3790        else if ( (insn->flags & (LO|FROM)) == (LO|FROM) )
3791          {
3792            printf("GPR_SD(destreg,0) = LO;\n");
3793            printf("GPR_SD(destreg,1) = LO1;\n");
3794          }
3795        else if ( (insn->flags & (HI|TO)) == (HI|TO) )
3796          {
3797            printf("HI  = RS_SD(0);\n");
3798            printf("HI1 = RS_SD(1);\n");
3799          }
3800        else if ( (insn->flags & (LO|TO)) == (LO|TO) )
3801          {
3802            printf("LO  = RS_SD(0);\n");
3803            printf("LO1 = RS_SD(1);\n");
3804          }
3805        break;
3806      }
3807
3808     case PMTHL:
3809      printf("LO_UW(0) = RS_UW(0);\n");
3810      printf("HI_UW(0) = RS_UW(1);\n");
3811      printf("LO_UW(2) = RS_UW(2);\n");
3812      printf("HI_UW(2) = RS_UW(3);\n");
3813      break;
3814
3815     case PMFHL:
3816      printf("if (op1 == 0)\n");
3817      printf("  {\n");
3818      printf("  GPR_UW(destreg,0) = LO_UW(0);\n");
3819      printf("  GPR_UW(destreg,1) = HI_UW(0);\n");
3820      printf("  GPR_UW(destreg,2) = LO_UW(2);\n");
3821      printf("  GPR_UW(destreg,3) = HI_UW(2);\n");
3822      printf("  }\n");
3823      printf("else if (op1 == 1)\n");
3824      printf("  {\n");
3825      printf("  GPR_UW(destreg,0) = LO_UW(1);\n");
3826      printf("  GPR_UW(destreg,1) = HI_UW(1);\n");
3827      printf("  GPR_UW(destreg,2) = LO_UW(3);\n");
3828      printf("  GPR_UW(destreg,3) = HI_UW(3);\n");
3829      printf("  }\n");
3830      printf("else if (op1 == 2)\n");
3831      printf("  {\n");
3832      printf("  unsigned long long t = ((uword64)HI_UW(0) << 32) | (uword64)LO_UW(0);\n");
3833      printf("  if ( t > 0x7FFFFFFF )\n");
3834      printf("    GPR_SD(destreg,0) = 0x7FFFFFFF;\n");
3835      printf("  else if ( t > (uword64)0xFFFFFFFF80000000LL )\n");
3836      printf("    GPR_SD(destreg,0) = (uword64)0xFFFFFFFF80000000LL;\n");
3837      printf("  else\n");
3838      printf("    GPR_SD(destreg,0) = SIGNEXTEND(t,32);\n");
3839      printf("  }\n");
3840      printf("else if (op1 == 3)\n");
3841      printf("  {\n");
3842      printf("  GPR_UH(destreg,0) = LO_UH(0);\n");
3843      printf("  GPR_UH(destreg,1) = LO_UH(2);\n");
3844      printf("  GPR_UH(destreg,2) = HI_UH(0);\n");
3845      printf("  GPR_UH(destreg,3) = HI_UH(2);\n");
3846      printf("  GPR_UH(destreg,4) = LO_UH(4);\n");
3847      printf("  GPR_UH(destreg,5) = LO_UH(6);\n");
3848      printf("  GPR_UH(destreg,6) = HI_UH(4);\n");
3849      printf("  GPR_UH(destreg,7) = HI_UH(6);\n");
3850      printf("  }\n");
3851      printf("else if (op1 == 4)\n");
3852      printf("  {\n");
3853      printf("  if (LO_UW(0) > 0x00007FFF)\n");
3854      printf("    GPR_UH(destreg,0) = 0x7FFF;\n");
3855      printf("  else if (LO_UW(0) >= 0xFFFF8000)\n");
3856      printf("    GPR_UH(destreg,0) = 0x8000;\n");
3857      printf("  else\n");
3858      printf("    GPR_UH(destreg,0) = LO_UH(0);\n");
3859
3860      printf("  if (LO_UW(1) > 0x00007FFF)\n");
3861      printf("    GPR_UH(destreg,1) = 0x7FFF;\n");
3862      printf("  else if (LO_UW(1) >= 0xFFFF8000)\n");
3863      printf("    GPR_UH(destreg,1) = 0x8000;\n");
3864      printf("  else\n");
3865      printf("    GPR_UH(destreg,1) = LO_UH(2);\n");
3866
3867      printf("  if (HI_UW(0) > 0x00007FFF)\n");
3868      printf("    GPR_UH(destreg,0) = 0x7FFF;\n");
3869      printf("  else if (HI_UW(0) >= 0xFFFF8000)\n");
3870      printf("    GPR_UH(destreg,0) = 0x8000;\n");
3871      printf("  else\n");
3872      printf("    GPR_UH(destreg,0) = HI_UH(0);\n");
3873
3874      printf("  if (HI_UW(1) > 0x00007FFF)\n");
3875      printf("    GPR_UH(destreg,1) = 0x7FFF;\n");
3876      printf("  else if (HI_UW(1) >= 0xFFFF8000)\n");
3877      printf("    GPR_UH(destreg,1) = 0x8000;\n");
3878      printf("  else\n");
3879      printf("    GPR_UH(destreg,1) = HI_UH(2);\n");
3880
3881      printf("  if (LO_UW(2) > 0x00007FFF)\n");
3882      printf("    GPR_UH(destreg,4) = 0x7FFF;\n");
3883      printf("  else if (LO_UW(2) >= 0xFFFF8000)\n");
3884      printf("    GPR_UH(destreg,4) = 0x8000;\n");
3885      printf("  else\n");
3886      printf("    GPR_UH(destreg,4) = LO_UH(4);\n");
3887
3888      printf("  if (LO_UW(3) > 0x00007FFF)\n");
3889      printf("    GPR_UH(destreg,5) = 0x7FFF;\n");
3890      printf("  else if (LO_UW(3) >= 0xFFFF8000)\n");
3891      printf("    GPR_UH(destreg,5) = 0x8000;\n");
3892      printf("  else\n");
3893      printf("    GPR_UH(destreg,5) = LO_UH(6);\n");
3894
3895      printf("  if (HI_UW(2) > 0x00007FFF)\n");
3896      printf("    GPR_UH(destreg,6) = 0x7FFF;\n");
3897      printf("  else if (HI_UW(2) >= 0xFFFF8000)\n");
3898      printf("    GPR_UH(destreg,6) = 0x8000;\n");
3899      printf("  else\n");
3900      printf("    GPR_UH(destreg,6) = HI_UH(4);\n");
3901
3902      printf("  if (HI_UW(3) > 0x00007FFF)\n");
3903      printf("    GPR_UH(destreg,7) = 0x7FFF;\n");
3904      printf("  else if (HI_UW(3) >= 0xFFFF8000)\n");
3905      printf("    GPR_UH(destreg,7) = 0x8000;\n");
3906      printf("  else\n");
3907      printf("    GPR_UH(destreg,7) = HI_UH(6);\n");
3908
3909      printf("  }\n");
3910      break;
3911
3912     case PLZCW:
3913       printf("unsigned long value;\n");
3914       printf("int test;\n");
3915       printf("int count;\n");
3916       printf("int i;\n");
3917
3918       printf("value = RS_UW(0);\n");
3919       printf("count = 0;\n");
3920       printf("test = !!(value & (1 << 31));\n");
3921       printf("for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)\n");
3922       printf("  count++;\n");
3923       printf("GPR_UW(destreg,0) = count;\n");
3924
3925       printf("value = RS_UW(1);\n");
3926       printf("count = 0;\n");
3927       printf("test = !!(value & (1 << 31));\n");
3928       printf("for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)\n");
3929       printf("  count++;\n");
3930       printf("GPR_UW(destreg,1) = count;\n");
3931       break;
3932
3933     case PEXT5:
3934       printf("int i;\n");
3935       printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
3936       printf("  {\n");
3937       printf("  int x = RT_UW(i);\n");
3938       printf("  GPR_UW(destreg,i) = ((x & (1  << 15)) << (24 - 15))  \n");
3939       printf("                    | ((x & (31 << 10)) << (19 - 10))  \n");
3940       printf("                    | ((x & (31 << 5))  << (11 - 5))   \n");
3941       printf("                    | ((x & (31 << 0))  << (3  - 0));  \n");
3942       printf("  }\n");
3943       break;
3944
3945     case PPAC5:
3946       printf("int i;\n");
3947       printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
3948       printf("  {\n");
3949       printf("  int x = RT_UW(i);\n");
3950       printf("  GPR_UW(destreg,i) = ((x & (1  << 24)) >> (24 - 15))  \n");
3951       printf("                    | ((x & (31 << 19)) >> (19 - 10))  \n");
3952       printf("                    | ((x & (31 << 11)) >> (11 - 5))   \n");
3953       printf("                    | ((x & (31 <<  3)) >> (3  - 0));  \n");
3954       printf("  }\n");
3955       break;
3956 /* end-sanitize-r5900 */
3957
3958     case NYI:
3959      fprintf(stderr,"Warning: Unimplemented opcode: %s\n",insn->name) ;
3960
3961      printf("SignalException(ReservedInstruction,instruction);\n");
3962      break;
3963
3964     default:
3965      fprintf(stderr,"Unrecognised opcode type %d\n",insn->type) ;
3966      exit(6) ;
3967    }
3968 }
3969
3970 /*---------------------------------------------------------------------------*/
3971
3972 /* The command-line feature controls are presented in a similar style
3973    to those offered by GCC, in the aim of providing a consistent
3974    interface to the user. */
3975 typedef enum {
3976   T_NONE,  /* no argument - mask and value fields control "feature" definition */
3977   T_NUM,   /* numeric argument - optionally preceded by '=' - mask field defines maximum value */
3978   T_STRING /* string argument - optionally prcededed by '=' */
3979 } mactypes;
3980
3981 struct {
3982   char *name;
3983   mactypes type;
3984   unsigned int mask;
3985   unsigned int value;
3986   char *desc;
3987 } machine_options[] = {
3988   {"ips",         T_NUM,   MASK_ISA,0,"\tSelect MIPS ISA version"},
3989   {"cpu",         T_STRING,0,0,"\t\tSelect particular MIPS architecture"},
3990   {"gp64",        T_NONE,  FEATURE_GP64,FEATURE_GP64,"\t\t\tSelect 64bit GP registers"},
3991   {"gp32",        T_NONE,  FEATURE_GP64,0,"\t\t\tSelect 32bit GP registers"},
3992   {"no-fp",       T_NONE,  FEATURE_HASFPU,0,"\t\tDisable FP simulation"},
3993   {"single-float",T_NONE,  (FEATURE_FPSINGLE | FEATURE_HASFPU),(FEATURE_FPSINGLE | FEATURE_HASFPU),"\t\tSelect single precision only FPU"},
3994   {"double-float",T_NONE,  (FEATURE_FPSINGLE | FEATURE_HASFPU),FEATURE_HASFPU,"\t\tSelect double precision FPU"},
3995   {0,             T_NONE,  0,0}
3996 };
3997
3998 /* The following architecture identies are those accepted by the "-mcpu" option: */
3999 struct architectures {
4000  const char *name;    /* ASCII string identifier for command-line, no white-space allowed */
4001  unsigned int idflag; /* or-ed into "isa" value */
4002 };
4003
4004 static const struct architectures available_architectures[] = {
4005   {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
4006   /* start-sanitize-r5900 */
4007   {"5900",ARCH_R5900},
4008   /* end-sanitize-r5900 */
4009   {0,     0}            /* terminator */
4010 };
4011
4012 /*---------------------------------------------------------------------------*/
4013
4014 static void
4015 usage(name)
4016      char *name;
4017 {
4018  int loop;
4019
4020  fprintf(stderr,"%s: Construct a MIPS simulator engine.\n",name);
4021
4022  fprintf(stderr,"\
4023 The output of this program is a block of 'C' code designed to be\n\
4024 included into the main simulation control loop of a device specific\n\
4025 simulator.\n");
4026
4027  fprintf(stderr,"\nOptions:\n");
4028  fprintf(stderr," -h --help\t\tProvide this help text\n");
4029  fprintf(stderr," -f --fast\t\tProvide the fastest possible engine (i.e. no statistics)\n");
4030  fprintf(stderr," -w --warnings\t\tEnable all the simulator engine warnings\n");
4031
4032  for (loop = 0; (machine_options[loop].name != 0); loop++) {
4033    fprintf(stderr," -m%s",machine_options[loop].name);
4034    switch (machine_options[loop].type) {
4035      case T_NUM :
4036        fprintf(stderr,"N (range 0..%d)",machine_options[loop].mask);
4037      case T_NONE :
4038        break;
4039
4040      case T_STRING :
4041        fprintf(stderr,"=name");
4042        break;
4043
4044      default :
4045        fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",name,machine_options[loop].type);
4046        exit(1);
4047    }
4048    fprintf(stderr,"%s\n",machine_options[loop].desc);
4049  }
4050
4051  fprintf(stderr,"\nAvailable \"-mcpu\" architectures: ");
4052  for (loop = 0; (available_architectures[loop].name != 0); loop++)
4053    fprintf(stderr,"%s ",available_architectures[loop].name);
4054  fprintf(stderr,"\n\n");
4055
4056  fprintf(stderr,"\
4057 The \"trace\" and \"warnings\" options do not define the output stream.\n\
4058 They only inform the code that includes the constructed engine to provide\n\
4059 the required features.\n\n\
4060 The \"-mips0\" option forces the construction of a simulator supporting\n\
4061 the highest available MIPS ISA supported.\n");
4062
4063  return;
4064 }
4065
4066 /*---------------------------------------------------------------------------*/
4067
4068 int
4069 main(argc,argv)
4070      int argc;
4071      char **argv;
4072 {
4073   int c;
4074   char *progname = argv[0];
4075   unsigned int doarch = DEF_ISA;
4076   unsigned int features = 0; /* default state */
4077
4078   if (DEF_FP)
4079    features |= FEATURE_HASFPU;
4080   if (!DEF_PROC64)
4081    features |= FEATURE_PROC32;
4082   if (DEF_FPSINGLE)
4083    features |= FEATURE_FPSINGLE;
4084
4085   if (features & FEATURE_PROC32)
4086    features &= ~FEATURE_GP64;
4087   else
4088    features |= FEATURE_GP64;
4089
4090   while (1) {
4091     int option_index = 0;
4092     static struct option cmdline[] = {
4093       {"fast",    0,0,'f'},
4094       {"help",    0,0,'h'},
4095       {"warnings",0,0,'w'},
4096       {0,         0,0,0}
4097     };
4098    
4099     c = getopt_long(argc,argv,"hm:tw",cmdline,&option_index);
4100     if (c == -1)
4101      break ; /* out of the while loop */
4102
4103     switch (c) {
4104       case 'h' : /* help */
4105        usage(progname);
4106        exit(0);
4107
4108       case 'f' : /* fast */
4109        features |= FEATURE_FAST;
4110        break;
4111
4112       case 'w' : /* warnings */
4113        features |= FEATURE_WARNINGS;
4114        /* TODO: Future extension: Allow better control over the warnings generated:
4115         disable warnings                -wnone                                  ~FEATURE_WARNINGS
4116         all possible warnings           -wall                                   FEATURE_WARNINGS
4117         pipeline stall occuring         -wstall                                 FEATURE_WARN_STALL
4118         LO/HI corruption                -wlo or -whi or -wlohi or -whilo        FEATURE_WARN_HILO
4119         write to zero                   -wzero                                  FEATURE_WARN_ZERO       actually performed in external code - though we should set a manifest
4120         bad r31 use                     -wr31                                   FEATURE_WARN_R31
4121         undefined results               -wresult                                FEATURE_WARN_RESULT
4122        */
4123        break;
4124
4125       case 'm' : /* machine options */
4126        {
4127          int loop;
4128
4129          for (loop = 0; (machine_options[loop].name != 0); loop++)
4130           if (strncmp(machine_options[loop].name,optarg,strlen(machine_options[loop].name)) == 0) {
4131             char *loptarg = (optarg + strlen(machine_options[loop].name));
4132             switch (machine_options[loop].type) {
4133               case T_NONE :
4134                if (*loptarg) {
4135                  fprintf(stderr,"%s: Spurious characters \"%s\" at end of -m%s option\n",progname,loptarg,machine_options[loop].name);
4136                  exit(1);
4137                }
4138                features &= ~(machine_options[loop].mask);
4139                features |= machine_options[loop].value;
4140                break;
4141
4142               case T_NUM :
4143                if (*loptarg && *loptarg == '=')
4144                 loptarg++;
4145
4146                if (strcmp(machine_options[loop].name,"ips") == 0) {
4147                  unsigned int num;
4148
4149                  if (!*loptarg) {
4150                    fprintf(stderr,"%s: ISA number expected after -mips\n",progname);
4151                    exit(1);
4152                  }
4153
4154                  num = my_strtoul(loptarg,&loptarg,10);
4155
4156                  if ((num == ULONG_MAX) && (errno = ERANGE)) {
4157                    fprintf(stderr,"%s: Invalid number given to -mips option\n",progname);
4158                    exit(1);
4159                  }
4160
4161                  if (*loptarg) {
4162                    fprintf(stderr,"%s: Spurious trailing characters after ISA number \"%s\"\n",progname,loptarg);
4163                    exit(1);
4164                  }
4165
4166                  if (num > MASK_ISA) {
4167                    fprintf(stderr,"%s: ISA number %d outside acceptable range (0..%d)\n",progname,num,MASK_ISA);
4168                    exit(1);
4169                  }
4170
4171                  doarch = ((doarch & ~MASK_ISA) | num);
4172                  if ((num == 0) || (num > 2)) {
4173                    if ((features & FEATURE_PROC32) || !(features & FEATURE_GP64))
4174                     fprintf(stderr,"%s: Warning: -mips%d forcing -mgp64\n",progname,num);
4175                    features |= FEATURE_GP64;
4176                    features &= ~FEATURE_PROC32;
4177                  } else {
4178                    if (!(features & FEATURE_PROC32) || (features & FEATURE_GP64))
4179                     fprintf(stderr,"%s: Warning: -mips%d forcing -mgp32\n",progname,num);
4180                    features &= ~FEATURE_GP64;
4181                    features |= FEATURE_PROC32;
4182                  }
4183                } else {
4184                  fprintf(stderr,"%s: FATAL: Unrecognised (numeric) machine option -m%s\n",progname,optarg);
4185                  exit(1);
4186                }
4187                break;
4188
4189               case T_STRING :
4190                if (*loptarg && *loptarg == '=')
4191                 loptarg++;
4192
4193                if (strcmp(machine_options[loop].name,"cpu") == 0) {
4194                  int archloop;
4195
4196                  if (!*loptarg) {
4197                    fprintf(stderr,"%s: Architecture identifier expected after -mcpu\n",progname);
4198                    exit(1);
4199                  }
4200
4201                  for (archloop = 0; (available_architectures[archloop].name != 0); archloop++) {
4202                    if ((*loptarg == 'v') || (*loptarg == 'V'))
4203                     loptarg++;
4204
4205                    if ((*loptarg == 'r') || (*loptarg == 'R'))
4206                     loptarg++;
4207
4208                    if (strcmp(available_architectures[archloop].name,loptarg) == 0) {
4209                      doarch |= available_architectures[archloop].idflag;
4210                      break;
4211                    }
4212                  }
4213
4214                  if (available_architectures[archloop].name == 0) {
4215                    fprintf(stderr,"%s: Unrecognised MIPS architecture \"%s\"\n",progname,loptarg);
4216                    exit(1);
4217                  }
4218                } else {
4219                  fprintf(stderr,"%s: FATAL: Unrecognised (string) machine option -m%s\n",progname,optarg);
4220                  exit(1);
4221                }
4222                break;
4223
4224               default :
4225                fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",progname,machine_options[loop].type);
4226                exit(1);
4227             }
4228             break;
4229           }
4230
4231          if (machine_options[loop].name == 0) {
4232            fprintf(stderr,"%s: Unrecognised option: -m%s\n",progname,optarg);
4233            exit(1);
4234          }
4235        }
4236        break;
4237
4238       case '?' :
4239        /* An error message should already have been displayed */
4240        exit(1);
4241
4242       default :
4243        fprintf(stderr,"%s: FATAL: getopt returned unrecognised code 0x%08X\n",progname,c);
4244        exit(1);
4245     }
4246   }
4247
4248   if (optind < argc) {
4249     fprintf(stderr,"%s: Spurios non-option arguments ",progname);
4250     while (optind < argc)
4251      fprintf(stderr,"\"%s\" ",argv[optind++]);
4252     fprintf(stderr,"\n");
4253     exit(1);
4254   }
4255
4256   if ((features & FEATURE_FAST) && (features & FEATURE_WARNINGS))
4257    fprintf(stderr,"Warning: Fast model generation selected, along with trace or warnings.\n");
4258
4259   process_instructions(doarch,features) ;
4260   return(0) ;
4261 }
4262
4263 /*---------------------------------------------------------------------------*/
4264
4265 /* We can't assume that the compiler for the build system has strtoul,
4266    so we provide our own copy.  */
4267
4268 /*
4269  * Copyright (c) 1990 Regents of the University of California.
4270  * All rights reserved.
4271  *
4272  * Redistribution and use in source and binary forms, with or without
4273  * modification, are permitted provided that the following conditions
4274  * are met:
4275  * 1. Redistributions of source code must retain the above copyright
4276  *    notice, this list of conditions and the following disclaimer.
4277  * 2. Redistributions in binary form must reproduce the above copyright
4278  *    notice, this list of conditions and the following disclaimer in the
4279  *    documentation and/or other materials provided with the distribution.
4280  * 3. All advertising materials mentioning features or use of this software
4281  *    must display the following acknowledgement:
4282  *      This product includes software developed by the University of
4283  *      California, Berkeley and its contributors.
4284  * 4. Neither the name of the University nor the names of its contributors
4285  *    may be used to endorse or promote products derived from this software
4286  *    without specific prior written permission.
4287  *
4288  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4289  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4290  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4291  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4292  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4293  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4294  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4295  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4296  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4297  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4298  * SUCH DAMAGE.
4299  */
4300
4301 /*
4302  * Convert a string to an unsigned long integer.
4303  *
4304  * Ignores `locale' stuff.  Assumes that the upper and lower case
4305  * alphabets and digits are each contiguous.
4306  */
4307 static unsigned long
4308 my_strtoul(nptr, endptr, base)
4309         const char *nptr;
4310         char **endptr;
4311         register int base;
4312 {
4313         register const char *s = nptr;
4314         register unsigned long acc;
4315         register int c;
4316         register unsigned long cutoff;
4317         register int neg = 0, any, cutlim;
4318
4319         /*
4320          * See strtol for comments as to the logic used.
4321          */
4322         do {
4323                 c = *s++;
4324         } while (isspace(c));
4325         if (c == '-') {
4326                 neg = 1;
4327                 c = *s++;
4328         } else if (c == '+')
4329                 c = *s++;
4330         if ((base == 0 || base == 16) &&
4331             c == '0' && (*s == 'x' || *s == 'X')) {
4332                 c = s[1];
4333                 s += 2;
4334                 base = 16;
4335         }
4336         if (base == 0)
4337                 base = c == '0' ? 8 : 10;
4338         cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
4339         cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
4340         for (acc = 0, any = 0;; c = *s++) {
4341                 if (isdigit(c))
4342                         c -= '0';
4343                 else if (isalpha(c))
4344                         c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4345                 else
4346                         break;
4347                 if (c >= base)
4348                         break;
4349                 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
4350                         any = -1;
4351                 else {
4352                         any = 1;
4353                         acc *= base;
4354                         acc += c;
4355                 }
4356         }
4357         if (any < 0) {
4358                 acc = ULONG_MAX;
4359                 errno = ERANGE;
4360         } else if (neg)
4361                 acc = -acc;
4362         if (endptr != 0)
4363                 *endptr = (char *) (any ? s - 1 : nptr);
4364         return (acc);
4365 }
4366
4367 /*---------------------------------------------------------------------------*/
4368
4369 /*> EOF gencode.c <*/
4370
4371
4372
4373
4374
4375
4376