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