#define FEATURE_WARN_MEM (1 << 27) /* 0 = nothing; 1 = generate warnings when memory problems are noticed */
#define FEATURE_WARN_R31 (1 << 28) /* 0 = nothing; 1 = generate warnings if r31 used dangerously */
#define FEATURE_WARN_RESULT (1 << 29) /* 0 = nothing; 1 = generate warnings when undefined results may occur */
+#define FEATURE_IGEN (1 << 20) /* 0 = nothing; 1 = generate igen formatted output file */
/* We used to enable FEATURE_WARN_ZERO, but it is perfectly legitimate to
have the zero register as a destination -- the zero register just doesn't
SHIFT, /* perform a logical or arithmetic shift */
TRAP, /* system exception generation */
BREAK, /* system breakpoint exception generation */
+ SDBBP, /* software debug breakpoint exception generation */
SYSCALL, /* system exception generation */
SYNC, /* system cache control */
DECODE, /* co-processor instruction */
#define DOUBLEWORD (3) /* 64bit */
#define SINGLE (4) /* single precision FP */
#define DOUBLE (5) /* double precision FP */
+/* start-sanitize-r5900 */
#define QUADWORD (6) /* 128bit */
+/* end-sanitize-r5900 */
/* Shorthand to get the size field from the flags value: */
#define GETDATASIZEINSN(i) (((i)->flags >> SIM_SH_SIZE) & SIM_MASK_SIZE)
#define ARCH_R5900 ((unsigned)1 << 30) /* Toshiba r5900 extension instructions */
/* end-sanitize-r5900 */
#define ARCH_R3900 ((unsigned)1 << 29) /* Toshiba r3900 (tx39) */
+/* start-sanitize-tx49 */
+#define ARCH_R4900 ((unsigned)1 << 28) /* Toshiba r4900 (tx49) */
+/* end-sanitize-tx49 */
+
/* start-sanitize-tx19 */
/* The r1900 (tx19) is a tx39 with a mips16 decoder. For the purposes
of implementing the simulator we treat them as the same. */
/* A list (or'ed) of extension insn sets that can be requested independant of the ISA# */
#define MASK_ISA_INDEP (0 \
| ARCH_R3900 \
+ /* start-sanitize-tx49 */ \
+ | ARCH_R4900 \
+ /* end-sanitize-tx49 */ \
/* start-sanitize-r5900 */ \
| ARCH_R5900 \
/* end-sanitize-r5900 */ \
#define G5 (0 \
| ARCH_R3900 \
+ /* start-sanitize-tx49 */ \
+ | ARCH_R4900 \
+ /* end-sanitize-tx49 */ \
/* start-sanitize-r5900 */ \
| ARCH_R5900 \
/* end-sanitize-r5900 */ \
#define G6 (3 | ARCH_R3900)
-#define T3 ARCH_R3900
+#define G7 (ARCH_R3900 \
+ /* start-sanitize-tx49 */ \
+ | ARCH_R4900 \
+ /* end-sanitize-tx49 */ \
+ )
+
+#define G8 (4 \
+ /* start-sanitize-tx49 */ \
+ | ARCH_R4900 \
+ /* end-sanitize-tx49 */ \
+ /* start-sanitize-r5900 */ \
+ | ARCH_R5900 \
+ /* end-sanitize-r5900 */ \
+ )
+
+#define G9 (3 \
+ /* start-sanitize-tx49 */ \
+ | ARCH_R4900 \
+ /* end-sanitize-tx49 */ \
+ )
+
/* start-sanitize-r5900 */
#define T5 ARCH_R5900
/* end-sanitize-r5900 */
{"BEQL", G4,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH, (EQ | LIKELY)},
{"BGEZ", 1,"000001sssss00001llllllllllllllll",REGIMM, BRANCH, (GT | EQ)},
{"BGEZAL", 1,"000001sssss10001llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)},
- {"BGEZALL",G4,"000001sssss10011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)},
+ {"BGEZALL",G4,"000001sssss10011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK | LIKELY)},
{"BGEZL", G4,"000001sssss00011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LIKELY)},
{"BGTZ", 1,"000111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT)},
{"BGTZL", G4,"010111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT | LIKELY)},
{"DIVU1", T5,"011100sssssggggg0000000000011011",MMINORM,DIV, (WORD | WORD32 | UNSIGNED | SIGNEXTEND | HI | LO | PIPE1)},
/* end-sanitize-r5900 */
{"DMADD16",G1,"000000sssssggggg0000000000101001",SPECIAL,MADD16, (DOUBLEWORD | HI | LO)},
- {"DMULT", 3,"000000sssssggggg0000000000011100",SPECIAL,MUL, (DOUBLEWORD | HI | LO)},
- {"DMULTU", 3,"000000sssssggggg0000000000011101",SPECIAL,MUL, (DOUBLEWORD | UNSIGNED | HI | LO)},
+ /* See note near MULT for explanation of 3op-ness. */
+ {"DMULT", G9,"000000sssssgggggddddd00000011100",SPECIAL,MUL, (OP3 | DOUBLEWORD | HI | LO)},
+ {"DMULTU", G9,"000000sssssgggggddddd00000011101",SPECIAL,MUL, (OP3 | DOUBLEWORD | UNSIGNED | HI | LO)},
{"DMxC1", 3,"01000100x01kkkkkvvvvv00000000000",COP1S, FPMOVEC, (FP | DOUBLEWORD)},
{"DSLL", 3,"00000000000gggggdddddaaaaa111000",SPECIAL,SHIFT, (DOUBLEWORD | LEFT | LOGICAL)},
{"DSLLV", 3,"000000sssssgggggddddd00000010100",SPECIAL,SHIFT, (DOUBLEWORD | LEFT | LOGICAL | REG)},
{"MSUB.D", G3,"010011bbbbbkkkkkvvvvvrrrrr101001",COP1X, FPSUB, (FP | MULTIPLY | DOUBLE)},
{"MSUB.S", G3,"010011bbbbbkkkkkvvvvvrrrrr101000",COP1X, FPSUB, (FP | MULTIPLY | SINGLE)},
{"MUL", 1,"01000110mmmkkkkkvvvvvrrrrr000010",COP1, FPMUL, (FP | HI | LO)},
+ /* The 3op version of MULT and MULTU are TX39 (and related chips) specific.
+ They should be removed from other chips sets, so that using the 3op opcode
+ causes a reserved instruction exception, but gencode can't deal with
+ that currently. */
{"MULT", 1,"000000sssssgggggddddd00000011000",SPECIAL,MUL, (OP3 | WORD | WORD32 | HI | LO)},
/* start-sanitize-r5900 */
{"MULT1", T5,"011100sssssgggggddddd00000011000",MMINORM,MUL, (OP3 | WORD | WORD32 | HI | LO | PIPE1)},
{"PXOR", T5,"011100SSSSSTTTTTddddd10011001001",MMI2, POP, (POP_XOR)},
/* end-sanitize-r5900 */
- {"PREF", G2,"110011sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, PREFETCH, (NONE)},
+ {"PREF", G8,"110011sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, PREFETCH, (NONE)},
{"PREFX", 4,"010011sssssgggggvvvvv00000001111",COP1X, FPPREFX, (FP)},
/* start-sanitize-r5900 */
{"SCD", 3,"111100sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD | ATOMIC)},
{"SD", 3,"111111sssssgggggeeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD)},
{"SDC1", 2,"111101sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD | COPROC)},
+ {"SDBBP", G7,"000000????????????????????001110",SPECIAL,SDBBP, (NOARG)},
{"SDC2", 2,"111110sssssttttteeeeeeeeeeeeeeee",NORMAL, STORE, (DOUBLEWORD | COPROC)},
{"SDL", 3,"101100sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (DOUBLEWORD | LEFT)},
{"SDR", 3,"101101sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (DOUBLEWORD | RIGHT)},
{"NOT", 1, "11101dddyyy01111Z", RR, OR, NOT },
{"OR", 1, "11101wwwyyy01101", RR, OR, NONE },
{"SB", 1, "11000xxxyyy55555", RRI, STORE, BYTE },
+{"SDBBP", G7, "11100??????00001", RR, SDBBP, NOARG },
{"SD", 3, "01111xxxyyyDDDDD", RRI, STORE, DOUBLEWORD },
{"SDSP", 3, "11111001yyyDDDDDs", RI64, STORE, DOUBLEWORD },
{"SDRASP", 3, "11111010CCCCCCCCsQ", I64, STORE, DOUBLEWORD },
{"XOR", 1, "11101wwwyyy01110", RR, XOR, NONE }
};
+/*---------------------------------------------------------------------------*/
+
+static void print_igen_insn_format PARAMS ((const char *bitmap,
+ inst_type mark,
+ int data_size,
+ const char *options,
+ const char *name));
+
+static void
+print_igen_insn_format (bitmap, mark, data_size, options, name)
+ const char *bitmap;
+ inst_type mark;
+ int data_size;
+ const char *options;
+ const char *name;
+{
+ const char *chp;
+ char lch = *bitmap;
+ for (chp = bitmap; *chp != '\0'; chp++)
+ {
+ if ((isdigit (lch) && !isdigit (*chp))
+ || (!isdigit (lch) && isdigit (*chp))
+ || (!isdigit (lch) && !isdigit (*chp) && lch != *chp))
+ {
+ lch = *chp;
+ printf (",");
+ }
+ switch (*chp)
+ {
+ case '?':
+ printf ("*");
+ break;
+ case '<':
+ printf ("s"); /* good guess */
+ break;
+ default:
+ printf ("%c", *chp);
+ break;
+ }
+ }
+ printf (":");
+ switch (mark)
+ {
+ case NORMAL:
+ printf ("NORMAL");
+ break;
+ case SPECIAL:
+ printf ("SPECIAL");
+ break;
+ case REGIMM:
+ printf ("REGIMM");
+ break;
+ case COP1:
+ printf ("COP1");
+ break;
+ case COP1X:
+ printf ("COP1X");
+ break;
+ case COP1S: /* These instructions live in the reserved FP format values: 0..15,18-19,22-31 */
+ printf ("COP1S");
+ break;
+
+ case MMINORM:
+ printf ("MMINORM");
+ break;
+ case MMI0:
+ printf ("MMI0");
+ break;
+ case MMI1:
+ printf ("MMI1");
+ break;
+ case MMI2:
+ printf ("MMI2");
+ break;
+ case MMI3:
+ printf ("MMI3");
+ break;
+
+ /* mips16 encoding types. */
+ case I:
+ printf ("I");
+ break;
+ case RI:
+ printf ("RI");
+ break;
+ case RR:
+ printf ("RR");
+ break;
+ case RRI:
+ printf ("RRI");
+ break;
+ case RRR:
+ printf ("RRR");
+ break;
+ case RRI_A:
+ printf ("RRI_A");
+ break;
+ case ISHIFT:
+ printf ("ISHIFT");
+ break;
+ case I8:
+ printf ("I8");
+ break;
+ case I8_MOVR32:
+ printf ("I8_MOVR32");
+ break;
+ case I8_MOV32R:
+ printf ("I8_MOV32R");
+ break;
+ case I64:
+ printf ("I64");
+ break;
+ case RI64:
+ printf ("RI64");
+ break;
+ }
+ printf (":");
+ switch (data_size)
+ {
+ case DOUBLEWORD:
+ printf ("64");
+ break;
+ /* start-sanitize-r5900 */
+ case QUADWORD:
+ printf ("128");
+ break;
+ /* end-sanitize-r5900 */
+ case -1:
+ printf ("16");
+ break;
+ default:
+ printf ("32");
+ }
+ printf (":%s:%s\n", options, name);
+}
+
+static void print_igen_insn_models PARAMS ((unsigned int isa));
+
+static void
+print_igen_insn_models (isa)
+ unsigned int isa;
+{
+ /* common mips ISAs */
+ switch ((isa & MASK_ISA))
+ {
+ case 1:
+ printf ("*mipsI:\n");
+ case 2:
+ printf ("*mipsII:\n");
+ case 3:
+ printf ("*mipsIII:\n");
+ /* start-sanitize-cygnus-never */
+ printf ("// %s-%s-%s\n", "start", "sanitize", "r5900");
+ /* end-sanitize-cygnus-never */
+ /* start-sanitize-r5900 */
+ printf ("*r5900:\n");
+ /* end-sanitize-r5900 */
+ /* start-sanitize-cygnus-never */
+ printf ("// %s-%s-%s\n", "end", "sanitize", "r5900");
+ /* end-sanitize-cygnus-never */
+ printf ("*r3900:\n");
+ /* start-sanitize-cygnus-never */
+ printf ("// %s-%s-%s\n", "start", "sanitize", "tx19");
+ /* end-sanitize-cygnus-never */
+ /* start-sanitize-tx19 */
+ printf ("*tx19:\n");
+ /* end-sanitize-tx19 */
+ /* start-sanitize-cygnus-never */
+ printf ("// %s-%s-%s\n", "end", "sanitize", "tx19");
+ /* end-sanitize-cygnus-never */
+ break;
+ default:
+ /* processor specific ISAs */
+ if ((isa & ARCH_VR4100))
+ printf ("*vr4100:\n");
+ /* start-sanitize-r5900 */
+ if ((isa & ARCH_R5900))
+ printf ("*r5900:\n");
+ /* end-sanitize-r5900 */
+ if ((isa & ARCH_R3900))
+ printf ("*r3900:\n");
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+
static int bitmap_val PARAMS ((const char *, int, int));
static void build_mips16_operands PARAMS ((const char *));
static void build_instruction
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return "DOUBLEWORD";
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return "QUADWORD";
+ /* end-sanitize-r5900 */
else
return 0;
}
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return "D";
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return "Q";
+ /* end-sanitize-r5900 */
else
return 0;
}
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
+ /* end-sanitize-r5900 */
else
return 0;
}
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
+ /* end-sanitize-r5900 */
else
return 0;
}
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
+ /* end-sanitize-r5900 */
else
return 0;
}
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return 0;
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return 0;
+ /* end-sanitize-r5900 */
else
return 0;
}
else if (GETDATASIZEINSN(insn) == DOUBLEWORD)
return "64";
+ /* start-sanitize-r5900 */
else if (GETDATASIZEINSN(insn) == QUADWORD)
return "128";
+ /* end-sanitize-r5900 */
else
return 0;
}
ensure that the following opcode processing is not
executed. i.e. the code falls straight out to the simulator
control loop. */
- printf(" sim_warning(\"Instruction has lo-order offset bits set in instruction\");\n");
+ printf(" sim_io_eprintf(sd,\"Instruction has lo-order offset bits set in instruction\\n\");\n");
printf(" }\n");
}
#endif
{
int j;
- printf ("((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (uword64) 1)");
+ printf ("((INDELAYSLOT () ? (INJALDELAYSLOT () ? cia - 4 : cia - 2) : (have_extendval ? cia - 2 : cia)) & ~ (uword64) 1)");
for (j = 0; j < opindex; j++)
if (ops[j]->shift != 0)
printf (" & ~ (uword64) 0x%x", (1 << ops[j]->shift) - 1);
if ((op->flags & MIPS16_JUMP_ADDR) != 0)
{
printf (" {\n");
- printf (" uword64 paddr;\n");
+ printf (" address_word paddr;\n");
printf (" int uncached;\n");
printf (" if (AddressTranslation (PC &~ (uword64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL))\n");
printf (" {\n");
if (doisa == 0)
doisa = maxisa;
- printf("#if defined(SIM_MANIFESTS)\n");
- printf("#define MIPSISA (%d)\n",doisa);
- if (proc64)
- printf("#define PROCESSOR_64BIT (1 == 1)\n");
- else
- printf("#define PROCESSOR_64BIT (1 == 0)\n");
+ if (!(features & FEATURE_IGEN))
+ {
+ printf("#if defined(SIM_MANIFESTS)\n");
+ printf("#define MIPSISA (%d)\n",doisa);
+ if (proc64)
+ printf("#define PROCESSOR_64BIT (1 == 1)\n");
+ else
+ printf("#define PROCESSOR_64BIT (1 == 0)\n");
#if 1 /* cheat: We only have a 64bit LoadMemory and StoreMemory routines at the moment */
- printf("#define LOADDRMASK (0x%08X)\n",0x7);
+ printf("#define LOADDRMASK (0x%08X)\n",0x7);
#else
- printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
+ printf("#define LOADDRMASK (0x%08X)\n",(proc64 ? 0x7 : 0x3));
#endif
- /* The FP registers are the same width as the CPU registers: */
- printf("#define GPRLEN (%d)\n",gprlen);
- printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
- printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
- printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
- if (dofp)
- printf("#define HASFPU (1 == 1)\n");
- if (features & FEATURE_FAST)
- printf("#define FASTSIM (1 == 1)\n");
- if (features & FEATURE_WARN_STALL)
- printf("#define WARN_STALL (1 == 1)\n");
- if (features & FEATURE_WARN_LOHI)
- printf("#define WARN_LOHI (1 == 1)\n");
- if (features & FEATURE_WARN_ZERO)
- printf("#define WARN_ZERO (1 == 1)\n");
- if (features & FEATURE_WARN_MEM)
- printf("#define WARN_MEM (1 == 1)\n");
- if (features & FEATURE_WARN_R31)
- printf("#define WARN_R31 (1 == 1)\n");
- if (features & FEATURE_WARN_RESULT)
- printf("#define WARN_RESULT (1 == 1)\n");
-
- printf("#else /* simulator engine */\n");
-
- printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
- printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
- if (dofp)
- printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
- printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
-
- if (proc64) {
- printf("#if !defined(PROCESSOR_64BIT)\n");
- printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
- printf("#endif\n");
- }
-
- printf("/* Actual instruction decoding block */\n");
- printf("if ((vaddr & 1) == 0){\n");
- {
- int limit;
- printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
- limit = (OP_MASK_OP + 1);
-
- printf("#ifdef DEBUG\n");
- printf("printf(\"DBG: instruction = 0x%%08X\\n\",instruction);\n");
- printf("#endif\n");
-
- printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
- limit += (OP_MASK_SPEC + 1);
-
- printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
- limit += (OP_MASK_RT + 1);
-
- printf("else if (num == 0x11) {\n");
- printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
- printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
- printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
- printf(" else\n");
- printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
- limit += (OP_MASK_SPEC + 1);
-
- printf(" else\n");
- /* To keep this code quick, we just clear out the "to" bit
- here. The proper (though slower) code would be to have another
- conditional, checking whether this instruction is a branch or
- not, before limiting the range to the bottom two bits of the
- move operation. */
- printf(" num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
- limit += (OP_MASK_COP1SPEC + 1);
-
- printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
- limit += (OP_MASK_SPEC + 1);
-
- printf("else if (num == 0x1C) {\n");
- printf(" int mmi_func = ((instruction >> %d) & 0x%08X);\n",OP_SH_MMI,OP_MASK_MMI);
-
- printf(" if (mmi_func == 0x08) \n");
- printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
- limit += (OP_MASK_MMISUB + 1);
-
- printf(" else if (mmi_func == 0x28) \n");
- printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
- limit += (OP_MASK_MMISUB + 1);
-
- printf(" else if (mmi_func == 0x09) \n");
- printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
- limit += (OP_MASK_MMISUB + 1);
-
- printf(" else if (mmi_func == 0x29) \n");
- printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
- limit += (OP_MASK_MMISUB + 1);
-
- printf(" else \n");
- printf(" num = (%d + mmi_func);\n",limit);
- limit += (OP_MASK_MMI + 1);
-
- printf("}\n");
-
- printf("/* Total possible switch entries: %d */\n",limit) ;
- }
-
- printf("#ifdef DEBUG\n");
- printf("printf(\"DBG: num = %%d\\n\",num);\n");
- printf("#endif\n");
-
- printf("switch (num)\n") ;
- printf("{\n");
-
+ /* The FP registers are the same width as the CPU registers: */
+ printf("#define GPRLEN (%d)\n",gprlen);
+ printf("typedef %s t_reg;\n",((gprlen == 64) ? "word64" : "int"));
+ printf("typedef %s ut_reg;\n",((gprlen == 64) ? "uword64" : "unsigned int"));
+ printf("typedef %s t_fpreg;\n",((gprlen == 64) ? "word64" : "int"));
+ if (dofp)
+ printf("#define HASFPU (1 == 1)\n");
+ if (features & FEATURE_FAST)
+ printf("#define FASTSIM (1 == 1)\n");
+ if (features & FEATURE_WARN_STALL)
+ printf("#define WARN_STALL (1 == 1)\n");
+ if (features & FEATURE_WARN_LOHI)
+ printf("#define WARN_LOHI (1 == 1)\n");
+ if (features & FEATURE_WARN_ZERO)
+ printf("#define WARN_ZERO (1 == 1)\n");
+ if (features & FEATURE_WARN_MEM)
+ printf("#define WARN_MEM (1 == 1)\n");
+ if (features & FEATURE_WARN_R31)
+ printf("#define WARN_R31 (1 == 1)\n");
+ if (features & FEATURE_WARN_RESULT)
+ printf("#define WARN_RESULT (1 == 1)\n");
+
+ printf("#else /* simulator engine */\n");
+
+ printf("/* Engine generated by \"%s\" at %s */\n","<SHOW PROGRAM ARGS>","<SHOW CURRENT DATE AND TIME>");
+ printf("/* Main instruction decode for %d-bit MIPS ISA %d (Table entry limit = %d) */\n",(proc64 ? 64 : 32),doisa,limit);
+ if (dofp)
+ printf("/* %sFP instructions included */\n",(fpsingle ? "Single precision " : ""));
+ printf("/* NOTE: \"DSPC\" is the delay slot PC address */\n");
+
+ if (proc64) {
+ printf("#if !defined(PROCESSOR_64BIT)\n");
+ printf("#error \"Automatically constructed decoder has been built for a 64bit processor\"\n");
+ printf("#endif\n");
+ }
+
+ printf("/* Actual instruction decoding block */\n");
+ printf("if ((vaddr & 1) == 0){\n");
+ {
+ int limit;
+ printf("int num = ((instruction >> %d) & 0x%08X);\n",OP_SH_OP,OP_MASK_OP);
+ limit = (OP_MASK_OP + 1);
+
+ printf("#ifdef DEBUG\n");
+ printf("printf(\"DBG: instruction = 0x%%08X\\n\",instruction);\n");
+ printf("#endif\n");
+
+ printf("if (num == 0x00) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
+ limit += (OP_MASK_SPEC + 1);
+
+ printf("else if (num == 0x01) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_RT,OP_MASK_RT);
+ limit += (OP_MASK_RT + 1);
+
+ printf("else if (num == 0x11) {\n");
+ printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1NORM,OP_SH_COP1NORM,(OP_MASK_COP1NORM << OP_SH_COP1NORM));
+ printf(" if ((instruction & (0x%08X << %d)) == 0x%08X)\n",OP_MASK_COP1CMP,OP_SH_COP1CMP,(OP_MASK_COP1CMP << OP_SH_COP1CMP));
+ printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,(OP_MASK_SPEC & (OP_MASK_COP1CMP << OP_SH_COP1CMP)));
+ printf(" else\n");
+ printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
+ limit += (OP_MASK_SPEC + 1);
+
+ printf(" else\n");
+ /* To keep this code quick, we just clear out the "to" bit
+ here. The proper (though slower) code would be to have another
+ conditional, checking whether this instruction is a branch or
+ not, before limiting the range to the bottom two bits of the
+ move operation. */
+ printf(" num = (%d + (((instruction >> %d) & 0x%08X) & ~0x%08X));\n",limit,OP_SH_COP1SPEC,OP_MASK_COP1SPEC,OP_MASK_COP1SCLR);
+ limit += (OP_MASK_COP1SPEC + 1);
+
+ printf("} else if (num == 0x13) num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_SPEC,OP_MASK_SPEC);
+ limit += (OP_MASK_SPEC + 1);
+
+ printf("else if (num == 0x1C) {\n");
+ printf(" int mmi_func = ((instruction >> %d) & 0x%08X);\n",OP_SH_MMI,OP_MASK_MMI);
+
+ printf(" if (mmi_func == 0x08) \n");
+ printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+ limit += (OP_MASK_MMISUB + 1);
+
+ printf(" else if (mmi_func == 0x28) \n");
+ printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+ limit += (OP_MASK_MMISUB + 1);
+
+ printf(" else if (mmi_func == 0x09) \n");
+ printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+ limit += (OP_MASK_MMISUB + 1);
+
+ printf(" else if (mmi_func == 0x29) \n");
+ printf(" num = (%d + ((instruction >> %d) & 0x%08X));\n",limit,OP_SH_MMISUB,OP_MASK_MMISUB);
+ limit += (OP_MASK_MMISUB + 1);
+
+ printf(" else \n");
+ printf(" num = (%d + mmi_func);\n",limit);
+ limit += (OP_MASK_MMI + 1);
+
+ printf("}\n");
+
+ printf("/* Total possible switch entries: %d */\n",limit) ;
+ }
+
+ printf("#ifdef DEBUG\n");
+ printf("printf(\"DBG: num = %%d\\n\",num);\n");
+ printf("#endif\n");
+
+ printf("switch (num)\n") ;
+ printf("{\n");
+ }
+
for (loop = 0; (loop < limit); loop++) {
/* First check if the insn is in a requested isa# independent set,
then check that the ISA number we are constructing for is
if (((isa & doarch & MASK_ISA_INDEP)
|| (((isa & MASK_ISA) <= doisa)
&& (((isa & MASK_ISA_DEP) == 0) || ((isa & MASK_ISA_DEP) & doarch) != 0)))
- && (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))) {
+ && (!(MIPS_DECODE[loop].flags & FP) || ((MIPS_DECODE[loop].flags & FP) && dofp))
+ || (features & FEATURE_IGEN)) {
unsigned int onemask;
unsigned int zeromask;
unsigned int dontmask;
convert_bitmap(MIPS_DECODE[loop].bitmap,&onemask,&zeromask,&dontmask);
if (!(MIPS_DECODE[loop].flags & COPROC)
- && ((GETDATASIZEINSN(&MIPS_DECODE[loop]) == DOUBLEWORD) && !proc64)) {
+ && ((GETDATASIZEINSN(&MIPS_DECODE[loop]) == DOUBLEWORD) && !proc64)
+ && !(features & FEATURE_IGEN)) {
fprintf(stderr,"DOUBLEWORD width specified for non 64-bit processor for instruction \"%s\"\n",MIPS_DECODE[loop].name);
exit(4);
}
fprintf(stderr,"Unrecognised opcode mark %d in table slot %d \"%s\"\n",MIPS_DECODE[loop].mark,loop,MIPS_DECODE[loop].name) ;
exit(5) ;
}
-
- printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
-
+
+ if (!(features & FEATURE_IGEN))
+ {
+ printf("case %d : /* \"%s\" %s */\n",number,MIPS_DECODE[loop].name,MIPS_DECODE[loop].bitmap) ;
+
#if defined(DEBUG)
- printf("/* DEBUG: mask 0x%08X */\n",mask) ;
- printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
+ printf("/* DEBUG: mask 0x%08X */\n",mask) ;
+ printf(" printf(\"\\\"%s\\\"\\n\");\n",MIPS_DECODE[loop].name);
#endif
-
- /* Check if there are any other explicit bits in the instruction: */
- if ((~mask & (onemask | zeromask)) != 0x00000000) {
- printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
- printf(" {\n") ;
- printf(" SignalException(ReservedInstruction,instruction);\n") ;
- printf(" }\n") ;
- printf(" else\n") ;
- }
-
- printf(" {\n") ;
-
+
+ /* Check if there are any other explicit bits in the instruction: */
+ if ((~mask & (onemask | zeromask)) != 0x00000000) {
+ printf(" if ((instruction & 0x%08X) != 0x%08X)\n",(onemask | zeromask),onemask) ;
+ printf(" {\n") ;
+ printf(" SignalException(ReservedInstruction,instruction);\n") ;
+ printf(" }\n") ;
+ printf(" else\n") ;
+ }
+
+ printf(" {\n") ;
+ }
+ else
+ {
+ /* start-sanitize-cygnus-never */
+ /* If any sanitization occures, this line should be printed */
+ if ((MIPS_DECODE[loop].isa & ARCH_R5900))
+ printf ("// %s-%s-%s\n", "start", "sanitize", "r5900");
+ /* end-sanitize-cygnus-never */
+ printf ("\n");
+ print_igen_insn_format (MIPS_DECODE[loop].bitmap,
+ MIPS_DECODE[loop].mark, /* format-name */
+ GETDATASIZEINSN (&MIPS_DECODE[loop]), /* filter-flags */
+ "", /* options */
+ MIPS_DECODE[loop].name);
+ print_igen_insn_models (MIPS_DECODE[loop].isa);
+ printf ("{\n") ;
+ printf (" unsigned32 instruction = instruction_0;\n");
+ }
+
/* Get hold of the operands */
/* NOTE: If we wanted to make the simulator code smaller, we
* could pull these into a common sequence before we perform
* compilation of the produced code.
*/
build_operands(doisa, features, &MIPS_DECODE[loop]);
-
+
printf(" {\n") ;
-
+
build_instruction (doisa, features, 0, &MIPS_DECODE[loop]);
-
+
printf(" }\n") ;
- printf(" }\n") ;
- printf(" break ;\n") ;
+ if (!(features & FEATURE_IGEN))
+ {
+ printf(" }\n") ;
+ printf(" break ;\n") ;
+ }
+ else
+ {
+ printf ("}\n");
+ printf ("\n");
+ /* start-sanitize-cygnus-never */
+ /* When sanitized, this output should never be produced */
+ if ((MIPS_DECODE[loop].isa & ARCH_R5900))
+ printf ("// %s-%s-%s\n", "end", "sanitize", "r5900");
+ /* end-sanitize-cygnus-never */
+ }
+
}
- }
-
- printf("default : /* Unrecognised instruction */\n") ;
- printf(" SignalException(ReservedInstruction,instruction);\n") ;
- printf(" break ;\n") ;
- printf("}\n}\n") ;
+ }
+
+ if (!(features & FEATURE_IGEN))
+ {
+ printf("default : /* Unrecognised instruction */\n") ;
+ printf(" SignalException(ReservedInstruction,instruction);\n") ;
+ printf(" break ;\n") ;
+ printf("}\n}\n") ;
+ }
+
/* Handle mips16 instructions. The switch table looks like this:
- 0 - 31: I, RI, and RRI instructions by major.
+ 0 - 31: I, RI, and RRI instructions by major.
32 - 35: ISHIFT instructions by function + 32
36 - 37: RRI_A instructions by function + 36
38 - 45: I8, I8_MOV32R, and I8_MOVR32 instructions by function + 38
82 - 89: I64 and RI64 instructions by funct + 82
90 - 97: jalr (RR minor 0) by y + 90
*/
- printf ("else {\n");
- printf ("static int extendval;\n");
- printf ("static int have_extendval;\n");
- printf ("int num = ((instruction >> %d) & 0x%08X);\n",
- MIPS16OP_SH_OP, MIPS16OP_MASK_OP);
- printf ("switch (num)\n{\n");
- printf ("case 0x6: num = 32 + (instruction & 3); break;\n");
- printf ("case 0x8: num = 36 + ((instruction & 0x10) >> 4); break;\n");
- printf ("case 0xc: num = 38 + ((instruction & 0x700) >> 8); break;\n");
- printf ("case 0x1c: num = 46 + (instruction & 3); break;\n");
- printf ("case 0x1d: num = 50 + (instruction & 0x1f);\n");
- printf (" if (num == 50) num = 90 + ((instruction & 0xe0) >> 5);\n");
- printf (" break;\n");
- printf ("case 0x1f: num = 82 + ((instruction & 0x700) >> 8); break;\n");
- printf ("default: break;\n}\n");
- printf ("switch (num)\n{\n");
-
+ if (!(features & FEATURE_IGEN))
+ {
+ printf ("else {\n");
+ printf ("static int extendval;\n");
+ printf ("static int have_extendval;\n");
+ printf ("int num = ((instruction >> %d) & 0x%08X);\n",
+ MIPS16OP_SH_OP, MIPS16OP_MASK_OP);
+ printf ("switch (num)\n{\n");
+ printf ("case 0x6: num = 32 + (instruction & 3); break;\n");
+ printf ("case 0x8: num = 36 + ((instruction & 0x10) >> 4); break;\n");
+ printf ("case 0xc: num = 38 + ((instruction & 0x700) >> 8); break;\n");
+ printf ("case 0x1c: num = 46 + (instruction & 3); break;\n");
+ printf ("case 0x1d: num = 50 + (instruction & 0x1f);\n");
+ printf (" if (num == 50) num = 90 + ((instruction & 0xe0) >> 5);\n");
+ printf (" break;\n");
+ printf ("case 0x1f: num = 82 + ((instruction & 0x700) >> 8); break;\n");
+ printf ("default: break;\n}\n");
+ printf ("switch (num)\n{\n");
+ }
+
for (loop = 0; loop < sizeof MIPS16_DECODE / sizeof MIPS16_DECODE[0]; loop++)
{
const char *bitmap;
int num;
-
+
if (! proc64 && GETDATASIZEINSN (&MIPS16_DECODE[loop]) == DOUBLEWORD)
continue;
-
+
bitmap = MIPS16_DECODE[loop].bitmap;
switch (MIPS16_DECODE[loop].mark)
{
case RR:
{
int minor;
-
+
minor = bitmap_val (bitmap, 0, 5);
if (minor != 0)
num = 50 + minor;
abort ();
}
- printf ("case %d: /* \"%s\" %s */\n", num, MIPS16_DECODE[loop].name,
- bitmap);
- printf (" {\n");
+ if (!(features & FEATURE_IGEN))
+ {
+ printf ("case %d: /* \"%s\" %s */\n", num, MIPS16_DECODE[loop].name,
+ bitmap);
+ printf (" {\n");
+ }
+ else
+ {
+ printf ("\n");
+ print_igen_insn_format (bitmap,
+ MIPS16_DECODE[loop].mark, /* format-name */
+ -1, /* filter-flags -- -1 => MIPS16 */
+ "", /* options */
+ MIPS16_DECODE[loop].name);
+ printf ("*mips16:\n");
+ printf ("{\n");
+ printf (" unsigned32 instruction = instruction_0;\n");
+ }
build_mips16_operands (bitmap);
}
printf (" }\n");
- printf (" }\n") ;
- printf (" break ;\n") ;
+ if (!(features & FEATURE_IGEN))
+ {
+ printf (" }\n") ;
+ printf (" break ;\n") ;
+ }
+ else
+ {
+ printf ("}\n");
+ printf ("\n");
+ }
}
- printf ("default : /* Unrecognised instruction */\n") ;
- printf (" SignalException(ReservedInstruction,instruction);\n") ;
- printf (" break ;\n") ;
- printf ("}\n}\n") ;
-
- printf("#endif /* simulator engine */\n");
-
+ if (!(features & FEATURE_IGEN))
+ {
+ printf ("default : /* Unrecognised instruction */\n") ;
+ printf (" SignalException(ReservedInstruction,instruction);\n") ;
+ printf (" break ;\n") ;
+ printf ("}\n}\n") ;
+
+ printf("#endif /* simulator engine */\n");
+ }
+
return ;
}
printf(" %s tempS UNUSED = (%s)temp;\n", signed_basetype, signed_basetype);
if (insn->flags & OVERFLOW) {
printf(" if (((op1 < 0) == (op2 < 0)) && ((tempS < 0) != (op1 < 0)))\n");
- printf(" SignalException(IntegerOverflow);\n");
+ printf(" SignalExceptionIntegerOverflow ();\n");
printf(" else\n");
}
if (!proc64 || (insn->flags & UNSIGNED) || (GETDATASIZEINSN(insn) == DOUBLEWORD))
printf(" %s tempS UNUSED = (%s)temp;\n", signed_basetype, signed_basetype);
if (insn->flags & OVERFLOW) { /* different signs => overflow if result_sign != arg_sign */
printf(" if (((op1 < 0) != (op2 < 0)) && ((tempS < 0) == (op1 < 0)))\n");
- printf(" SignalException(IntegerOverflow);\n");
+ printf(" SignalExceptionIntegerOverflow ();\n");
printf(" else\n");
}
/* UNSIGNED 32bit operations on a 64bit processor should
{
char* pipe = (insn->flags & PIPE1) ? "1" : "";
- if (features & FEATURE_WARN_LOHI) {
- printf(" CHECKHILO(\"Multiplication\");\n");
- }
printf(" {\n");
if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
printf(" uword64 mid;\n");
int boolU = (insn->flags & UNSIGNED);
char* pipe = (insn->flags & PIPE1) ? "1" : "";
- if (features & FEATURE_WARN_LOHI) {
- printf(" CHECKHILO(\"Division\");\n");
- }
printf(" {\n");
if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
if (insn->flags & LEFT)
printf(" GPR[destreg] = %s%s;\n",regname,(pipe1 ? "1" : ""));
else {
- if (features & FEATURE_WARN_LOHI) {
- printf(" if (%s%sACCESS != 0)\n",regname,(pipe1 ? "1" : ""));
- printf(" sim_warning(\"MT (move-to) over-writing %s register value\");\n",regname);
- }
printf(" %s%s = op1;\n",regname,(pipe1 ? "1" : ""));
}
- if (features & FEATURE_WARN_LOHI)
- printf(" %s%sACCESS = 3; /* 3rd instruction will be safe */\n",regname,(pipe1 ? "1" : ""));
} else
if (insn->flags & SHIFT16)
printf(" GPR[destreg] = (op2 << 16);\n");
printf(" SignalException(BreakPoint,instruction);\n");
break ;
+ case SDBBP:
+ printf(" SignalException(DebugBreakPoint,instruction);\n");
+ break ;
+
case TRAP:
{
int boolNOT = (insn->flags & NOT);
break ;
case DECODE:
- printf(" decode_coproc(instruction);\n");
+ printf(" DecodeCoproc(instruction);\n");
break ;
case CACHE:
/* 16-bit offset is sign-extended and added to the base register to make a virtual address */
/* The virtual address is translated to a physical address using the TLB */
/* The hint specifies a cache operation for that address */
- printf(" uword64 vaddr = (op1 + offset);\n");
- printf(" uword64 paddr;\n");
+ printf(" address_word vaddr = (op1 + offset);\n");
+ printf(" address_word paddr;\n");
printf(" int uncached;\n");
/* NOTE: We are assuming that the AddressTranslation is a load: */
printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
/* Some of this code is shared with the standard multiply
routines, so an effort should be made to merge where
possible. */
- if (features & FEATURE_WARN_LOHI) {
- printf(" CHECKHILO(\"Multiply-Add\");\n");
- }
if (features & FEATURE_WARN_RESULT) {
/* Give user a warning if either op1 or op2 are not 16bit signed integers */
printf(" if (NOTHALFWORDVALUE(op1) || NOTHALFWORDVALUE(op2))\n");
- printf(" sim_warning(\"MADD16 operation with non-16bit operands\");\n");
+ printf(" sim_io_eprintf(sd,\"MADD16 operation with non-16bit operands\\n\");\n");
}
printf(" {\n");
printf(" uword64 temp = (op1 * op2);\n"); /* 16x16 multiply */
case RSVD: /* "Reserved Instruction" on MIPS IV, or if co-proc 3 absent. Otherwise "CoProcessorUnusable" */
if (doisa < 4) {
printf(" if (CoProcPresent(3))\n");
- printf(" SignalException(CoProcessorUnusable);\n");
+ printf(" SignalExceptionCoProcessorUnusable ();\n");
printf(" else\n");
}
printf(" SignalException(ReservedInstruction,instruction);\n");
if (insn->flags & LINK) {
if (features & FEATURE_WARN_R31) {
printf(" if (((instruction >> %d) & 0x%08X) == 31)\n",OP_SH_RS,OP_MASK_RS);
- printf(" sim_warning(\"Branch with link using r31 as source operand\");\n");
+ printf(" sim_io_eprintf(sd,\"Branch with link using r31 as source operand\\n\");\n");
}
printf(" GPR[31] = (PC + 4); /* NOTE: PC is already 8 ahead */\n");
}
datalen = 8;
accesslength = "AccessLength_DOUBLEWORD";
break ;
+ /* start-sanitize-r5900 */
case QUADWORD :
datalen = 16;
accesslength = "AccessLength_QUADWORD";
break ;
+ /* end-sanitize-r5900 */
}
if (insn->flags & REG)
- printf(" uword64 vaddr = ((uword64)op1 + op2);\n");
+ printf(" address_word vaddr = ((uword64)op1 + op2);\n");
else
- printf(" uword64 vaddr = ((uword64)op1 + offset);\n");
- printf(" uword64 paddr;\n");
+ printf(" address_word vaddr = ((uword64)op1 + offset);\n");
+ printf(" address_word paddr;\n");
printf(" int uncached;\n");
/* The following check should only occur on normal (non-shifted) memory loads */
if ((datalen != 1) && !(insn->flags & (LEFT | RIGHT))) {
printf(" if ((vaddr & %d) != 0)\n",(datalen - 1));
- printf(" SignalException(%s);\n",(isload ? "AddressLoad" : "AddressStore"));
+ printf(" SignalException%s();\n",(isload ? "AddressLoad" : "AddressStore"));
printf(" else\n") ;
}
switch (datalen) {
case 8:
- if (!proc64) {
- fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",insn->name);
- exit(4);
- }
- /* fall through to... */
+ if (!(features & FEATURE_IGEN))
+ {
+ if (!proc64) {
+ fprintf(stderr,"DOUBLEWORD shifted memory transfers only valid for 64-bit processors \"%s\"\n",insn->name);
+ exit(4);
+ }
+ }
+ /* fall through to... */
case 4:
{
printf(" uword64 mask = %d;\n",((datalen == 8) ? 0x7 : 0x3));
printf(" int byte;\n");
printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse));\n");
printf(" byte = ((vaddr & mask) ^ bigend);\n");
- printf(" if (%s!ByteSwapMem)\n",((insn->flags & LEFT) ? "!" : ""));
+ printf(" if (%sBigEndianMem)\n",((insn->flags & LEFT) ? "!" : ""));
printf(" paddr &= ~mask;\n");
if (isload) {
exit(6);
}
} else { /* normal memory transfer */
- if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
- fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
- exit(4);
- /* TODO: The R4000 documentation states that a LWU
- instruction executed when in a 32bit processor mode
- should cause a ReservedInstruction exception. This
- will mean adding a run-time check into the code
- sequence. */
- }
-
+ if (!(features & FEATURE_IGEN))
+ {
+ if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
+ fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
+ exit(4);
+ /* TODO: The R4000 documentation states that a LWU
+ instruction executed when in a 32bit processor mode
+ should cause a ReservedInstruction exception. This
+ will mean adding a run-time check into the code
+ sequence. */
+ }
+ }
+
if (isload) {
#if 1 /* see the comments attached to LOADDRMASK above */
printf(" uword64 mask = 0x7;\n");
printf(" unsigned int byte UNUSED;\n");
/* TODO: This should really also check for 32bit world performing 32bit access */
- if (datalen < 8) /* not for DOUBLEWORD or QUADWORD*/
- printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
+ if (datalen < 8)
+ /* not for DOUBLEWORD */
+ /* start-sanitize-r5900 */
+ /* not for QUADWORD */
+ /* end-sanitize-r5900 */
+ printf(" paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift)));\n");
printf(" LoadMemory(&memval,&memval1,uncached,%s,paddr,vaddr,isDATA,isREAL);\n",accesslength);
/* The following will only make sense if the
"LoadMemory" above returns a DOUBLEWORD entity */
- if (datalen < 8) { /* not for DOUBLEWORD or QUADWORD*/
+ if (datalen < 8) {
+ /* not for DOUBLEWORD */
+ /* start-sanitize-r5900 */
+ /* not for QUADWORD */
+ /* end-sanitize-r5900 */
int valmask;
switch (datalen) {
case 1:
else
printf(" memval = ((uword64) op2 << (8 * byte));\n");
} else if (datalen <= 8) { /* SD and SCD */
- if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
- fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
- exit(4);
- }
+ if (! (features & FEATURE_IGEN))
+ {
+ if (!(insn->flags & COPROC) && ((datalen == 8) || ((datalen == 4) & (insn->flags & UNSIGNED))) && !proc64) {
+ fprintf(stderr,"Operation not available with 32bit wide memory access \"%s\"\n",insn->name);
+ exit(4);
+ }
+ }
if (insn->flags & COPROC)
printf(" memval = (uword64)COP_SD(%s,%s);\n",
((insn->flags & REG)
case FPPREFX:
/* This code could be merged with the PREFIX generation above: */
- printf(" uword64 vaddr = ((uword64)op1 + (uword64)op2);\n");
- printf(" uword64 paddr;\n");
+ printf(" address_word vaddr = ((uword64)op1 + (uword64)op2);\n");
+ printf(" address_word paddr;\n");
printf(" int uncached;\n");
printf(" if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL))\n");
printf(" Prefetch(uncached,paddr,vaddr,isDATA,fs);\n");
printf(" FGR[fs] = (SET64HI(0xDEADC0DE) | WORD64LO(GPR[ft]));\n");
printf(" else\n");
printf(" FGR[fs] = WORD64LO(GPR[ft]);\n");
- printf(" fpr_state[fs] = fmt_uninterpreted;\n");
+ printf(" FPR_STATE[fs] = fmt_uninterpreted;\n");
}
} else if (GETDATASIZEINSN(insn) == DOUBLEWORD) {
if (doisa < 4) {
} else {
printf(" if (SizeFGR() == 64) {\n");
printf(" FGR[fs] = GPR[ft];\n");
- printf(" fpr_state[fs] = fmt_uninterpreted;\n");
+ printf(" FPR_STATE[fs] = fmt_uninterpreted;\n");
printf(" } else\n");
printf(" if ((fs & 0x1) == 0)\n");
printf(" {\n");
printf(" FGR[fs + 1] = WORD64HI(GPR[ft]);\n");
printf(" FGR[fs] = WORD64LO(GPR[ft]);\n");
- printf(" fpr_state[fs + 1] = fmt_uninterpreted;\n");
- printf(" fpr_state[fs] = fmt_uninterpreted;\n");
+ printf(" FPR_STATE[fs + 1] = fmt_uninterpreted;\n");
+ printf(" FPR_STATE[fs] = fmt_uninterpreted;\n");
printf(" }\n");
if (features & FEATURE_WARN_RESULT) {
printf(" else\n");
printf(" if ((format != fmt_single) && (format != fmt_double))\n");
printf(" SignalException(ReservedInstruction,instruction);\n");
printf(" else\n");
- printf(" StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)));\n",((insn->flags & RECIP) ? "Recip" : ""));
+ printf(" StoreFPR(destreg,format,%s(SquareRoot(ValueFPR(fs,format),format)%s));\n",
+ ((insn->flags & RECIP) ? "Recip" : ""),
+ ((insn->flags & RECIP) ? ",format" : ""));
break ;
case FPCEIL:
fprintf(stderr,"Error: Invalid data size %d for FPSUB operation\n",GETDATASIZEINSN(insn));
exit(1);
}
- printf(" StoreFPR(destreg,%s,%s(Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",type,((insn->flags & NOT) ? "Negate" : ""),type,type,type,type,type,type);
+ if (insn->flags & NOT)
+ printf (" StoreFPR(destreg,%s,Negate(Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s),%s));\n",
+ type, type, type, type, type, type, type);
+ else
+ printf (" StoreFPR(destreg,%s,Sub(Multiply(ValueFPR(fs,%s),ValueFPR(ft,%s),%s),ValueFPR(fr,%s),%s));\n",
+ type, type, type, type, type, type);
} else {
printf(" if ((format != fmt_single) && (format != fmt_double))\n");
printf(" SignalException(ReservedInstruction,instruction);\n");
printf(" if (NaN(ofs,format) || NaN(oft,format)) {\n");
printf(" if (FCSR & FP_ENABLE(IO)) {\n");
printf(" FCSR |= FP_CAUSE(IO);\n");
- printf(" SignalException(FPE);\n");
+ printf(" SignalExceptionFPE ();\n");
printf(" ignore = 1;\n");
printf(" }\n");
printf(" } else {\n");
static const struct architectures available_architectures[] = {
{"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */
{"3900",ARCH_R3900}, /* Toshiba R3900 (TX39) */
+ /* start-sanitize-tx49 */
+ {"4900",ARCH_R4900}, /* Toshiba R4900 (TX49) */
+ /* end-sanitize-tx49 */
/* start-sanitize-tx19 */
{"1900",ARCH_R3900}, /* Toshiba R1900 (TX19) */
/* end-sanitize-tx19 */
{"fast", 0,0,'f'},
{"help", 0,0,'h'},
{"warnings",0,0,'w'},
+ {"igen", 0,0,'i'},
{0, 0,0,0}
};
features |= FEATURE_FAST;
break;
+ case 'i' : /* igen formatted output */
+ features |= FEATURE_IGEN;
+ break;
+
case 'w' : /* warnings */
features |= FEATURE_WARNINGS;
/* TODO: Future extension: Allow better control over the warnings generated:
/*---------------------------------------------------------------------------*/
/*> EOF gencode.c <*/
-
-
-
-
-
-
-