* config/mips/tm-mips.h (COERCE_FLOAT_TO_DOUBLE): Only prefer
[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: */
402 {"ABS", 1,"01000110mmm00000dddddaaaaa000101",COP1, FPABS, (FP)},
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
700/*---------------------------------------------------------------------------*/
701/* doisa = number of MIPS ISA simulator table is being constructed for.
702 * proc64 = TRUE if constructing 64bit processor world.
703 * dofp = boolean, TRUE if FP instructions are to be included.
704 * fpsingle = boolean, TRUE if only single precision FP instructions to be included.
705 */
706
707void
708process_instructions(doarch,features)
709 unsigned int doarch;
710 unsigned int features;
711{
712 int doisa = (doarch & MASK_ISA);
713 int limit = (sizeof(MIPS_DECODE) / sizeof(instruction));
714 int gprlen=((features & FEATURE_GP64) ? 64 : 32);
8ad57737
JSC
715 int proc64 = ((features & FEATURE_PROC32) ? 0 : -1);
716 int dofp = (features & FEATURE_HASFPU);
717 int fpsingle = (features & FEATURE_FPSINGLE);
8bae0a0c 718 int maxisa;
8ad57737
JSC
719 int loop;
720
721 if (limit < 1) {
722 fprintf(stderr,"process_instructions: invalid structure length\n");
723 exit(1);
724 }
725
726 if (proc64 && (gprlen != 64)) {
727 fprintf(stderr,"Error: 64bit processor build specified, with MIPS ISA I or II\n");
728 exit(3);
729 }
730
8ad57737
JSC
731 /* NOTE: "proc64" also differentiates between 32- and 64-bit wide memory */
732
8bae0a0c
JSC
733 maxisa = 0;
734 for (loop = 0; (loop < limit); loop++)
735 if ((MIPS_DECODE[loop].isa & MASK_ISA) > maxisa)
736 maxisa = (MIPS_DECODE[loop].isa & MASK_ISA);
737
738 if (doisa == 0)
739 doisa = maxisa;
740
8ad57737 741 printf("#if defined(SIM_MANIFESTS)\n");
8bae0a0c 742 printf("#define MIPSISA (%d)\n",doisa);
8ad57737
JSC
743 if (proc64)
744 printf("#define PROCESSOR_64BIT (1 == 1)\n");
745 printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
8bae0a0c 746 /* The FP registers are the same width as the CPU registers: */
8ad57737 747 printf("#define GPRLEN (%d)\n",gprlen);
8ad57737
JSC
748 printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
749 printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
8bae0a0c 750 printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
8ad57737
JSC
751 if (dofp)
752 printf("#define HASFPU (1 == 1)\n");
753 if (features & FEATURE_FAST)
754 printf("#define FASTSIM (1 == 1)\n");
755 if (features & FEATURE_WARN_STALL)
756 printf("#define WARN_STALL (1 == 1)\n");
757 if (features & FEATURE_WARN_LOHI)
758 printf("#define WARN_LOHI (1 == 1)\n");
759 if (features & FEATURE_WARN_ZERO)
760 printf("#define WARN_ZERO (1 == 1)\n");
761 if (features & FEATURE_WARN_MEM)
762 printf("#define WARN_MEM (1 == 1)\n");
763 if (features & FEATURE_WARN_R31)
764 printf("#define WARN_R31 (1 == 1)\n");
765 if (features & FEATURE_WARN_RESULT)
766 printf("#define WARN_RESULT (1 == 1)\n");
767
768 printf("#else /* simulator engine */\n");
769
770 printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
771 printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
772 if (dofp)
773 printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
774 printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
775
776 if (proc64) {
777 printf("#if !defined(PROCESSOR_64BIT)\n");
778 printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
779 printf("#endif\n");
780 }
781
782 printf("/* Actual instruction decoding block */\n");
783 printf("{\n");
8bae0a0c
JSC
784 {
785 int limit;
786 printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
787 limit = (OP_MASK_OP + 1);
788 printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
789 limit += (OP_MASK_SPEC + 1);
790 printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
791 limit += (OP_MASK_RT + 1);
792 printf("else if (num == 0x11) {\n");
793 printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
794 printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
795 printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
796 printf(" else\n");
797 printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
798 limit += (OP_MASK_SPEC + 1);
799 printf(" else\n");
800 /* To keep this code quick, we just clear out the "to" bit
801 here. The proper (though slower) code would be to have another
802 conditional, checking whether this instruction is a branch or
803 not, before limiting the range to the bottom two bits of the
804 move operation. */
805 printf(" num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
806 limit += (OP_MASK_COP1SPEC + 1);
807 printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
808 limit += (OP_MASK_SPEC + 1);
809 printf("/* Total possible switch entries: %d */\n",limit) ;
810 }
8ad57737
JSC
811 printf("switch (num)\n") ;
812 printf("{\n");
813
814 for (loop = 1; (loop < limit); loop++) {
815 /* First check that the ISA number we are constructing for is
816 valid, before checking if the instruction matches any of the
817 architecture specific flags. NOTE: We allow a selected ISA of
818 zero to be used to match all standard instructions. */
8bae0a0c 819 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
820 unsigned int onemask;
821 unsigned int zeromask;
822 unsigned int dontmask;
823 unsigned int mask;
824 unsigned int number;
825 unsigned int flags = convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
826 char *regtype = ((gprlen == 64) ? "uword64" : "unsigned int");
827
828 if ((GETDATASIZE() == DOUBLEWORD) && !proc64) {
829 fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
830 exit(4);
831 }
832
833#if defined(DEBUG)
834 printf("/* DEBUG: onemask 0x%08X */\n",onemask) ;
835 printf("/* DEBUG: zeromask 0x%08X */\n",zeromask) ;
836 printf("/* DEBUG: dontmask 0x%08X */\n",dontmask) ;
837#endif
838
839 switch (MIPS_DECODE[loop].mark) {
840 case NORMAL :
841 mask = (OP_MASK_OP << OP_SH_OP) ;
842 number = ((onemask >> OP_SH_OP) & OP_MASK_OP) ;
843 break ;
844
845 case SPECIAL :
846 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
847 number = ((OP_MASK_OP + 1) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
848 break ;
849
850 case REGIMM :
851 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_RT << OP_SH_RT)) ;
852 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_RT) & OP_MASK_RT)) ;
853 break ;
854
855 case COP1 :
856 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
857 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1)) + ((onemask >> OP_SH_SPEC) & OP_MASK_SPEC)) ;
858 break ;
859
8bae0a0c
JSC
860 case COP1S :
861 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_COP1SPEC << OP_SH_COP1SPEC)) ;
862 number = (((OP_MASK_OP + 1) + (OP_MASK_SPEC + 1) + (OP_MASK_RT + 1) + (OP_MASK_SPEC + 1)) + ((onemask >> OP_SH_COP1SPEC) & OP_MASK_COP1SPEC)) ;
863 break;
864
8ad57737
JSC
865 case COP1X :
866 mask = ((OP_MASK_OP << OP_SH_OP) | (OP_MASK_SPEC << OP_SH_SPEC)) ;
8bae0a0c 867 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
868 break ;
869
870 default :
871 fprintf(stderr,"Unrecognised opcode mark %d in table slot %d \"%s\"\n",MIPS_DECODE[loop].mark,loop,MIPS_DECODE[loop].name) ;
872 exit(5) ;
873 }
874
875 printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
876
877#if defined(DEBUG)
878 printf("/* DEBUG: mask 0x%08X */\n",mask) ;
879 printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
880#endif
881
882 /* Check if there are any other explicit bits in the instruction: */
883 if ((~mask & (onemask | zeromask)) != 0x00000000) {
884 printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
885 printf(" {\n") ;
886 printf(" SignalException(ReservedInstruction,instruction);\n") ;
887 printf(" }\n") ;
888 printf(" else\n") ;
889 }
890
891 if ((flags == 0) && !(MIPS_DECODE[loop].flags & NOARG)) {
892 fprintf(stderr,"Bitmap error: Instruction with no operand fields \"%s\"\n",MIPS_DECODE[loop].name) ;
893 exit(5) ;
894 }
895
896 printf(" {\n") ;
897
898 /* Get hold of the operands */
899 /* NOTE: If we wanted to make the simulator code smaller, we
900 * could pull these into a common sequence before we perform
901 * the instruction decoding. However, this would affect the
902 * performance since unnecessary field extraction would be
903 * occurring for certain instructions.
904 *
905 * Also we do not perform checking for multiple definitions of a
906 * particular operand here, since they are caught by the
907 * compilation of the produced code.
908 */
909 build_operands(flags);
910
911 /* Finish constructing the jump address if required: */
912 if (flags & fieldval('j'))
913 printf(" op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */\n");
914
915 /* Now perform required operand checks: */
916
917/* The following code has been removed, since it seems perfectly
918 reasonable to have a non-aligned offset that is added to another
919 non-aligned base to create an aligned address. Some more
920 information on exactly what the MIPS IV specification requires is
921 needed before deciding on the best strategy. Experimentation with a
922 VR4300 suggests that we do not need to raise the warning. */
923#if 0
924 /* For MIPS IV (and onwards), certain instruction operand values
925 will give undefined results. For the simulator we could
926 generate explicit exceptions (i.e. ReservedInstruction) to
927 make it easier to spot invalid use. However, for the moment we
928 just raise a warning. NOTE: This is a different check to the
929 later decoding, which checks for the final address being
930 valid. */
8bae0a0c 931 if ((flags & (fieldval('e') | fieldval('w') | fieldval('h'))) && (doisa >= 4)) {
8ad57737
JSC
932 printf(" if (instruction & 0x%1X)\n",((flags & fieldval('e')) ? 0x7 : ((flags & fieldval('w')) ? 0x3 : 0x1)));
933 printf(" {\n");
934 /* NOTE: If we change this to a SignalException(), we must
935 ensure that the following opcode processing is not
936 executed. i.e. the code falls straight out to the simulator
937 control loop. */
938 printf(" WARNING(\"Instruction has lo-order offset bits set in instruction\");\n");
939 printf(" }\n");
940 }
941#endif
942
943 /* The extended condition codes only appeared in ISA IV */
8bae0a0c 944 if ((flags & fieldval('p')) && (doisa < 4)) {
8ad57737
JSC
945 printf(" if (condition_code != 0)\n");
946 printf(" {\n");
947 printf(" SignalException(ReservedInstruction,instruction);\n");
948 printf(" }\n");
949 printf(" else\n");
950 }
951
952 if ((MIPS_DECODE[loop].flags & WORD32) && (GETDATASIZE() != WORD)) {
953 fprintf(stderr,"Error in opcode table: WORD32 set for non-WORD opcode\n");
954 exit(1);
955 }
956
8bae0a0c
JSC
957#if 1
958 /* The R4000 book differs slightly from the MIPS IV ISA
959 manual. An example is the sign-extension of a 64-bit processor
960 SUBU operation, and what is meant by an Undefined Result. This
961 is now provided purely as a warning. After examining a HW
962 implementation, this is now purely a warning... and the actual
963 operation is performed, with possibly undefined results. */
964 if (((MIPS_DECODE[loop].flags & WORD32) && proc64) && (features & FEATURE_WARN_RESULT)) {
965 /* The compiler should optimise out an OR with zero */
966 printf(" if (%s | %s)\n",((flags & fieldval('s')) ? "NOTWORDVALUE(op1)" : "0"),((flags & fieldval('g')) ? "NOTWORDVALUE(op2)" : "0"));
967 printf(" UndefinedResult();\n") ;
968 }
969#else
8ad57737
JSC
970 /* Check that the source is a 32bit value */
971 if ((MIPS_DECODE[loop].flags & WORD32) && proc64) {
8bae0a0c 972 /* The compiler should optimise out an OR with zero */
8ad57737
JSC
973 printf(" if (%s | %s)\n",((flags & fieldval('s')) ? "NOTWORDVALUE(op1)" : "0"),((flags & fieldval('g')) ? "NOTWORDVALUE(op2)" : "0"));
974 printf(" UndefinedResult();\n") ;
975 printf(" else\n") ;
976 }
8bae0a0c 977#endif
8ad57737
JSC
978
979 printf(" {\n") ;
980
981 switch (MIPS_DECODE[loop].type) {
982 /* TODO: To make these easier to edit and maintain, they should
983 actually be provided as source macros (or inline functions)
8bae0a0c
JSC
984 OUTSIDE this main switch statement. The PPC simulator has a
985 neater scheme for describing the instruction sequences. */
8ad57737
JSC
986
987 case ADD:
8bae0a0c 988 case SUB:
8ad57737
JSC
989 {
990 char *basetype = "unknown";
991 switch (GETDATASIZE()) {
992 case WORD :
993 basetype = "int";
994 break;
995 case DOUBLEWORD :
996 basetype = "long long";
997 break;
998 default :
8bae0a0c 999 fprintf(stderr,"Opcode table error: size of ADD/SUB operands not known (%d)\n",GETDATASIZE());
8ad57737
JSC
1000 exit(1);
1001 }
1002
1003 if ((MIPS_DECODE[loop].type) == ADD) {
1004 printf(" unsigned %s temp = (unsigned %s)(op1 + op2);\n",basetype,basetype);
1005 printf(" signed %s tempS = (signed %s)temp;\n",basetype,basetype);
8bae0a0c
JSC
1006 if (MIPS_DECODE[loop].flags & OVERFLOW) {
1007 printf(" if (((op1 < 0) == (op2 < 0)) && ((tempS < 0) != (op1 < 0)))\n");
1008 printf(" SignalException(IntegerOverflow);\n");
1009 printf(" else\n");
1010 }
8ad57737
JSC
1011 if (!proc64 || (MIPS_DECODE[loop].flags & UNSIGNED) || (GETDATASIZE() == DOUBLEWORD))
1012 printf(" GPR[destreg] = (%s)temp;\n",regtype);
1013 else /* only sign-extend when placing 32bit result in 64bit processor */
1014 printf(" GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
1015 } else { /* SUB */
1016 printf(" unsigned %s temp = (unsigned %s)(op1 - op2);\n",basetype,basetype);
1017 printf(" signed %s tempS = (signed %s)temp;\n",basetype,basetype);
1018 if (MIPS_DECODE[loop].flags & OVERFLOW) { /* different signs => overflow if result_sign != arg_sign */
1019 printf(" if (((op1 < 0) != (op2 < 0)) && ((tempS < 0) == (op1 < 0)))\n");
1020 printf(" SignalException(IntegerOverflow);\n");
1021 printf(" else\n");
1022 }
1023 /* UNSIGNED 32bit operations on a 64bit processor should
1024 *STILL* be sign-extended. We have cheated in the
1025 data-structure, by not marking it with UNSIGNED, and not
1026 setting OVERFLOW. */
1027 if (!proc64 || (MIPS_DECODE[loop].flags & UNSIGNED) || (GETDATASIZE() == DOUBLEWORD))
1028 printf(" GPR[destreg] = (%s)temp;\n",regtype);
1029 else /* only sign-extend when placing 32bit result in 64bit processor */
1030 printf(" GPR[destreg] = SIGNEXTEND(((%s)temp),32);\n",regtype);
1031 }
1032 }
1033 break ;
1034
8bae0a0c 1035 case MUL:
8ad57737
JSC
1036 if (features & FEATURE_WARN_LOHI) {
1037 printf(" CHECKHILO(\"Multiplication\");\n");
1038 }
1039 printf(" {\n");
1040 if (GETDATASIZE() == DOUBLEWORD) {
1041 printf(" uword64 mid;\n");
1042 printf(" uword64 temp;\n");
a647a859
JSC
1043 printf(" LO = ((uword64)WORD64LO(op1) * WORD64LO(op2));\n");
1044 printf(" HI = ((uword64)WORD64HI(op1) * WORD64HI(op2));\n");
1045 printf(" mid = ((uword64)WORD64HI(op1) * WORD64LO(op2));\n");
1046 printf(" temp = (LO + SET64HI(WORD64LO(mid)));\n");
8ad57737
JSC
1047 printf(" if ((temp == mid) ? (LO != 0) : (temp < mid))\n");
1048 printf(" HI += 1;\n");
a647a859
JSC
1049 printf(" HI += WORD64HI(mid);\n");
1050 printf(" mid = ((uword64)WORD64LO(op1) * WORD64HI(op2));\n");
1051 printf(" LO = (temp + SET64HI(WORD64LO(mid)));\n");
8ad57737
JSC
1052 printf(" if ((LO == mid) ? (temp != 0) : (LO < mid))\n");
1053 printf(" HI += 1;\n");
a647a859 1054 printf(" HI += WORD64HI(mid);\n");
8ad57737
JSC
1055 } else {
1056 printf(" uword64 temp = (op1 * op2);\n");
a647a859
JSC
1057 printf(" LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
1058 printf(" HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
8ad57737
JSC
1059 }
1060 printf(" }\n");
1061 break ;
1062
8bae0a0c 1063 case DIV:
8ad57737
JSC
1064 {
1065 int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1066
1067 if (features & FEATURE_WARN_LOHI) {
1068 printf(" CHECKHILO(\"Division\");\n");
1069 }
1070 printf(" {\n");
1071 if (GETDATASIZE() == DOUBLEWORD) {
1072 printf(" LO = ((%slong long)op1 / (%slong long)op2);\n",(boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
1073 printf(" HI = ((%slong long)op1 %c (%slong long)op2);\n",(boolU ? "unsigned " : ""),'%',(boolU ? "unsigned " : ""));
1074 } else {
1075 printf(" LO = SIGNEXTEND(((%sint)op1 / (%sint)op2),32);\n",(boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
1076 printf(" HI = SIGNEXTEND(((%sint)op1 %c (%sint)op2),32);\n",(boolU ? "unsigned " : ""),'%',(boolU ? "unsigned " : ""));
1077 }
1078 printf(" }\n");
1079 }
1080 break ;
1081
8bae0a0c 1082 case SHIFT:
8ad57737
JSC
1083 {
1084 int datalen = GETDATASIZE();
1085 int bits = ((datalen == WORD) ? 32 : 64);
1086 char *ltype = ((datalen == WORD) ? "unsigned int" : "uword64");
1087
1088 /* Check that the specified SHIFT is valid: */
1089 if ((datalen == BYTE) || (datalen == HALFWORD)) {
1090 fprintf(stderr,"Shift \"%s\" specified with BYTE or HALFWORD\n",MIPS_DECODE[loop].name);
1091 exit(9);
1092 }
1093 if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & RIGHT)) {
1094 fprintf(stderr,"Shift \"%s\" specified with both LEFT and RIGHT\n",MIPS_DECODE[loop].name);
1095 exit(9);
1096 }
1097 if (!(MIPS_DECODE[loop].flags & LEFT) && !(MIPS_DECODE[loop].flags & RIGHT)) {
1098 fprintf(stderr,"Shift \"%s\" specified with neither LEFT or RIGHT\n",MIPS_DECODE[loop].name);
1099 exit(9);
1100 }
1101 if ((MIPS_DECODE[loop].flags & LOGICAL) && (MIPS_DECODE[loop].flags & ARITHMETIC)) {
1102 fprintf(stderr,"Shift \"%s\" specified with both LOGICAL and ARITHMETIC\n",MIPS_DECODE[loop].name);
1103 exit(9);
1104 }
1105 if (!(MIPS_DECODE[loop].flags & LOGICAL) && !(MIPS_DECODE[loop].flags & ARITHMETIC)) {
1106 fprintf(stderr,"Shift \"%s\" specified with neither LOGICAL or ARITHMETIC\n",MIPS_DECODE[loop].name);
1107 exit(9);
1108 }
1109 if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & ARITHMETIC)) {
1110 fprintf(stderr,"Arithmetic LEFT shift \"%s\" specified\n",MIPS_DECODE[loop].name);
1111 exit(9);
1112 }
1113
1114 /* If register specified shift, then extract the relevant shift amount: */
1115 if (flags & fieldval('s'))
1116 printf(" op1 &= 0x%02X;\n",(bits - 1));
1117
1118 /* If HI32 specified, then shift range is 32..63 */
1119 if (MIPS_DECODE[loop].flags & HI32)
1120 printf(" op1 |= (1 << 6);\n");
1121
8bae0a0c
JSC
1122 /* We do not need to perform pre-masking with 0xFFFFFFFF when
1123 dealing with 32bit shift lefts, since the sign-extension
1124 code will replace any remaining hi-bits: */
1125 if (MIPS_DECODE[loop].flags & LEFT)
1126 printf(" GPR[destreg] = ((unsigned long long)op2 << op1);\n");
1127 else
1128 printf(" GPR[destreg] = ((unsigned long long)(op2%s) >> op1);\n",((bits == 32) ? " & 0xFFFFFFFF" : ""));
8ad57737
JSC
1129
1130 /* For ARITHMETIC shifts, we must duplicate the sign-bit */
1131 if (MIPS_DECODE[loop].flags & ARITHMETIC)
1132 printf(" GPR[destreg] |= ((op2 & ((%s)1 << %d)) ? ((((%s)1 << (op1 + 1)) - 1) << (%d - op1)) : 0);\n",ltype,(bits - 1),ltype,(bits - 1));
1133
1134 /* Ensure WORD values are sign-extended into 64bit registers */
1135 if ((bits == 32) && (gprlen == 64))
1136 printf(" GPR[destreg] = SIGNEXTEND(GPR[destreg],%d);\n",bits);
1137 }
1138 break ;
1139
8bae0a0c 1140 case MOVE:
8ad57737
JSC
1141 if (MIPS_DECODE[loop].flags & (HI | LO)) {
1142 char *regname = ((MIPS_DECODE[loop].flags & LO) ? "LO" : "HI");
1143 if (flags & fieldval('d'))
1144 printf(" GPR[destreg] = %s;\n",regname);
1145 else {
1146 if (features & FEATURE_WARN_LOHI) {
1147 printf(" if (%sACCESS != 0)\n",regname);
1148 printf(" WARNING(\"MT (move-to) over-writing %s register value\");\n",regname);
1149 }
1150 printf(" %s = op1;\n",regname);
1151 }
1152 if (features & FEATURE_WARN_LOHI)
1153 printf(" %sACCESS = 3; /* 3rd instruction will be safe */\n",regname);
1154 } else
1155 if (MIPS_DECODE[loop].flags & SHIFT16)
1156 printf(" GPR[destreg] = (op2 << 16);\n");
1157 else {
1158 /* perform conditional move */
1159 if (!(MIPS_DECODE[loop].flags & EQ)) {
1160 fprintf(stderr,"Standard conditional %s does not have the equality flag\n",MIPS_DECODE[loop].name);
1161 exit(8);
1162 }
1163 printf(" if (op2 %c= 0)\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1164 printf(" GPR[destreg] = op1;\n");
1165 }
1166 break ;
1167
8bae0a0c 1168 case SYNC:
8ad57737
JSC
1169 printf(" SyncOperation(op1);\n");
1170 break ;
1171
8bae0a0c 1172 case SYSCALL:
8ad57737
JSC
1173 printf(" SignalException(SystemCall);\n");
1174 break ;
1175
8bae0a0c 1176 case BREAK:
8ad57737
JSC
1177 printf(" SignalException(BreakPoint);\n");
1178 break ;
1179
8bae0a0c 1180 case TRAP:
8ad57737
JSC
1181 {
1182 int boolNOT = (MIPS_DECODE[loop].flags & NOT);
1183 int boolEQ = (MIPS_DECODE[loop].flags & EQ);
1184 int boolGT = (MIPS_DECODE[loop].flags & GT);
1185 int boolLT = (MIPS_DECODE[loop].flags & LT);
1186 int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1187
1188 if (boolGT && boolLT) {
1189 fprintf(stderr,"GT and LT specified for \"%s\"\n",MIPS_DECODE[loop].name);
1190 exit(8);
1191 }
1192
1193 if (boolNOT && (boolGT || boolLT)) {
1194 fprintf(stderr,"NOT specified with GT or LT specified for \"%s\"\n",MIPS_DECODE[loop].name);
1195 exit(8);
1196 }
1197
1198 printf(" if ((%slong long)op1 ",(boolU ? "unsigned " : ""));
1199 printf("%c%s",(boolNOT ? '!' : (boolLT ? '<' : (boolGT ? '>' : '='))),(boolEQ ? "=" : ""));
1200 printf(" (%slong long)op2)\n",(boolU ? "unsigned " : ""));
1201 printf(" SignalException(Trap);\n");
1202 }
1203 break ;
1204
8bae0a0c 1205 case SET:
8ad57737
JSC
1206 {
1207 int boolU = (MIPS_DECODE[loop].flags & UNSIGNED);
1208
1209 if (!(MIPS_DECODE[loop].flags & LT)) {
1210 fprintf(stderr,"Set instruction without LT specified \"%s\"\n",MIPS_DECODE[loop].name);
1211 exit(8);
1212 }
1213
1214 printf(" if ((%slong long)op1 < (%slong long)op2)\n",(boolU ? "unsigned " : ""),(boolU ? "unsigned " : ""));
1215 printf(" GPR[destreg] = 1;\n");
1216 printf(" else\n");
1217 printf(" GPR[destreg] = 0;\n");
1218 }
1219 break ;
1220
8bae0a0c 1221 case AND:
8ad57737
JSC
1222 printf(" GPR[destreg] = (op1 & op2);\n");
1223 break ;
1224
8bae0a0c 1225 case OR:
8ad57737
JSC
1226 printf(" GPR[destreg] = (%sop1 | op2);\n",((MIPS_DECODE[loop].flags & NOT) ? "~" : ""));
1227 break ;
1228
8bae0a0c 1229 case XOR:
8ad57737
JSC
1230 printf(" GPR[destreg] = (op1 ^ op2);\n");
1231 break ;
1232
8bae0a0c 1233 case DECODE:
8ad57737
JSC
1234 printf(" decode_coproc(instruction);\n");
1235 break ;
1236
8bae0a0c 1237 case CACHE:
8ad57737
JSC
1238 /* 16-bit offset is sign-extended and added to the base register to make a virtual address */
1239 /* The virtual address is translated to a physical address using the TLB */
1240 /* The hint specifies a cache operation for that address */
1241 printf(" uword64 vaddr = (op1 + offset);\n");
1242 printf(" uword64 paddr;\n");
1243 printf(" int uncached;\n");
1244 /* NOTE: We are assuming that the AddressTranslation is a load: */
1245 printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
1246 printf(" CacheOp(hint,vaddr,paddr,instruction);\n");
1247 break;
1248
8bae0a0c 1249 case MADD16: /* VR4100 specific multiply-add instructions */
8ad57737
JSC
1250 /* Some of this code is shared with the standard multiply
1251 routines, so an effort should be made to merge where
1252 possible. */
1253 if (features & FEATURE_WARN_LOHI) {
1254 printf(" CHECKHILO(\"Multiply-Add\");\n");
1255 }
1256 if (features & FEATURE_WARN_RESULT) {
1257 /* Give user a warning if either op1 or op2 are not 16bit signed integers */
1258 printf(" if (NOTHALFWORDVALUE(op1) || NOTHALFWORDVALUE(op2))\n");
1259 printf(" WARNING(\"MADD16 operation with non-16bit operands\");\n");
1260 }
1261 printf(" {\n");
1262 printf(" uword64 temp = (op1 * op2);\n"); /* 16x16 multiply */
1263 if (GETDATASIZE() == DOUBLEWORD) {
1264 printf(" LO = LO + temp;\n");
1265 } else { /* WORD */
a647a859
JSC
1266 printf(" temp += (SET64HI(WORD64LO(HI)) | WORD64LO(LO));\n");
1267 printf(" LO = SIGNEXTEND((%s)WORD64LO(temp),32);\n",regtype);
1268 printf(" HI = SIGNEXTEND((%s)WORD64HI(temp),32);\n",regtype);
8ad57737
JSC
1269 }
1270 printf(" }\n");
1271 break;
1272
8bae0a0c
JSC
1273 case RSVD: /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "CoProcessorUnusable" */
1274 if (doisa < 4) {
8ad57737
JSC
1275 printf(" if (CoProcPresent(3))\n");
1276 printf(" SignalException(CoProcessorUnusable);\n");
1277 printf(" else\n");
1278 }
1279 printf(" SignalException(ReservedInstruction,instruction);\n");
1280 break ;
1281
8bae0a0c 1282 case JUMP:
8ad57737
JSC
1283 if (MIPS_DECODE[loop].flags & LINK) {
1284 if (!(MIPS_DECODE[loop].flags & REG))
1285 printf(" int destreg = 31;\n");
1286 printf(" GPR[destreg] = (PC + 4); /* NOTE: The PC is already 4 ahead within the simulator */\n");
1287 }
1288
1289 printf(" /* NOTE: The jump occurs AFTER the next instruction has been executed */\n");
1290 printf(" DSPC = op1;\n");
1291 printf(" DELAYSLOT();\n");
1292 break ;
1293
8bae0a0c
JSC
1294 case BRANCH: /* execute delay slot instruction before branch unless (LIKELY && branch_not_taken) */
1295 if (MIPS_DECODE[loop].flags & FP) {
1296 if (doisa < 4) {
1297 printf(" if (condition_code != 0)\n");
1298 printf(" SignalException(ReservedInstruction,instruction);\n");
1299 printf(" else {\n");
1300 }
1301 /* "PREVCOC1()" should be the COC1 value at the start of the preceding instruction */
1302 printf(" int condition = (%s == boolean);\n",((doisa < 4) ? "PREVCOC1()" : "GETFCC(condition_code)"));
1303 } else {
1304 if ((MIPS_DECODE[loop].flags & NOT) && !(MIPS_DECODE[loop].flags & EQ)) {
1305 fprintf(stderr,"NOT specified when not EQ in \"%s\"\n",MIPS_DECODE[loop].name);
1306 exit(7);
1307 }
1308 if ((MIPS_DECODE[loop].flags & NOT) && (MIPS_DECODE[loop].flags & (GT | LT))) {
1309 fprintf(stderr,"NOT specified with GT or LT in \"%s\"\n",MIPS_DECODE[loop].name);
1310 exit(7);
1311 }
1312 /* GT LT */
1313 if (MIPS_DECODE[loop].flags & GT)
1314 printf(" int condition = (op1 >%s 0);\n",((MIPS_DECODE[loop].flags & EQ) ? "=" : ""));
1315 else
1316 if (MIPS_DECODE[loop].flags & LT)
1317 printf(" int condition = (op1 <%s 0);\n",((MIPS_DECODE[loop].flags & EQ) ? "=" : ""));
1318 else
1319 if (MIPS_DECODE[loop].flags & EQ)
1320 printf(" int condition = (op1 %c= op2);\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
8ad57737 1321 }
8ad57737
JSC
1322
1323 if (MIPS_DECODE[loop].flags & LINK) {
1324 if (features & FEATURE_WARN_R31) {
1325 printf(" if (((instruction >> %d) & 0x%08X) == 31)\n",OP_SH_RS,OP_MASK_RS);
1326 printf(" WARNING(\"Branch with link using r31 as source operand\");\n");
1327 }
1328 printf(" GPR[31] = (PC + 4); /* NOTE: PC is already 8 ahead */\n");
1329 }
1330
1331 printf(" /* NOTE: The branch occurs AFTER the next instruction has been executed */\n");
1332 printf(" if (condition) {\n");
1333 printf(" DSPC = (PC + offset);\n");
1334 printf(" DELAYSLOT();\n");
1335 printf(" }\n");
8bae0a0c
JSC
1336 if ((MIPS_DECODE[loop].flags & FP) && (doisa != 1)) {
1337 printf(" else if (likely) {\n");
1338 printf(" NULLIFY();\n");
1339 printf(" }\n");
1340 } else if (MIPS_DECODE[loop].flags & LIKELY) {
8ad57737
JSC
1341 printf(" else\n");
1342 printf(" NULLIFY();\n");
1343 }
8bae0a0c
JSC
1344 if ((MIPS_DECODE[loop].flags & FP) && (doisa < 4))
1345 printf(" }\n");
8ad57737
JSC
1346 break ;
1347
8bae0a0c
JSC
1348 case PREFETCH: /* The beginning is shared with normal load operations */
1349 case LOAD:
1350 case STORE:
8ad57737
JSC
1351 {
1352 int isload = ((MIPS_DECODE[loop].type == LOAD) || (MIPS_DECODE[loop].type == PREFETCH));
1353 int datalen;
1354 char *accesslength = "<UNKNOWN>";
1355
1356 switch (GETDATASIZE()) {
1357 case BYTE :
1358 datalen = 1;
1359 accesslength = "AccessLength_BYTE";
1360 break ;
1361
1362 case HALFWORD :
1363 datalen = 2;
1364 accesslength = "AccessLength_HALFWORD";
1365 break ;
1366
1367 case WORD :
1368 datalen = 4;
1369 accesslength = "AccessLength_WORD";
1370 break ;
1371
1372 case DOUBLEWORD :
1373 datalen = 8;
1374 accesslength = "AccessLength_DOUBLEWORD";
1375 break ;
1376 }
1377
8bae0a0c
JSC
1378 if (MIPS_DECODE[loop].flags & REG)
1379 printf(" uword64 vaddr = ((unsigned long long)op1 + op2);\n");
1380 else
1381 printf(" uword64 vaddr = ((unsigned long long)op1 + offset);\n");
8ad57737
JSC
1382 printf(" uword64 paddr;\n");
1383 printf(" int uncached;\n");
1384
1385 /* The following check should only occur on normal (non-shifted) memory loads */
1386 if ((datalen != 1) && !(MIPS_DECODE[loop].flags & (LEFT | RIGHT))) {
1387 printf(" if ((vaddr & %d) != 0)\n",(datalen - 1));
1388 printf(" SignalException(%s);\n",(isload ? "AddressLoad" : "AddressStore"));
1389 printf(" else\n") ;
1390 }
1391
1392 printf(" {\n");
1393 printf(" if (AddressTranslation(vaddr,isDATA,%s,&paddr,&uncached,isTARGET,isREAL))\n",(isload ? "isLOAD" : "isSTORE"));
1394
1395 if (MIPS_DECODE[loop].type == PREFETCH)
1396 printf(" Prefetch(uncached,paddr,vaddr,isDATA,hint);\n");
1397 else {
1398 printf(" {\n");
1399 printf(" %s memval;\n",(proc64 ? "uword64" : "unsigned int"));
1400
8bae0a0c
JSC
1401 if ((MIPS_DECODE[loop].flags & COPROC) && ((datalen != 4) && (datalen != 8))) {
1402 fprintf(stderr,"Co-processor transfer operation not WORD or DOUBLEWORD in length \"%s\"\n",MIPS_DECODE[loop].name);
1403 exit(6);
1404 }
8ad57737 1405
8bae0a0c
JSC
1406 if (MIPS_DECODE[loop].flags & (LEFT | RIGHT)) {
1407 if ((MIPS_DECODE[loop].flags & LEFT) && (MIPS_DECODE[loop].flags & RIGHT)) {
1408 fprintf(stderr,"Memory transfer with both LEFT and RIGHT specified \"%s\"\n",MIPS_DECODE[loop].name);
1409 exit(4);
8ad57737 1410 }
8ad57737 1411
8bae0a0c
JSC
1412 switch (datalen) {
1413 case 8:
1414 if (!proc64) {
1415 fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",MIPS_DECODE[loop].name);
1416 exit(4);
1417 }
1418 /* fall through to... */
1419 case 4:
1420 {
1421 char *maskstr = ((datalen == 8) ? "((uword64)-1)" : "0xFFFFFFFF");
1422
1423 printf(" uword64 mask = %d;\n",((datalen == 8) ? 0x7 : 0x3));
1424 printf(" unsigned int reverse = (ReverseEndian ? mask : 0);\n");
1425 printf(" unsigned int bigend = (BigEndianCPU ? mask : 0);\n");
1426 printf(" int byte;\n");
1427 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));\n");
1428 printf(" byte = ((vaddr & mask) ^ bigend);\n");
1429 printf(" if (%sBigEndianMem)\n",((MIPS_DECODE[loop].flags & LEFT) ? "!" : ""));
1430 printf(" paddr &= ~mask;\n");
1431
1432 if (isload) {
1433 if (MIPS_DECODE[loop].flags & LEFT)
1434 printf(" memval = LoadMemory(uncached,byte,paddr,vaddr,isDATA,isREAL);\n");
1435 else
1436 printf(" memval = LoadMemory(uncached,(%d - byte),paddr,vaddr,isDATA,isREAL);\n",(datalen - 1));
8ad57737 1437 }
8ad57737 1438
8bae0a0c 1439 if (MIPS_DECODE[loop].flags & LEFT) {
8ad57737 1440 if (isload) {
8bae0a0c
JSC
1441 /* For WORD transfers work out if the value will
1442 be in the top or bottom of the DOUBLEWORD
1443 returned: */
1444 if (proc64 && (datalen == 4)) {
1445 printf(" if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1446 printf(" memval >>= 32;\n");
1447 printf(" }\n");
8ad57737 1448 }
8bae0a0c
JSC
1449 printf(" GPR[destreg] = ((memval << ((%d - byte) * 8)) | (GPR[destreg] & (((uword64)1 << ((%d - byte) * 8)) - 1)));\n",(datalen - 1),(datalen - 1));
1450 if (proc64 && (datalen == 4))
1451 printf(" GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
1452 } else { /* store */
1453 printf(" memval = (op2 >> (8 * (%d - byte)));\n",(datalen - 1));
1454 /* TODO: This is duplicated in the LOAD code
1455 above - and the RIGHT LOAD and STORE code
1456 below. It should be merged if possible. */
1457 if (proc64 && (datalen == 4)) {
1458 printf(" if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1459 printf(" memval <<= 32;\n");
1460 printf(" }\n");
8ad57737 1461 }
8bae0a0c
JSC
1462 printf(" StoreMemory(uncached,byte,memval,paddr,vaddr,isREAL);\n");
1463 }
1464 } else { /* RIGHT */
1465 if (isload) {
1466 if (proc64 && (datalen == 4)) {
1467 printf(" if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) {\n");
1468 printf(" memval >>= 32;\n");
1469 printf(" }\n");
1470 }
1471 printf(" {\n");
1472 printf(" uword64 srcmask;\n");
1473 /* All of this extra code is just a bodge
1474 required because some hosts don't allow
1475 ((v) << 64). The SPARC just leaves the (v)
1476 value un-touched. */
1477 printf(" if (byte == 0)\n");
1478 printf(" srcmask = 0;\n");
1479 printf(" else\n");
1480 printf(" srcmask = ((uword64)-1 << (8 * (%d - byte)));\n",datalen);
1481 printf(" GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte)));\n",datalen);
1482 printf(" }\n");
1483 if (proc64 && (datalen == 4))
1484 printf(" GPR[destreg] = SIGNEXTEND(GPR[destreg],32);\n");
1485 } else { /* store */
1486 printf(" memval = (op2 << (byte * 8));\n");
1487 printf(" StoreMemory(uncached,(%s - byte),memval,paddr,vaddr,isREAL);\n",accesslength);
8ad57737
JSC
1488 }
1489 }
8ad57737 1490 }
8bae0a0c 1491 break;
8ad57737 1492
8bae0a0c
JSC
1493 default:
1494 fprintf(stderr,"Shifted memory transfer not WORD or DOUBLEWORD in length \"%s\"\n",MIPS_DECODE[loop].name);
1495 exit(6);
1496 }
1497 } else { /* normal memory transfer */
1498 if (((datalen == 8) || ((datalen == 4) & (MIPS_DECODE[loop].flags & UNSIGNED))) && !proc64) {
1499 fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",MIPS_DECODE[loop].name);
1500 exit(4);
1501 /* TODO: The R4000 documentation states that a LWU
1502 instruction executed when in a 32bit processor mode
1503 should cause a ReservedInstruction exception. This
1504 will mean adding a run-time check into the code
1505 sequence. */
1506 }
8ad57737 1507
8bae0a0c
JSC
1508 if (isload) {
1509 printf(" uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
1510 printf(" unsigned int shift = %d;\n",(datalen >> 1));
1511 printf(" unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
1512 printf(" unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
1513 printf(" unsigned int byte;\n");
8ad57737 1514
8bae0a0c
JSC
1515 if (datalen != 8) /* not for DOUBLEWORD */
1516 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
8ad57737 1517
8bae0a0c 1518 printf(" memval = LoadMemory(uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
8ad57737 1519
8bae0a0c
JSC
1520 /* The following will only make sense if the
1521 "LoadMemory" above returns a DOUBLEWORD entity */
1522 if (datalen != 8) { /* not for DOUBLEWORD */
1523 int valmask;
1524 switch (datalen) {
1525 case 1:
1526 valmask = 0xFF;
1527 break;
1528
1529 case 2:
1530 valmask = 0xFFFF;
1531 break;
1532
1533 case 4:
1534 valmask = 0xFFFFFFFF;
1535 break;
1536
1537 default:
1538 fprintf(stderr,"Unrecognised datalen (%d) when processing \"%s\"\n",datalen,MIPS_DECODE[loop].name);
1539 exit(4);
1540 }
1541 printf(" byte = ((vaddr & mask) ^ (bigend << shift));\n");
1542 /* NOTE: The R4000 user manual has the COP_LW
1543 occuring in the same cycle as the rest of the
1544 instruction, yet the MIPS IV shows the operation
1545 happening on the next cycle. To keep the simulator
1546 simple, this code follows the R4000
1547 manual. Experimentation with a silicon
1548 implementation will be needed to ascertain the
1549 correct operation. */
1550 if (MIPS_DECODE[loop].flags & COPROC)
1551 printf(" COP_LW(((instruction >> 26) & 0x3),destreg,(unsigned int)");
1552 else
1553 printf(" GPR[destreg] = (");
1554
1555 if (MIPS_DECODE[loop].flags & SIGNEXTEND)
1556 printf("SIGNEXTEND(");
1557 printf("((memval >> (8 * byte)) & 0x%08X)",valmask);
1558 if (MIPS_DECODE[loop].flags & SIGNEXTEND)
1559 printf(",%d)",(datalen * 8));
1560 printf(");\n");
1561 } else {
1562 if (MIPS_DECODE[loop].flags & COPROC)
1563 printf(" COP_LD(((instruction >> 26) & 0x3),destreg,memval);;\n");
1564 else
1565 printf(" GPR[destreg] = memval;\n");
1566 }
1567 } else { /* store operation */
1568 if ((datalen == 1) || (datalen == 2)) {
1569 /* SH and SB */
1570 printf(" uword64 mask = %d;\n",(proc64 ? 0x7 : 0x3));
1571 printf(" unsigned int shift = %d;\n",(datalen >> 1));
1572 printf(" unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0);\n");
1573 printf(" unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0);\n");
1574 printf(" unsigned int byte;\n");
8ad57737 1575
8bae0a0c
JSC
1576 printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
1577 printf(" byte = ((vaddr & mask) ^ (bigend << shift));\n");
1578 printf(" memval = (op2 << (8 * byte));\n");
1579 } else
1580 if (proc64 && (datalen == 4)) { /* proc64 SC and SW */
1581 printf(" unsigned int byte;\n");
1582 printf(" paddr = ((paddr & ~0x7) | ((paddr & 0x7) ^ (ReverseEndian << 2)));\n");
1583 printf(" byte = ((vaddr & 0x7) ^ (BigEndianCPU << 2));\n");
1584 if (MIPS_DECODE[loop].flags & COPROC)
1585 printf(" memval = (((unsigned long long)COP_SW(((instruction >> 26) & 0x3),%s)) << (8 * byte));\n",((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
1586 else
1587 printf(" memval = (op2 << (8 * byte));\n");
1588 } else { /* !proc64 SC and SW, plus proc64 SD and SCD */
1589 if (MIPS_DECODE[loop].flags & COPROC)
1590 printf(" memval = (unsigned long long)COP_S%c(((instruction >> 26) & 0x3),%s);\n",((datalen == 8) ? 'D' : 'W'),((MIPS_DECODE[loop].flags & FP) ? "fs" : "destreg"));
1591 else
1592 printf(" memval = op2;\n");
1593 }
1594
1595 if (MIPS_DECODE[loop].flags & ATOMIC)
1596 printf(" if (LLBIT)\n");
1597
1598 printf(" {\n");
1599 printf(" StoreMemory(uncached,%s,memval,paddr,vaddr,isREAL);\n",accesslength);
1600 printf(" }\n");
1601 }
8ad57737 1602
8bae0a0c
JSC
1603 if (MIPS_DECODE[loop].flags & ATOMIC) {
1604 if ((datalen != 4) && (datalen != 8)) {
1605 fprintf(stderr,"ATOMIC can only be applied to WORD and DOUBLEWORD instructions \"%s\"\n",MIPS_DECODE[loop].name);
1606 exit(4);
1607 } else
1608 if (isload)
1609 printf(" LLBIT = 1;\n");
1610 else {
1611 /* The documentation states that:
1612
1613 SC *WILL* fail if coherent store into the same
1614 block occurs, or if an exception occurs between
1615 the LL and SC instructions.
1616
1617 SC *MAY* fail if a load, store or prefetch is
1618 executed on the processor (VR4300 doesn't seem
1619 to), or if the instructions between the LL and
1620 SC are not in a 2048byte contiguous VM range.
1621
1622 SC *MUST* have been preceded by an LL
1623 (i.e. LLBIT will be set), and it must use the
1624 same Vaddr, Paddr and cache-coherence algorithm
1625 as the LL (which means we should store this
1626 information from the load-conditional).
1627 */
1628 printf(" GPR[(instruction >> %d) & 0x%08X] = LLBIT;\n",OP_SH_RT,OP_MASK_RT);
1629 }
1630 }
1631 }
8ad57737
JSC
1632 printf(" }\n");
1633 }
1634 printf(" }\n");
1635 }
1636 break ;
1637
8bae0a0c
JSC
1638 case FPPREFX:
1639 /* This code could be merged with the PREFIX generation above: */
1640 printf(" uword64 vaddr = ((unsigned long long)op1 + (unsigned long long)op2);\n");
1641 printf(" uword64 paddr;\n");
1642 printf(" int uncached;\n");
1643 printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
1644 printf(" Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
8ad57737
JSC
1645 break ;
1646
8bae0a0c
JSC
1647 case FPMOVEC:
1648 if (MIPS_DECODE[loop].flags & CONTROL) {
1649 /* The following "magic" of interpreting the FP
1650 control-register number would not be needed if we were not
1651 trying to match our internal register numbers with those
1652 used by GDB. */
1653 printf(" if (to) {\n");
1654 if (doisa < 4) {
1655 printf(" if (fs == 0) {\n");
a647a859 1656 printf(" PENDING_FILL((fs + FCR0IDX),WORD64LO(GPR[ft]));\n");
8bae0a0c 1657 printf(" } else if (fs == 31) {\n");
a647a859 1658 printf(" PENDING_FILL((fs + FCR31IDX),WORD64LO(GPR[ft]));\n");
8bae0a0c
JSC
1659 printf(" } /* else NOP */\n");
1660 printf(" PENDING_FILL(COCIDX,0); /* special case */\n");
1661 } else {
1662 printf(" if (fs == 0) {\n");
a647a859 1663 printf(" FCR0 = WORD64LO(GPR[ft]);\n");
8bae0a0c 1664 printf(" } else if (fs == 31) {\n");
a647a859 1665 printf(" FCR31 = WORD64LO(GPR[ft]);\n");
8bae0a0c
JSC
1666 printf(" } /* else NOP */\n");
1667 printf(" SETFCC(0,((FCR31 & (1 << 23)) ? 1 : 0)); /* COC[1] */\n");
1668 }
1669 printf(" } else { /* control from */\n");
1670 if (doisa < 4) {
1671 printf(" if (fs == 0) {\n");
1672 printf(" PENDING_FILL(ft,SIGNEXTEND(FCR0,32));\n");
1673 printf(" } else if (fs == 31) {\n");
1674 printf(" PENDING_FILL(ft,SIGNEXTEND(FCR31,32));\n");
1675 printf(" } /* else NOP */\n");
1676 } else {
1677 printf(" if (fs == 0) {\n");
1678 printf(" GPR[ft] = SIGNEXTEND(FCR0,32);\n");
1679 printf(" } else if (fs == 31) {\n");
1680 printf(" GPR[ft] = SIGNEXTEND(FCR31,32);\n");
1681 printf(" } /* else NOP */\n");
1682 }
1683 printf(" }\n");
1684 } else {
1685 printf(" if (to) {\n");
1686 if (GETDATASIZE() == WORD) {
1687 if (doisa < 4) {
1688 printf(" if (SizeFGR() == 64) {\n");
a647a859 1689 printf(" PENDING_FILL((fs + FGRIDX),(SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft])));\n");
8bae0a0c 1690 printf(" } else { \n");
a647a859 1691 printf(" PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
8bae0a0c
JSC
1692 printf(" }\n");
1693 } else {
1694 printf(" if (SizeFGR() == 64)\n");
a647a859 1695 printf(" FGR[fs] = (SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft]));\n");
8bae0a0c 1696 printf(" else\n");
a647a859 1697 printf(" FGR[fs] = WORD64LO(GPR[ft]);\n");
8bae0a0c
JSC
1698 printf(" fpr_state[fs] = fmt_uninterpreted;\n");
1699 }
1700 } else if (GETDATASIZE() == DOUBLEWORD) {
1701 if (doisa < 4) {
1702 printf(" if (SizeFGR() == 64) {\n");
1703 printf(" PENDING_FILL((fs + FGRIDX),GPR[ft]);\n");
1704 printf(" } else\n");
1705 printf(" if ((fs & 0x1) == 0)\n");
1706 printf(" {\n");
a647a859
JSC
1707 printf(" PENDING_FILL(((fs + 1) + FGRIDX),WORD64HI(GPR[ft]));\n");
1708 printf(" PENDING_FILL((fs + FGRIDX),WORD64LO(GPR[ft]));\n");
8bae0a0c
JSC
1709 printf(" }\n");
1710 if (features & FEATURE_WARN_RESULT) {
1711 printf(" else\n");
1712 printf(" UndefinedResult();\n");
1713 }
1714 } else {
1715 printf(" if (SizeFGR() == 64) {\n");
1716 printf(" FGR[fs] = GPR[ft];\n");
1717 printf(" fpr_state[fs] = fmt_uninterpreted;\n");
1718 printf(" } else\n");
1719 printf(" if ((fs & 0x1) == 0)\n");
1720 printf(" {\n");
a647a859
JSC
1721 printf(" FGR[fs + 1] = WORD64HI(GPR[ft]);\n");
1722 printf(" FGR[fs] = WORD64LO(GPR[ft]);\n");
8bae0a0c
JSC
1723 printf(" fpr_state[fs + 1] = fmt_uninterpreted;\n");
1724 printf(" fpr_state[fs] = fmt_uninterpreted;\n");
1725 printf(" }\n");
1726 if (features & FEATURE_WARN_RESULT) {
1727 printf(" else\n");
1728 printf(" UndefinedResult();\n");
1729 }
1730 }
1731 } else {
1732 fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
1733 exit(1);
1734 }
1735 printf(" } else {\n");
1736 if (GETDATASIZE() == WORD) {
1737 if (doisa < 4) /* write-back occurs in next cycle */
1738 printf(" PENDING_FILL(ft,SIGNEXTEND(FGR[fs],32));\n");
1739 else /* in this cycle */
1740 printf(" GPR[ft] = SIGNEXTEND(FGR[fs],32);\n");
1741 } else if (GETDATASIZE() == DOUBLEWORD) {
1742 if (doisa < 4) {
1743 printf(" if (SizeFGR() == 64) {\n");
1744 printf(" PENDING_FILL(ft,FGR[fs]);\n");
1745 printf(" } else\n");
1746 printf(" if ((fs & 0x1) == 0) {\n");
a647a859 1747 printf(" PENDING_FILL(ft,(SET64HI(FGR[fs+1]) | FGR[fs]));\n");
8bae0a0c 1748 printf(" } else {\n");
a647a859 1749 printf(" PENDING_FILL(ft,SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
8bae0a0c
JSC
1750 if (features & FEATURE_WARN_RESULT)
1751 printf(" UndefinedResult();\n");
1752 printf(" }\n");
1753 } else {
1754 printf(" if (SizeFGR() == 64)\n");
1755 printf(" GPR[ft] = FGR[fs];\n");
1756 printf(" else\n");
1757 printf(" if ((fs & 0x1) == 0)\n");
a647a859 1758 printf(" GPR[ft] = (SET64HI(FGR[fs + 1]) | FGR[fs]);\n");
8bae0a0c 1759 printf(" else {\n");
a647a859 1760 printf(" GPR[ft] = (SET64HI(0xDEADC0DE) | 0xBAD0BAD0);\n");
8bae0a0c
JSC
1761 if (features & FEATURE_WARN_RESULT)
1762 printf(" UndefinedResult();\n");
1763 printf(" }\n");
1764 }
1765 } else {
1766 fprintf(stderr,"Invalid data width specified in FPU Move operation\n");
1767 exit(1);
1768 }
1769 printf(" }\n");
1770 }
8ad57737
JSC
1771 break ;
1772
8bae0a0c
JSC
1773 case FPMOVE:
1774 if (MIPS_DECODE[loop].flags & CONDITIONAL) {
1775 if (MIPS_DECODE[loop].flags & INTEGER) { /* moving GPR - testing FGR */
1776 printf(" if (GETFCC(condition_code) == boolean)\n");
1777 printf(" GPR[destreg] = op1;\n");
1778 } else {
1779 if (MIPS_DECODE[loop].flags & EQ) /* moving FGR - testing GPR */
1780 printf(" if (op2 %c= 0)\n",((MIPS_DECODE[loop].flags & NOT) ? '!' : '='));
1781 else
1782 printf(" if (GETFCC(condition_code) == boolean)\n");
1783 printf(" StoreFPR(destreg,format,ValueFPR(fs,format));\n");
1784 printf(" else\n");
1785 printf(" StoreFPR(destreg,format,ValueFPR(destreg,format));\n");
1786 }
1787 } else { /* simple MOVE */
1788 printf(" StoreFPR(destreg,format,ValueFPR(fs,format));\n");
1789 }
8ad57737
JSC
1790 break ;
1791
8bae0a0c
JSC
1792 case FPNEG:
1793 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1794 printf(" SignalException(ReservedInstruction,instruction);\n");
1795 printf(" else\n");
1796 printf(" StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format));\n");
8ad57737
JSC
1797 break ;
1798
8bae0a0c
JSC
1799 case FPABS:
1800 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1801 printf(" SignalException(ReservedInstruction,instruction);\n");
1802 printf(" else\n");
1803 printf(" StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format));\n");
8ad57737
JSC
1804 break ;
1805
8bae0a0c
JSC
1806 case FPDIV:
1807 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1808 printf(" SignalException(ReservedInstruction,instruction);\n");
1809 printf(" else\n");
1810 printf(" StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
8ad57737
JSC
1811 break ;
1812
8bae0a0c
JSC
1813 case FPMUL:
1814 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1815 printf(" SignalException(ReservedInstruction,instruction);\n");
1816 printf(" else\n");
1817 printf(" StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
8ad57737
JSC
1818 break ;
1819
8bae0a0c
JSC
1820 case FPRECIP:
1821 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1822 printf(" SignalException(ReservedInstruction,instruction);\n");
1823 printf(" else\n");
1824 printf(" StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format));\n");
8ad57737
JSC
1825 break ;
1826
8bae0a0c
JSC
1827 case FPSQRT:
1828 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1829 printf(" SignalException(ReservedInstruction,instruction);\n");
1830 printf(" else\n");
1831 printf(" StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)));\n",((MIPS_DECODE[loop].flags & RECIP) ? "Recip" : ""));
8ad57737
JSC
1832 break ;
1833
8bae0a0c
JSC
1834 case FPCEIL:
1835 case FPFLOOR:
1836 case FPTRUNC:
1837 case FPROUND:
1838 {
1839 char *op = "";
1840 char *type = "";
8ad57737 1841
8bae0a0c
JSC
1842 switch (MIPS_DECODE[loop].type) {
1843 case FPCEIL:
1844 op = "FP_RM_TOPINF";
1845 break;
1846 case FPFLOOR:
1847 op = "FP_RM_TOMINF";
1848 break;
1849 case FPTRUNC:
1850 op = "FP_RM_TOZERO";
1851 break;
1852 case FPROUND:
1853 op = "FP_RM_NEAREST";
1854 break;
1855 default:
1856 fprintf(stderr,"Error: Handled missing for FP reason code %d\n",MIPS_DECODE[loop].type);
1857 exit(1);
1858 }
8ad57737 1859
8bae0a0c
JSC
1860 switch (GETDATASIZE()) {
1861 case WORD :
1862 type = "fmt_word";
1863 break;
1864 case DOUBLEWORD :
1865 type = "fmt_long";
1866 break;
1867 default:
1868 fprintf(stderr,"Error in instruction encoding table for FP %s operation (not WORD or DOUBLEWORD)\n",op);
1869 exit(1);
1870 }
1871 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1872 printf(" SignalException(ReservedInstruction,instruction);\n");
1873 printf(" else\n");
1874 printf(" StoreFPR(destreg,%s,Convert(%s,ValueFPR(fs,format),format,%s));\n",type,op,type);
1875 }
8ad57737
JSC
1876 break ;
1877
8bae0a0c
JSC
1878 case FPCONVERT:
1879 {
1880 char *type = "";
1881 switch (GETDATASIZE()) {
1882 case SINGLE:
1883 type = "fmt_single";
1884 break;
1885 case DOUBLE:
1886 type = "fmt_double";
1887 break;
1888 case WORD:
1889 type = "fmt_word";
1890 break;
1891 case DOUBLEWORD:
1892 type = "fmt_long";
1893 break;
1894 default :
1895 fprintf(stderr,"Error: Unknown data size %d in FPCONVERT instruction\n",GETDATASIZE());
1896 exit(1);
1897 }
8ad57737 1898
8bae0a0c
JSC
1899 /* Not all combinations of conversion are valid at the
1900 moment: When converting to a fixed-point format, only
1901 floating-point sources are allowed. */
1902 printf(" if ((format == %s) | %s)\n",type,((MIPS_DECODE[loop].flags & FIXED) ? "((format == fmt_long) || (format == fmt_word))": "0"));
1903 printf(" SignalException(ReservedInstruction,instruction);\n");
1904 printf(" else\n");
1905 printf(" StoreFPR(destreg,%s,Convert(GETRM(),ValueFPR(fs,format),format,%s));\n",type,type);
1906 }
8ad57737
JSC
1907 break ;
1908
8bae0a0c
JSC
1909 case FPSUB:
1910 if (MIPS_DECODE[loop].flags & MULTIPLY) {
1911 char *type = "";
1912 switch (GETDATASIZE()) {
1913 case SINGLE:
1914 type = "fmt_single";
1915 break;
1916 case DOUBLE:
1917 type = "fmt_double";
1918 break;
1919 default:
1920 fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZE());
1921 exit(1);
1922 }
1923 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);
1924 } else {
1925 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1926 printf(" SignalException(ReservedInstruction,instruction);\n");
1927 printf(" else\n");
1928 printf(" StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
1929 }
8ad57737
JSC
1930 break ;
1931
8bae0a0c
JSC
1932 case FPADD:
1933 if (MIPS_DECODE[loop].flags & MULTIPLY) {
1934 char *type = "";
1935 switch (GETDATASIZE()) {
1936 case SINGLE:
1937 type = "fmt_single";
1938 break;
1939 case DOUBLE:
1940 type = "fmt_double";
1941 break;
1942 default:
1943 fprintf(stderr,"Error: Invalid data size %d for FPADD operation in instruction table\n",GETDATASIZE());
1944 exit(1);
1945 }
1946 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);
1947 } else {
1948 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1949 printf(" SignalException(ReservedInstruction,instruction);\n");
1950 printf(" else\n");
1951 printf(" StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format));\n");
1952 }
8ad57737
JSC
1953 break ;
1954
8bae0a0c 1955 case FPCOMPARE:
8ad57737
JSC
1956 /* For the MIPS I,II or III there *MUST* be at least one
1957 instruction between the compare that sets a condition code
8bae0a0c
JSC
1958 and the branch that tests it. NOTE: However the hardware
1959 does not detect this condition. */
1960 /* Explicitly limit the operation to S and D formats: */
1961 printf(" if ((format != fmt_single) && (format != fmt_double))\n");
1962 printf(" SignalException(ReservedInstruction,instruction);\n") ;
1963 printf(" else {\n");
1964 if (doisa < 4) {
1965 printf(" if ((cmpflags & (1 << 3)) || (condition_code != 0))\n");
1966 printf(" SignalException(ReservedInstruction,instruction);\n") ;
1967 printf(" else\n");
1968 }
1969 printf(" {\n");
1970 printf(" int ignore = 0;\n");
1971 printf(" int less = 0;\n");
1972 printf(" int equal = 0;\n");
1973 printf(" int unordered = 1;\n");
1974 printf(" unsigned long long ofs = ValueFPR(fs,format);\n");
1975 printf(" unsigned long long oft = ValueFPR(ft,format);\n");
1976 printf(" if (NaN(ofs,format) || NaN(oft,format)) {\n");
1977 printf(" if (FCSR & FP_ENABLE(IO)) {\n");
1978 printf(" FCSR |= FP_CAUSE(IO);\n");
1979 printf(" SignalException(FPE);\n");
1980 printf(" ignore = 1;\n");
1981 printf(" }\n");
1982 printf(" } else {\n");
1983 printf(" less = Less(ofs,oft,format);\n");
1984 printf(" equal = Equal(ofs,oft,format);\n");
1985 printf(" unordered = 0;\n");
1986 printf(" }\n");
1987 printf(" if (!ignore) {\n");
1988 printf(" int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered));\n");
1989 printf(" SETFCC(condition_code,condition);\n");
1990 printf(" }\n");
1991 printf(" }\n");
1992 printf(" }\n");
8ad57737
JSC
1993 break ;
1994
8bae0a0c 1995 default:
8ad57737
JSC
1996 fprintf(stderr,"Unrecognised opcode type %d\n",MIPS_DECODE[loop].type) ;
1997 exit(6) ;
1998 }
1999 printf(" }\n") ;
2000 printf(" }\n") ;
2001 printf(" break ;\n") ;
2002 }
2003 }
2004
2005 printf("default : /* Unrecognised instruction */\n") ;
2006 printf(" SignalException(ReservedInstruction,instruction);\n") ;
2007 printf(" break ;\n") ;
2008 printf("}\n}\n") ;
2009 printf("#endif /* simulator engine */\n");
2010
2011 return ;
2012}
2013
2014/*---------------------------------------------------------------------------*/
2015
2016/* The command-line feature controls are presented in a similar style
2017 to those offered by GCC, in the aim of providing a consistent
2018 interface to the user. */
2019typedef enum {
2020 T_NONE, /* no argument - mask and value fields control "feature" definition */
2021 T_NUM, /* numeric argument - optionally preceded by '=' - mask field defines maximum value */
2022 T_STRING /* string argument - optionally prcededed by '=' */
2023} mactypes;
2024
2025struct {
2026 char *name;
2027 mactypes type;
2028 unsigned int mask;
2029 unsigned int value;
2030 char *desc;
2031} machine_options[] = {
2032 {"ips", T_NUM, MASK_ISA,0,"\tSelect MIPS ISA version"},
2033 {"cpu", T_STRING,0,0,"\t\tSelect particular MIPS architecture"},
2034 {"gp64", T_NONE, FEATURE_GP64,FEATURE_GP64,"\t\t\tSelect 64bit GP registers"},
2035 {"gp32", T_NONE, FEATURE_GP64,0,"\t\t\tSelect 32bit GP registers"},
2036 {"no-fp", T_NONE, FEATURE_HASFPU,0,"\t\tDisable FP simulation"},
8ad57737
JSC
2037 {"single-float",T_NONE, (FEATURE_FPSINGLE | FEATURE_HASFPU),(FEATURE_FPSINGLE | FEATURE_HASFPU),"\t\tSelect single precision only FPU"},
2038 {"double-float",T_NONE, (FEATURE_FPSINGLE | FEATURE_HASFPU),FEATURE_HASFPU,"\t\tSelect double precision FPU"},
2039 {0, T_NONE, 0,0}
2040};
2041
2042/* The following architecture identies are those accepted by the "-mcpu" option: */
2043struct architectures {
2044 const char *name; /* ASCII string identifier for command-line, no white-space allowed */
2045 unsigned int idflag; /* or-ed into "isa" value */
2046};
2047
2048static const struct architectures available_architectures[] = {
2049 {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
2050 {0, 0} /* terminator */
2051};
2052
2053/*---------------------------------------------------------------------------*/
2054
2055static void
2056usage(name)
2057 char *name;
2058{
2059 int loop;
2060
2061 fprintf(stderr,"%s: Construct a MIPS simulator engine.\n",name);
2062
2063 fprintf(stderr,"\
2064The output of this program is a block of 'C' code designed to be\n\
2065included into the main simulation control loop of a device specific\n\
2066simulator.\n");
2067
2068 fprintf(stderr,"\nOptions:\n");
2069 fprintf(stderr," -h --help\t\tProvide this help text\n");
2070 fprintf(stderr," -f --fast\t\tProvide the fastest possible engine (i.e. no statistics)\n");
2071 fprintf(stderr," -w --warnings\t\tEnable all the simulator engine warnings\n");
2072
2073 for (loop = 0; (machine_options[loop].name != 0); loop++) {
2074 fprintf(stderr," -m%s",machine_options[loop].name);
2075 switch (machine_options[loop].type) {
2076 case T_NUM :
2077 fprintf(stderr,"N (range 0..%d)",machine_options[loop].mask);
2078 case T_NONE :
2079 break;
2080
2081 case T_STRING :
2082 fprintf(stderr,"=name");
2083 break;
2084
2085 default :
2086 fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",machine_options[loop].type);
2087 exit(1);
2088 }
2089 fprintf(stderr,"%s\n",machine_options[loop].desc);
2090 }
2091
2092 fprintf(stderr,"\nAvailable \"-mcpu\" architectures: ");
2093 for (loop = 0; (available_architectures[loop].name != 0); loop++)
2094 fprintf(stderr,"%s ",available_architectures[loop].name);
2095 fprintf(stderr,"\n\n");
2096
2097 fprintf(stderr,"\
2098The \"trace\" and \"warnings\" options do not define the output stream.\n\
2099They only inform the code that includes the constructed engine to provide\n\
2100the required features.\n\n\
2101The \"-mips0\" option forces the construction of a simulator supporting\n\
2102the highest available MIPS ISA supported.\n");
2103
2104 return;
2105}
2106
2107/*---------------------------------------------------------------------------*/
2108
2109int
2110main(argc,argv)
2111 int argc;
2112 char **argv;
2113{
2114 int c;
2115 char *progname = argv[0];
2116 unsigned int doarch = DEF_ISA;
2117 unsigned int features = 0; /* default state */
2118
2119 if (DEF_FP)
2120 features |= FEATURE_HASFPU;
2121 if (!DEF_PROC64)
2122 features |= FEATURE_PROC32;
2123 if (DEF_FPSINGLE)
2124 features |= FEATURE_FPSINGLE;
2125
2126 if (features & FEATURE_PROC32)
8bae0a0c 2127 features &= ~FEATURE_GP64;
8ad57737 2128 else
8bae0a0c 2129 features |= FEATURE_GP64;
8ad57737
JSC
2130
2131 while (1) {
2132 int this_option_optind = (optind ? optind : 1);
2133 int option_index = 0;
2134 static struct option cmdline[] = {
2135 {"fast", 0,0,'f'},
2136 {"help", 0,0,'h'},
2137 {"warnings",0,0,'w'},
2138 {0, 0,0,0}
2139 };
2140
2141 c = getopt_long(argc,argv,"hm:tw",cmdline,&option_index);
2142 if (c == -1)
2143 break ; /* out of the while loop */
2144
2145 switch (c) {
2146 case 'h' : /* help */
2147 usage(progname);
2148 exit(0);
2149
2150 case 'f' : /* fast */
2151 features |= FEATURE_FAST;
2152 break;
2153
2154 case 'w' : /* warnings */
2155 features |= FEATURE_WARNINGS;
2156 /* TODO: Future extension: Allow better control over the warnings generated:
2157 disable warnings -wnone ~FEATURE_WARNINGS
2158 all possible warnings -wall FEATURE_WARNINGS
2159 pipeline stall occuring -wstall FEATURE_WARN_STALL
2160 LO/HI corruption -wlo or -whi or -wlohi or -whilo FEATURE_WARN_HILO
2161 write to zero -wzero FEATURE_WARN_ZERO actually performed in external code - though we should set a manifest
2162 bad r31 use -wr31 FEATURE_WARN_R31
2163 undefined results -wresult FEATURE_WARN_RESULT
2164 */
2165 break;
2166
2167 case 'm' : /* machine options */
2168 {
2169 int loop;
2170
2171 for (loop = 0; (machine_options[loop].name != 0); loop++)
2172 if (strncmp(machine_options[loop].name,optarg,strlen(machine_options[loop].name)) == 0) {
2173 char *loptarg = (optarg + strlen(machine_options[loop].name));
2174 switch (machine_options[loop].type) {
2175 case T_NONE :
2176 if (*loptarg) {
2177 fprintf(stderr,"%s: Spurious characters \"%s\" at end of -m%s option\n",progname,loptarg,machine_options[loop].name);
2178 exit(1);
2179 }
2180 features &= ~(machine_options[loop].mask);
2181 features |= machine_options[loop].value;
2182 break;
2183
2184 case T_NUM :
2185 if (*loptarg && *loptarg == '=')
2186 loptarg++;
2187
2188 if (strcmp(machine_options[loop].name,"ips") == 0) {
2189 unsigned int num;
2190
2191 if (!*loptarg) {
2192 fprintf(stderr,"%s: ISA number expected after -mips\n",progname);
2193 exit(1);
2194 }
2195
2196 num = strtoul(loptarg,&loptarg,10);
2197
2198 if ((num == ULONG_MAX) && (errno = ERANGE)) {
2199 fprintf(stderr,"%s: Invalid number given to -mips option\n",progname);
2200 exit(1);
2201 }
2202
2203 if (*loptarg) {
2204 fprintf(stderr,"%s: Spurious trailing characters after ISA number \"%s\"\n",progname,loptarg);
2205 exit(1);
2206 }
2207
2208 if (num > MASK_ISA) {
2209 fprintf(stderr,"%s: ISA number %d outside acceptable range (0..%d)\n",progname,num,MASK_ISA);
2210 exit(1);
2211 }
2212
2213 doarch = ((doarch & ~MASK_ISA) | num);
2214 if ((num == 0) || (num > 2)) {
8bae0a0c
JSC
2215 if ((features & FEATURE_PROC32) || !(features & FEATURE_GP64))
2216 fprintf(stderr,"%s: Warning: -mips%d forcing -mgp64\n",progname,num);
2217 features |= FEATURE_GP64;
8ad57737
JSC
2218 features &= ~FEATURE_PROC32;
2219 } else {
8bae0a0c
JSC
2220 if (!(features & FEATURE_PROC32) || (features & FEATURE_GP64))
2221 fprintf(stderr,"%s: Warning: -mips%d forcing -mgp32\n",progname,num);
2222 features &= ~FEATURE_GP64;
8ad57737
JSC
2223 features |= FEATURE_PROC32;
2224 }
2225 } else {
2226 fprintf(stderr,"%s: FATAL: Unrecognised (numeric) machine option -m%s\n",progname,optarg);
2227 exit(1);
2228 }
2229 break;
2230
2231 case T_STRING :
2232 if (*loptarg && *loptarg == '=')
2233 loptarg++;
2234
2235 if (strcmp(machine_options[loop].name,"cpu") == 0) {
2236 int archloop;
2237
2238 if (!*loptarg) {
2239 fprintf(stderr,"%s: Architecture identifier expected after -mcpu\n",progname);
2240 exit(1);
2241 }
2242
2243 for (archloop = 0; (available_architectures[archloop].name != 0); archloop++) {
2244 if ((*loptarg == 'v') || (*loptarg == 'V'))
2245 *loptarg++;
2246
2247 if (*loptarg && (*loptarg == 'r') || (*loptarg == 'R'))
2248 *loptarg++;
2249
2250 if (strcmp(available_architectures[archloop].name,loptarg) == 0) {
2251 doarch |= available_architectures[archloop].idflag;
2252 break;
2253 }
2254 }
2255
2256 if (available_architectures[archloop].name == 0) {
2257 fprintf(stderr,"%s: Unrecognised MIPS architecture \"%s\"\n",progname,loptarg);
2258 exit(1);
2259 }
2260 } else {
2261 fprintf(stderr,"%s: FATAL: Unrecognised (string) machine option -m%s\n",progname,optarg);
2262 exit(1);
2263 }
2264 break;
2265
2266 default :
2267 fprintf(stderr,"%s: FATAL error: unrecognised machine option type ID %d\n",progname,machine_options[loop].type);
2268 exit(1);
2269 }
2270 break;
2271 }
2272
2273 if (machine_options[loop].name == 0) {
2274 fprintf(stderr,"%s: Unrecognised option: -m%s\n",progname,optarg);
2275 exit(1);
2276 }
2277 }
2278 break;
2279
2280 case '?' :
2281 /* An error message should already have been displayed */
2282 exit(1);
2283
2284 default :
2285 fprintf(stderr,"%s: FATAL: getopt returned unrecognised code 0x%08X\n",progname,c);
2286 exit(1);
2287 }
2288 }
2289
2290 if (optind < argc) {
2291 fprintf(stderr,"%s: Spurios non-option arguments ",progname);
2292 while (optind < argc)
2293 fprintf(stderr,"\"%s\" ",argv[optind++]);
2294 fprintf(stderr,"\n");
2295 exit(1);
2296 }
2297
2298 if ((features & FEATURE_FAST) && (features & FEATURE_WARNINGS))
2299 fprintf(stderr,"Warning: Fast model generation selected, along with trace or warnings.\n");
2300
2301 process_instructions(doarch,features) ;
2302 return(0) ;
2303}
2304
2305/*---------------------------------------------------------------------------*/
2306/*> EOF gencode.c <*/
This page took 0.174099 seconds and 4 git commands to generate.