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