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