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