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