Move register definitions and macros out of interp.c and into sim-main.h
[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_io_eprintf(sd,\"Instruction has lo-order offset bits set in instruction\\n\");\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(" SignalExceptionIntegerOverflow ();\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(" SignalExceptionIntegerOverflow ();\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_io_eprintf(sd,\"MT (move-to) over-writing %s register value\\n\");\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(" DecodeCoproc(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_io_eprintf(sd,\"MADD16 operation with non-16bit operands\\n\");\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(" SignalExceptionCoProcessorUnusable ();\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_io_eprintf(sd,\"Branch with link using r31 as source operand\\n\");\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)%s));\n",
3460 ((insn->flags & RECIP) ? "Recip" : ""),
3461 ((insn->flags & RECIP) ? ",format" : ""));
3462 break ;
3463
3464 case FPCEIL:
3465 case FPFLOOR:
3466 case FPTRUNC:
3467 case FPROUND:
3468 {
3469 char *op = "";
3470 char *type = "";
3471
3472 switch (insn->type) {
3473 case FPCEIL:
3474 op = "FP_RM_TOPINF";
3475 break;
3476 case FPFLOOR:
3477 op = "FP_RM_TOMINF";
3478 break;
3479 case FPTRUNC:
3480 op = "FP_RM_TOZERO";
3481 break;
3482 case FPROUND:
3483 op = "FP_RM_NEAREST";
3484 break;
3485 default:
3486 fprintf(stderr,"Error: Handled missing for FP reason code %d\n",insn->type);
3487 exit(1);
3488 }
3489
3490 switch (GETDATASIZEINSN(insn)) {
3491 case WORD :
3492 type = "fmt_word";
3493 break;
3494 case DOUBLEWORD :
3495 type = "fmt_long";
3496 break;
3497 default:
3498 fprintf(stderr,"Error in instruction encoding table for FP %s operation (not WORD or DOUBLEWORD)\n",op);
3499 exit(1);
3500 }
3501 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
3502 printf(" SignalException(ReservedInstruction,instruction);\n");
3503 printf(" else\n");
3504 printf(" StoreFPR(destreg,%s,Convert(%s,ValueFPR(fs,format),format,%s));\n",type,op,type);
3505 }
3506 break ;
3507
3508 case FPCONVERT:
3509 {
3510 char *type = "";
3511 switch (GETDATASIZEINSN(insn)) {
3512 case SINGLE:
3513 type = "fmt_single";
3514 break;
3515 case DOUBLE:
3516 type = "fmt_double";
3517 break;
3518 case WORD:
3519 type = "fmt_word";
3520 break;
3521 case DOUBLEWORD:
3522 type = "fmt_long";
3523 break;
3524 default :
3525 fprintf(stderr,"Error: Unknown data size %d in FPCONVERT instruction\n",GETDATASIZEINSN(insn));
3526 exit(1);
3527 }
3528
3529 /* Not all combinations of conversion are valid at the
3530 moment: When converting to a fixed-point format, only
3531 floating-point sources are allowed. */
3532 printf(" if ((format == %s) | %s)\n",type,((insn->flags & FIXED) ? "((format == fmt_long) || (format == fmt_word))": "0"));
3533 printf(" SignalException(ReservedInstruction,instruction);\n");
3534 printf(" else\n");
3535 printf(" StoreFPR(destreg,%s,Convert(GETRM(),ValueFPR(fs,format),format,%s));\n",type,type);
3536 }
3537 break ;
3538
3539 case FPSUB:
3540 if (insn->flags & MULTIPLY) {
3541 char *type = "";
3542 switch (GETDATASIZEINSN(insn)) {
3543 case SINGLE:
3544 type = "fmt_single";
3545 break;
3546 case DOUBLE:
3547 type = "fmt_double";
3548 break;
3549 default:
3550 fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZEINSN(insn));
3551 exit(1);
3552 }
3553 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);
3554 } else {
3555 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
3556 printf(" SignalException(ReservedInstruction,instruction);\n");
3557 printf(" else\n");
3558 printf(" StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
3559 }
3560 break ;
3561
3562 case FPADD:
3563 if (insn->flags & MULTIPLY) {
3564 char *type = "";
3565 switch (GETDATASIZEINSN(insn)) {
3566 case SINGLE:
3567 type = "fmt_single";
3568 break;
3569 case DOUBLE:
3570 type = "fmt_double";
3571 break;
3572 default:
3573 fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZEINSN(insn));
3574 exit(1);
3575 }
3576 if (insn->flags & NOT)
3577 printf (" StoreFPR(destreg,%s,Negate(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
3578 type, type, type, type, type, type, type);
3579 else
3580 printf (" StoreFPR(destreg,%s,Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
3581 type, type, type, type, type, type);
3582 } else {
3583 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
3584 printf(" SignalException(ReservedInstruction,instruction);\n");
3585 printf(" else\n");
3586 printf(" StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
3587 }
3588 break ;
3589
3590 case FPCOMPARE:
3591 /* For the MIPS I,II or III there *MUST* be at least one
3592 instruction between the compare that sets a condition code
3593 and the branch that tests it. NOTE: However the hardware
3594 does not detect this condition. */
3595 /* Explicitly limit the operation to S and D formats: */
3596 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
3597 printf(" SignalException(ReservedInstruction,instruction);\n") ;
3598 printf(" else {\n");
3599 if (doisa < 4) {
3600 printf(" if (condition_code != 0)\n");
3601 printf(" SignalException(ReservedInstruction,instruction);\n") ;
3602 printf(" else\n");
3603 }
3604 printf(" {\n");
3605 printf(" int ignore = 0;\n");
3606 printf(" int less = 0;\n");
3607 printf(" int equal = 0;\n");
3608 printf(" int unordered = 1;\n");
3609 printf(" uword64 ofs = ValueFPR(fs,format);\n");
3610 printf(" uword64 oft = ValueFPR(ft,format);\n");
3611 printf(" if (NaN(ofs,format) || NaN(oft,format)) {\n");
3612 printf(" if (FCSR & FP_ENABLE(IO)) {\n");
3613 printf(" FCSR |= FP_CAUSE(IO);\n");
3614 printf(" SignalExceptionFPE ();\n");
3615 printf(" ignore = 1;\n");
3616 printf(" }\n");
3617 printf(" } else {\n");
3618 printf(" less = Less(ofs,oft,format);\n");
3619 printf(" equal = Equal(ofs,oft,format);\n");
3620 printf(" unordered = 0;\n");
3621 printf(" }\n");
3622 printf(" if (!ignore) {\n");
3623 printf(" int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered));\n");
3624 printf(" SETFCC(condition_code,condition);\n");
3625 printf(" }\n");
3626 printf(" }\n");
3627 printf(" }\n");
3628 break ;
3629
3630 case MADD:
3631 {
3632 char* pipeline = (insn->flags & PIPE1) ? "1" : "";
3633 int notsigned = (insn->flags & UNSIGNED);
3634 char* prodtype = notsigned ? "uword64" : "word64";
3635
3636 printf("%s prod = (%s)WORD64(WORD64LO(HI%s),WORD64LO(LO%s)) + ((%s)%s(op1%s) * (%s)%s(op2%s));\n",
3637 prodtype, prodtype, pipeline, pipeline,
3638 prodtype, (notsigned ? "WORD64LO" : "SIGNEXTEND"), (notsigned ? "" : ",32"),
3639 prodtype, (notsigned ? "WORD64LO" : "SIGNEXTEND"), (notsigned ? "" : ",32")
3640 );
3641 printf("LO%s = SIGNEXTEND(prod,32);\n", pipeline );
3642 printf("HI%s = SIGNEXTEND( WORD64HI(prod), 32);\n", pipeline );
3643 printf("if( destreg != 0 ) GPR[destreg] = LO%s;\n", pipeline );
3644 break;
3645 }
3646
3647 /* start-sanitize-r5900 */
3648 case MxSA:
3649 {
3650 if (insn->flags & TO)
3651 printf("SA = op1;\n");
3652 else
3653 printf("GPR[destreg] = SA;\n");
3654 break;
3655 }
3656
3657 case MTSAB:
3658 printf("SA = ((op1 & 0xF) ^ (op2 & 0xF)) * 8;\n");
3659 break;
3660
3661 case MTSAH:
3662 printf("SA = ((op1 & 0x7) ^ (op2 & 0x7)) * 16;\n");
3663 break;
3664
3665 case QFSRV:
3666 printf("int bytes = (SA / 8) %% 16;\n"); /* mod 16 to avoid garbage */
3667 printf("if (SA %% 8)\n");
3668 printf(" SignalException(ReservedInstruction,instruction);\n");
3669 printf("else\n");
3670 printf(" {\n");
3671 printf(" int i;\n");
3672 printf(" for(i=0;i<(16-bytes);i++)\n");
3673 printf(" GPR_SB(destreg,i) = RT_SB(bytes+i);\n");
3674 printf(" for(;i<16;i++)\n");
3675 printf(" GPR_SB(destreg,i) = RS_SB(i-(16-bytes));\n");
3676 printf(" }\n");
3677 break;
3678
3679 case PADD:
3680 {
3681 char* op = (insn->flags & SUBTRACT) ? "-" : "+";
3682 char* name = name_for_data_len( insn );
3683 char* letter = letter_for_data_len( insn );
3684
3685 char* tmptype;
3686 char* maximum;
3687 char* maxsat;
3688 char* minimum;
3689 char* signletter;
3690
3691 if ( insn->flags & UNSIGNED )
3692 {
3693 tmptype = type_for_data_len( insn, 0/*unsigned*/ );
3694 signletter = "U";
3695 maximum = umax_for_data_len( insn );
3696 maxsat = (insn->flags & SUBTRACT) ? "0" : maximum;
3697 minimum = 0;
3698 }
3699 else if ( insn->flags & SATURATE )
3700 {
3701 tmptype = type_for_data_len( insn, 1/*signed*/ );
3702 signletter = "S";
3703 maximum = max_for_data_len( insn );
3704 maxsat = maximum;
3705 minimum = min_for_data_len( insn );
3706 }
3707 else
3708 {
3709 tmptype = type_for_data_len( insn, 1/*signed*/ );
3710 signletter = "S";
3711 maximum = 0;
3712 maxsat = 0;
3713 minimum = 0;
3714 }
3715
3716 printf(" int i;\n");
3717 printf(" for (i=0; i < %sS_IN_MMI_REGS; i++)\n", name );
3718 printf(" {\n");
3719 printf(" %s s = RS_%s%s(i);\n", tmptype, signletter, letter);
3720 printf(" %s t = RT_%s%s(i);\n", tmptype, signletter, letter);
3721 printf(" %s r = s %s t;\n", tmptype, op);
3722 if ( maximum )
3723 {
3724 printf(" if (r > %s)\n", maximum);
3725 printf(" GPR_%s%s(destreg,i) = %s;\n", signletter, letter, maxsat );
3726 if ( minimum )
3727 {
3728 printf(" else if (r < %s)\n", minimum);
3729 printf(" GPR_%s%s(destreg,i) = %s;\n", signletter, letter, minimum );
3730 }
3731 printf(" else\n");
3732 printf(" ");
3733 }
3734 printf(" GPR_%s%s(destreg,i) = r;\n", signletter, letter );
3735 printf(" }\n");
3736 break;
3737 }
3738
3739 case PMULTH:
3740 {
3741 char* op;
3742 if ( insn->flags & SUBTRACT )
3743 op = "-";
3744 else if ( insn->flags & ADDITION )
3745 op = "+";
3746 else
3747 op = "";
3748
3749 printf("GPR_SW(destreg,0) = LO_SW(0) %s= (RS_SH(0) * RT_SH(0));\n", op);
3750 printf(" LO_SW(1) %s= (RS_SH(1) * RT_SH(1));\n", op);
3751 printf("GPR_SW(destreg,1) = HI_SW(0) %s= (RS_SH(2) * RT_SH(2));\n", op);
3752 printf(" HI_SW(1) %s= (RS_SH(3) * RT_SH(3));\n", op);
3753 printf("GPR_SW(destreg,2) = LO_SW(2) %s= (RS_SH(4) * RT_SH(4));\n", op);
3754 printf(" LO_SW(3) %s= (RS_SH(5) * RT_SH(5));\n", op);
3755 printf("GPR_SW(destreg,3) = HI_SW(2) %s= (RS_SH(6) * RT_SH(6));\n", op);
3756 printf(" HI_SW(3) %s= (RS_SH(7) * RT_SH(7));\n", op);
3757 break;
3758 }
3759
3760 case PMULTW:
3761 {
3762 char* op;
3763 char* sign = (insn->flags & UNSIGNED) ? "U" : "S";
3764 char* prodtype = (insn->flags & UNSIGNED) ? "unsigned64" : "signed64";
3765 char* constructor = (insn->flags & UNSIGNED) ? "UWORD64" : "WORD64";
3766
3767 if ( insn->flags & SUBTRACT )
3768 {
3769 op = "-";
3770 printf(" %s sum0 = %s( HI_SW(0), LO_SW(0) );\n", prodtype, constructor );
3771 printf(" %s sum1 = %s( HI_SW(2), LO_SW(2) );\n", prodtype, constructor );
3772 }
3773 else if ( insn->flags & ADDITION )
3774 {
3775 op = "+";
3776 printf(" %s sum0 = %s( HI_SW(0), LO_SW(0) );\n", prodtype, constructor );
3777 printf(" %s sum1 = %s( HI_SW(2), LO_SW(2) );\n", prodtype, constructor );
3778 }
3779 else
3780 {
3781 op = "";
3782 printf(" %s sum0 = 0;\n", prodtype );
3783 printf(" %s sum1 = 0;\n", prodtype );
3784 }
3785
3786 printf(" %s prod0 = (%s)RS_%sW(0) * (%s)RT_%sW(0);\n", prodtype, prodtype, sign, prodtype, sign );
3787 printf(" %s prod1 = (%s)RS_%sW(2) * (%s)RT_%sW(2);\n", prodtype, prodtype, sign, prodtype, sign );
3788
3789 printf(" sum0 %s= prod0;\n", op );
3790 printf(" sum1 %s= prod1;\n", op );
3791
3792 printf(" GPR_%sD(destreg,0) = sum0;\n", sign );
3793 printf(" GPR_%sD(destreg,1) = sum1;\n", sign );
3794
3795 printf(" LO = SIGNEXTEND( sum0, 32 );\n");
3796 printf(" HI = SIGNEXTEND( WORD64HI(sum0), 32 );\n");
3797 printf(" LO1 = SIGNEXTEND( sum1, 32 );\n");
3798 printf(" HI1 = SIGNEXTEND( WORD64HI(sum1), 32 );\n");
3799 break;
3800 }
3801
3802 case PDIVW:
3803 {
3804 char* sign = (insn->flags & UNSIGNED) ? "U" : "S";
3805 int i;
3806 for (i = 0; i < 2; i ++)
3807 {
3808 char hi = (i == 0 ? ' ' : '1');
3809 int d = i * 2;
3810 if (! (insn->flags & UNSIGNED))
3811 {
3812 printf("if (RT_SW(%d) == -1)\n", d );
3813 printf(" {\n");
3814 printf(" LO%c = -RS_%sW(%d);\n", hi, sign, d );
3815 printf(" HI%c = 0;\n", hi );
3816 printf(" }\nelse ");
3817 };
3818 printf("if (RT_UW(%d) != 0)\n", d );
3819 printf(" {\n");
3820 printf(" LO%c = (signed32)(RS_%sW(%d) / RT_%sW(%d));\n", hi, sign, d, sign, d );
3821 printf(" HI%c = (signed32)(RS_%sW(%d) %% RT_%sW(%d));\n", hi, sign, d, sign, d );
3822 printf(" }\n");
3823 }
3824 break;
3825 }
3826
3827 case PDIVBW:
3828 printf("signed32 devisor = RT_SH(0);\n");
3829 printf("if (devisor == -1)\n");
3830 printf(" {\n");
3831 printf(" LO_SW(0) = -RS_SW(0);\n");
3832 printf(" HI_SW(0) = 0;\n");
3833 printf(" LO_SW(1) = -RS_SW(1);\n");
3834 printf(" HI_SW(1) = 0;\n");
3835 printf(" LO_SW(2) = -RS_SW(2);\n");
3836 printf(" HI_SW(2) = 0;\n");
3837 printf(" LO_SW(3) = -RS_SW(3);\n");
3838 printf(" HI_SW(3) = 0;\n");
3839 printf(" }\n");
3840 printf("else if (devisor != 0)\n");
3841 printf(" {\n");
3842 printf(" LO_SW(0) = RS_SW(0) / devisor;\n");
3843 printf(" HI_SW(0) = SIGNEXTEND( (RS_SW(0) %% devisor), 16 );\n");
3844 printf(" LO_SW(1) = RS_SW(1) / devisor;\n");
3845 printf(" HI_SW(1) = SIGNEXTEND( (RS_SW(1) %% devisor), 16 );\n");
3846 printf(" LO_SW(2) = RS_SW(2) / devisor;\n");
3847 printf(" HI_SW(2) = SIGNEXTEND( (RS_SW(2) %% devisor), 16 );\n");
3848 printf(" LO_SW(3) = RS_SW(3) / devisor;\n");
3849 printf(" HI_SW(3) = SIGNEXTEND( (RS_SW(3) %% devisor), 16 );\n");
3850 printf(" }\n");
3851 break;
3852
3853 case PADSBH:
3854 printf("int i;\n");
3855 printf("for(i=0;i<HALFWORDS_IN_MMI_REGS/2;i++)\n");
3856 printf(" GPR_SH(destreg,i) = RS_SH(i) - RT_SH(i);\n");
3857 printf("for(;i<HALFWORDS_IN_MMI_REGS;i++)\n");
3858 printf(" GPR_SH(destreg,i) = RS_SH(i) + RT_SH(i);\n");
3859 break;
3860
3861 case PHMADDH:
3862 {
3863 char* op = (insn->flags & SUBTRACT) ? "-" : "+";
3864 printf("GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) %s (RS_SH(0) * RT_SH(0));\n", op );
3865 printf("GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) %s (RS_SH(2) * RT_SH(2));\n", op );
3866 printf("GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) %s (RS_SH(4) * RT_SH(4));\n", op );
3867 printf("GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) %s (RS_SH(6) * RT_SH(6));\n", op );
3868 }
3869 break;
3870
3871 case PSHIFT:
3872 {
3873 char* name = name_for_data_len( insn );
3874 char* letter = letter_for_data_len( insn );
3875 char* bits = bits_for_data_len( insn );
3876 char* shift = (insn->flags & RIGHT) ? ">>" : "<<";
3877 char* sign = (insn->flags & ARITHMETIC) ? "S" : "U";
3878
3879 printf("int shift_by = op1 & (%s-1);\n", bits );
3880 printf("int i;\n");
3881 printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3882 printf(" GPR_%s%s(destreg,i) = ", sign, letter );
3883 if ( insn->flags & ARITHMETIC )
3884 printf("SIGNEXTEND( ");
3885 printf("(RT_%s%s(i) %s shift_by)", sign, letter, shift );
3886 if ( insn->flags & ARITHMETIC )
3887 printf(", (%s-shift_by) )", bits );
3888 printf(";\n");
3889 break;
3890 }
3891
3892 case PSLLVW:
3893 printf("int s0 = (RS_UB(0) & 0x1F);\n");
3894 printf("int s1 = (RS_UB(8) & 0x1F);\n");
3895 printf("signed32 temp0 = RT_UW(0) << s0;\n");
3896 printf("signed32 temp1 = RT_UW(2) << s1;\n");
3897 printf("GPR_SD(destreg,0) = (signed64)temp0;\n");
3898 printf("GPR_SD(destreg,1) = (signed64)temp1;\n");
3899 break;
3900
3901 case PSRLVW:
3902 printf("GPR_UD(destreg,0) = SIGNEXTEND ( RT_UW(0) >> (RS_UB(0) & 0x1F), 31);\n");
3903 printf("GPR_UD(destreg,1) = SIGNEXTEND ( RT_UW(2) >> (RS_UB(8) & 0x1F), 31);\n");
3904 break;
3905
3906 case PSRAVW:
3907 printf("GPR_SD(destreg,0) = SIGNEXTEND( (RT_SW (0) >> (RS_UB(0) & 0x1F)), 32-(RS_UB(0) & 0x1F) );\n");
3908 printf("GPR_SD(destreg,1) = SIGNEXTEND( (RT_SW (2) >> (RS_UB(8) & 0x1F)), 32-(RS_UB(8) & 0x1F) );\n");
3909 break;
3910
3911 case POP:
3912 {
3913 char* op1;
3914 char* op2;
3915
3916 if ( GET_OP_FROM_INSN(insn) == POP_AND )
3917 {
3918 op1 = "&";
3919 op2 = "";
3920 }
3921 else if ( GET_OP_FROM_INSN(insn) == POP_OR )
3922 {
3923 op1 = "|";
3924 op2 = "";
3925 }
3926 else if ( GET_OP_FROM_INSN(insn) == POP_NOR )
3927 {
3928 op1 = "|";
3929 op2 = "~";
3930 }
3931 else if ( GET_OP_FROM_INSN(insn) == POP_XOR )
3932 {
3933 op1 = "^";
3934 op2 = "";
3935 }
3936
3937 printf("int i;\n");
3938 printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
3939 printf(" GPR_UW(destreg,i) = %s(RS_UW(i) %s RT_UW(i));\n", op2, op1 );
3940 break;
3941 }
3942
3943 case PCMP:
3944 {
3945 char* name = name_for_data_len( insn );
3946 char* letter = letter_for_data_len( insn );
3947 char* maximum = umax_for_data_len( insn );
3948 char* op = (insn->flags & GT) ? ">" : "==";
3949
3950 printf("int i;\n");
3951 printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3952 printf(" {\n");
3953 printf(" if (RS_S%s(i) %s RT_S%s(i)) GPR_S%s(destreg,i) = %s;\n",
3954 letter, op, letter, letter, maximum );
3955 printf(" else GPR_S%s(destreg,i) = 0;\n", letter );
3956 printf(" }\n");
3957 break;
3958 }
3959
3960 case PMAXMIN:
3961 {
3962 char* name = name_for_data_len( insn );
3963 char* letter = letter_for_data_len( insn );
3964 char* op = (insn->flags & GT) ? ">" : "<";
3965
3966 printf("int i;\n");
3967 printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3968 printf(" {\n");
3969 printf(" if (RS_S%s(i) %s RT_S%s(i)) GPR_S%s(destreg,i) = RS_S%s(i);\n",
3970 letter, op, letter, letter, letter );
3971 printf(" else GPR_S%s(destreg,i) = RT_S%s(i);\n", letter, letter );
3972 printf(" }\n");
3973 break;
3974 }
3975
3976 case PABS:
3977 {
3978 char* name = name_for_data_len( insn );
3979 char* letter = letter_for_data_len( insn );
3980 char* min = min_for_data_len( insn );
3981 char* max = max_for_data_len( insn );
3982
3983 printf("int i;\n");
3984 printf("for(i=0;i<%sS_IN_MMI_REGS;i++)\n", name );
3985 printf(" {\n");
3986 printf(" if (RT_S%s(i) >= 0)\n", letter );
3987 printf(" GPR_S%s(destreg,i) = RT_S%s(i);\n", letter, letter );
3988 printf(" else if (RT_S%s(i) == %s)\n", letter, min );
3989 printf(" GPR_S%s(destreg,i) = %s;\n", letter, max );
3990 printf(" else\n");
3991 printf(" GPR_S%s(destreg,i) = -RT_S%s(i);\n", letter, letter );
3992 printf(" }\n");
3993 break;
3994 }
3995
3996 case PCPYH:
3997 printf("GPR_UH(destreg,7) = GPR_UH(destreg,6) = GPR_UH(destreg,5) = GPR_UH(destreg,4) = RT_UH(4);\n");
3998 printf("GPR_UH(destreg,3) = GPR_UH(destreg,2) = GPR_UH(destreg,1) = GPR_UH(destreg,0) = RT_UH(0);\n");
3999 break;
4000
4001 case PCPYLD:
4002 printf("GPR_UD(destreg,0) = RT_UD(0);\n");
4003 printf("GPR_UD(destreg,1) = RS_UD(0);\n");
4004 break;
4005
4006 case PCPYUD:
4007 printf("GPR_UD(destreg,0) = RS_UD(1);\n");
4008 printf("GPR_UD(destreg,1) = RT_UD(1);\n");
4009 break;
4010
4011 case PEXCH:
4012 printf("GPR_UH(destreg,0) = RT_UH(0);\n");
4013 printf("GPR_UH(destreg,1) = RT_UH(2);\n");
4014 printf("GPR_UH(destreg,2) = RT_UH(1);\n");
4015 printf("GPR_UH(destreg,3) = RT_UH(3);\n");
4016 printf("GPR_UH(destreg,4) = RT_UH(4);\n");
4017 printf("GPR_UH(destreg,5) = RT_UH(6);\n");
4018 printf("GPR_UH(destreg,6) = RT_UH(5);\n");
4019 printf("GPR_UH(destreg,7) = RT_UH(7);\n");
4020 break;
4021
4022 case PEXCW:
4023 printf("GPR_UW(destreg,0) = RT_UW(0);\n");
4024 printf("GPR_UW(destreg,1) = RT_UW(2);\n");
4025 printf("GPR_UW(destreg,2) = RT_UW(1);\n");
4026 printf("GPR_UW(destreg,3) = RT_UW(3);\n");
4027 break;
4028
4029 case PEXOH:
4030 printf("GPR_UH(destreg,0) = RT_UH(2);\n");
4031 printf("GPR_UH(destreg,1) = RT_UH(1);\n");
4032 printf("GPR_UH(destreg,2) = RT_UH(0);\n");
4033 printf("GPR_UH(destreg,3) = RT_UH(3);\n");
4034 printf("GPR_UH(destreg,4) = RT_UH(6);\n");
4035 printf("GPR_UH(destreg,5) = RT_UH(5);\n");
4036 printf("GPR_UH(destreg,6) = RT_UH(4);\n");
4037 printf("GPR_UH(destreg,7) = RT_UH(7);\n");
4038 break;
4039
4040 case PEXOW:
4041 printf("GPR_UW(destreg,0) = RT_UW(2);\n");
4042 printf("GPR_UW(destreg,1) = RT_UW(1);\n");
4043 printf("GPR_UW(destreg,2) = RT_UW(0);\n");
4044 printf("GPR_UW(destreg,3) = RT_UW(3);\n");
4045 break;
4046
4047 case PEXTLB:
4048 printf("GPR_UB(destreg,0) = RT_UB(0);\n");
4049 printf("GPR_UB(destreg,1) = RS_UB(0);\n");
4050 printf("GPR_UB(destreg,2) = RT_UB(1);\n");
4051 printf("GPR_UB(destreg,3) = RS_UB(1);\n");
4052 printf("GPR_UB(destreg,4) = RT_UB(2);\n");
4053 printf("GPR_UB(destreg,5) = RS_UB(2);\n");
4054 printf("GPR_UB(destreg,6) = RT_UB(3);\n");
4055 printf("GPR_UB(destreg,7) = RS_UB(3);\n");
4056 printf("GPR_UB(destreg,8) = RT_UB(4);\n");
4057 printf("GPR_UB(destreg,9) = RS_UB(4);\n");
4058 printf("GPR_UB(destreg,10) = RT_UB(5);\n");
4059 printf("GPR_UB(destreg,11) = RS_UB(5);\n");
4060 printf("GPR_UB(destreg,12) = RT_UB(6);\n");
4061 printf("GPR_UB(destreg,13) = RS_UB(6);\n");
4062 printf("GPR_UB(destreg,14) = RT_UB(7);\n");
4063 printf("GPR_UB(destreg,15) = RS_UB(7);\n");
4064 break;
4065
4066 case PEXTLH:
4067 printf("GPR_UH(destreg,0) = RT_UH(0);\n");
4068 printf("GPR_UH(destreg,1) = RS_UH(0);\n");
4069 printf("GPR_UH(destreg,2) = RT_UH(1);\n");
4070 printf("GPR_UH(destreg,3) = RS_UH(1);\n");
4071 printf("GPR_UH(destreg,4) = RT_UH(2);\n");
4072 printf("GPR_UH(destreg,5) = RS_UH(2);\n");
4073 printf("GPR_UH(destreg,6) = RT_UH(3);\n");
4074 printf("GPR_UH(destreg,7) = RS_UH(3);\n");
4075 break;
4076
4077 case PEXTLW:
4078 printf("GPR_UW(destreg,0) = RT_UW(0);\n");
4079 printf("GPR_UW(destreg,1) = RS_UW(0);\n");
4080 printf("GPR_UW(destreg,2) = RT_UW(1);\n");
4081 printf("GPR_UW(destreg,3) = RS_UW(1);\n");
4082 break;
4083
4084 case PEXTUB:
4085 printf("GPR_UB(destreg,0) = RT_UB(8);\n");
4086 printf("GPR_UB(destreg,1) = RS_UB(8);\n");
4087 printf("GPR_UB(destreg,2) = RT_UB(9);\n");
4088 printf("GPR_UB(destreg,3) = RS_UB(9);\n");
4089 printf("GPR_UB(destreg,4) = RT_UB(10);\n");
4090 printf("GPR_UB(destreg,5) = RS_UB(10);\n");
4091 printf("GPR_UB(destreg,6) = RT_UB(11);\n");
4092 printf("GPR_UB(destreg,7) = RS_UB(11);\n");
4093 printf("GPR_UB(destreg,8) = RT_UB(12);\n");
4094 printf("GPR_UB(destreg,9) = RS_UB(12);\n");
4095 printf("GPR_UB(destreg,10) = RT_UB(13);\n");
4096 printf("GPR_UB(destreg,11) = RS_UB(13);\n");
4097 printf("GPR_UB(destreg,12) = RT_UB(14);\n");
4098 printf("GPR_UB(destreg,13) = RS_UB(14);\n");
4099 printf("GPR_UB(destreg,14) = RT_UB(15);\n");
4100 printf("GPR_UB(destreg,15) = RS_UB(15);\n");
4101 break;
4102
4103 case PEXTUH:
4104 printf("GPR_UH(destreg,0) = RT_UH(4);\n");
4105 printf("GPR_UH(destreg,1) = RS_UH(4);\n");
4106 printf("GPR_UH(destreg,2) = RT_UH(5);\n");
4107 printf("GPR_UH(destreg,3) = RS_UH(5);\n");
4108 printf("GPR_UH(destreg,4) = RT_UH(6);\n");
4109 printf("GPR_UH(destreg,5) = RS_UH(6);\n");
4110 printf("GPR_UH(destreg,6) = RT_UH(7);\n");
4111 printf("GPR_UH(destreg,7) = RS_UH(7);\n");
4112 break;
4113
4114 case PEXTUW:
4115 printf("GPR_UW(destreg,0) = RT_UW(2);\n");
4116 printf("GPR_UW(destreg,1) = RS_UW(2);\n");
4117 printf("GPR_UW(destreg,2) = RT_UW(3);\n");
4118 printf("GPR_UW(destreg,3) = RS_UW(3);\n");
4119 break;
4120
4121 case PPACB:
4122 printf("GPR_UB(destreg,0) = RT_UB(0);\n");
4123 printf("GPR_UB(destreg,1) = RT_UB(2);\n");
4124 printf("GPR_UB(destreg,2) = RT_UB(4);\n");
4125 printf("GPR_UB(destreg,3) = RT_UB(6);\n");
4126 printf("GPR_UB(destreg,4) = RT_UB(8);\n");
4127 printf("GPR_UB(destreg,5) = RT_UB(10);\n");
4128 printf("GPR_UB(destreg,6) = RT_UB(12);\n");
4129 printf("GPR_UB(destreg,7) = RT_UB(14);\n");
4130 printf("GPR_UB(destreg,8) = RS_UB(0);\n");
4131 printf("GPR_UB(destreg,9) = RS_UB(2);\n");
4132 printf("GPR_UB(destreg,10) = RS_UB(4);\n");
4133 printf("GPR_UB(destreg,11) = RS_UB(6);\n");
4134 printf("GPR_UB(destreg,12) = RS_UB(8);\n");
4135 printf("GPR_UB(destreg,13) = RS_UB(10);\n");
4136 printf("GPR_UB(destreg,14) = RS_UB(12);\n");
4137 printf("GPR_UB(destreg,15) = RS_UB(14);\n");
4138 break;
4139
4140 case PPACH:
4141 printf("GPR_UH(destreg,0) = RT_UH(0);\n");
4142 printf("GPR_UH(destreg,1) = RT_UH(2);\n");
4143 printf("GPR_UH(destreg,2) = RT_UH(4);\n");
4144 printf("GPR_UH(destreg,3) = RT_UH(6);\n");
4145 printf("GPR_UH(destreg,4) = RS_UH(0);\n");
4146 printf("GPR_UH(destreg,5) = RS_UH(2);\n");
4147 printf("GPR_UH(destreg,6) = RS_UH(4);\n");
4148 printf("GPR_UH(destreg,7) = RS_UH(6);\n");
4149 break;
4150
4151 case PPACW:
4152 printf("GPR_UW(destreg,0) = RT_UW(0);\n");
4153 printf("GPR_UW(destreg,1) = RT_UW(2);\n");
4154 printf("GPR_UW(destreg,2) = RS_UW(0);\n");
4155 printf("GPR_UW(destreg,3) = RS_UW(2);\n");
4156 break;
4157
4158 case PREVH:
4159 printf("GPR_UH(destreg,0) = RT_UH(3);\n");
4160 printf("GPR_UH(destreg,1) = RT_UH(2);\n");
4161 printf("GPR_UH(destreg,2) = RT_UH(1);\n");
4162 printf("GPR_UH(destreg,3) = RT_UH(0);\n");
4163 printf("GPR_UH(destreg,4) = RT_UH(7);\n");
4164 printf("GPR_UH(destreg,5) = RT_UH(6);\n");
4165 printf("GPR_UH(destreg,6) = RT_UH(5);\n");
4166 printf("GPR_UH(destreg,7) = RT_UH(4);\n");
4167 break;
4168
4169 case PROT3W:
4170 printf("GPR_UW(destreg,0) = RT_UW(0);\n");
4171 printf("GPR_UW(destreg,1) = RT_UW(3);\n");
4172 printf("GPR_UW(destreg,2) = RT_UW(1);\n");
4173 printf("GPR_UW(destreg,3) = RT_UW(2);\n");
4174 break;
4175
4176 case PINTH:
4177 printf("GPR_UH(destreg,0) = RT_UH(0);\n");
4178 printf("GPR_UH(destreg,1) = RS_UH(4);\n");
4179 printf("GPR_UH(destreg,2) = RT_UH(1);\n");
4180 printf("GPR_UH(destreg,3) = RS_UH(5);\n");
4181 printf("GPR_UH(destreg,4) = RT_UH(2);\n");
4182 printf("GPR_UH(destreg,5) = RS_UH(6);\n");
4183 printf("GPR_UH(destreg,6) = RT_UH(3);\n");
4184 printf("GPR_UH(destreg,7) = RS_UH(7);\n");
4185 break;
4186
4187 case PINTOH:
4188 printf("GPR_UH(destreg,0) = RT_UH(0);\n");
4189 printf("GPR_UH(destreg,1) = RS_UH(0);\n");
4190 printf("GPR_UH(destreg,2) = RT_UH(2);\n");
4191 printf("GPR_UH(destreg,3) = RS_UH(2);\n");
4192 printf("GPR_UH(destreg,4) = RT_UH(4);\n");
4193 printf("GPR_UH(destreg,5) = RS_UH(4);\n");
4194 printf("GPR_UH(destreg,6) = RT_UH(6);\n");
4195 printf("GPR_UH(destreg,7) = RS_UH(6);\n");
4196 break;
4197
4198 case PMXX: /* Parallel move HI or LO / TO or FROM */
4199 {
4200 if ( (insn->flags & (HI|FROM)) == (HI|FROM) )
4201 {
4202 printf("GPR_SD(destreg,0) = HI;\n");
4203 printf("GPR_SD(destreg,1) = HI1;\n");
4204 }
4205 else if ( (insn->flags & (LO|FROM)) == (LO|FROM) )
4206 {
4207 printf("GPR_SD(destreg,0) = LO;\n");
4208 printf("GPR_SD(destreg,1) = LO1;\n");
4209 }
4210 else if ( (insn->flags & (HI|TO)) == (HI|TO) )
4211 {
4212 printf("HI = RS_SD(0);\n");
4213 printf("HI1 = RS_SD(1);\n");
4214 }
4215 else if ( (insn->flags & (LO|TO)) == (LO|TO) )
4216 {
4217 printf("LO = RS_SD(0);\n");
4218 printf("LO1 = RS_SD(1);\n");
4219 }
4220 break;
4221 }
4222
4223 case PMTHL:
4224 printf("LO_UW(0) = RS_UW(0);\n");
4225 printf("HI_UW(0) = RS_UW(1);\n");
4226 printf("LO_UW(2) = RS_UW(2);\n");
4227 printf("HI_UW(2) = RS_UW(3);\n");
4228 break;
4229
4230 case PMFHL:
4231 printf("if (op1 == 0)\n");
4232 printf(" {\n");
4233 printf(" GPR_UW(destreg,0) = LO_UW(0);\n");
4234 printf(" GPR_UW(destreg,1) = HI_UW(0);\n");
4235 printf(" GPR_UW(destreg,2) = LO_UW(2);\n");
4236 printf(" GPR_UW(destreg,3) = HI_UW(2);\n");
4237 printf(" }\n");
4238 printf("else if (op1 == 1)\n");
4239 printf(" {\n");
4240 printf(" GPR_UW(destreg,0) = LO_UW(1);\n");
4241 printf(" GPR_UW(destreg,1) = HI_UW(1);\n");
4242 printf(" GPR_UW(destreg,2) = LO_UW(3);\n");
4243 printf(" GPR_UW(destreg,3) = HI_UW(3);\n");
4244 printf(" }\n");
4245 printf("else if (op1 == 2)\n");
4246 printf(" {\n");
4247 printf(" /* NOTE: This code implements a saturate according to the\n");
4248 printf(" figure on page B-115 and not according to the\n");
4249 printf(" definition on page B-113 */\n");
4250 printf(" signed64 t = ((unsigned64)HI_UW(0) << 32) | (unsigned64)LO_UW(0);\n");
4251 printf(" signed64 u = ((unsigned64)HI_UW(2) << 32) | (unsigned64)LO_UW(2);\n");
4252 printf(" if ( t > SIGNED64 (0x000000007FFFFFFF) )\n");
4253 printf(" GPR_SD(destreg,0) = SIGNED64 (0x000000007FFFFFFF);\n");
4254 printf(" else if ( t < - SIGNED64 (0x0000000080000000) )\n");
4255 printf(" GPR_SD(destreg,0) = - SIGNED64 (0x0000000080000000);\n");
4256 printf(" else\n");
4257 printf(" GPR_SD(destreg,0) = t;\n");
4258 printf(" if ( u > SIGNED64 (0x000000007FFFFFFF) )\n");
4259 printf(" GPR_SD(destreg,1) = SIGNED64 (0x000000007FFFFFFF);\n");
4260 printf(" else if ( u < - SIGNED64 (0x0000000080000000) )\n");
4261 printf(" GPR_SD(destreg,1) = - SIGNED64 (0x0000000080000000);\n");
4262 printf(" else\n");
4263 printf(" GPR_SD(destreg,1) = u;\n");
4264 printf(" }\n");
4265 printf("else if (op1 == 3)\n");
4266 printf(" {\n");
4267 printf(" GPR_UH(destreg,0) = LO_UH(0);\n");
4268 printf(" GPR_UH(destreg,1) = LO_UH(2);\n");
4269 printf(" GPR_UH(destreg,2) = HI_UH(0);\n");
4270 printf(" GPR_UH(destreg,3) = HI_UH(2);\n");
4271 printf(" GPR_UH(destreg,4) = LO_UH(4);\n");
4272 printf(" GPR_UH(destreg,5) = LO_UH(6);\n");
4273 printf(" GPR_UH(destreg,6) = HI_UH(4);\n");
4274 printf(" GPR_UH(destreg,7) = HI_UH(6);\n");
4275 printf(" }\n");
4276 printf("else if (op1 == 4)\n");
4277 printf(" {\n");
4278 printf(" if (LO_SW(0) > 0x7FFF)\n");
4279 printf(" GPR_UH(destreg,0) = 0x7FFF;\n");
4280 printf(" else if (LO_SW(0) < -0x8000)\n");
4281 printf(" GPR_UH(destreg,0) = 0x8000;\n");
4282 printf(" else\n");
4283 printf(" GPR_UH(destreg,0) = LO_UH(0);\n");
4284
4285 printf(" if (LO_SW(1) > 0x7FFF)\n");
4286 printf(" GPR_UH(destreg,1) = 0x7FFF;\n");
4287 printf(" else if (LO_SW(1) < -0x8000)\n");
4288 printf(" GPR_UH(destreg,1) = 0x8000;\n");
4289 printf(" else\n");
4290 printf(" GPR_UH(destreg,1) = LO_UH(2);\n");
4291
4292 printf(" if (HI_SW(0) > 0x7FFF)\n");
4293 printf(" GPR_UH(destreg,2) = 0x7FFF;\n");
4294 printf(" else if (HI_SW(0) < -0x8000)\n");
4295 printf(" GPR_UH(destreg,2) = 0x8000;\n");
4296 printf(" else\n");
4297 printf(" GPR_UH(destreg,2) = HI_UH(0);\n");
4298
4299 printf(" if (HI_SW(1) > 0x7FFF)\n");
4300 printf(" GPR_UH(destreg,3) = 0x7FFF;\n");
4301 printf(" else if (HI_SW(1) < -0x8000)\n");
4302 printf(" GPR_UH(destreg,3) = 0x8000;\n");
4303 printf(" else\n");
4304 printf(" GPR_UH(destreg,3) = HI_UH(2);\n");
4305
4306 printf(" if (LO_SW(2) > 0x7FFF)\n");
4307 printf(" GPR_UH(destreg,4) = 0x7FFF;\n");
4308 printf(" else if (LO_SW(2) < -0x8000)\n");
4309 printf(" GPR_UH(destreg,4) = 0x8000;\n");
4310 printf(" else\n");
4311 printf(" GPR_UH(destreg,4) = LO_UH(4);\n");
4312
4313 printf(" if (LO_SW(3) > 0x7FFF)\n");
4314 printf(" GPR_UH(destreg,5) = 0x7FFF;\n");
4315 printf(" else if (LO_SW(3) < -0x8000)\n");
4316 printf(" GPR_UH(destreg,5) = 0x8000;\n");
4317 printf(" else\n");
4318 printf(" GPR_UH(destreg,5) = LO_UH(6);\n");
4319
4320 printf(" if (HI_SW(2) > 0x7FFF)\n");
4321 printf(" GPR_UH(destreg,6) = 0x7FFF;\n");
4322 printf(" else if (HI_SW(2) < -0x8000)\n");
4323 printf(" GPR_UH(destreg,6) = 0x8000;\n");
4324 printf(" else\n");
4325 printf(" GPR_UH(destreg,6) = HI_UH(4);\n");
4326
4327 printf(" if (HI_SW(3) > 0x7FFF)\n");
4328 printf(" GPR_UH(destreg,7) = 0x7FFF;\n");
4329 printf(" else if (HI_SW(3) < -0x8000)\n");
4330 printf(" GPR_UH(destreg,7) = 0x8000;\n");
4331 printf(" else\n");
4332 printf(" GPR_UH(destreg,7) = HI_UH(6);\n");
4333
4334 printf(" }\n");
4335 break;
4336
4337 case PLZCW:
4338 printf("unsigned long value;\n");
4339 printf("int test;\n");
4340 printf("int count;\n");
4341 printf("int i;\n");
4342
4343 printf("value = RS_UW(0);\n");
4344 printf("count = 0;\n");
4345 printf("test = !!(value & (1 << 31));\n");
4346 printf("for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)\n");
4347 printf(" count++;\n");
4348 printf("GPR_UW(destreg,0) = count;\n");
4349
4350 printf("value = RS_UW(1);\n");
4351 printf("count = 0;\n");
4352 printf("test = !!(value & (1 << 31));\n");
4353 printf("for(i=30; i>=0 && (test == !!(value & (1 << i))); i--)\n");
4354 printf(" count++;\n");
4355 printf("GPR_UW(destreg,1) = count;\n");
4356 break;
4357
4358 case PEXT5:
4359 printf("int i;\n");
4360 printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
4361 printf(" {\n");
4362 printf(" unsigned32 x = RT_UW(i);\n");
4363 printf(" GPR_UW(destreg,i) = ((x & (1 << 15)) << (31 - 15)) \n");
4364 printf(" | ((x & (31 << 10)) << (19 - 10)) \n");
4365 printf(" | ((x & (31 << 5)) << (11 - 5)) \n");
4366 printf(" | ((x & (31 << 0)) << (3 - 0)); \n");
4367 printf(" }\n");
4368 break;
4369
4370 case PPAC5:
4371 printf("int i;\n");
4372 printf("for(i=0;i<WORDS_IN_MMI_REGS;i++)\n");
4373 printf(" {\n");
4374 printf(" unsigned32 x = RT_UW(i);\n");
4375 printf(" GPR_UW(destreg,i) = ((x & (1 << 31)) >> (31 - 15)) \n");
4376 printf(" | ((x & (31 << 19)) >> (19 - 10)) \n");
4377 printf(" | ((x & (31 << 11)) >> (11 - 5)) \n");
4378 printf(" | ((x & (31 << 3)) >> (3 - 0)); \n");
4379 printf(" }\n");
4380 break;
4381 /* end-sanitize-r5900 */
4382
4383 case NYI:
4384 fprintf(stderr,"Warning: Unimplemented opcode: %s\n",insn->name) ;
4385
4386 printf("SignalException(ReservedInstruction,instruction);\n");
4387 break;
4388
4389 default:
4390 fprintf(stderr,"Unrecognised opcode type %d\n",insn->type) ;
4391 exit(6) ;
4392 }
4393 }
4394
4395 /*---------------------------------------------------------------------------*/
4396
4397 /* The command-line feature controls are presented in a similar style
4398 to those offered by GCC, in the aim of providing a consistent
4399 interface to the user. */
4400 typedef enum {
4401 T_NONE, /* no argument - mask and value fields control "feature" definition */
4402 T_NUM, /* numeric argument - optionally preceded by '=' - mask field defines maximum value */
4403 T_STRING /* string argument - optionally prcededed by '=' */
4404 } mactypes;
4405
4406 struct {
4407 char *name;
4408 mactypes type;
4409 unsigned int mask;
4410 unsigned int value;
4411 char *desc;
4412 } machine_options[] = {
4413 {"ips", T_NUM, MASK_ISA,0,"\tSelect MIPS ISA version"},
4414 {"cpu", T_STRING,0,0,"\t\tSelect particular MIPS architecture"},
4415 {"gp64", T_NONE, FEATURE_GP64,FEATURE_GP64,"\t\t\tSelect 64bit GP registers"},
4416 {"gp32", T_NONE, FEATURE_GP64,0,"\t\t\tSelect 32bit GP registers"},
4417 {"no-fp", T_NONE, FEATURE_HASFPU,0,"\t\tDisable FP simulation"},
4418 {"single-float",T_NONE, (FEATURE_FPSINGLE | FEATURE_HASFPU),(FEATURE_FPSINGLE | FEATURE_HASFPU),"\t\tSelect single precision only FPU"},
4419 {"double-float",T_NONE, (FEATURE_FPSINGLE | FEATURE_HASFPU),FEATURE_HASFPU,"\t\tSelect double precision FPU"},
4420 {0, T_NONE, 0,0}
4421 };
4422
4423 /* The following architecture identies are those accepted by the "-mcpu" option: */
4424 struct architectures {
4425 const char *name; /* ASCII string identifier for command-line, no white-space allowed */
4426 unsigned int idflag; /* or-ed into "isa" value */
4427 };
4428
4429 static const struct architectures available_architectures[] = {
4430 {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
4431 {"3900",ARCH_R3900}, /* Toshiba R3900 (TX39) */
4432 /* start-sanitize-tx19 */
4433 {"1900",ARCH_R3900}, /* Toshiba R1900 (TX19) */
4434 /* end-sanitize-tx19 */
4435 /* start-sanitize-r5900 */
4436 {"5900",ARCH_R5900},
4437 /* end-sanitize-r5900 */
4438 {0, 0} /* terminator */
4439 };
4440
4441 /*---------------------------------------------------------------------------*/
4442
4443 static void
4444 usage(name)
4445 char *name;
4446 {
4447 int loop;
4448
4449 fprintf(stderr,"%s: Construct a MIPS simulator engine.\n",name);
4450
4451 fprintf(stderr,"\
4452 The output of this program is a block of 'C' code designed to be\n\
4453 included into the main simulation control loop of a device specific\n\
4454 simulator.\n");
4455
4456 fprintf(stderr,"\nOptions:\n");
4457 fprintf(stderr," -h --help\t\tProvide this help text\n");
4458 fprintf(stderr," -f --fast\t\tProvide the fastest possible engine (i.e. no statistics)\n");
4459 fprintf(stderr," -w --warnings\t\tEnable all the simulator engine warnings\n");
4460
4461 for (loop = 0; (machine_options[loop].name != 0); loop++) {
4462 fprintf(stderr," -m%s",machine_options[loop].name);
4463 switch (machine_options[loop].type) {
4464 case T_NUM :
4465 fprintf(stderr,"N (range 0..%d)",machine_options[loop].mask);
4466 case T_NONE :
4467 break;
4468
4469 case T_STRING :
4470 fprintf(stderr,"=name");
4471 break;
4472
4473 default :
4474 fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",name,machine_options[loop].type);
4475 exit(1);
4476 }
4477 fprintf(stderr,"%s\n",machine_options[loop].desc);
4478 }
4479
4480 fprintf(stderr,"\nAvailable \"-mcpu\" architectures: ");
4481 for (loop = 0; (available_architectures[loop].name != 0); loop++)
4482 fprintf(stderr,"%s ",available_architectures[loop].name);
4483 fprintf(stderr,"\n\n");
4484
4485 fprintf(stderr,"\
4486 The \"trace\" and \"warnings\" options do not define the output stream.\n\
4487 They only inform the code that includes the constructed engine to provide\n\
4488 the required features.\n\n\
4489 The \"-mips0\" option forces the construction of a simulator supporting\n\
4490 the highest available MIPS ISA supported.\n");
4491
4492 return;
4493 }
4494
4495 /*---------------------------------------------------------------------------*/
4496
4497 int
4498 main(argc,argv)
4499 int argc;
4500 char **argv;
4501 {
4502 int c;
4503 char *progname = argv[0];
4504 unsigned int doarch = DEF_ISA;
4505 unsigned int features = 0; /* default state */
4506
4507 if (DEF_FP)
4508 features |= FEATURE_HASFPU;
4509 if (!DEF_PROC64)
4510 features |= FEATURE_PROC32;
4511 if (DEF_FPSINGLE)
4512 features |= FEATURE_FPSINGLE;
4513
4514 if (features & FEATURE_PROC32)
4515 features &= ~FEATURE_GP64;
4516 else
4517 features |= FEATURE_GP64;
4518
4519 while (1) {
4520 int option_index = 0;
4521 static struct option cmdline[] = {
4522 {"fast", 0,0,'f'},
4523 {"help", 0,0,'h'},
4524 {"warnings",0,0,'w'},
4525 {"igen", 0,0,'i'},
4526 {0, 0,0,0}
4527 };
4528
4529 c = getopt_long(argc,argv,"hm:tw",cmdline,&option_index);
4530 if (c == -1)
4531 break ; /* out of the while loop */
4532
4533 switch (c) {
4534 case 'h' : /* help */
4535 usage(progname);
4536 exit(0);
4537
4538 case 'f' : /* fast */
4539 features |= FEATURE_FAST;
4540 break;
4541
4542 case 'i' : /* igen formatted output */
4543 features |= FEATURE_IGEN;
4544 break;
4545
4546 case 'w' : /* warnings */
4547 features |= FEATURE_WARNINGS;
4548 /* TODO: Future extension: Allow better control over the warnings generated:
4549 disable warnings -wnone ~FEATURE_WARNINGS
4550 all possible warnings -wall FEATURE_WARNINGS
4551 pipeline stall occuring -wstall FEATURE_WARN_STALL
4552 LO/HI corruption -wlo or -whi or -wlohi or -whilo FEATURE_WARN_HILO
4553 write to zero -wzero FEATURE_WARN_ZERO actually performed in external code - though we should set a manifest
4554 bad r31 use -wr31 FEATURE_WARN_R31
4555 undefined results -wresult FEATURE_WARN_RESULT
4556 */
4557 break;
4558
4559 case 'm' : /* machine options */
4560 {
4561 int loop;
4562
4563 for (loop = 0; (machine_options[loop].name != 0); loop++)
4564 if (strncmp(machine_options[loop].name,optarg,strlen(machine_options[loop].name)) == 0) {
4565 char *loptarg = (optarg + strlen(machine_options[loop].name));
4566 switch (machine_options[loop].type) {
4567 case T_NONE :
4568 if (*loptarg) {
4569 fprintf(stderr,"%s: Spurious characters \"%s\" at end of -m%s option\n",progname,loptarg,machine_options[loop].name);
4570 exit(1);
4571 }
4572 features &= ~(machine_options[loop].mask);
4573 features |= machine_options[loop].value;
4574 break;
4575
4576 case T_NUM :
4577 if (*loptarg && *loptarg == '=')
4578 loptarg++;
4579
4580 if (strcmp(machine_options[loop].name,"ips") == 0) {
4581 unsigned int num;
4582
4583 if (!*loptarg) {
4584 fprintf(stderr,"%s: ISA number expected after -mips\n",progname);
4585 exit(1);
4586 }
4587
4588 num = my_strtoul(loptarg,&loptarg,10);
4589
4590 if ((num == ULONG_MAX) && (errno = ERANGE)) {
4591 fprintf(stderr,"%s: Invalid number given to -mips option\n",progname);
4592 exit(1);
4593 }
4594
4595 if (*loptarg) {
4596 fprintf(stderr,"%s: Spurious trailing characters after ISA number \"%s\"\n",progname,loptarg);
4597 exit(1);
4598 }
4599
4600 if (num > MASK_ISA) {
4601 fprintf(stderr,"%s: ISA number %d outside acceptable range (0..%d)\n",progname,num,MASK_ISA);
4602 exit(1);
4603 }
4604
4605 doarch = ((doarch & ~MASK_ISA) | num);
4606 if ((num == 0) || (num > 2)) {
4607 if ((features & FEATURE_PROC32) || !(features & FEATURE_GP64))
4608 fprintf(stderr,"%s: Warning: -mips%d forcing -mgp64\n",progname,num);
4609 features |= FEATURE_GP64;
4610 features &= ~FEATURE_PROC32;
4611 } else {
4612 if (!(features & FEATURE_PROC32) || (features & FEATURE_GP64))
4613 fprintf(stderr,"%s: Warning: -mips%d forcing -mgp32\n",progname,num);
4614 features &= ~FEATURE_GP64;
4615 features |= FEATURE_PROC32;
4616 }
4617 } else {
4618 fprintf(stderr,"%s: FATAL: Unrecognised (numeric) machine option -m%s\n",progname,optarg);
4619 exit(1);
4620 }
4621 break;
4622
4623 case T_STRING :
4624 if (*loptarg && *loptarg == '=')
4625 loptarg++;
4626
4627 if (strcmp(machine_options[loop].name,"cpu") == 0) {
4628 int archloop;
4629
4630 if (!*loptarg) {
4631 fprintf(stderr,"%s: Architecture identifier expected after -mcpu\n",progname);
4632 exit(1);
4633 }
4634
4635 for (archloop = 0; (available_architectures[archloop].name != 0); archloop++) {
4636 if ((*loptarg == 'v') || (*loptarg == 'V'))
4637 loptarg++;
4638
4639 if ((*loptarg == 'r') || (*loptarg == 'R'))
4640 loptarg++;
4641
4642 if (strcmp(available_architectures[archloop].name,loptarg) == 0) {
4643 doarch |= available_architectures[archloop].idflag;
4644 break;
4645 }
4646 }
4647
4648 if (available_architectures[archloop].name == 0) {
4649 fprintf(stderr,"%s: Unrecognised MIPS architecture \"%s\"\n",progname,loptarg);
4650 exit(1);
4651 }
4652 } else {
4653 fprintf(stderr,"%s: FATAL: Unrecognised (string) machine option -m%s\n",progname,optarg);
4654 exit(1);
4655 }
4656 break;
4657
4658 default :
4659 fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",progname,machine_options[loop].type);
4660 exit(1);
4661 }
4662 break;
4663 }
4664
4665 if (machine_options[loop].name == 0) {
4666 fprintf(stderr,"%s: Unrecognised option: -m%s\n",progname,optarg);
4667 exit(1);
4668 }
4669 }
4670 break;
4671
4672 case '?' :
4673 /* An error message should already have been displayed */
4674 exit(1);
4675
4676 default :
4677 fprintf(stderr,"%s: FATAL: getopt returned unrecognised code 0x%08X\n",progname,c);
4678 exit(1);
4679 }
4680 }
4681
4682 if (optind < argc) {
4683 fprintf(stderr,"%s: Spurios non-option arguments ",progname);
4684 while (optind < argc)
4685 fprintf(stderr,"\"%s\" ",argv[optind++]);
4686 fprintf(stderr,"\n");
4687 exit(1);
4688 }
4689
4690 if ((features & FEATURE_FAST) && (features & FEATURE_WARNINGS))
4691 fprintf(stderr,"Warning: Fast model generation selected, along with trace or warnings.\n");
4692
4693 process_instructions(doarch,features) ;
4694 return(0) ;
4695 }
4696
4697 /*---------------------------------------------------------------------------*/
4698
4699 /* We can't assume that the compiler for the build system has strtoul,
4700 so we provide our own copy. */
4701
4702 /*
4703 * Copyright (c) 1990 Regents of the University of California.
4704 * All rights reserved.
4705 *
4706 * Redistribution and use in source and binary forms, with or without
4707 * modification, are permitted provided that the following conditions
4708 * are met:
4709 * 1. Redistributions of source code must retain the above copyright
4710 * notice, this list of conditions and the following disclaimer.
4711 * 2. Redistributions in binary form must reproduce the above copyright
4712 * notice, this list of conditions and the following disclaimer in the
4713 * documentation and/or other materials provided with the distribution.
4714 * 3. All advertising materials mentioning features or use of this software
4715 * must display the following acknowledgement:
4716 * This product includes software developed by the University of
4717 * California, Berkeley and its contributors.
4718 * 4. Neither the name of the University nor the names of its contributors
4719 * may be used to endorse or promote products derived from this software
4720 * without specific prior written permission.
4721 *
4722 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
4723 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4724 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4725 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
4726 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4727 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4728 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4729 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4730 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4731 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4732 * SUCH DAMAGE.
4733 */
4734
4735 /*
4736 * Convert a string to an unsigned long integer.
4737 *
4738 * Ignores `locale' stuff. Assumes that the upper and lower case
4739 * alphabets and digits are each contiguous.
4740 */
4741 static unsigned long
4742 my_strtoul(nptr, endptr, base)
4743 const char *nptr;
4744 char **endptr;
4745 register int base;
4746 {
4747 register const char *s = nptr;
4748 register unsigned long acc;
4749 register int c;
4750 register unsigned long cutoff;
4751 register int neg = 0, any, cutlim;
4752
4753 /*
4754 * See strtol for comments as to the logic used.
4755 */
4756 do {
4757 c = *s++;
4758 } while (isspace(c));
4759 if (c == '-') {
4760 neg = 1;
4761 c = *s++;
4762 } else if (c == '+')
4763 c = *s++;
4764 if ((base == 0 || base == 16) &&
4765 c == '0' && (*s == 'x' || *s == 'X')) {
4766 c = s[1];
4767 s += 2;
4768 base = 16;
4769 }
4770 if (base == 0)
4771 base = c == '0' ? 8 : 10;
4772 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
4773 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
4774 for (acc = 0, any = 0;; c = *s++) {
4775 if (isdigit(c))
4776 c -= '0';
4777 else if (isalpha(c))
4778 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
4779 else
4780 break;
4781 if (c >= base)
4782 break;
4783 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
4784 any = -1;
4785 else {
4786 any = 1;
4787 acc *= base;
4788 acc += c;
4789 }
4790 }
4791 if (any < 0) {
4792 acc = ULONG_MAX;
4793 errno = ERANGE;
4794 } else if (neg)
4795 acc = -acc;
4796 if (endptr != 0)
4797 *endptr = (char *) (any ? s - 1 : nptr);
4798 return (acc);
4799 }
4800
4801 /*---------------------------------------------------------------------------*/
4802
4803 /*> EOF gencode.c <*/
This page took 0.208733 seconds and 5 git commands to generate.