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