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