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