Correct flags for PMADDUW insn
[binutils-gdb.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, (ADDITION | 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) : (have_extendval ? 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