* ecoff.c (ecoff_directive_endef): Avoid a division by zero error
[deliverable/binutils-gdb.git] / sim / mips / gencode.c
CommitLineData
8ad57737 1/*> gencode.c <*/
a647a859
JSC
2/* Instruction handling support for the MIPS architecture simulator.
3
4 This file is part of the MIPS sim
5
6 THIS SOFTWARE IS NOT COPYRIGHTED
7
8 Cygnus offers the following for use in the public domain. Cygnus
9 makes no warranty with regard to the software or it's performance
10 and the user accepts the software "AS IS" with all faults.
11
12 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
16 $Revision$
17 $Author$
18 $Date$
19*/
8ad57737
JSC
20
21#if 0
22#define DEBUG (1) /* Just for testing */
23#endif
24
25/* The Makefile currently defines "INSIDE_SIMULATOR" as part of the
26 build. It is not currently used by the MIPS simulator world
27 though. */
28
29/* All output sent to stdout is for the simulator engine. All program
30 related warnings and errors should be sent to stderr. */
31
32/* The simulator decode table is constructed this way to allow the
33 minimal code required for a particular instruction type to be
34 coded. This avoids a large simulator source file, with lots of
35 build-time conditionals controlling what code is included. However
36 this two-stage process does mean that care must be taken to ensure
37 that the correct decoding source is generated for a particular MIPS
38 simulator. */
39
40/* Notes:
41
42 We could provide pipeline modelling by splitting the simulation of
43 instructions into seperate bytecodes for each pipeline
44 stage. e.g. for the VR4300 each instruction would generate 5
45 bytecodes, one for each pipeline stage. The simulator control would
46 then insert these into the relevant pipeline slots, and execute a
47 complete slots worth of bytecodes. However, the shape of the
48 pipeline, and what parts of each instruction are executed in each
49 pipeline stage, are different between MIPS implementations. If we
50 were to construct a simulator for a particular MIPS architecture
51 this would be a good solution.
52
53 To avoid having to provide multiple different pipeline models, a
54 simple approach for dealing with the delay slots, and register
55 dependencies has been used. The "MIPS IV Instruction Set" document
56 (Revision 3.1 - January 1995) details the standard MIPS instruction
57 set, and it defines operations in instruction (not pipe-line)
58 cycles. This means we only need to worry about a few cases where
59 the result is not available until after the next instruction, or
60 where registers in the previous two instruction cycles may be
61 corrupted. The case for corruption only occurs with HI or LO
62 register access, so we can just keep a count within the engine for
63 upto two cycles before marking the register as safe. We then only
64 need to check the safety flag when performing an update that
65 involves the HI or LO register. The only other case is the
66 BC1F/BC1T instructions in the FP unit. For ISAs I, II and III there
67 must be an instruction between the FP CMP and the BC1[FT]. We can
68 perform the same instruction cycle count scheme, so we can raise a
69 warning if an attempt is made to access the condition code early
70 (NOTE: The hardware does not interlock on this operation, so the
71 simulator should just raise a warning).
72
73 For the situations where a result is not available until later, we
74 implent a slot to hold pending values. After the PC is incremented,
75 and before the instruction is decoded we can execute the required
76 register update (or remainder of instruction processing). */
77
78/* The FP instruction decoding is also provided by this code. The
79 instructions are marked as "FP" ones so that we can construct a
80 simulator without an FPU if required. Similarly we mark
81 instructions as Single or Double precision, since some MIPS
82 processors only have single precision FP hardware. */
83
84/* NOTE: Ideally all state should be passed as parameters. This allows
85 a single simulator engine to be used for multiple concurrent
86 simulations. More importantly, if a suitably powerful control is in
87 place it will allow speculative simulation, since the context can
88 be saved easily, and then restored after performing some
89 simulation. The down-side is that for certain host architectures it
90 can slow the simulator down (e.g. if globals can be accessed faster
91 than local structures). However, this is not actually the case at
92 the moment. The constructed engine uses direct names (that can be
93 macro definitions). This keeps the engine source smalled (using
94 short-hands), and it also allows the user to control whether they
95 want to use global, or indirected memory locations. i.e. whether
96 they want a single- or multi-threaded simulator engine. */
97
98/* The constructed simulator engine contains manifests for each of the
99 features supported. The code that includes the engine can then
100 discover the available features during its build. This information
101 can be used to control run-time features provided by the final
102 simulator. */
103
104/*---------------------------------------------------------------------------*/
105
106/* Program defaults */
107#define DEF_ISA (3)
108#define DEF_PROC64 (1 == 1)
109#define DEF_FP (1 == 1)
110#define DEF_FPSINGLE (1 == 0)
111
112#define FEATURE_PROC32 (1 << 0) /* 0 = 64bit; 1 = 32bit */
113#define FEATURE_HASFPU (1 << 1) /* 0 = no FPU; 1 = include FPU */
114#define FEATURE_FPSINGLE (1 << 1) /* 0 = double; 1 = single (only used if FEATURE_HASFPU defined) */
115#define FEATURE_GP64 (1 << 2) /* 0 = GPRLEN 32; 1 = GPRLEN 64 */
8ad57737
JSC
116#define FEATURE_FAST (1 << 17) /* 0 = normal; 1 = disable features that slow performance */
117#define FEATURE_WARN_STALL (1 << 24) /* 0 = nothing; 1 = generate warnings when pipeline would stall */
118#define FEATURE_WARN_LOHI (1 << 25) /* 0 = nothing; 1 = generate warnings when LO/HI corrupted */
119#define FEATURE_WARN_ZERO (1 << 26) /* 0 = nothing; 1 = generate warnings if attempt to write register zero */
120#define FEATURE_WARN_MEM (1 << 27) /* 0 = nothing; 1 = generate warnings when memory problems are noticed */
121#define FEATURE_WARN_R31 (1 << 28) /* 0 = nothing; 1 = generate warnings if r31 used dangerously */
122#define FEATURE_WARN_RESULT (1 << 29) /* 0 = nothing; 1 = generate warnings when undefined results may occur */
123
8bae0a0c
JSC
124#if 1
125#define FEATURE_WARNINGS (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_ZERO | FEATURE_WARN_R31)
126#else
8ad57737 127#define FEATURE_WARNINGS (FEATURE_WARN_STALL | FEATURE_WARN_LOHI | FEATURE_WARN_ZERO | FEATURE_WARN_R31 | FEATURE_WARN_RESULT)
8bae0a0c 128#endif
8ad57737
JSC
129
130/* FEATURE_WARN_STALL */
131/* If MIPS I we want to raise a warning if an attempt is made to
132 access Rn in an instruction immediately following an Rn update
133 "WARNING : Invalid value read". The simulator engine is designed
134 that the previous value is read in such cases, to allow programs
135 that make use of this feature to execute. *
136/* If MIPS II or later, attempting to read a register before the
137 update has completed will generate a "WARNING : Processor stall"
138 message (since the processor will lock the pipeline until the value
139 becomes available). */
140
141/* FEATURE_WARN_LOHI */
142/* Warn if an attempt is made to read the HI/LO registers before the
143 update has completed, or if an attempt is made to update the
144 registers whilst an update is occurring. */
145
146/* FEATURE_WARN_ZERO */
147/* Notify the user if an attempt is made to use GPR 0 as a destination. */
148
149/* FEATURE_WARN_R31 */
150/* Notify the user if register r31 (the default procedure call return
151 address) is used unwisely. e.g. If r31 is used as the source in a
152 branch-and-link instruction, it would mean that an exception in the
153 delay slot instruction would not allow the branch to be re-started
154 (since r31 will have been overwritten by the link operation during
155 the first execution of the branch). */
156
157/* FEATURE_WARN_RESULT */
158/* Certain instructions do not raise exceptions when invalid operands
159 are given, they will just result in undefined values being
160 generated. This option controls whether the simulator flags such
161 events. */
162
163/*---------------------------------------------------------------------------*/
164
165#include <stdio.h>
166#include <getopt.h>
167#include <limits.h>
168#include <errno.h>
8bae0a0c 169#include "opcode/mips.h"
8ad57737 170
8bae0a0c 171/* The following manifests do not appear in "include/opcode/mips.h" */
8ad57737
JSC
172#define OP_SH_LOCC (8) /* FP condition code */
173#define OP_SH_HICC (18) /* FP condition code */
174#define OP_MASK_CC (0x07)
8bae0a0c
JSC
175
176#define OP_SH_COP1NORM (25) /* Normal COP1 encoding */
177#define OP_MASK_COP1NORM (0x01) /* a single bit */
178#define OP_SH_COP1SPEC (21) /* Special COP1 encodings (within format field) */
179#define OP_MASK_COP1SPEC (0x0F) /* Bits we are interested in */
180#define OP_MASK_COP1SCLR (0x04) /* Bits to be explicitly cleared */
181#define OP_MASK_COP1CMP (0x3) /* Unfortunately another conditional field needed to decode the FP instructions */
182#define OP_SH_COP1CMP (4)
183
8ad57737
JSC
184#define OP_SH_FORMAT (21) /* FP short format field */
185#define OP_MASK_FORMAT (0x07)
8bae0a0c 186
8ad57737
JSC
187#define OP_SH_TRUE (16)
188#define OP_MASK_TRUE (0x01)
8bae0a0c 189
8ad57737
JSC
190#define OP_SH_GE (17)
191#define OP_MASK_GE (0x01)
8bae0a0c 192
8ad57737
JSC
193#define OP_SH_UNSIGNED (16)
194#define OP_MASK_UNSIGNED (0x01)
8bae0a0c 195
8ad57737
JSC
196#define OP_SH_HINT (16)
197#define OP_MASK_HINT (0x1F)
198
8bae0a0c 199#if 0
8ad57737
JSC
200#ifndef TRUE
201#define TRUE (1 == 1)
202#define FALSE (1 == 0)
203#endif
8bae0a0c 204#endif
8ad57737
JSC
205
206/*---------------------------------------------------------------------------*/
207
208/* Holding the instruction table this way makes it easier to check the
209 instruction values defined, and to add instructions to the
210 system. However, it makes the process of constructing the simulator
211 a bit more complicated: */
212
213/* The "bitmap" is encoded as follows (NOTE: Only lower-case
214 alphabetic characters should be used, since the letter ordinal is
215 used as a bit position): */
216
217typedef struct operand_encoding {
218 char id; /* character identifier */
219 int fpos; /* first bit position */
220 int flen; /* field length in bits */
221 char * const type;
222 char * const name;
223 unsigned int flags;
224} operand_encoding;
225
226/* Values for the "flags" field: */
227#define OP_NONE (0 << 0) /* To keep the source tidy */
228#define OP_GPR (1 << 0) /* Get operand from integer register bank */
8bae0a0c
JSC
229#define OP_SIGNX (1 << 1) /* Sign-extend the operand */
230#define OP_SHIFT2 (1 << 2) /* Shift field left by 2 */
231#define OP_BITS5 (1 << 3) /* Only take the lo 5-bits of the operand */
8ad57737
JSC
232
233struct operand_encoding opfields[] = {
8bae0a0c
JSC
234 {'0',-1,-1,"", "", (OP_NONE)}, /* special case for explicit zero */
235 {'1',-1,-1,"", "", (OP_NONE)}, /* special case for explicit one */
236 {'?',-1,-1,"", "", (OP_NONE)}, /* undefined (do not care at this level) */
8ad57737 237 /* The rest are the explicit operand fields: */
8bae0a0c
JSC
238 {'a', 6, 5,"int", "op1", (OP_NONE)}, /* shift amount (or hint) */
239 {'b',21, 5,"int", "fr", (OP_NONE)}, /* fr register */
240 {'c',16, 1,"int", "boolean", (OP_NONE)}, /* TRUE or FALSE boolean */
241 {'d',11, 5,"int", "destreg", (OP_NONE)}, /* integer destination/rd register */
242 {'e', 0,16,"t_reg", "offset", (OP_SIGNX)}, /* signed offset (lo-3bits must be zero) */
243 {'f',17, 1,"int", "likely", (OP_NONE)}, /* set if branch LIKELY */
244 {'g',16, 5,"t_reg", "op2", (OP_GPR)}, /* integer source rt register */
245 {'h', 0,16,"t_reg", "offset", (OP_SIGNX)}, /* signed offset (lo-1bit must be zero) */
246 {'i', 0,16,"t_reg", "op2", (OP_SIGNX)}, /* signed immediate (op2) */
247 {'j', 0,26,"ut_reg","op1", (OP_SHIFT2)},/* shifted left 2 bits and combined with hi-order bits of address in the delay slot */
248 {'k',16, 5,"int", "ft", (OP_NONE)},
249 {'l', 0,16,"t_reg", "offset", (OP_SIGNX | OP_SHIFT2)}, /* signed offset shifted left 2 to make 18bit signed offset */
250 {'m',21, 3,"int", "format", (OP_NONE)}, /* FP format field */
251 {'n',16, 5,"int", "hint", (OP_NONE)}, /* hint */
252 {'o',21, 5,"t_reg", "op1", (OP_GPR | OP_BITS5)}, /* integer source/rs register (but never treated as 32bit word) */
253 {'p', 8, 3,"int", "condition_code",(OP_NONE)}, /* FP condition code field */
254 {'q',18, 3,"int", "condition_code",(OP_NONE)}, /* FP condition code field */
255 {'r', 6, 5,"int", "destreg", (OP_NONE)}, /* FP fd register */
256 {'s',21, 5,"t_reg", "op1", (OP_GPR)}, /* integer source/rs register */
257 {'t',16, 5,"int", "destreg", (OP_NONE)}, /* integer target rt (destination) register */
258 {'u', 0, 4,"int", "cmpflags", (OP_NONE)}, /* FP comparison control flags */
259 {'v',11, 5,"int", "fs", (OP_NONE)}, /* FP fs register (or PREFX hint) */
260 {'w', 0,16,"t_reg", "offset", (OP_SIGNX)}, /* signed offset (lo-2bits must be zero) */
261 {'x',23, 1,"int", "to", (OP_NONE)}, /* TRUE if move To; FALSE if move From */
262 {'y', 0,16,"t_reg", "offset", (OP_SIGNX)}, /* signed offset */
263 {'z', 0,16,"ut_reg","op2", (OP_NONE)}, /* unsigned immediate (zero extended) */
8ad57737
JSC
264};
265
266/* Main instruction encoding types: */
267typedef enum {
268 NORMAL,
269 SPECIAL,
270 REGIMM,
271 COP1,
272 COP1X,
8bae0a0c 273 COP1S, /* These instructions live in the reserved FP format values: 0..15,18-19,22-31 */
8ad57737
JSC
274 UNKNOWN
275} inst_type;
276
277/* Main instruction families: */
278typedef enum {
279 ADD, /* res = operand1 + operand2 */
280 SUB, /* res = operand1 - operand2 */
281 MUL, /* res = operand1 * operand2 */
282 DIV, /* res = operand1 / operand2 */
283 AND, /* res = operand1 & operand2 */
284 OR, /* res = operand1 | operand2 */
285 XOR, /* res = operand1 ^ operand2 */
286 MOVE, /* res = operand1 */
287 BRANCH, /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
288 JUMP, /* execute delay slot instruction before jump */
289 LOAD, /* load from memory */
290 STORE, /* store to memory */
291 PREFETCH, /* prefetch data into cache */
292 SET, /* set register on result of condition code */
293 SHIFT, /* perform a logical or arithmetic shift */
294 TRAP, /* system exception generation */
295 BREAK, /* system breakpoint exception generation */
296 SYSCALL, /* system exception generation */
297 SYNC, /* system cache control */
298 DECODE, /* co-processor instruction */
299 CACHE, /* co-processor 0 CACHE instruction */
300 MADD16, /* VR4100 specific multiply-add extensions */
301 FPMOVE,
8bae0a0c 302 FPMOVEC,
8ad57737
JSC
303 FPFLOOR,
304 FPCEIL,
305 FPTRUNC,
306 FPROUND,
307 FPNEG,
308 FPABS,
309 FPDIV,
310 FPMUL,
311 FPSUB,
312 FPADD,
8ad57737 313 FPPREFX,
8ad57737
JSC
314 FPRECIP,
315 FPSQRT,
316 FPCONVERT,
317 FPCOMPARE,
318 RSVD /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "Reserved Instruction" */
319} opcode_type;
320
321/* Flags field: */
322#define NONE (0 << 0) /* Zero value (used to keep source tidy) */
323#define SIM_SH_SIZE (0)
8bae0a0c
JSC
324#define SIM_MASK_SIZE (0x7)
325#define BYTE (0) /* 8bit */
326#define HALFWORD (1) /* 16bit */
327#define WORD (2) /* 32bit */
328#define DOUBLEWORD (3) /* 64bit */
329#define SINGLE (4) /* single precision FP */
330#define DOUBLE (5) /* double precision FP */
8ad57737
JSC
331
332/* Shorthand to get the size field from the flags value: */
333#define GETDATASIZE() ((MIPS_DECODE[loop].flags >> SIM_SH_SIZE) & SIM_MASK_SIZE)
334
335/* The rest are single bit flags: */
8ad57737
JSC
336#define MULTIPLY (1 << 3) /* actually FP multiply ADD/SUB modifier */
337#define EQ (1 << 4)
338#define GT (1 << 5)
339#define LT (1 << 6)
340#define NOT (1 << 7)
341#define LIKELY (1 << 8)
342#define SIGNEXTEND (1 << 9)
343#define OVERFLOW (1 << 10)
344#define LINK (1 << 11)
345#define ATOMIC (1 << 12)
346#define SHIFT16 (1 << 13)
347#define REG (1 << 14)
348#define LEFT (1 << 15) /* Deliberate explicit encodings to allow check for neither, or both */
349#define RIGHT (1 << 16) /* Mutually exclusive with "LEFT" */
350#define LOGICAL (1 << 17)
351#define ARITHMETIC (1 << 18)
352#define UNSIGNED (1 << 19)
353#define HI32 (1 << 20)
354#define HI (1 << 21) /* accesses or updates the HI register */
355#define LO (1 << 22) /* accesses or updates the LO register */
356#define WORD32 (1 << 23)
357#define FP (1 << 24) /* Floating Point operation */
358#define FIXED (1 << 25) /* fixed point arithmetic */
8bae0a0c
JSC
359#define COPROC (1 << 26)
360#define INTEGER (1 << 27)
361#define CONDITIONAL (1 << 28)
362#define RECIP (1 << 29)
363#define CONTROL (1 << 30)
8ad57737 364#define NOARG (1 << 31) /* Instruction has no (defined) operands */
8bae0a0c
JSC
365/* NOTE: We can overload the use of certain of these flags, since not
366 all options are applicable to all instruction types. This will free
367 up more space for new flags. */
8ad57737
JSC
368
369typedef struct instruction {
370 char *name; /* ASCII mnemonic name */
371 unsigned int isa; /* MIPS ISA number where instruction introduced */
372 char *bitmap; /* 32character string describing instruction operands */
373 inst_type mark; /* type of MIPS instruction encoding */
374 opcode_type type; /* main instruction family */
375 unsigned int flags; /* flags describing instruction features */
376} instruction;
377/* The number of pipeline cycles taken by an instruction varies
378 between MIPS processors. This means that the information must be
379 encoded elsewhere, in a CPU specific structure. */
380
381/* NOTE: Undefined instructions cause "Reserved Instruction"
382 exceptions. i.e. if there is no bit-mapping defined then the
383 instruction is deemed to be undefined. */
384
385/* NOTE: The "isa" field is also used to encode flags for particular
386 chip architecture extensions. e.g. the NEC VR4100 specific
387 instructions. Normally chip extensions are added via the COP0
388 space. However, the VR4100 (and possibly other devices) also use
389 the normal instruction space. */
390#define MASK_ISA (0x000000FF) /* Start by leaving 8bits for the ISA ID */
391/* The other bits are allocated downwards, to avoid renumbering if we
392 have to extend the bits allocated to the pure ISA number. */
393#define ARCH_VR4100 ((unsigned)1 << 31) /* NEC VR4100 extension instructions */
394
395/* The HIBERNATE, STANDBY and SUSPEND instructions are encoded in the
396 COP0 space. This means that an external decoder should be added
397 when constructing a full VR4100 simulator. However some arithmetic
398 instructions are encoded in the normal instruction space. */
399
400struct instruction MIPS_DECODE[] = {
401 /* The instructions are alphabetical, and not in instruction bit-order: */
a9f7253f 402 {"ABS", 1,"01000110mmm00000vvvvvrrrrr000101",COP1, FPABS, (FP)},
8ad57737 403 {"ADD", 1,"000000sssssgggggddddd00000100000",SPECIAL,ADD, (WORD | WORD32 | OVERFLOW)}, /* rd = rs + rt */
8bae0a0c 404 {"ADD", 1,"01000110mmmkkkkkvvvvvrrrrr000000",COP1, FPADD, (FP)},
8ad57737
JSC
405 {"ADDI", 1,"001000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD, (WORD | WORD32 | OVERFLOW)},
406 {"ADDU", 1,"000000sssssgggggddddd00000100001",SPECIAL,ADD, (WORD | WORD32)}, /* rd = rs + rt */
407 {"ADDIU", 1,"001001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD, (WORD | WORD32)},
408 {"AND", 1,"000000sssssgggggddddd00000100100",SPECIAL,AND, (NONE)}, /* rd = rs AND rt */
409 {"ANDI", 1,"001100ssssstttttzzzzzzzzzzzzzzzz",NORMAL, AND, (NONE)},
8bae0a0c 410 {"BC1", 1,"01000101000qqqfcllllllllllllllll",COP1S, BRANCH, (FP)},
8ad57737
JSC
411 {"BEQ", 1,"000100sssssgggggllllllllllllllll",NORMAL, BRANCH, (EQ)},
412 {"BEQL", 2,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH, (EQ | LIKELY)},
413 {"BGEZ", 1,"000001sssss00001llllllllllllllll",REGIMM, BRANCH, (GT | EQ)},
414 {"BGEZAL", 1,"000001sssss10001llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)},
415 {"BGEZALL", 2,"000001sssss10011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)},
416 {"BGEZL", 2,"000001sssss00011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LIKELY)},
417 {"BGTZ", 1,"000111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT)},
418 {"BGTZL", 2,"010111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT | LIKELY)},
419 {"BLEZ", 1,"000110sssss00000llllllllllllllll",NORMAL, BRANCH, (LT | EQ)},
420 {"BLEZL", 2,"010110sssss00000llllllllllllllll",NORMAL, BRANCH, (LT | EQ | LIKELY)},
421 {"BLTZ", 1,"000001sssss00000llllllllllllllll",REGIMM, BRANCH, (LT)},
422 {"BLTZAL", 1,"000001sssss10000llllllllllllllll",REGIMM, BRANCH, (LT | LINK)},
423 {"BLTZALL", 2,"000001sssss10010llllllllllllllll",REGIMM, BRANCH, (LT | LINK | LIKELY)},
424 {"BLTZL", 2,"000001sssss00010llllllllllllllll",REGIMM, BRANCH, (LT | LIKELY)},
425 {"BNE", 1,"000101sssssgggggllllllllllllllll",NORMAL, BRANCH, (NOT | EQ)},
426 {"BNEL", 2,"010101sssssgggggllllllllllllllll",NORMAL, BRANCH, (NOT | EQ | LIKELY)},
427 {"BREAK", 1,"000000????????????????????001101",SPECIAL,BREAK, (NOARG)},
428 {"CEIL.L", 3,"01000110mmm00000vvvvvrrrrr001010",COP1, FPCEIL, (FP | FIXED | DOUBLEWORD)},
429 {"CEIL.W", 2,"01000110mmm00000vvvvvrrrrr001110",COP1, FPCEIL, (FP | FIXED | WORD)},
430 {"COP0", 1,"010000??????????????????????????",NORMAL, DECODE, (NOARG)},
431 {"COP2", 1,"010010??????????????????????????",NORMAL, DECODE, (NOARG)},
432 {"CVT.D", 1,"01000110mmm00000vvvvvrrrrr100001",COP1, FPCONVERT,(FP | DOUBLE)},
433 {"CVT.L", 3,"01000110mmm00000vvvvvrrrrr100101",COP1, FPCONVERT,(FP | FIXED | DOUBLEWORD)},
434 {"CVT.S", 1,"01000110mmm00000vvvvvrrrrr100000",COP1, FPCONVERT,(FP | SINGLE)},
435 {"CVT.W", 1,"01000110mmm00000vvvvvrrrrr100100",COP1, FPCONVERT,(FP | FIXED | WORD)},
436 {"C.%s", 1,"01000110mmmkkkkkvvvvvppp0011uuuu",COP1, FPCOMPARE,(FP)},
8bae0a0c 437 {"CxC1", 1,"01000100x10kkkkkvvvvv00000000000",COP1S, FPMOVEC, (FP | WORD | CONTROL)},
8ad57737
JSC
438 {"DADD", 3,"000000sssssgggggddddd00000101100",SPECIAL,ADD, (DOUBLEWORD | OVERFLOW)},
439 {"DADDI", 3,"011000ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD, (DOUBLEWORD | OVERFLOW)},
440 {"DADDU", 3,"000000sssssgggggddddd00000101101",SPECIAL,ADD, (DOUBLEWORD | UNSIGNED)},
441 {"DADDIU", 3,"011001ssssstttttiiiiiiiiiiiiiiii",NORMAL, ADD, (DOUBLEWORD | UNSIGNED)},
442 {"DDIV", 3,"000000sssssggggg0000000000011110",SPECIAL,DIV, (DOUBLEWORD | HI | LO)},
443 {"DDIVU", 3,"000000sssssggggg0000000000011111",SPECIAL,DIV, (DOUBLEWORD | UNSIGNED | HI | LO)},
444 {"DIV", 1,"000000sssssggggg0000000000011010",SPECIAL,DIV, (WORD | WORD32 | SIGNEXTEND | HI | LO)},
445 {"DIV", 1,"01000110mmmkkkkkvvvvvrrrrr000011",COP1, FPDIV, (FP | WORD | HI | LO)},
446 {"DIVU", 1,"000000sssssggggg0000000000011011",SPECIAL,DIV, (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO)},
447 {"DMADD16", (ARCH_VR4100 | 3),"000000sssssggggg0000000000101001",SPECIAL,MADD16, (DOUBLEWORD | HI | LO)},
448 {"DMULT", 3,"000000sssssggggg0000000000011100",SPECIAL,MUL, (DOUBLEWORD | HI | LO)},
449 {"DMULTU", 3,"000000sssssggggg0000000000011101",SPECIAL,MUL, (DOUBLEWORD | UNSIGNED | HI | LO)},
8bae0a0c 450 {"DMxC1", 3,"01000100x01kkkkkvvvvv00000000000",COP1S, FPMOVEC, (FP | DOUBLEWORD)},
8ad57737
JSC
451 {"DSLL", 3,"00000000000gggggdddddaaaaa111000",SPECIAL,SHIFT, (DOUBLEWORD | LEFT | LOGICAL)},
452 {"DSLLV", 3,"000000sssssgggggddddd00000010100",SPECIAL,SHIFT, (DOUBLEWORD | LEFT | LOGICAL)},
453 {"DSLL32", 3,"00000000000gggggdddddaaaaa111100",SPECIAL,SHIFT, (DOUBLEWORD | LEFT | LOGICAL | HI32)}, /* rd = rt << (sa + 32) */
454 {"DSRA", 3,"00000000000gggggdddddaaaaa111011",SPECIAL,SHIFT, (DOUBLEWORD | RIGHT | ARITHMETIC)},
455 {"DSRAV", 3,"000000sssssgggggddddd00000010111",SPECIAL,SHIFT, (DOUBLEWORD | RIGHT | ARITHMETIC)},
456 {"DSRA32", 3,"00000000000gggggdddddaaaaa111111",SPECIAL,SHIFT, (DOUBLEWORD | RIGHT | ARITHMETIC | HI32)}, /* rd = rt >> (sa + 32) */
457 {"DSRL", 3,"00000000000gggggdddddaaaaa111010",SPECIAL,SHIFT, (DOUBLEWORD | RIGHT | LOGICAL)},
458 {"DSRLV", 3,"000000sssssgggggddddd00000010110",SPECIAL,SHIFT, (DOUBLEWORD | RIGHT | LOGICAL)},
459 {"DSRL32", 3,"00000000000gggggdddddaaaaa111110",SPECIAL,SHIFT, (DOUBLEWORD | RIGHT | LOGICAL | HI32)},
460 {"DSUB", 3,"000000sssssgggggddddd00000101110",SPECIAL,SUB, (DOUBLEWORD)},
461 {"DSUBU", 3,"000000sssssgggggddddd00000101111",SPECIAL,SUB, (DOUBLEWORD | UNSIGNED)},
462 {"FLOOR.L", 3,"01000110mmm00000vvvvvrrrrr001011",COP1, FPFLOOR, (FP | FIXED | DOUBLEWORD)},
463 {"FLOOR.W", 2,"01000110mmm00000vvvvvrrrrr001111",COP1, FPFLOOR, (FP | FIXED | WORD)},
464 {"J", 1,"000010jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP, (NONE)}, /* NOTE: boundary case due to delay slot address being used */
465 {"JAL", 1,"000011jjjjjjjjjjjjjjjjjjjjjjjjjj",NORMAL, JUMP, (LINK)}, /* NOTE: boundary case due to delay slot address being used */
466 {"JALR", 1,"000000sssss00000ddddd00000001001",SPECIAL,JUMP, (LINK | REG)},
467 {"JR", 1,"000000sssss000000000000000001000",SPECIAL,JUMP, (NONE)}, /* need to check PC as part of instruction fetch */
468 {"LB", 1,"100000ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (BYTE | SIGNEXTEND)}, /* NOTE: "i" rather than "o" because BYTE addressing is allowed */
469 {"LBU", 1,"100100ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (BYTE)}, /* NOTE: See "LB" comment */
470 {"LD", 3,"110111sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD, (DOUBLEWORD)},
471 {"LDC1", 2,"110101sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD, (DOUBLEWORD | COPROC)},
472 {"LDC2", 2,"110110sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD, (DOUBLEWORD | COPROC)},
473 {"LDL", 3,"011010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (DOUBLEWORD | LEFT)}, /* NOTE: See "LB" comment */
474 {"LDR", 3,"011011ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (DOUBLEWORD | RIGHT)}, /* NOTE: See "LB" comment */
8bae0a0c 475 {"LDXC1", 4,"010011sssssggggg00000rrrrr000001",COP1X, LOAD, (FP | DOUBLEWORD | COPROC | REG)},
8ad57737
JSC
476 {"LH", 1,"100001sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD, (HALFWORD | SIGNEXTEND)},
477 {"LHU", 1,"100101sssssttttthhhhhhhhhhhhhhhh",NORMAL, LOAD, (HALFWORD)},
478 {"LL", 2,"110000ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD, (WORD | ATOMIC | SIGNEXTEND)},
479 {"LLD", 3,"110100sssssttttteeeeeeeeeeeeeeee",NORMAL, LOAD, (DOUBLEWORD | ATOMIC)},
480 {"LUI", 1,"00111100000tttttiiiiiiiiiiiiiiii",NORMAL, MOVE, (SHIFT16)}, /* Cheat and specify sign-extension of immediate field */
481 {"LW", 1,"100011ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD, (WORD | SIGNEXTEND)},
482 {"LWC1", 1,"110001ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD, (WORD | COPROC)},
483 {"LWC2", 1,"110010ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD, (WORD | COPROC)},
484 {"LWL", 1,"100010ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (WORD | LEFT)},
485 {"LWR", 1,"100110ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (WORD | RIGHT)},
486 {"LWU", 3,"100111ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD, (WORD)},
8bae0a0c 487 {"LWXC1", 4,"010011sssssggggg00000rrrrr000000",COP1X, LOAD, (FP | WORD | COPROC | REG)},
8ad57737
JSC
488 {"MADD16", (ARCH_VR4100 | 3),"000000sssssggggg0000000000101000",SPECIAL,MADD16, (WORD | HI | LO)},
489 {"MADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr100001",COP1X, FPADD, (FP | MULTIPLY | DOUBLE)},
490 {"MADD.S", 4,"010011bbbbbkkkkkvvvvvrrrrr100000",COP1X, FPADD, (FP | MULTIPLY | SINGLE)},
491 {"MFHI", 1,"0000000000000000ddddd00000010000",SPECIAL,MOVE, (HI)}, /* with following, from and to denoted by usage of "s" or "d" */
492 {"MFLO", 1,"0000000000000000ddddd00000010010",SPECIAL,MOVE, (LO)},
493 {"MTHI", 1,"000000sssss000000000000000010001",SPECIAL,MOVE, (HI)},
494 {"MTLO", 1,"000000sssss000000000000000010011",SPECIAL,MOVE, (LO)},
495 {"MOV", 1,"01000110mmm00000vvvvvrrrrr000110",COP1, FPMOVE, (FP)},
496 {"MOVN", 4,"000000sssssgggggddddd00000001011",SPECIAL,MOVE, (NOT | EQ)},
8bae0a0c
JSC
497 {"MOVN", 4,"01000110mmmgggggvvvvvrrrrr010011",COP1, FPMOVE, (FP | NOT | EQ)},
498 {"MOV%c", 4,"000000sssssqqq0cddddd00000000001",SPECIAL,FPMOVE, (FP | CONDITIONAL | INTEGER)},
499 {"MOV%c", 4,"01000110mmmqqq0cvvvvvrrrrr010001",COP1, FPMOVE, (FP | CONDITIONAL)},
8ad57737 500 {"MOVZ", 4,"000000sssssgggggddddd00000001010",SPECIAL,MOVE, (EQ)},
8bae0a0c 501 {"MOVZ", 4,"01000110mmmgggggvvvvvrrrrr010010",COP1, FPMOVE, (FP | EQ)},
8ad57737
JSC
502 {"MSUB.D", 4,"010011bbbbbkkkkkvvvvvrrrrr101001",COP1X, FPSUB, (FP | MULTIPLY | DOUBLE)},
503 {"MSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X, FPSUB, (FP | MULTIPLY | SINGLE)},
504 {"MUL", 1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1, FPMUL, (FP | HI | LO)},
505 {"MULT", 1,"000000sssssggggg0000000000011000",SPECIAL,MUL, (WORD | WORD32 | HI | LO)},
506 {"MULTU", 1,"000000sssssggggg0000000000011001",SPECIAL,MUL, (WORD | WORD32 | HI | LO)},
8bae0a0c
JSC
507 {"MxC1", 1,"01000100x00kkkkkvvvvv00000000000",COP1S, FPMOVEC, (FP | WORD)},
508 {"NEG", 1,"01000110mmm00000vvvvvrrrrr000111",COP1, FPNEG, (FP)},
8ad57737
JSC
509 {"NMADD.D", 4,"010011bbbbbkkkkkvvvvvrrrrr110001",COP1X, FPADD, (FP | NOT | MULTIPLY | DOUBLE)},
510 {"NMADD.S", 4,"010011bbbbbkkkkkvvvvvrrrrr110000",COP1X, FPADD, (FP | NOT | MULTIPLY | SINGLE)},
511 {"NMSUB.D", 4,"010011bbbbbkkkkkvvvvvrrrrr111001",COP1X, FPSUB, (FP | NOT | MULTIPLY | DOUBLE)},
512 {"NMSUB.S", 4,"010011bbbbbkkkkkvvvvvrrrrr111000",COP1X, FPSUB, (FP | NOT | MULTIPLY | SINGLE)},
513 {"NOR", 1,"000000sssssgggggddddd00000100111",SPECIAL,OR, (NOT)},
514 {"OR", 1,"000000sssssgggggddddd00000100101",SPECIAL,OR, (NONE)},
515 {"ORI", 1,"001101ssssstttttzzzzzzzzzzzzzzzz",NORMAL, OR, (NONE)},
516 {"PREF", 4,"110011sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, PREFETCH, (NONE)},
8bae0a0c 517 {"PREFX", 4,"010011sssssgggggvvvvv00000001111",COP1X, FPPREFX, (FP)},
8ad57737
JSC
518 {"RECIP", 4,"01000110mmm00000vvvvvrrrrr010101",COP1, FPRECIP, (FP)},
519 {"ROUND.L", 3,"01000110mmm00000vvvvvrrrrr001000",COP1, FPROUND, (FP | FIXED | DOUBLEWORD)},
520 {"ROUND.W", 2,"01000110mmm00000vvvvvrrrrr001100",COP1, FPROUND, (FP | FIXED | WORD)},
8bae0a0c 521 {"RSQRT", 4,"01000110mmm00000vvvvvrrrrr010110",COP1, FPSQRT, (FP | RECIP)},
8ad57737
JSC
522 {"SB", 1,"101000sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (BYTE)},
523 {"SC", 2,"111000sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE, (WORD | ATOMIC)},
524 {"SCD", 3,"111100sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD | ATOMIC)},
525 {"SD", 3,"111111sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD)},
526 {"SDC1", 2,"111101sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD | COPROC)},
527 {"SDC2", 2,"111110sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD | COPROC)},
528 {"SDL", 3,"101100sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (DOUBLEWORD | LEFT)},
529 {"SDR", 3,"101101sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (DOUBLEWORD | RIGHT)},
8bae0a0c 530 {"SDXC1", 4,"010011sssssgggggvvvvv00000001001",COP1X, STORE, (FP | DOUBLEWORD | COPROC | REG)},
8ad57737
JSC
531 {"SH", 1,"101001sssssggggghhhhhhhhhhhhhhhh",NORMAL, STORE, (HALFWORD)},
532 {"SLL", 1,"00000000000gggggdddddaaaaa000000",SPECIAL,SHIFT, (WORD | LEFT | LOGICAL)}, /* rd = rt << sa */
533 {"SLLV", 1,"000000ooooogggggddddd00000000100",SPECIAL,SHIFT, (WORD | LEFT | LOGICAL)}, /* rd = rt << rs - with "SLL" depends on "s" and "a" field values */
534 {"SLT", 1,"000000sssssgggggddddd00000101010",SPECIAL,SET, (LT)},
535 {"SLTI", 1,"001010ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET, (LT)},
536 {"SLTU", 1,"000000sssssgggggddddd00000101011",SPECIAL,SET, (LT | UNSIGNED)},
537 {"SLTIU", 1,"001011ssssstttttiiiiiiiiiiiiiiii",NORMAL, SET, (LT | UNSIGNED)},
538 {"SQRT", 2,"01000110mmm00000vvvvvrrrrr000100",COP1, FPSQRT, (FP)},
8bae0a0c
JSC
539 {"SRA", 1,"00000000000gggggdddddaaaaa000011",SPECIAL,SHIFT, (WORD | WORD32 | RIGHT | ARITHMETIC)},
540 {"SRAV", 1,"000000ooooogggggddddd00000000111",SPECIAL,SHIFT, (WORD | WORD32 | RIGHT | ARITHMETIC)},
541 {"SRL", 1,"00000000000gggggdddddaaaaa000010",SPECIAL,SHIFT, (WORD | WORD32 | RIGHT | LOGICAL)},
542 {"SRLV", 1,"000000ooooogggggddddd00000000110",SPECIAL,SHIFT, (WORD | WORD32 | RIGHT | LOGICAL)},
8ad57737
JSC
543 {"SUB", 1,"000000sssssgggggddddd00000100010",SPECIAL,SUB, (WORD | WORD32 | OVERFLOW)},
544 {"SUB", 1,"01000110mmmkkkkkvvvvvrrrrr000001",COP1, FPSUB, (FP)},
545 {"SUBU", 1,"000000sssssgggggddddd00000100011",SPECIAL,SUB, (WORD | WORD32)},
546 {"SW", 1,"101011sssssgggggwwwwwwwwwwwwwwww",NORMAL, STORE, (WORD)},
547 {"SWC1", 1,"111001ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE, (WORD | COPROC)},
548 {"SWC2", 1,"111010ssssstttttwwwwwwwwwwwwwwww",NORMAL, STORE, (WORD | COPROC)},
549 {"SWL", 1,"101010sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (WORD | LEFT)},
550 {"SWR", 1,"101110sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (WORD | RIGHT)},
8bae0a0c 551 {"SWXC1", 4,"010011sssssgggggvvvvv00000001000",COP1X, STORE, (FP | WORD | COPROC | REG)},
8ad57737
JSC
552 {"SYNC", 2,"000000000000000000000aaaaa001111",SPECIAL,SYNC, (NONE)}, /* z = 5bit stype field */
553 {"SYSCALL", 1,"000000????????????????????001100",SPECIAL,SYSCALL, (NOARG)},
554 {"TEQ", 2,"000000sssssggggg??????????110100",SPECIAL,TRAP, (EQ)},
555 {"TEQI", 2,"000001sssss01100iiiiiiiiiiiiiiii",REGIMM, TRAP, (EQ)},
556 {"TGE", 2,"000000sssssggggg??????????110000",SPECIAL,TRAP, (GT | EQ)},
557 {"TGEI", 2,"000001sssss01000iiiiiiiiiiiiiiii",REGIMM, TRAP, (GT | EQ)},
558 {"TGEIU", 2,"000001sssss01001iiiiiiiiiiiiiiii",REGIMM, TRAP, (GT | EQ | UNSIGNED)},
559 {"TGEU", 2,"000000sssssggggg??????????110001",SPECIAL,TRAP, (GT | EQ | UNSIGNED)},
560 {"TLT", 2,"000000sssssggggg??????????110010",SPECIAL,TRAP, (LT)},
561 {"TLTI", 2,"000001sssss01010iiiiiiiiiiiiiiii",REGIMM, TRAP, (LT)},
562 {"TLTIU", 2,"000001sssss01011iiiiiiiiiiiiiiii",REGIMM, TRAP, (LT | UNSIGNED)},
563 {"TLTU", 2,"000000sssssggggg??????????110011",SPECIAL,TRAP, (LT | UNSIGNED)},
564 {"TNE", 2,"000000sssssggggg??????????110110",SPECIAL,TRAP, (NOT | EQ)},
565 {"TNEI", 2,"000001sssss01110iiiiiiiiiiiiiiii",REGIMM, TRAP, (NOT | EQ)},
566 {"TRUNC.L", 3,"01000110mmm00000vvvvvrrrrr001001",COP1, FPTRUNC, (FP | FIXED | DOUBLEWORD)},
567 {"TRUNC.W", 2,"01000110mmm00000vvvvvrrrrr001101",COP1, FPTRUNC, (FP | FIXED | WORD)},
568 {"XOR", 1,"000000sssssgggggddddd00000100110",SPECIAL,XOR, (NONE)},
569 {"XORI", 1,"001110ssssstttttzzzzzzzzzzzzzzzz",NORMAL, XOR, (NONE)},
570 {"CACHE", 3,"101111sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, CACHE, (NONE)},
571 {"<INT>", 1,"111011sssssgggggyyyyyyyyyyyyyyyy",NORMAL, RSVD, (NONE)},
572};
573
574/*---------------------------------------------------------------------------*/
575
576/* We use the letter ordinal as the bit-position in our flags field: */
577#define fieldval(l) (1 << ((l) - 'a'))
578
579unsigned int
580convert_bitmap(bitmap,onemask,zeromask,dontmask)
581 char *bitmap;
582 unsigned int *onemask, *zeromask, *dontmask;
583{
584 unsigned int flags = 0x00000000;
585 int loop; /* current bitmap position */
586 int lastsp = -1; /* last bitmap field starting position */
587 int lastoe = -1; /* last bitmap field encoding */
588
589 *onemask = 0x00000000;
590 *zeromask = 0x00000000;
591 *dontmask = 0x00000000;
592
593 if (strlen(bitmap) != 32) {
594 fprintf(stderr,"Invalid bitmap string - not 32 characters long \"%s\"\n",bitmap);
595 exit(3);
596 }
597
598 for (loop = 0; (loop < 32); loop++) {
599 int oefield ;
600 for (oefield = 0; (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))); oefield++)
601 if (bitmap[31 - loop] == opfields[oefield].id)
602 break;
603 if (oefield < (sizeof(opfields) / sizeof(struct operand_encoding))) {
604 if ((lastoe != -1) && (lastoe != oefield))
605 if ((loop - lastsp) != (opfields[lastoe].flen)) {
8bae0a0c 606 fprintf(stderr,"Invalid field length %d for bitmap field '%c' (0x%02X) (should be %d) : bitmap = \"%s\"\n",(loop - lastsp),(((bitmap[31 - loop] < 0x20) || (bitmap[31 - loop] >= 0x7F)) ? '.' : bitmap[31 - loop]),bitmap[31 - loop],opfields[lastoe].flen,bitmap);
8ad57737
JSC
607 exit(4);
608 }
609
610 switch (bitmap[31 - loop]) {
611 case '0' : /* fixed value */
612 *zeromask |= (1 << loop);
613 lastsp = loop;
614 lastoe = -1;
615 break;
616
617 case '1' : /* fixed value */
618 *onemask |= (1 << loop);
619 lastsp = loop;
620 lastoe = -1;
621 break;
622
623 case '?' : /* fixed value */
624 *dontmask |= (1 << loop);
625 lastsp = loop;
626 lastoe = -1;
627 break;
628
629 default : /* check character encoding */
630 {
631 if (opfields[oefield].fpos != -1) {
632 /* If flag not set, then check starting position: */
633 if (!(flags & fieldval(bitmap[31 - loop]))) {
634 if (loop != opfields[oefield].fpos) {
635 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);
636 exit(4);
637 }
638 flags |= fieldval(bitmap[31 - loop]);
639 lastsp = loop;
640 lastoe = oefield;
641 }
642 }
643 *dontmask |= (1 << loop);
644 }
645 break;
646 }
647 } else {
648 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);
649 exit(4);
650 }
651 }
652
653 /* NOTE: Since we check for the position and size of fields when
654 parsing the "bitmap" above, we do *NOT* need to check that invalid
655 field combinations have been used. */
656
657 return(flags);
658}
659
660/*---------------------------------------------------------------------------*/
661
662static void
663build_operands(flags)
664 unsigned int flags;
665{
666 int loop;
667 for (loop = 0; (loop < (sizeof(opfields) / sizeof(operand_encoding))); loop++)
668 if ((opfields[loop].fpos != -1) && (flags & fieldval(opfields[loop].id))) {
669 printf(" %s %s = ",opfields[loop].type,opfields[loop].name);
670
671 if (opfields[loop].flags & OP_SIGNX)
672 printf("SIGNEXTEND((%s)",opfields[loop].type);
673
8bae0a0c
JSC
674 if (opfields[loop].flags & OP_GPR)
675 printf("GPR[");
8ad57737
JSC
676
677 if (opfields[loop].flags & OP_SHIFT2)
678 printf("(");
679
680 printf("((instruction >> %d) & 0x%08X)",opfields[loop].fpos,((1 << opfields[loop].flen) - 1));
681
682 if (opfields[loop].flags & OP_SHIFT2)
683 printf(" << 2)");
684
8bae0a0c 685 if (opfields[loop].flags & OP_GPR)
8ad57737
JSC
686 printf("]");
687
688 if (opfields[loop].flags & OP_BITS5)
689 printf("&0x1F");
690
691 if (opfields[loop].flags & OP_SIGNX)
692 printf(",%d)",(opfields[loop].flen + ((opfields[loop].flags & OP_SHIFT2) ? 2 : 0)));
693
694 printf(";\n");
695 }
696
697 return;
698}
699
e871dd18
JSC
700/*---------------------------------------------------------------------------*/
701
702typedef enum {
703 s_left,
704 s_right
705} e_endshift;
706
707static void
708build_endian_shift(proc64,datalen,endbit,direction,shift)
709 int proc64;
710 int datalen;
711 int endbit;
712 e_endshift direction;
713 int shift;
714{
715 if (proc64 && (datalen == 4)) {
716 printf(" if ((vaddr & (1 << %d)) ^ (BigEndianCPU << %d)) {\n",endbit,endbit);
717 printf(" memval %s= %d;\n",direction == s_left ? "<<" : ">>",shift);
718 printf(" }\n");
719 }
720
721 return;
722}
723
8ad57737
JSC
724/*---------------------------------------------------------------------------*/
725/* doisa = number of MIPS ISA simulator table is being constructed for.
726 * proc64 = TRUE if constructing 64bit processor world.
727 * dofp = boolean, TRUE if FP instructions are to be included.
728 * fpsingle = boolean, TRUE if only single precision FP instructions to be included.
729 */
730
731void
732process_instructions(doarch,features)
733 unsigned int doarch;
734 unsigned int features;
735{
736 int doisa = (doarch & MASK_ISA);
737 int limit = (sizeof(MIPS_DECODE) / sizeof(instruction));
738 int gprlen=((features & FEATURE_GP64) ? 64 : 32);
8ad57737
JSC
739 int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
740 int dofp = (features & FEATURE_HASFPU);
741 int fpsingle = (features & FEATURE_FPSINGLE);
8bae0a0c 742 int maxisa;
8ad57737
JSC
743 int loop;
744
745 if (limit < 1) {
746 fprintf(stderr,"process_instructions: invalid structure length\n");
747 exit(1);
748 }
749
750 if (proc64 && (gprlen != 64)) {
751 fprintf(stderr,"Error: 64bit processor build specified, with MIPS ISA I or II\n");
752 exit(3);
753 }
754
8ad57737
JSC
755 /* NOTE: "proc64" also differentiates between 32- and 64-bit wide memory */
756
8bae0a0c
JSC
757 maxisa = 0;
758 for (loop = 0; (loop < limit); loop++)
759 if ((MIPS_DECODE[loop].isa & MASK_ISA) > maxisa)
760 maxisa = (MIPS_DECODE[loop].isa & MASK_ISA);
761
762 if (doisa == 0)
763 doisa = maxisa;
764
8ad57737 765 printf("#if defined(SIM_MANIFESTS)\n");
8bae0a0c 766 printf("#define MIPSISA (%d)\n",doisa);
8ad57737
JSC
767 if (proc64)
768 printf("#define PROCESSOR_64BIT (1 == 1)\n");
c98ec95d
JSC
769 else
770 printf("#define PROCESSOR_64BIT (1 == 0)\n");
771#if 1 /* cheat: We only have a 64bit LoadMemory and StoreMemory routines at the moment */
772 printf("#define LOADDRMASK (0x%08X)\n",0x7);
773#else
8ad57737 774 printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
c98ec95d 775#endif
8bae0a0c 776 /* The FP registers are the same width as the CPU registers: */
8ad57737 777 printf("#define GPRLEN (%d)\n",gprlen);
8ad57737
JSC
778 printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
779 printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
8bae0a0c 780 printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
8ad57737
JSC
781 if (dofp)
782 printf("#define HASFPU (1 == 1)\n");
783 if (features & FEATURE_FAST)
784 printf("#define FASTSIM (1 == 1)\n");
785 if (features & FEATURE_WARN_STALL)
786 printf("#define WARN_STALL (1 == 1)\n");
787 if (features & FEATURE_WARN_LOHI)
788 printf("#define WARN_LOHI (1 == 1)\n");
789 if (features & FEATURE_WARN_ZERO)
790 printf("#define WARN_ZERO (1 == 1)\n");
791 if (features & FEATURE_WARN_MEM)
792 printf("#define WARN_MEM (1 == 1)\n");
793 if (features & FEATURE_WARN_R31)
794 printf("#define WARN_R31 (1 == 1)\n");
795 if (features & FEATURE_WARN_RESULT)
796 printf("#define WARN_RESULT (1 == 1)\n");
797
798 printf("#else /* simulator engine */\n");
799
800 printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
801 printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
802 if (dofp)
803 printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
804 printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
805
806 if (proc64) {
807 printf("#if !defined(PROCESSOR_64BIT)\n");
808 printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
809 printf("#endif\n");
810 }
811
812 printf("/* Actual instruction decoding block */\n");
813 printf("{\n");
8bae0a0c
JSC
814 {
815 int limit;
816 printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
817 limit = (OP_MASK_OP + 1);
818 printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
819 limit += (OP_MASK_SPEC + 1);
820 printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
821 limit += (OP_MASK_RT + 1);
822 printf("else if (num == 0x11) {\n");
823 printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
824 printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
825 printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
826 printf(" else\n");
827 printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
828 limit += (OP_MASK_SPEC + 1);
829 printf(" else\n");
830 /* To keep this code quick, we just clear out the "to" bit
831 here. The proper (though slower) code would be to have another
832 conditional, checking whether this instruction is a branch or
833 not, before limiting the range to the bottom two bits of the
834 move operation. */
835 printf(" num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
836 limit += (OP_MASK_COP1SPEC + 1);
837 printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
838 limit += (OP_MASK_SPEC + 1);
839 printf("/* Total possible switch entries: %d */\n",limit) ;
840 }
8ad57737
JSC
841 printf("switch (num)\n") ;
842 printf("{\n");
843
a9f7253f 844 for (loop = 0; (loop < limit); loop++) {
8ad57737
JSC
845 /* First check that the ISA number we are constructing for is
846 valid, before checking if the instruction matches any of the
847 architecture specific flags. NOTE: We allow a selected ISA of
848 zero to be used to match all standard instructions. */
8bae0a0c 849 if ((((MIPS_DECODE[loop].isa & MASK_ISA) <= doisa) && (((MIPS_DECODE[loop].isa & ~MASK_ISA) == 0) || ((MIPS_DECODE[loop].isa & ~MASK_ISA) & doarch) != 0)) && (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))) {
8ad57737
JSC
850 unsigned int onemask;
851 unsigned int zeromask;
852 unsigned int dontmask;
853 unsigned int mask;
854 unsigned int number;
855 unsigned int flags = convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
856 char *regtype = ((gprlen == 64) ? "uword64" : "unsigned int");
857
c98ec95d 858 if (!(MIPS_DECODE[loop].flags & COPROC) && ((GETDATASIZE() == DOUBLEWORD) && !proc64)) {
8ad57737
JSC
859 fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
860 exit(4);
861 }
862
863#if defined(DEBUG)
864 printf("/* DEBUG: onemask 0x%08X */\n",onemask) ;
865 printf("/* DEBUG: zeromask 0x%08X */\n",zeromask) ;
866 printf("/* DEBUG: dontmask 0x%08X */\n",dontmask) ;
867#endif
868
869 switch (MIPS_DECODE[loop].mark) {
870 case NORMAL :
871 mask = (OP_MASK_OP << OP_SH_OP) ;
872 number = ((onemask >> OP_SH_OP) & OP_MASK_OP) ;
873 break ;
874
875 case SPECIAL :
876 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
877 number = ((OP_MASK_OP + 1) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
878 break ;
879
880 case REGIMM :
881 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_RT << OP_SH_RT)) ;
882 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_RT) & OP_MASK_RT)) ;
883 break ;
884
885 case COP1 :
886 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
887 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
888 break ;
889
8bae0a0c
JSC
890 case COP1S :
891 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_COP1SPEC << OP_SH_COP1SPEC)) ;
892 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_COP1SPEC) & OP_MASK_COP1SPEC)) ;
893 break;
894
8ad57737
JSC
895 case COP1X :
896 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
8bae0a0c 897 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_COP1SPEC + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
8ad57737
JSC
898 break ;
899
900 default :
901 fprintf(stderr,"Unrecognised opcode mark %d in table slot %d \"%s\"\n",MIPS_DECODE[loop].mark,loop,MIPS_DECODE[loop].name) ;
902 exit(5) ;
903 }
904
905 printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
906
907#if defined(DEBUG)
908 printf("/* DEBUG: mask 0x%08X */\n",mask) ;
909 printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
910#endif
911
912 /* Check if there are any other explicit bits in the instruction: */
913 if ((~mask & (onemask | zeromask)) != 0x00000000) {
914 printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
915 printf(" {\n") ;
916 printf(" SignalException(ReservedInstruction,instruction);\n") ;
917 printf(" }\n") ;
918 printf(" else\n") ;
919 }
920
921 if ((flags == 0) && !(MIPS_DECODE[loop].flags & NOARG)) {
922 fprintf(stderr,"Bitmap error: Instruction with no operand fields \"%s\"\n",MIPS_DECODE[loop].name) ;
923 exit(5) ;
924 }
925
926 printf(" {\n") ;
927
928 /* Get hold of the operands */
929 /* NOTE: If we wanted to make the simulator code smaller, we
930 * could pull these into a common sequence before we perform
931 * the instruction decoding. However, this would affect the
932 * performance since unnecessary field extraction would be
933 * occurring for certain instructions.
934 *
935 * Also we do not perform checking for multiple definitions of a
936 * particular operand here, since they are caught by the
937 * compilation of the produced code.
938 */
939 build_operands(flags);
940
941 /* Finish constructing the jump address if required: */
942 if (flags & fieldval('j'))
943 printf(" op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */\n");
944
945 /* Now perform required operand checks: */
946
947/* The following code has been removed, since it seems perfectly
948 reasonable to have a non-aligned offset that is added to another
949 non-aligned base to create an aligned address. Some more
950 information on exactly what the MIPS IV specification requires is
951 needed before deciding on the best strategy. Experimentation with a
952 VR4300 suggests that we do not need to raise the warning. */
953#if 0
954 /* For MIPS IV (and onwards), certain instruction operand values
955 will give undefined results. For the simulator we could
956 generate explicit exceptions (i.e. ReservedInstruction) to
957 make it easier to spot invalid use. However, for the moment we
958 just raise a warning. NOTE: This is a different check to the
959 later decoding, which checks for the final address being
960 valid. */
8bae0a0c 961 if ((flags & (fieldval('e') | fieldval('w') | fieldval('h'))) && (doisa >= 4)) {
8ad57737
JSC
962 printf(" if (instruction & 0x%1X)\n",((flags & fieldval('e')) ? 0x7 : ((flags & fieldval('w')) ? 0x3 : 0x1)));
963 printf(" {\n");
964 /* NOTE: If we change this to a SignalException(), we must
965 ensure that the following opcode processing is not
966 executed. i.e. the code falls straight out to the simulator
967 control loop. */
968 printf(" WARNING(\"Instruction has lo-order offset bits set in instruction\");\n");
969 printf(" }\n");
970 }
971#endif
972
973 /* The extended condition codes only appeared in ISA IV */
8bae0a0c 974 if ((flags & fieldval('p')) && (doisa < 4)) {
8ad57737
JSC
975 printf(" if (condition_code != 0)\n");
976 printf(" {\n");
977 printf(" SignalException(ReservedInstruction,instruction);\n");
978 printf(" }\n");
979 printf(" else\n");
980 }
981
982 if ((MIPS_DECODE[loop].flags & WORD32) && (GETDATASIZE() != WORD)) {
983 fprintf(stderr,"Error in opcode table: WORD32 set for non-WORD opcode\n");
984 exit(1);
985 }
986
8bae0a0c
JSC
987#if 1
988 /* The R4000 book differs slightly from the MIPS IV ISA
989 manual. An example is the sign-extension of a 64-bit processor
990 SUBU operation, and what is meant by an Undefined Result. This
991 is now provided purely as a warning. After examining a HW
992 implementation, this is now purely a warning... and the actual
993 operation is performed, with possibly undefined results. */
994 if (((MIPS_DECODE[loop].flags & WORD32) && proc64) && (features & FEATURE_WARN_RESULT)) {
995 /* The compiler should optimise out an OR with zero */
996 printf(" if (%s | %s)\n",((flags & fieldval('s')) ? "NOTWORDVALUE(op1)" : "0"),((flags & fieldval('g')) ? "NOTWORDVALUE(op2)" : "0"));
997 printf(" UndefinedResult();\n") ;
998 }
999#else
8ad57737
JSC
1000 /* Check that the source is a 32bit value */
1001 if ((MIPS_DECODE[loop].flags & WORD32) && proc64) {
8bae0a0c 1002 /* The compiler should optimise out an OR with zero */
8ad57737
JSC
1003 printf(" if (%s | %s)\n",((flags & fieldval('s')) ? "NOTWORDVALUE(op1)" : "0"),((flags & fieldval('g')) ? "NOTWORDVALUE(op2)" : "0"));
1004 printf(" UndefinedResult();\n") ;
1005 printf(" else\n") ;
1006 }
8bae0a0c 1007#endif
8ad57737
JSC
1008
1009 printf(" {\n") ;
1010
1011 switch (MIPS_DECODE[loop].type) {
1012 /* TODO: To make these easier to edit and maintain, they should
1013 actually be provided as source macros (or inline functions)
8bae0a0c
JSC
1014 OUTSIDE this main switch statement. The PPC simulator has a
1015 neater scheme for describing the instruction sequences. */
8ad57737
JSC
1016
1017 case ADD:
8bae0a0c 1018 case SUB:
8ad57737 1019 {
4fa14cf7
SG
1020 char *signed_basetype = "unknown";
1021 char *unsigned_basetype = "unknown";
1022
8ad57737
JSC
1023 switch (GETDATASIZE()) {
1024 case WORD :
4fa14cf7
SG
1025 signed_basetype = "signed int";
1026 unsigned_basetype = "unsigned int";
8ad57737
JSC
1027 break;
1028 case DOUBLEWORD :
4fa14cf7
SG
1029 signed_basetype = "word64";
1030 unsigned_basetype = "uword64";
8ad57737
JSC
1031 break;
1032 default :
8bae0a0c 1033 fprintf(stderr,"Opcode table error: size of ADD/SUB operands not known (%d)\n",GETDATASIZE());
8ad57737
JSC
1034 exit(1);
1035 }
1036
1037 if ((MIPS_DECODE[loop].type) == ADD) {
4fa14cf7
SG
1038 printf(" %s temp = (%s)(op1 + op2);\n", unsigned_basetype, unsigned_basetype);
1039 printf(" %s tempS = (%s)temp;\n", signed_basetype, signed_basetype);
8bae0a0c
JSC
1040 if (MIPS_DECODE[loop].flags & OVERFLOW) {
1041 printf(" if (((op1 < 0) == (op2 < 0)) && ((tempS < 0) != (op1 < 0)))\n");
1042 printf(" SignalException(IntegerOverflow);\n");
1043 printf(" else\n");
1044 }
8ad57737
JSC
1045 if (!proc64 || (MIPS_DECODE[loop].flags & UNSIGNED) || (GETDATASIZE() == DOUBLEWORD))
1046 printf(" GPR[destreg] = (%s)temp;\n",regtype);
1047 else /* only sign-extend when placing 32bit result in 64bit processor */
1048 printf(" GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
1049 } else { /* SUB */
4fa14cf7
SG
1050 printf(" %s temp = (%s)(op1 - op2);\n", unsigned_basetype, unsigned_basetype);
1051 printf(" %s tempS = (%s)temp;\n", signed_basetype, signed_basetype);
8ad57737
JSC
1052 if (MIPS_DECODE[loop].flags & OVERFLOW) { /* different signs => overflow if result_sign != arg_sign */
1053 printf(" if (((op1 < 0) != (op2 < 0)) && ((tempS < 0) == (op1 < 0)))\n");
1054 printf(" SignalException(IntegerOverflow);\n");
1055 printf(" else\n");
1056 }
1057 /* UNSIGNED 32bit operations on a 64bit processor should
1058 *STILL* be sign-extended. We have cheated in the
1059 data-structure, by not marking it with UNSIGNED, and not
1060 setting OVERFLOW. */
1061 if (!proc64 || (MIPS_DECODE[loop].flags & UNSIGNED) || (GETDATASIZE() == DOUBLEWORD))
1062 printf(" GPR[destreg] = (%s)temp;\n",regtype);
1063 else /* only sign-extend when placing 32bit result in 64bit processor */
1064 printf(" GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
1065 }
1066 }
1067 break ;
1068
8bae0a0c 1069 case MUL:
8ad57737
JSC
1070 if (features & FEATURE_WARN_LOHI) {
1071 printf(" CHECKHILO(\"Multiplication\");\n");
1072 }
1073 printf(" {\n");
1074 if (GETDATASIZE() == DOUBLEWORD) {
1075 printf(" uword64 mid;\n");
1076 printf(" uword64 temp;\n");
a647a859
JSC
1077 printf(" LO = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n");
1078 printf(" HI = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n");
1079 printf(" mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
1080 printf(" temp = (LO + SET64HI(WORD64LO(mid)));\n");
8ad57737
JSC
1081 printf(" if ((temp == mid) ? (LO != 0) : (temp < mid))\n");
1082 printf(" HI += 1;\n");
a647a859
JSC
1083 printf(" HI += WORD64HI(mid);\n");
1084 printf(" mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
1085 printf(" LO = (temp + SET64HI(WORD64LO(mid)));\n");
8ad57737
JSC
1086 printf(" if ((LO == mid) ? (temp != 0) : (LO < mid))\n");
1087 printf(" HI += 1;\n");
a647a859 1088 printf(" HI += WORD64HI(mid);\n");
8ad57737
JSC
1089 } else {
1090 printf(" uword64 temp = (op1 * op2);\n");
a647a859
JSC
1091 printf(" LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
1092 printf(" HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
8ad57737
JSC
1093 }
1094 printf(" }\n");
1095 break ;
1096
8bae0a0c 1097 case DIV:
8ad57737
JSC
1098 {
1099 int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1100
1101 if (features & FEATURE_WARN_LOHI) {
1102 printf(" CHECKHILO(\"Division\");\n");
1103 }
1104 printf(" {\n");
1105 if (GETDATASIZE() == DOUBLEWORD) {
e871dd18
JSC
1106 printf(" LO = ((%sword64)op1 / (%sword64)op2);\n",(boolU ? "u" : ""),(boolU ? "u" : ""));
1107 printf(" HI = ((%sword64)op1 %c (%sword64)op2);\n",(boolU ? "u" : ""),'%',(boolU ? "u" : ""));
8ad57737
JSC
1108 } else {
1109 printf(" LO = SIGNEXTEND(((%sint)op1 / (%sint)op2),32);\n",(boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
1110 printf(" HI = SIGNEXTEND(((%sint)op1 %c (%sint)op2),32);\n",(boolU ? "unsigned " : ""),'%',(boolU ? "unsigned " : ""));
1111 }
1112 printf(" }\n");
1113 }
1114 break ;
1115
8bae0a0c 1116 case SHIFT:
8ad57737
JSC
1117 {
1118 int datalen = GETDATASIZE();
1119 int bits = ((datalen == WORD) ? 32 : 64);
1120 char *ltype = ((datalen == WORD) ? "unsigned int" : "uword64");
1121
1122 /* Check that the specified SHIFT is valid: */
1123 if ((datalen == BYTE) || (datalen == HALFWORD)) {
1124 fprintf(stderr,"Shift \"%s\" specified with BYTE or HALFWORD\n",MIPS_DECODE[loop].name);
1125 exit(9);
1126 }
1127 if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & RIGHT)) {
1128 fprintf(stderr,"Shift \"%s\" specified with both LEFT and RIGHT\n",MIPS_DECODE[loop].name);
1129 exit(9);
1130 }
1131 if (!(MIPS_DECODE[loop].flags & LEFT) && !(MIPS_DECODE[loop].flags & RIGHT)) {
1132 fprintf(stderr,"Shift \"%s\" specified with neither LEFT or RIGHT\n",MIPS_DECODE[loop].name);
1133 exit(9);
1134 }
1135 if ((MIPS_DECODE[loop].flags & LOGICAL) && (MIPS_DECODE[loop].flags & ARITHMETIC)) {
1136 fprintf(stderr,"Shift \"%s\" specified with both LOGICAL and ARITHMETIC\n",MIPS_DECODE[loop].name);
1137 exit(9);
1138 }
1139 if (!(MIPS_DECODE[loop].flags & LOGICAL) && !(MIPS_DECODE[loop].flags & ARITHMETIC)) {
1140 fprintf(stderr,"Shift \"%s\" specified with neither LOGICAL or ARITHMETIC\n",MIPS_DECODE[loop].name);
1141 exit(9);
1142 }
1143 if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & ARITHMETIC)) {
1144 fprintf(stderr,"Arithmetic LEFT shift \"%s\" specified\n",MIPS_DECODE[loop].name);
1145 exit(9);
1146 }
1147
1148 /* If register specified shift, then extract the relevant shift amount: */
1149 if (flags & fieldval('s'))
1150 printf(" op1 &= 0x%02X;\n",(bits - 1));
1151
1152 /* If HI32 specified, then shift range is 32..63 */
1153 if (MIPS_DECODE[loop].flags & HI32)
1154 printf(" op1 |= (1 << 6);\n");
1155
8bae0a0c
JSC
1156 /* We do not need to perform pre-masking with 0xFFFFFFFF when
1157 dealing with 32bit shift lefts, since the sign-extension
1158 code will replace any remaining hi-bits: */
1159 if (MIPS_DECODE[loop].flags & LEFT)
e871dd18 1160 printf(" GPR[destreg] = ((uword64)op2 << op1);\n");
8bae0a0c 1161 else
e871dd18 1162 printf(" GPR[destreg] = ((uword64)(op2%s) >> op1);\n",((bits == 32) ? " & 0xFFFFFFFF" : ""));
8ad57737
JSC
1163
1164 /* For ARITHMETIC shifts, we must duplicate the sign-bit */
1165 if (MIPS_DECODE[loop].flags & ARITHMETIC)
1166 printf(" GPR[destreg] |= ((op2 & ((%s)1 << %d)) ? ((((%s)1 << (op1 + 1)) - 1) << (%d - op1)) : 0);\n",ltype,(bits - 1),ltype,(bits - 1));
1167
1168 /* Ensure WORD values are sign-extended into 64bit registers */
1169 if ((bits == 32) && (gprlen == 64))
1170 printf(" GPR[destreg] = SIGNEXTEND(GPR[destreg],%d);\n",bits);
1171 }
1172 break ;
1173
8bae0a0c 1174 case MOVE:
8ad57737
JSC
1175 if (MIPS_DECODE[loop].flags & (HI | LO)) {
1176 char *regname = ((MIPS_DECODE[loop].flags & LO) ? "LO" : "HI");
1177 if (flags & fieldval('d'))
1178 printf(" GPR[destreg] = %s;\n",regname);
1179 else {
1180 if (features & FEATURE_WARN_LOHI) {
1181 printf(" if (%sACCESS != 0)\n",regname);
1182 printf(" WARNING(\"MT (move-to) over-writing %s register value\");\n",regname);
1183 }
1184 printf(" %s = op1;\n",regname);
1185 }
1186 if (features & FEATURE_WARN_LOHI)
1187 printf(" %sACCESS = 3; /* 3rd instruction will be safe */\n",regname);
1188 } else
1189 if (MIPS_DECODE[loop].flags & SHIFT16)
1190 printf(" GPR[destreg] = (op2 << 16);\n");
1191 else {
1192 /* perform conditional move */
1193 if (!(MIPS_DECODE[loop].flags & EQ)) {
1194 fprintf(stderr,"Standard conditional %s does not have the equality flag\n",MIPS_DECODE[loop].name);
1195 exit(8);
1196 }
1197 printf(" if (op2 %c= 0)\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1198 printf(" GPR[destreg] = op1;\n");
1199 }
1200 break ;
1201
8bae0a0c 1202 case SYNC:
8ad57737
JSC
1203 printf(" SyncOperation(op1);\n");
1204 break ;
1205
8bae0a0c 1206 case SYSCALL:
8ad57737
JSC
1207 printf(" SignalException(SystemCall);\n");
1208 break ;
1209
8bae0a0c 1210 case BREAK:
8ad57737
JSC
1211 printf(" SignalException(BreakPoint);\n");
1212 break ;
1213
8bae0a0c 1214 case TRAP:
8ad57737
JSC
1215 {
1216 int boolNOT = (MIPS_DECODE[loop].flags & NOT);
1217 int boolEQ = (MIPS_DECODE[loop].flags & EQ);
1218 int boolGT = (MIPS_DECODE[loop].flags & GT);
1219 int boolLT = (MIPS_DECODE[loop].flags & LT);
1220 int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1221
1222 if (boolGT && boolLT) {
1223 fprintf(stderr,"GT and LT specified for \"%s\"\n",MIPS_DECODE[loop].name);
1224 exit(8);
1225 }
1226
1227 if (boolNOT && (boolGT || boolLT)) {
1228 fprintf(stderr,"NOT specified with GT or LT specified for \"%s\"\n",MIPS_DECODE[loop].name);
1229 exit(8);
1230 }
1231
e871dd18 1232 printf(" if ((%sword64)op1 ",(boolU ? "u" : ""));
8ad57737 1233 printf("%c%s",(boolNOT ? '!' : (boolLT ? '<' : (boolGT ? '>' : '='))),(boolEQ ? "=" : ""));
e871dd18 1234 printf(" (%sword64)op2)\n",(boolU ? "u" : ""));
8ad57737
JSC
1235 printf(" SignalException(Trap);\n");
1236 }
1237 break ;
1238
8bae0a0c 1239 case SET:
8ad57737
JSC
1240 {
1241 int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1242
1243 if (!(MIPS_DECODE[loop].flags & LT)) {
1244 fprintf(stderr,"Set instruction without LT specified \"%s\"\n",MIPS_DECODE[loop].name);
1245 exit(8);
1246 }
1247
e871dd18 1248 printf(" if ((%sword64)op1 < (%sword64)op2)\n",(boolU ? "u" : ""),(boolU ? "u" : ""));
8ad57737
JSC
1249 printf(" GPR[destreg] = 1;\n");
1250 printf(" else\n");
1251 printf(" GPR[destreg] = 0;\n");
1252 }
1253 break ;
1254
8bae0a0c 1255 case AND:
8ad57737
JSC
1256 printf(" GPR[destreg] = (op1 & op2);\n");
1257 break ;
1258
8bae0a0c 1259 case OR:
8ad57737
JSC
1260 printf(" GPR[destreg] = (%sop1 | op2);\n",((MIPS_DECODE[loop].flags & NOT) ? "~" : ""));
1261 break ;
1262
8bae0a0c 1263 case XOR:
8ad57737
JSC
1264 printf(" GPR[destreg] = (op1 ^ op2);\n");
1265 break ;
1266
8bae0a0c 1267 case DECODE:
8ad57737
JSC
1268 printf(" decode_coproc(instruction);\n");
1269 break ;
1270
8bae0a0c 1271 case CACHE:
8ad57737
JSC
1272 /* 16-bit offset is sign-extended and added to the base register to make a virtual address */
1273 /* The virtual address is translated to a physical address using the TLB */
1274 /* The hint specifies a cache operation for that address */
1275 printf(" uword64 vaddr = (op1 + offset);\n");
1276 printf(" uword64 paddr;\n");
1277 printf(" int uncached;\n");
1278 /* NOTE: We are assuming that the AddressTranslation is a load: */
1279 printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
1280 printf(" CacheOp(hint,vaddr,paddr,instruction);\n");
1281 break;
1282
8bae0a0c 1283 case MADD16: /* VR4100 specific multiply-add instructions */
8ad57737
JSC
1284 /* Some of this code is shared with the standard multiply
1285 routines, so an effort should be made to merge where
1286 possible. */
1287 if (features & FEATURE_WARN_LOHI) {
1288 printf(" CHECKHILO(\"Multiply-Add\");\n");
1289 }
1290 if (features & FEATURE_WARN_RESULT) {
1291 /* Give user a warning if either op1 or op2 are not 16bit signed integers */
1292 printf(" if (NOTHALFWORDVALUE(op1) || NOTHALFWORDVALUE(op2))\n");
1293 printf(" WARNING(\"MADD16 operation with non-16bit operands\");\n");
1294 }
1295 printf(" {\n");
1296 printf(" uword64 temp = (op1 * op2);\n"); /* 16x16 multiply */
1297 if (GETDATASIZE() == DOUBLEWORD) {
1298 printf(" LO = LO + temp;\n");
1299 } else { /* WORD */
a647a859
JSC
1300 printf(" temp += (SET64HI(WORD64LO(HI)) | WORD64LO(LO));\n");
1301 printf(" LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
1302 printf(" HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
8ad57737
JSC
1303 }
1304 printf(" }\n");
1305 break;
1306
8bae0a0c
JSC
1307 case RSVD: /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "CoProcessorUnusable" */
1308 if (doisa < 4) {
8ad57737
JSC
1309 printf(" if (CoProcPresent(3))\n");
1310 printf(" SignalException(CoProcessorUnusable);\n");
1311 printf(" else\n");
1312 }
1313 printf(" SignalException(ReservedInstruction,instruction);\n");
1314 break ;
1315
8bae0a0c 1316 case JUMP:
8ad57737
JSC
1317 if (MIPS_DECODE[loop].flags & LINK) {
1318 if (!(MIPS_DECODE[loop].flags & REG))
1319 printf(" int destreg = 31;\n");
1320 printf(" GPR[destreg] = (PC + 4); /* NOTE: The PC is already 4 ahead within the simulator */\n");
1321 }
1322
1323 printf(" /* NOTE: The jump occurs AFTER the next instruction has been executed */\n");
1324 printf(" DSPC = op1;\n");
1325 printf(" DELAYSLOT();\n");
1326 break ;
1327
8bae0a0c
JSC
1328 case BRANCH: /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
1329 if (MIPS_DECODE[loop].flags & FP) {
1330 if (doisa < 4) {
1331 printf(" if (condition_code != 0)\n");
1332 printf(" SignalException(ReservedInstruction,instruction);\n");
1333 printf(" else {\n");
1334 }
1335 /* "PREVCOC1()" should be the COC1 value at the start of the preceding instruction */
1336 printf(" int condition = (%s == boolean);\n",((doisa < 4) ? "PREVCOC1()" : "GETFCC(condition_code)"));
1337 } else {
1338 if ((MIPS_DECODE[loop].flags & NOT) && !(MIPS_DECODE[loop].flags & EQ)) {
1339 fprintf(stderr,"NOT specified when not EQ in \"%s\"\n",MIPS_DECODE[loop].name);
1340 exit(7);
1341 }
1342 if ((MIPS_DECODE[loop].flags & NOT) && (MIPS_DECODE[loop].flags & (GT | LT))) {
1343 fprintf(stderr,"NOT specified with GT or LT in \"%s\"\n",MIPS_DECODE[loop].name);
1344 exit(7);
1345 }
1346 /* GT LT */
1347 if (MIPS_DECODE[loop].flags & GT)
1348 printf(" int condition = (op1 >%s 0);\n",((MIPS_DECODE[loop].flags & EQ) ? "=" : ""));
1349 else
1350 if (MIPS_DECODE[loop].flags & LT)
1351 printf(" int condition = (op1 <%s 0);\n",((MIPS_DECODE[loop].flags & EQ) ? "=" : ""));
1352 else
1353 if (MIPS_DECODE[loop].flags & EQ)
1354 printf(" int condition = (op1 %c= op2);\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
8ad57737 1355 }
8ad57737
JSC
1356
1357 if (MIPS_DECODE[loop].flags & LINK) {
1358 if (features & FEATURE_WARN_R31) {
1359 printf(" if (((instruction >> %d) & 0x%08X) == 31)\n",OP_SH_RS,OP_MASK_RS);
1360 printf(" WARNING(\"Branch with link using r31 as source operand\");\n");
1361 }
1362 printf(" GPR[31] = (PC + 4); /* NOTE: PC is already 8 ahead */\n");
1363 }
1364
1365 printf(" /* NOTE: The branch occurs AFTER the next instruction has been executed */\n");
1366 printf(" if (condition) {\n");
1367 printf(" DSPC = (PC + offset);\n");
1368 printf(" DELAYSLOT();\n");
1369 printf(" }\n");
8bae0a0c
JSC
1370 if ((MIPS_DECODE[loop].flags & FP) && (doisa != 1)) {
1371 printf(" else if (likely) {\n");
1372 printf(" NULLIFY();\n");
1373 printf(" }\n");
1374 } else if (MIPS_DECODE[loop].flags & LIKELY) {
8ad57737
JSC
1375 printf(" else\n");
1376 printf(" NULLIFY();\n");
1377 }
8bae0a0c
JSC
1378 if ((MIPS_DECODE[loop].flags & FP) && (doisa < 4))
1379 printf(" }\n");
8ad57737
JSC
1380 break ;
1381
8bae0a0c
JSC
1382 case PREFETCH: /* The beginning is shared with normal load operations */
1383 case LOAD:
1384 case STORE:
8ad57737
JSC
1385 {
1386 int isload = ((MIPS_DECODE[loop].type == LOAD) || (MIPS_DECODE[loop].type == PREFETCH));
1387 int datalen;
1388 char *accesslength = "<UNKNOWN>";
1389
1390 switch (GETDATASIZE()) {
1391 case BYTE :
1392 datalen = 1;
1393 accesslength = "AccessLength_BYTE";
1394 break ;
1395
1396 case HALFWORD :
1397 datalen = 2;
1398 accesslength = "AccessLength_HALFWORD";
1399 break ;
1400
1401 case WORD :
1402 datalen = 4;
1403 accesslength = "AccessLength_WORD";
1404 break ;
1405
1406 case DOUBLEWORD :
1407 datalen = 8;
1408 accesslength = "AccessLength_DOUBLEWORD";
1409 break ;
1410 }
1411
8bae0a0c 1412 if (MIPS_DECODE[loop].flags & REG)
e871dd18 1413 printf(" uword64 vaddr = ((uword64)op1 + op2);\n");
8bae0a0c 1414 else
e871dd18 1415 printf(" uword64 vaddr = ((uword64)op1 + offset);\n");
8ad57737
JSC
1416 printf(" uword64 paddr;\n");
1417 printf(" int uncached;\n");
1418
1419 /* The following check should only occur on normal (non-shifted) memory loads */
1420 if ((datalen != 1) && !(MIPS_DECODE[loop].flags & (LEFT | RIGHT))) {
1421 printf(" if ((vaddr & %d) != 0)\n",(datalen - 1));
1422 printf(" SignalException(%s);\n",(isload ? "AddressLoad" : "AddressStore"));
1423 printf(" else\n") ;
1424 }
1425
1426 printf(" {\n");
1427 printf(" if (AddressTranslation(vaddr,isDATA,%s,&paddr,&uncached,isTARGET,isREAL))\n",(isload ? "isLOAD" : "isSTORE"));
1428
1429 if (MIPS_DECODE[loop].type == PREFETCH)
1430 printf(" Prefetch(uncached,paddr,vaddr,isDATA,hint);\n");
1431 else {
1432 printf(" {\n");
1433 printf(" %s memval;\n",(proc64 ? "uword64" : "unsigned int"));
1434
8bae0a0c
JSC
1435 if ((MIPS_DECODE[loop].flags & COPROC) && ((datalen != 4) && (datalen != 8))) {
1436 fprintf(stderr,"Co-processor transfer operation not WORD or DOUBLEWORD in length \"%s\"\n",MIPS_DECODE[loop].name);
1437 exit(6);
1438 }
8ad57737 1439
8bae0a0c
JSC
1440 if (MIPS_DECODE[loop].flags & (LEFT | RIGHT)) {
1441 if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & RIGHT)) {
1442 fprintf(stderr,"Memory transfer with both LEFT and RIGHT specified \"%s\"\n",MIPS_DECODE[loop].name);
1443 exit(4);
8ad57737 1444 }
8ad57737 1445
8bae0a0c
JSC
1446 switch (datalen) {
1447 case 8:
1448 if (!proc64) {
1449 fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",MIPS_DECODE[loop].name);
1450 exit(4);
1451 }
1452 /* fall through to... */
1453 case 4:
1454 {
1455 char *maskstr = ((datalen == 8) ? "((uword64)-1)" : "0xFFFFFFFF");
1456
1457 printf(" uword64 mask = %d;\n",((datalen == 8) ? 0x7 : 0x3));
1458 printf(" unsigned int reverse = (ReverseEndian ? mask : 0);\n");
1459 printf(" unsigned int bigend = (BigEndianCPU ? mask : 0);\n");
1460 printf(" int byte;\n");
1461 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));\n");
1462 printf(" byte = ((vaddr & mask) ^ bigend);\n");
1463 printf(" if (%sBigEndianMem)\n",((MIPS_DECODE[loop].flags & LEFT) ? "!" : ""));
1464 printf(" paddr &= ~mask;\n");
1465
1466 if (isload) {
1467 if (MIPS_DECODE[loop].flags & LEFT)
1468 printf(" memval = LoadMemory(uncached,byte,paddr,vaddr,isDATA,isREAL);\n");
1469 else
1470 printf(" memval = LoadMemory(uncached,(%d - byte),paddr,vaddr,isDATA,isREAL);\n",(datalen - 1));
8ad57737 1471 }
8ad57737 1472
8bae0a0c 1473 if (MIPS_DECODE[loop].flags & LEFT) {
8ad57737 1474 if (isload) {
8bae0a0c
JSC
1475 /* For WORD transfers work out if the value will
1476 be in the top or bottom of the DOUBLEWORD
1477 returned: */
e871dd18
JSC
1478#if 1
1479 build_endian_shift(proc64,datalen,2,s_right,32);
1480#else
8bae0a0c
JSC
1481 if (proc64 && (datalen == 4)) {
1482 printf(" if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1483 printf(" memval >>= 32;\n");
1484 printf(" }\n");
8ad57737 1485 }
e871dd18 1486#endif
8bae0a0c
JSC
1487 printf(" GPR[destreg] = ((memval << ((%d - byte) * 8)) | (GPR[destreg] & (((uword64)1 << ((%d - byte) * 8)) - 1)));\n",(datalen - 1),(datalen - 1));
1488 if (proc64 && (datalen == 4))
1489 printf(" GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
1490 } else { /* store */
1491 printf(" memval = (op2 >> (8 * (%d - byte)));\n",(datalen - 1));
e871dd18
JSC
1492#if 1
1493 build_endian_shift(proc64,datalen,2,s_left,32);
1494#else
8bae0a0c
JSC
1495 /* TODO: This is duplicated in the LOAD code
1496 above - and the RIGHT LOAD and STORE code
1497 below. It should be merged if possible. */
1498 if (proc64 && (datalen == 4)) {
1499 printf(" if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1500 printf(" memval <<= 32;\n");
1501 printf(" }\n");
8ad57737 1502 }
e871dd18 1503#endif
8bae0a0c
JSC
1504 printf(" StoreMemory(uncached,byte,memval,paddr,vaddr,isREAL);\n");
1505 }
1506 } else { /* RIGHT */
1507 if (isload) {
e871dd18
JSC
1508#if 1
1509 build_endian_shift(proc64,datalen,2,s_right,32);
1510#else
8bae0a0c
JSC
1511 if (proc64 && (datalen == 4)) {
1512 printf(" if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1513 printf(" memval >>= 32;\n");
1514 printf(" }\n");
1515 }
e871dd18 1516#endif
8bae0a0c
JSC
1517 printf(" {\n");
1518 printf(" uword64 srcmask;\n");
1519 /* All of this extra code is just a bodge
1520 required because some hosts don't allow
1521 ((v) << 64). The SPARC just leaves the (v)
1522 value un-touched. */
1523 printf(" if (byte == 0)\n");
1524 printf(" srcmask = 0;\n");
1525 printf(" else\n");
1526 printf(" srcmask = ((uword64)-1 << (8 * (%d - byte)));\n",datalen);
1527 printf(" GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));\n",datalen);
1528 printf(" }\n");
1529 if (proc64 && (datalen == 4))
1530 printf(" GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
1531 } else { /* store */
1532 printf(" memval = (op2 << (byte * 8));\n");
1533 printf(" StoreMemory(uncached,(%s - byte),memval,paddr,vaddr,isREAL);\n",accesslength);
8ad57737
JSC
1534 }
1535 }
8ad57737 1536 }
8bae0a0c 1537 break;
8ad57737 1538
8bae0a0c
JSC
1539 default:
1540 fprintf(stderr,"Shifted memory transfer not WORD or DOUBLEWORD in length \"%s\"\n",MIPS_DECODE[loop].name);
1541 exit(6);
1542 }
1543 } else { /* normal memory transfer */
c98ec95d 1544 if (!(MIPS_DECODE[loop].flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (MIPS_DECODE[loop].flags & UNSIGNED))) && !proc64) {
8bae0a0c
JSC
1545 fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",MIPS_DECODE[loop].name);
1546 exit(4);
1547 /* TODO: The R4000 documentation states that a LWU
1548 instruction executed when in a 32bit processor mode
1549 should cause a ReservedInstruction exception. This
1550 will mean adding a run-time check into the code
1551 sequence. */
1552 }
8ad57737 1553
8bae0a0c 1554 if (isload) {
c98ec95d
JSC
1555#if 1 /* see the comments attached to LOADDRMASK above */
1556 printf(" uword64 mask = 0x7;\n");
1557#else
8bae0a0c 1558 printf(" uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
c98ec95d 1559#endif
8bae0a0c
JSC
1560 printf(" unsigned int shift = %d;\n",(datalen >> 1));
1561 printf(" unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
1562 printf(" unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
1563 printf(" unsigned int byte;\n");
8ad57737 1564
c98ec95d 1565/* TODO: This should really also check for 32bit world performing 32bit access */
8bae0a0c
JSC
1566 if (datalen != 8) /* not for DOUBLEWORD */
1567 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
8ad57737 1568
8bae0a0c 1569 printf(" memval = LoadMemory(uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
8ad57737 1570
8bae0a0c
JSC
1571 /* The following will only make sense if the
1572 "LoadMemory" above returns a DOUBLEWORD entity */
1573 if (datalen != 8) { /* not for DOUBLEWORD */
1574 int valmask;
1575 switch (datalen) {
1576 case 1:
1577 valmask = 0xFF;
1578 break;
1579
1580 case 2:
1581 valmask = 0xFFFF;
1582 break;
1583
1584 case 4:
1585 valmask = 0xFFFFFFFF;
1586 break;
1587
1588 default:
1589 fprintf(stderr,"Unrecognised datalen (%d) when processing \"%s\"\n",datalen,MIPS_DECODE[loop].name);
1590 exit(4);
1591 }
1592 printf(" byte = ((vaddr & mask) ^ (bigend << shift));\n");
1593 /* NOTE: The R4000 user manual has the COP_LW
1594 occuring in the same cycle as the rest of the
1595 instruction, yet the MIPS IV shows the operation
1596 happening on the next cycle. To keep the simulator
1597 simple, this code follows the R4000
1598 manual. Experimentation with a silicon
1599 implementation will be needed to ascertain the
1600 correct operation. */
1601 if (MIPS_DECODE[loop].flags & COPROC)
1602 printf(" COP_LW(((instruction >> 26) & 0x3),destreg,(unsigned int)");
1603 else
1604 printf(" GPR[destreg] = (");
1605
1606 if (MIPS_DECODE[loop].flags & SIGNEXTEND)
1607 printf("SIGNEXTEND(");
1608 printf("((memval >> (8 * byte)) & 0x%08X)",valmask);
1609 if (MIPS_DECODE[loop].flags & SIGNEXTEND)
1610 printf(",%d)",(datalen * 8));
1611 printf(");\n");
1612 } else {
1613 if (MIPS_DECODE[loop].flags & COPROC)
1614 printf(" COP_LD(((instruction >> 26) & 0x3),destreg,memval);;\n");
1615 else
1616 printf(" GPR[destreg] = memval;\n");
1617 }
1618 } else { /* store operation */
1619 if ((datalen == 1) || (datalen == 2)) {
1620 /* SH and SB */
c98ec95d
JSC
1621#if 1 /* see the comments attached to LOADDRMASK above */
1622 printf(" uword64 mask = 0x7;\n");
1623#else
8bae0a0c 1624 printf(" uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
c98ec95d 1625#endif
8bae0a0c
JSC
1626 printf(" unsigned int shift = %d;\n",(datalen >> 1));
1627 printf(" unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
1628 printf(" unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
1629 printf(" unsigned int byte;\n");
8ad57737 1630
8bae0a0c
JSC
1631 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
1632 printf(" byte = ((vaddr & mask) ^ (bigend << shift));\n");
1633 printf(" memval = (op2 << (8 * byte));\n");
1634 } else
1635 if (proc64 && (datalen == 4)) { /* proc64 SC and SW */
c98ec95d
JSC
1636#if 1 /* see the comments attached to LOADDRMASK above */
1637 printf(" uword64 mask = 0x7;\n");
1638#else
1639 printf(" uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
1640#endif
8bae0a0c 1641 printf(" unsigned int byte;\n");
c98ec95d
JSC
1642 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2)));\n");
1643 printf(" byte = ((vaddr & mask) ^ (BigEndianCPU << 2));\n");
8bae0a0c 1644 if (MIPS_DECODE[loop].flags & COPROC)
e871dd18 1645 printf(" memval = (((uword64)COP_SW(((instruction >> 26) & 0x3),%s)) << (8 * byte));\n",((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
8bae0a0c
JSC
1646 else
1647 printf(" memval = (op2 << (8 * byte));\n");
1648 } else { /* !proc64 SC and SW, plus proc64 SD and SCD */
1649 if (MIPS_DECODE[loop].flags & COPROC)
e871dd18 1650 printf(" memval = (uword64)COP_S%c(((instruction >> 26) & 0x3),%s);\n",((datalen == 8) ? 'D' : 'W'),((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
8bae0a0c
JSC
1651 else
1652 printf(" memval = op2;\n");
1653 }
1654
1655 if (MIPS_DECODE[loop].flags & ATOMIC)
1656 printf(" if (LLBIT)\n");
1657
1658 printf(" {\n");
1659 printf(" StoreMemory(uncached,%s,memval,paddr,vaddr,isREAL);\n",accesslength);
1660 printf(" }\n");
1661 }
8ad57737 1662
8bae0a0c
JSC
1663 if (MIPS_DECODE[loop].flags & ATOMIC) {
1664 if ((datalen != 4) && (datalen != 8)) {
1665 fprintf(stderr,"ATOMIC can only be applied to WORD and DOUBLEWORD instructions \"%s\"\n",MIPS_DECODE[loop].name);
1666 exit(4);
1667 } else
1668 if (isload)
1669 printf(" LLBIT = 1;\n");
1670 else {
1671 /* The documentation states that:
1672
1673 SC *WILL* fail if coherent store into the same
1674 block occurs, or if an exception occurs between
1675 the LL and SC instructions.
1676
1677 SC *MAY* fail if a load, store or prefetch is
1678 executed on the processor (VR4300 doesn't seem
1679 to), or if the instructions between the LL and
1680 SC are not in a 2048byte contiguous VM range.
1681
1682 SC *MUST* have been preceded by an LL
1683 (i.e. LLBIT will be set), and it must use the
1684 same Vaddr, Paddr and cache-coherence algorithm
1685 as the LL (which means we should store this
1686 information from the load-conditional).
1687 */
1688 printf(" GPR[(instruction >> %d) & 0x%08X] = LLBIT;\n",OP_SH_RT,OP_MASK_RT);
1689 }
1690 }
1691 }
8ad57737
JSC
1692 printf(" }\n");
1693 }
1694 printf(" }\n");
1695 }
1696 break ;
1697
8bae0a0c
JSC
1698 case FPPREFX:
1699 /* This code could be merged with the PREFIX generation above: */
e871dd18 1700 printf(" uword64 vaddr = ((uword64)op1 + (uword64)op2);\n");
8bae0a0c
JSC
1701 printf(" uword64 paddr;\n");
1702 printf(" int uncached;\n");
1703 printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
1704 printf(" Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
8ad57737
JSC
1705 break ;
1706
8bae0a0c
JSC
1707 case FPMOVEC:
1708 if (MIPS_DECODE[loop].flags & CONTROL) {
1709 /* The following "magic" of interpreting the FP
1710 control-register number would not be needed if we were not
1711 trying to match our internal register numbers with those
1712 used by GDB. */
1713 printf(" if (to) {\n");
1714 if (doisa < 4) {
1715 printf(" if (fs == 0) {\n");
a647a859 1716 printf(" PENDING_FILL((fs + FCR0IDX),WORD64LO(GPR[ft]));\n");
8bae0a0c 1717 printf(" } else if (fs == 31) {\n");
a647a859 1718 printf(" PENDING_FILL((fs + FCR31IDX),WORD64LO(GPR[ft]));\n");
8bae0a0c
JSC
1719 printf(" } /* else NOP */\n");
1720 printf(" PENDING_FILL(COCIDX,0); /* special case */\n");
1721 } else {
1722 printf(" if (fs == 0) {\n");
a647a859 1723 printf(" FCR0 = WORD64LO(GPR[ft]);\n");
8bae0a0c 1724 printf(" } else if (fs == 31) {\n");
a647a859 1725 printf(" FCR31 = WORD64LO(GPR[ft]);\n");
8bae0a0c
JSC
1726 printf(" } /* else NOP */\n");
1727 printf(" SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0)); /* COC[1] */\n");
1728 }
1729 printf(" } else { /* control from */\n");
1730 if (doisa < 4) {
1731 printf(" if (fs == 0) {\n");
1732 printf(" PENDING_FILL(ft,SIGNEXTEND(FCR0,32));\n");
1733 printf(" } else if (fs == 31) {\n");
1734 printf(" PENDING_FILL(ft,SIGNEXTEND(FCR31,32));\n");
1735 printf(" } /* else NOP */\n");
1736 } else {
1737 printf(" if (fs == 0) {\n");
1738 printf(" GPR[ft] = SIGNEXTEND(FCR0,32);\n");
1739 printf(" } else if (fs == 31) {\n");
1740 printf(" GPR[ft] = SIGNEXTEND(FCR31,32);\n");
1741 printf(" } /* else NOP */\n");
1742 }
1743 printf(" }\n");
1744 } else {
1745 printf(" if (to) {\n");
1746 if (GETDATASIZE() == WORD) {
1747 if (doisa < 4) {
1748 printf(" if (SizeFGR() == 64) {\n");
a647a859 1749 printf(" PENDING_FILL((fs + FGRIDX),(SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft])));\n");
8bae0a0c 1750 printf(" } else { \n");
a647a859 1751 printf(" PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
8bae0a0c
JSC
1752 printf(" }\n");
1753 } else {
1754 printf(" if (SizeFGR() == 64)\n");
a647a859 1755 printf(" FGR[fs] = (SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft]));\n");
8bae0a0c 1756 printf(" else\n");
a647a859 1757 printf(" FGR[fs] = WORD64LO(GPR[ft]);\n");
8bae0a0c
JSC
1758 printf(" fpr_state[fs] = fmt_uninterpreted;\n");
1759 }
1760 } else if (GETDATASIZE() == DOUBLEWORD) {
1761 if (doisa < 4) {
1762 printf(" if (SizeFGR() == 64) {\n");
1763 printf(" PENDING_FILL((fs + FGRIDX),GPR[ft]);\n");
1764 printf(" } else\n");
1765 printf(" if ((fs & 0x1) == 0)\n");
1766 printf(" {\n");
a647a859
JSC
1767 printf(" PENDING_FILL(((fs + 1) + FGRIDX),WORD64HI(GPR[ft]));\n");
1768 printf(" PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
8bae0a0c
JSC
1769 printf(" }\n");
1770 if (features & FEATURE_WARN_RESULT) {
1771 printf(" else\n");
1772 printf(" UndefinedResult();\n");
1773 }
1774 } else {
1775 printf(" if (SizeFGR() == 64) {\n");
1776 printf(" FGR[fs] = GPR[ft];\n");
1777 printf(" fpr_state[fs] = fmt_uninterpreted;\n");
1778 printf(" } else\n");
1779 printf(" if ((fs & 0x1) == 0)\n");
1780 printf(" {\n");
a647a859
JSC
1781 printf(" FGR[fs + 1] = WORD64HI(GPR[ft]);\n");
1782 printf(" FGR[fs] = WORD64LO(GPR[ft]);\n");
8bae0a0c
JSC
1783 printf(" fpr_state[fs + 1] = fmt_uninterpreted;\n");
1784 printf(" fpr_state[fs] = fmt_uninterpreted;\n");
1785 printf(" }\n");
1786 if (features & FEATURE_WARN_RESULT) {
1787 printf(" else\n");
1788 printf(" UndefinedResult();\n");
1789 }
1790 }
1791 } else {
1792 fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
1793 exit(1);
1794 }
1795 printf(" } else {\n");
1796 if (GETDATASIZE() == WORD) {
1797 if (doisa < 4) /* write-back occurs in next cycle */
1798 printf(" PENDING_FILL(ft,SIGNEXTEND(FGR[fs],32));\n");
1799 else /* in this cycle */
1800 printf(" GPR[ft] = SIGNEXTEND(FGR[fs],32);\n");
1801 } else if (GETDATASIZE() == DOUBLEWORD) {
1802 if (doisa < 4) {
1803 printf(" if (SizeFGR() == 64) {\n");
1804 printf(" PENDING_FILL(ft,FGR[fs]);\n");
1805 printf(" } else\n");
1806 printf(" if ((fs & 0x1) == 0) {\n");
a647a859 1807 printf(" PENDING_FILL(ft,(SET64HI(FGR[fs+1]) | FGR[fs]));\n");
8bae0a0c 1808 printf(" } else {\n");
a647a859 1809 printf(" PENDING_FILL(ft,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
8bae0a0c
JSC
1810 if (features & FEATURE_WARN_RESULT)
1811 printf(" UndefinedResult();\n");
1812 printf(" }\n");
1813 } else {
1814 printf(" if (SizeFGR() == 64)\n");
1815 printf(" GPR[ft] = FGR[fs];\n");
1816 printf(" else\n");
1817 printf(" if ((fs & 0x1) == 0)\n");
a647a859 1818 printf(" GPR[ft] = (SET64HI(FGR[fs + 1]) | FGR[fs]);\n");
8bae0a0c 1819 printf(" else {\n");
a647a859 1820 printf(" GPR[ft] = (SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
8bae0a0c
JSC
1821 if (features & FEATURE_WARN_RESULT)
1822 printf(" UndefinedResult();\n");
1823 printf(" }\n");
1824 }
1825 } else {
1826 fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
1827 exit(1);
1828 }
1829 printf(" }\n");
1830 }
8ad57737
JSC
1831 break ;
1832
8bae0a0c
JSC
1833 case FPMOVE:
1834 if (MIPS_DECODE[loop].flags & CONDITIONAL) {
1835 if (MIPS_DECODE[loop].flags & INTEGER) { /* moving GPR - testing FGR */
1836 printf(" if (GETFCC(condition_code) == boolean)\n");
1837 printf(" GPR[destreg] = op1;\n");
1838 } else {
1839 if (MIPS_DECODE[loop].flags & EQ) /* moving FGR - testing GPR */
1840 printf(" if (op2 %c= 0)\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1841 else
1842 printf(" if (GETFCC(condition_code) == boolean)\n");
1843 printf(" StoreFPR(destreg,format,ValueFPR(fs,format));\n");
1844 printf(" else\n");
1845 printf(" StoreFPR(destreg,format,ValueFPR(destreg,format));\n");
1846 }
1847 } else { /* simple MOVE */
1848 printf(" StoreFPR(destreg,format,ValueFPR(fs,format));\n");
1849 }
8ad57737
JSC
1850 break ;
1851
8bae0a0c
JSC
1852 case FPNEG:
1853 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1854 printf(" SignalException(ReservedInstruction,instruction);\n");
1855 printf(" else\n");
1856 printf(" StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));\n");
8ad57737
JSC
1857 break ;
1858
8bae0a0c
JSC
1859 case FPABS:
1860 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1861 printf(" SignalException(ReservedInstruction,instruction);\n");
1862 printf(" else\n");
1863 printf(" StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));\n");
8ad57737
JSC
1864 break ;
1865
8bae0a0c
JSC
1866 case FPDIV:
1867 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1868 printf(" SignalException(ReservedInstruction,instruction);\n");
1869 printf(" else\n");
1870 printf(" StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
8ad57737
JSC
1871 break ;
1872
8bae0a0c
JSC
1873 case FPMUL:
1874 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1875 printf(" SignalException(ReservedInstruction,instruction);\n");
1876 printf(" else\n");
1877 printf(" StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
8ad57737
JSC
1878 break ;
1879
8bae0a0c
JSC
1880 case FPRECIP:
1881 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1882 printf(" SignalException(ReservedInstruction,instruction);\n");
1883 printf(" else\n");
1884 printf(" StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));\n");
8ad57737
JSC
1885 break ;
1886
8bae0a0c
JSC
1887 case FPSQRT:
1888 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1889 printf(" SignalException(ReservedInstruction,instruction);\n");
1890 printf(" else\n");
1891 printf(" StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)));\n",((MIPS_DECODE[loop].flags & RECIP) ? "Recip" : ""));
8ad57737
JSC
1892 break ;
1893
8bae0a0c
JSC
1894 case FPCEIL:
1895 case FPFLOOR:
1896 case FPTRUNC:
1897 case FPROUND:
1898 {
1899 char *op = "";
1900 char *type = "";
8ad57737 1901
8bae0a0c
JSC
1902 switch (MIPS_DECODE[loop].type) {
1903 case FPCEIL:
1904 op = "FP_RM_TOPINF";
1905 break;
1906 case FPFLOOR:
1907 op = "FP_RM_TOMINF";
1908 break;
1909 case FPTRUNC:
1910 op = "FP_RM_TOZERO";
1911 break;
1912 case FPROUND:
1913 op = "FP_RM_NEAREST";
1914 break;
1915 default:
1916 fprintf(stderr,"Error: Handled missing for FP reason code %d\n",MIPS_DECODE[loop].type);
1917 exit(1);
1918 }
8ad57737 1919
8bae0a0c
JSC
1920 switch (GETDATASIZE()) {
1921 case WORD :
1922 type = "fmt_word";
1923 break;
1924 case DOUBLEWORD :
1925 type = "fmt_long";
1926 break;
1927 default:
1928 fprintf(stderr,"Error in instruction encoding table for FP %s operation (not WORD or DOUBLEWORD)\n",op);
1929 exit(1);
1930 }
1931 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1932 printf(" SignalException(ReservedInstruction,instruction);\n");
1933 printf(" else\n");
1934 printf(" StoreFPR(destreg,%s,Convert(%s,ValueFPR(fs,format),format,%s));\n",type,op,type);
1935 }
8ad57737
JSC
1936 break ;
1937
8bae0a0c
JSC
1938 case FPCONVERT:
1939 {
1940 char *type = "";
1941 switch (GETDATASIZE()) {
1942 case SINGLE:
1943 type = "fmt_single";
1944 break;
1945 case DOUBLE:
1946 type = "fmt_double";
1947 break;
1948 case WORD:
1949 type = "fmt_word";
1950 break;
1951 case DOUBLEWORD:
1952 type = "fmt_long";
1953 break;
1954 default :
1955 fprintf(stderr,"Error: Unknown data size %d in FPCONVERT instruction\n",GETDATASIZE());
1956 exit(1);
1957 }
8ad57737 1958
8bae0a0c
JSC
1959 /* Not all combinations of conversion are valid at the
1960 moment: When converting to a fixed-point format, only
1961 floating-point sources are allowed. */
1962 printf(" if ((format == %s) | %s)\n",type,((MIPS_DECODE[loop].flags & FIXED) ? "((format == fmt_long) || (format == fmt_word))": "0"));
1963 printf(" SignalException(ReservedInstruction,instruction);\n");
1964 printf(" else\n");
1965 printf(" StoreFPR(destreg,%s,Convert(GETRM(),ValueFPR(fs,format),format,%s));\n",type,type);
1966 }
8ad57737
JSC
1967 break ;
1968
8bae0a0c
JSC
1969 case FPSUB:
1970 if (MIPS_DECODE[loop].flags & MULTIPLY) {
1971 char *type = "";
1972 switch (GETDATASIZE()) {
1973 case SINGLE:
1974 type = "fmt_single";
1975 break;
1976 case DOUBLE:
1977 type = "fmt_double";
1978 break;
1979 default:
1980 fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZE());
1981 exit(1);
1982 }
1983 printf(" StoreFPR(destreg,%s,%s(Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",type,((MIPS_DECODE[loop].flags & NOT) ? "Negate" : ""),type,type,type,type,type,type);
1984 } else {
1985 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1986 printf(" SignalException(ReservedInstruction,instruction);\n");
1987 printf(" else\n");
1988 printf(" StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
1989 }
8ad57737
JSC
1990 break ;
1991
8bae0a0c
JSC
1992 case FPADD:
1993 if (MIPS_DECODE[loop].flags & MULTIPLY) {
1994 char *type = "";
1995 switch (GETDATASIZE()) {
1996 case SINGLE:
1997 type = "fmt_single";
1998 break;
1999 case DOUBLE:
2000 type = "fmt_double";
2001 break;
2002 default:
2003 fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZE());
2004 exit(1);
2005 }
2006 printf(" StoreFPR(destreg,%s,%s(Add(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",type,((MIPS_DECODE[loop].flags & NOT) ? "Negate" : ""),type,type,type,type,type,type);
2007 } else {
2008 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
2009 printf(" SignalException(ReservedInstruction,instruction);\n");
2010 printf(" else\n");
2011 printf(" StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
2012 }
8ad57737
JSC
2013 break ;
2014
8bae0a0c 2015 case FPCOMPARE:
8ad57737
JSC
2016 /* For the MIPS I,II or III there *MUST* be at least one
2017 instruction between the compare that sets a condition code
8bae0a0c
JSC
2018 and the branch that tests it. NOTE: However the hardware
2019 does not detect this condition. */
2020 /* Explicitly limit the operation to S and D formats: */
2021 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
2022 printf(" SignalException(ReservedInstruction,instruction);\n") ;
2023 printf(" else {\n");
2024 if (doisa < 4) {
2025 printf(" if ((cmpflags & (1 << 3)) || (condition_code != 0))\n");
2026 printf(" SignalException(ReservedInstruction,instruction);\n") ;
2027 printf(" else\n");
2028 }
2029 printf(" {\n");
2030 printf(" int ignore = 0;\n");
2031 printf(" int less = 0;\n");
2032 printf(" int equal = 0;\n");
2033 printf(" int unordered = 1;\n");
e871dd18
JSC
2034 printf(" uword64 ofs = ValueFPR(fs,format);\n");
2035 printf(" uword64 oft = ValueFPR(ft,format);\n");
8bae0a0c
JSC
2036 printf(" if (NaN(ofs,format) || NaN(oft,format)) {\n");
2037 printf(" if (FCSR & FP_ENABLE(IO)) {\n");
2038 printf(" FCSR |= FP_CAUSE(IO);\n");
2039 printf(" SignalException(FPE);\n");
2040 printf(" ignore = 1;\n");
2041 printf(" }\n");
2042 printf(" } else {\n");
2043 printf(" less = Less(ofs,oft,format);\n");
2044 printf(" equal = Equal(ofs,oft,format);\n");
2045 printf(" unordered = 0;\n");
2046 printf(" }\n");
2047 printf(" if (!ignore) {\n");
2048 printf(" int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered));\n");
2049 printf(" SETFCC(condition_code,condition);\n");
2050 printf(" }\n");
2051 printf(" }\n");
2052 printf(" }\n");
8ad57737
JSC
2053 break ;
2054
8bae0a0c 2055 default:
8ad57737
JSC
2056 fprintf(stderr,"Unrecognised opcode type %d\n",MIPS_DECODE[loop].type) ;
2057 exit(6) ;
2058 }
2059 printf(" }\n") ;
2060 printf(" }\n") ;
2061 printf(" break ;\n") ;
2062 }
2063 }
2064
2065 printf("default : /* Unrecognised instruction */\n") ;
2066 printf(" SignalException(ReservedInstruction,instruction);\n") ;
2067 printf(" break ;\n") ;
2068 printf("}\n}\n") ;
2069 printf("#endif /* simulator engine */\n");
2070
2071 return ;
2072}
2073
2074/*---------------------------------------------------------------------------*/
2075
2076/* The command-line feature controls are presented in a similar style
2077 to those offered by GCC, in the aim of providing a consistent
2078 interface to the user. */
2079typedef enum {
2080 T_NONE, /* no argument - mask and value fields control "feature" definition */
2081 T_NUM, /* numeric argument - optionally preceded by '=' - mask field defines maximum value */
2082 T_STRING /* string argument - optionally prcededed by '=' */
2083} mactypes;
2084
2085struct {
2086 char *name;
2087 mactypes type;
2088 unsigned int mask;
2089 unsigned int value;
2090 char *desc;
2091} machine_options[] = {
2092 {"ips", T_NUM, MASK_ISA,0,"\tSelect MIPS ISA version"},
2093 {"cpu", T_STRING,0,0,"\t\tSelect particular MIPS architecture"},
2094 {"gp64", T_NONE, FEATURE_GP64,FEATURE_GP64,"\t\t\tSelect 64bit GP registers"},
2095 {"gp32", T_NONE, FEATURE_GP64,0,"\t\t\tSelect 32bit GP registers"},
2096 {"no-fp", T_NONE, FEATURE_HASFPU,0,"\t\tDisable FP simulation"},
8ad57737
JSC
2097 {"single-float",T_NONE, (FEATURE_FPSINGLE | FEATURE_HASFPU),(FEATURE_FPSINGLE | FEATURE_HASFPU),"\t\tSelect single precision only FPU"},
2098 {"double-float",T_NONE, (FEATURE_FPSINGLE | FEATURE_HASFPU),FEATURE_HASFPU,"\t\tSelect double precision FPU"},
2099 {0, T_NONE, 0,0}
2100};
2101
2102/* The following architecture identies are those accepted by the "-mcpu" option: */
2103struct architectures {
2104 const char *name; /* ASCII string identifier for command-line, no white-space allowed */
2105 unsigned int idflag; /* or-ed into "isa" value */
2106};
2107
2108static const struct architectures available_architectures[] = {
2109 {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
2110 {0, 0} /* terminator */
2111};
2112
2113/*---------------------------------------------------------------------------*/
2114
2115static void
2116usage(name)
2117 char *name;
2118{
2119 int loop;
2120
2121 fprintf(stderr,"%s: Construct a MIPS simulator engine.\n",name);
2122
2123 fprintf(stderr,"\
2124The output of this program is a block of 'C' code designed to be\n\
2125included into the main simulation control loop of a device specific\n\
2126simulator.\n");
2127
2128 fprintf(stderr,"\nOptions:\n");
2129 fprintf(stderr," -h --help\t\tProvide this help text\n");
2130 fprintf(stderr," -f --fast\t\tProvide the fastest possible engine (i.e. no statistics)\n");
2131 fprintf(stderr," -w --warnings\t\tEnable all the simulator engine warnings\n");
2132
2133 for (loop = 0; (machine_options[loop].name != 0); loop++) {
2134 fprintf(stderr," -m%s",machine_options[loop].name);
2135 switch (machine_options[loop].type) {
2136 case T_NUM :
2137 fprintf(stderr,"N (range 0..%d)",machine_options[loop].mask);
2138 case T_NONE :
2139 break;
2140
2141 case T_STRING :
2142 fprintf(stderr,"=name");
2143 break;
2144
2145 default :
2146 fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",machine_options[loop].type);
2147 exit(1);
2148 }
2149 fprintf(stderr,"%s\n",machine_options[loop].desc);
2150 }
2151
2152 fprintf(stderr,"\nAvailable \"-mcpu\" architectures: ");
2153 for (loop = 0; (available_architectures[loop].name != 0); loop++)
2154 fprintf(stderr,"%s ",available_architectures[loop].name);
2155 fprintf(stderr,"\n\n");
2156
2157 fprintf(stderr,"\
2158The \"trace\" and \"warnings\" options do not define the output stream.\n\
2159They only inform the code that includes the constructed engine to provide\n\
2160the required features.\n\n\
2161The \"-mips0\" option forces the construction of a simulator supporting\n\
2162the highest available MIPS ISA supported.\n");
2163
2164 return;
2165}
2166
2167/*---------------------------------------------------------------------------*/
2168
2169int
2170main(argc,argv)
2171 int argc;
2172 char **argv;
2173{
2174 int c;
2175 char *progname = argv[0];
2176 unsigned int doarch = DEF_ISA;
2177 unsigned int features = 0; /* default state */
2178
2179 if (DEF_FP)
2180 features |= FEATURE_HASFPU;
2181 if (!DEF_PROC64)
2182 features |= FEATURE_PROC32;
2183 if (DEF_FPSINGLE)
2184 features |= FEATURE_FPSINGLE;
2185
2186 if (features & FEATURE_PROC32)
8bae0a0c 2187 features &= ~FEATURE_GP64;
8ad57737 2188 else
8bae0a0c 2189 features |= FEATURE_GP64;
8ad57737
JSC
2190
2191 while (1) {
2192 int this_option_optind = (optind ? optind : 1);
2193 int option_index = 0;
2194 static struct option cmdline[] = {
2195 {"fast", 0,0,'f'},
2196 {"help", 0,0,'h'},
2197 {"warnings",0,0,'w'},
2198 {0, 0,0,0}
2199 };
2200
2201 c = getopt_long(argc,argv,"hm:tw",cmdline,&option_index);
2202 if (c == -1)
2203 break ; /* out of the while loop */
2204
2205 switch (c) {
2206 case 'h' : /* help */
2207 usage(progname);
2208 exit(0);
2209
2210 case 'f' : /* fast */
2211 features |= FEATURE_FAST;
2212 break;
2213
2214 case 'w' : /* warnings */
2215 features |= FEATURE_WARNINGS;
2216 /* TODO: Future extension: Allow better control over the warnings generated:
2217 disable warnings -wnone ~FEATURE_WARNINGS
2218 all possible warnings -wall FEATURE_WARNINGS
2219 pipeline stall occuring -wstall FEATURE_WARN_STALL
2220 LO/HI corruption -wlo or -whi or -wlohi or -whilo FEATURE_WARN_HILO
2221 write to zero -wzero FEATURE_WARN_ZERO actually performed in external code - though we should set a manifest
2222 bad r31 use -wr31 FEATURE_WARN_R31
2223 undefined results -wresult FEATURE_WARN_RESULT
2224 */
2225 break;
2226
2227 case 'm' : /* machine options */
2228 {
2229 int loop;
2230
2231 for (loop = 0; (machine_options[loop].name != 0); loop++)
2232 if (strncmp(machine_options[loop].name,optarg,strlen(machine_options[loop].name)) == 0) {
2233 char *loptarg = (optarg + strlen(machine_options[loop].name));
2234 switch (machine_options[loop].type) {
2235 case T_NONE :
2236 if (*loptarg) {
2237 fprintf(stderr,"%s: Spurious characters \"%s\" at end of -m%s option\n",progname,loptarg,machine_options[loop].name);
2238 exit(1);
2239 }
2240 features &= ~(machine_options[loop].mask);
2241 features |= machine_options[loop].value;
2242 break;
2243
2244 case T_NUM :
2245 if (*loptarg && *loptarg == '=')
2246 loptarg++;
2247
2248 if (strcmp(machine_options[loop].name,"ips") == 0) {
2249 unsigned int num;
2250
2251 if (!*loptarg) {
2252 fprintf(stderr,"%s: ISA number expected after -mips\n",progname);
2253 exit(1);
2254 }
2255
2256 num = strtoul(loptarg,&loptarg,10);
2257
2258 if ((num == ULONG_MAX) && (errno = ERANGE)) {
2259 fprintf(stderr,"%s: Invalid number given to -mips option\n",progname);
2260 exit(1);
2261 }
2262
2263 if (*loptarg) {
2264 fprintf(stderr,"%s: Spurious trailing characters after ISA number \"%s\"\n",progname,loptarg);
2265 exit(1);
2266 }
2267
2268 if (num > MASK_ISA) {
2269 fprintf(stderr,"%s: ISA number %d outside acceptable range (0..%d)\n",progname,num,MASK_ISA);
2270 exit(1);
2271 }
2272
2273 doarch = ((doarch & ~MASK_ISA) | num);
2274 if ((num == 0) || (num > 2)) {
8bae0a0c
JSC
2275 if ((features & FEATURE_PROC32) || !(features & FEATURE_GP64))
2276 fprintf(stderr,"%s: Warning: -mips%d forcing -mgp64\n",progname,num);
2277 features |= FEATURE_GP64;
8ad57737
JSC
2278 features &= ~FEATURE_PROC32;
2279 } else {
8bae0a0c
JSC
2280 if (!(features & FEATURE_PROC32) || (features & FEATURE_GP64))
2281 fprintf(stderr,"%s: Warning: -mips%d forcing -mgp32\n",progname,num);
2282 features &= ~FEATURE_GP64;
8ad57737
JSC
2283 features |= FEATURE_PROC32;
2284 }
2285 } else {
2286 fprintf(stderr,"%s: FATAL: Unrecognised (numeric) machine option -m%s\n",progname,optarg);
2287 exit(1);
2288 }
2289 break;
2290
2291 case T_STRING :
2292 if (*loptarg && *loptarg == '=')
2293 loptarg++;
2294
2295 if (strcmp(machine_options[loop].name,"cpu") == 0) {
2296 int archloop;
2297
2298 if (!*loptarg) {
2299 fprintf(stderr,"%s: Architecture identifier expected after -mcpu\n",progname);
2300 exit(1);
2301 }
2302
2303 for (archloop = 0; (available_architectures[archloop].name != 0); archloop++) {
2304 if ((*loptarg == 'v') || (*loptarg == 'V'))
2305 *loptarg++;
2306
2307 if (*loptarg && (*loptarg == 'r') || (*loptarg == 'R'))
2308 *loptarg++;
2309
2310 if (strcmp(available_architectures[archloop].name,loptarg) == 0) {
2311 doarch |= available_architectures[archloop].idflag;
2312 break;
2313 }
2314 }
2315
2316 if (available_architectures[archloop].name == 0) {
2317 fprintf(stderr,"%s: Unrecognised MIPS architecture \"%s\"\n",progname,loptarg);
2318 exit(1);
2319 }
2320 } else {
2321 fprintf(stderr,"%s: FATAL: Unrecognised (string) machine option -m%s\n",progname,optarg);
2322 exit(1);
2323 }
2324 break;
2325
2326 default :
2327 fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",progname,machine_options[loop].type);
2328 exit(1);
2329 }
2330 break;
2331 }
2332
2333 if (machine_options[loop].name == 0) {
2334 fprintf(stderr,"%s: Unrecognised option: -m%s\n",progname,optarg);
2335 exit(1);
2336 }
2337 }
2338 break;
2339
2340 case '?' :
2341 /* An error message should already have been displayed */
2342 exit(1);
2343
2344 default :
2345 fprintf(stderr,"%s: FATAL: getopt returned unrecognised code 0x%08X\n",progname,c);
2346 exit(1);
2347 }
2348 }
2349
2350 if (optind < argc) {
2351 fprintf(stderr,"%s: Spurios non-option arguments ",progname);
2352 while (optind < argc)
2353 fprintf(stderr,"\"%s\" ",argv[optind++]);
2354 fprintf(stderr,"\n");
2355 exit(1);
2356 }
2357
2358 if ((features & FEATURE_FAST) && (features & FEATURE_WARNINGS))
2359 fprintf(stderr,"Warning: Fast model generation selected, along with trace or warnings.\n");
2360
2361 process_instructions(doarch,features) ;
2362 return(0) ;
2363}
2364
2365/*---------------------------------------------------------------------------*/
2366/*> EOF gencode.c <*/
This page took 0.14344 seconds and 4 git commands to generate.