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