X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=sim%2Fmips%2Fgencode.c;h=44fac70846184ae1f6075dee127455a43d10f3a8;hb=c0a4c3ba170e91bf93d16e0a6340980f6d62901a;hp=f5221ae0265d88355f56b2cc340f023fe35c18eb;hpb=b637f306bac78d02ec2944199271dd989a31abb2;p=deliverable%2Fbinutils-gdb.git diff --git a/sim/mips/gencode.c b/sim/mips/gencode.c index f5221ae026..44fac70846 100644 --- a/sim/mips/gencode.c +++ b/sim/mips/gencode.c @@ -116,6 +116,7 @@ #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 @@ -290,6 +291,7 @@ typedef enum { 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 */ @@ -312,8 +314,8 @@ typedef enum { FPSQRT, FPCONVERT, FPCOMPARE, - /* start-sanitize-r5900 */ MADD, + /* start-sanitize-r5900 */ PABS, PADD, PADSBH, @@ -374,7 +376,9 @@ typedef enum { #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) @@ -475,15 +479,22 @@ typedef struct instruction { /* start-sanitize-r5900 */ #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 */ -#define ARCH_TX19 ((unsigned)1 << 27) /* Toshiba TX19 extention instruction */ +/* The r1900 (tx19) is a tx39 with a mips16 decoder. For the purposes + of implementing the simulator we treat them as the same. */ /* end-sanitize-tx19 */ /* A list (or'ed) of extension insn sets that can be requested independant of the ISA# */ #define MASK_ISA_INDEP (0 \ - /* start-sanitize-tx19 */ \ - | ARCH_TX19 \ - /* end-sanitize-tx19 */ \ + | ARCH_R3900 \ + /* start-sanitize-tx49 */ \ + | ARCH_R4900 \ + /* end-sanitize-tx49 */ \ /* start-sanitize-r5900 */ \ | ARCH_R5900 \ /* end-sanitize-r5900 */ \ @@ -491,7 +502,6 @@ typedef struct instruction { #define MASK_ISA_DEP ~(MASK_ISA_INDEP | MASK_ISA) - /* Very short names for use in the table below to keep it neet. */ #define G1 (3 | ARCH_VR4100) @@ -509,7 +519,40 @@ typedef struct instruction { /* end-sanitize-r5900 */ \ | 0) - +#define G4 (2 | ARCH_R3900) + +#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 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 @@ -533,21 +576,21 @@ struct instruction MIPS_DECODE[] = { {"ANDI", 1,"001100ssssstttttzzzzzzzzzzzzzzzz",NORMAL, AND, (NONE)}, {"BC1", 1,"01000101000qqqfcllllllllllllllll",COP1S, BRANCH, (FP)}, {"BEQ", 1,"000100sssssgggggllllllllllllllll",NORMAL, BRANCH, (EQ)}, - {"BEQL", 2,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH, (EQ | LIKELY)}, + {"BEQL", G4,"010100sssssgggggllllllllllllllll",NORMAL, BRANCH, (EQ | LIKELY)}, {"BGEZ", 1,"000001sssss00001llllllllllllllll",REGIMM, BRANCH, (GT | EQ)}, {"BGEZAL", 1,"000001sssss10001llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)}, - {"BGEZALL", 2,"000001sssss10011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)}, - {"BGEZL", 2,"000001sssss00011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LIKELY)}, + {"BGEZALL",G4,"000001sssss10011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LINK)}, + {"BGEZL", G4,"000001sssss00011llllllllllllllll",REGIMM, BRANCH, (GT | EQ | LIKELY)}, {"BGTZ", 1,"000111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT)}, - {"BGTZL", 2,"010111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT | LIKELY)}, + {"BGTZL", G4,"010111sssss00000llllllllllllllll",NORMAL, BRANCH, (GT | LIKELY)}, {"BLEZ", 1,"000110sssss00000llllllllllllllll",NORMAL, BRANCH, (LT | EQ)}, - {"BLEZL", 2,"010110sssss00000llllllllllllllll",NORMAL, BRANCH, (LT | EQ | LIKELY)}, + {"BLEZL", G4,"010110sssss00000llllllllllllllll",NORMAL, BRANCH, (LT | EQ | LIKELY)}, {"BLTZ", 1,"000001sssss00000llllllllllllllll",REGIMM, BRANCH, (LT)}, {"BLTZAL", 1,"000001sssss10000llllllllllllllll",REGIMM, BRANCH, (LT | LINK)}, - {"BLTZALL", 2,"000001sssss10010llllllllllllllll",REGIMM, BRANCH, (LT | LINK | LIKELY)}, - {"BLTZL", 2,"000001sssss00010llllllllllllllll",REGIMM, BRANCH, (LT | LIKELY)}, + {"BLTZALL",G4,"000001sssss10010llllllllllllllll",REGIMM, BRANCH, (LT | LINK | LIKELY)}, + {"BLTZL", G4,"000001sssss00010llllllllllllllll",REGIMM, BRANCH, (LT | LIKELY)}, {"BNE", 1,"000101sssssgggggllllllllllllllll",NORMAL, BRANCH, (NOT | EQ)}, - {"BNEL", 2,"010101sssssgggggllllllllllllllll",NORMAL, BRANCH, (NOT | EQ | LIKELY)}, + {"BNEL", G4,"010101sssssgggggllllllllllllllll",NORMAL, BRANCH, (NOT | EQ | LIKELY)}, {"BREAK", 1,"000000????????????????????001101",SPECIAL,BREAK, (NOARG)}, {"CEIL.L", 3,"01000110mmm00000vvvvvrrrrr001010",COP1, FPCEIL, (FP | FIXED | DOUBLEWORD)}, {"CEIL.W", 2,"01000110mmm00000vvvvvrrrrr001110",COP1, FPCEIL, (FP | FIXED | WORD)}, @@ -575,8 +618,9 @@ struct instruction MIPS_DECODE[] = { {"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)}, @@ -619,10 +663,10 @@ struct instruction MIPS_DECODE[] = { {"LWR", 1,"100110ssssstttttyyyyyyyyyyyyyyyy",NORMAL, LOAD, (WORD | RIGHT)}, {"LWU", 3,"100111ssssstttttwwwwwwwwwwwwwwww",NORMAL, LOAD, (WORD)}, {"LWXC1", G3,"010011sssssggggg00000rrrrr000000",COP1X, LOAD, (FP | WORD | COPROC | REG)}, + {"MADD", G5,"011100sssssgggggddddd00000000000",MMINORM,MADD, (NONE)}, + {"MADDU", G5,"011100sssssgggggddddd00000000001",MMINORM,MADD, (UNSIGNED)}, /* start-sanitize-r5900 */ - {"MADD", T5,"011100sssssgggggddddd00000000000",MMINORM,MADD, (NONE)}, {"MADD1", T5,"011100sssssgggggddddd00000100000",MMINORM,MADD, (PIPE1)}, - {"MADDU", T5,"011100sssssgggggddddd00000000001",MMINORM,MADD, (UNSIGNED)}, {"MADDU1", T5,"011100sssssgggggddddd00000100001",MMINORM,MADD, (UNSIGNED | PIPE1)}, /* end-sanitize-r5900 */ {"MADD16", G1,"000000sssssggggg0000000000101000",SPECIAL,MADD16, (WORD | HI | LO)}, @@ -658,6 +702,10 @@ struct instruction MIPS_DECODE[] = { {"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)}, @@ -798,7 +846,7 @@ struct instruction MIPS_DECODE[] = { {"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 */ @@ -814,6 +862,7 @@ struct instruction MIPS_DECODE[] = { {"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)}, @@ -842,7 +891,7 @@ struct instruction MIPS_DECODE[] = { {"SWL", 1,"101010sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (WORD | LEFT)}, {"SWR", 1,"101110sssssgggggyyyyyyyyyyyyyyyy",NORMAL, STORE, (WORD | RIGHT)}, {"SWXC1", G3,"010011sssssgggggvvvvv00000001000",COP1X, STORE, (FP | WORD | COPROC | REG)}, - {"SYNC", 2,"000000000000000000000aaaaa001111",SPECIAL,SYNC, (NONE)}, /* z = 5bit stype field */ + {"SYNC", G4,"000000000000000000000aaaaa001111",SPECIAL,SYNC, (NONE)}, /* z = 5bit stype field */ {"SYSCALL", 1,"000000????????????????????001100",SPECIAL,SYSCALL, (NOARG)}, {"TEQ", 2,"000000sssssggggg??????????110100",SPECIAL,TRAP, (EQ)}, {"TEQI", 2,"000001sssss01100iiiiiiiiiiiiiiii",REGIMM, TRAP, (EQ)}, @@ -860,7 +909,7 @@ struct instruction MIPS_DECODE[] = { {"TRUNC.W", 2,"01000110mmm00000vvvvvrrrrr001101",COP1, FPTRUNC, (FP | FIXED | WORD)}, {"XOR", 1,"000000sssssgggggddddd00000100110",SPECIAL,XOR, (NONE)}, {"XORI", 1,"001110ssssstttttzzzzzzzzzzzzzzzz",NORMAL, XOR, (NONE)}, - {"CACHE", 3,"101111sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, CACHE, (NONE)}, + {"CACHE", G6,"101111sssssnnnnnyyyyyyyyyyyyyyyy",NORMAL, CACHE, (NONE)}, {"", 1,"111011sssssgggggyyyyyyyyyyyyyyyy",NORMAL, RSVD, (NONE)}, }; @@ -932,6 +981,7 @@ static const struct instruction MIPS16_DECODE[] = { {"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 }, @@ -953,6 +1003,192 @@ static const struct instruction MIPS16_DECODE[] = { {"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 @@ -976,9 +1212,11 @@ name_for_data_len( insn ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return "DOUBLEWORD"; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return "QUADWORD"; + /* end-sanitize-r5900 */ else return 0; } @@ -999,9 +1237,11 @@ letter_for_data_len( insn ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return "D"; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return "Q"; + /* end-sanitize-r5900 */ else return 0; } @@ -1023,9 +1263,11 @@ type_for_data_len( insn , is_signed ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return 0; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return 0; + /* end-sanitize-r5900 */ else return 0; } @@ -1046,9 +1288,11 @@ max_for_data_len( insn ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return 0; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return 0; + /* end-sanitize-r5900 */ else return 0; } @@ -1069,9 +1313,11 @@ min_for_data_len( insn ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return 0; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return 0; + /* end-sanitize-r5900 */ else return 0; } @@ -1092,9 +1338,11 @@ umax_for_data_len( insn ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return 0; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return 0; + /* end-sanitize-r5900 */ else return 0; } @@ -1115,9 +1363,11 @@ bits_for_data_len( insn ) else if (GETDATASIZEINSN(insn) == DOUBLEWORD) return "64"; + /* start-sanitize-r5900 */ else if (GETDATASIZEINSN(insn) == QUADWORD) return "128"; + /* end-sanitize-r5900 */ else return 0; } @@ -1355,7 +1605,7 @@ build_operands(doisa,features,insn) 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 @@ -1550,7 +1800,7 @@ build_mips16_operands (bitmap) { 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); @@ -1650,7 +1900,7 @@ build_mips16_operands (bitmap) 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"); @@ -1744,125 +1994,128 @@ process_instructions(doarch,features) 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","",""); - 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","",""); + 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 @@ -1873,7 +2126,8 @@ process_instructions(doarch,features) 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; @@ -1883,7 +2137,8 @@ process_instructions(doarch,features) 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); } @@ -1973,25 +2228,45 @@ process_instructions(doarch,features) 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 @@ -2004,24 +2279,42 @@ process_instructions(doarch,features) * 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 @@ -2030,31 +2323,34 @@ process_instructions(doarch,features) 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) { @@ -2080,7 +2376,7 @@ process_instructions(doarch,features) case RR: { int minor; - + minor = bitmap_val (bitmap, 0, 5); if (minor != 0) num = 50 + minor; @@ -2096,10 +2392,25 @@ process_instructions(doarch,features) 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); @@ -2115,17 +2426,28 @@ process_instructions(doarch,features) } 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 ; } @@ -2174,7 +2496,7 @@ build_instruction (doisa, features, mips16, insn) 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)) @@ -2186,7 +2508,7 @@ build_instruction (doisa, features, mips16, insn) 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 @@ -2266,12 +2588,12 @@ build_instruction (doisa, features, mips16, insn) printf(" %sword64 d2 = op2;\n", (boolU ? "u" : "")); printf(" if (d2 == 0)\n"); printf(" {\n"); - printf(" LO%s = 0x8000000000000000LL;\n", pipe); + printf(" LO%s = SIGNED64 (0x8000000000000000);\n", pipe); printf(" HI%s = 0;\n", pipe); printf(" }\n"); - printf(" else if (d2 == -1 && d1 == 0x8000000000000000LL)\n"); + printf(" else if (d2 == -1 && d1 == SIGNED64 (0x8000000000000000))\n"); printf(" {\n"); - printf(" LO%s = 0x8000000000000000LL;\n", pipe); + printf(" LO%s = SIGNED64 (0x8000000000000000);\n", pipe); printf(" HI%s = 0;\n", pipe); printf(" }\n"); printf(" else\n"); @@ -2377,7 +2699,7 @@ build_instruction (doisa, features, mips16, insn) 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(" sim_io_eprintf(sd,\"MT (move-to) over-writing %s register value\\n\");\n",regname); } printf(" %s%s = op1;\n",regname,(pipe1 ? "1" : "")); } @@ -2409,6 +2731,10 @@ build_instruction (doisa, features, mips16, insn) printf(" SignalException(BreakPoint,instruction);\n"); break ; + case SDBBP: + printf(" SignalException(DebugBreakPoint,instruction);\n"); + break ; + case TRAP: { int boolNOT = (insn->flags & NOT); @@ -2468,15 +2794,15 @@ build_instruction (doisa, features, mips16, insn) 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"); @@ -2493,7 +2819,7 @@ build_instruction (doisa, features, mips16, insn) 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 */ @@ -2510,7 +2836,7 @@ build_instruction (doisa, features, mips16, insn) 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"); @@ -2532,7 +2858,8 @@ build_instruction (doisa, features, mips16, insn) printf(" op1 = WORD64LO(op1);\n"); printf(" /* NOTE: The jump occurs AFTER the next instruction has been executed */\n"); printf(" DSPC = op1;\n"); - if (insn->flags & LINK) + if ((insn->flags & LINK) + && ! (insn->flags & REG)) printf(" JALDELAYSLOT();\n"); else printf(" DELAYSLOT();\n"); @@ -2570,7 +2897,7 @@ build_instruction (doisa, features, mips16, insn) 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"); } @@ -2626,24 +2953,26 @@ build_instruction (doisa, features, mips16, insn) 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") ; } @@ -2670,11 +2999,14 @@ build_instruction (doisa, features, mips16, insn) 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)); @@ -2683,7 +3015,7 @@ build_instruction (doisa, features, mips16, insn) 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) { @@ -2769,16 +3101,19 @@ build_instruction (doisa, features, mips16, insn) 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"); @@ -2791,14 +3126,22 @@ build_instruction (doisa, features, mips16, insn) 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: @@ -2888,10 +3231,13 @@ build_instruction (doisa, features, mips16, insn) 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) @@ -2954,8 +3300,8 @@ build_instruction (doisa, features, mips16, insn) 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"); @@ -3012,7 +3358,7 @@ build_instruction (doisa, features, mips16, insn) 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) { @@ -3031,14 +3377,14 @@ build_instruction (doisa, features, mips16, insn) } 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"); @@ -3145,7 +3491,9 @@ build_instruction (doisa, features, mips16, insn) 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: @@ -3237,7 +3585,12 @@ build_instruction (doisa, features, mips16, insn) 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"); @@ -3298,7 +3651,7 @@ build_instruction (doisa, features, mips16, insn) 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"); @@ -3314,7 +3667,6 @@ build_instruction (doisa, features, mips16, insn) printf(" }\n"); break ; -/* start-sanitize-r5900 */ case MADD: { char* pipeline = (insn->flags & PIPE1) ? "1" : ""; @@ -3332,6 +3684,7 @@ build_instruction (doisa, features, mips16, insn) break; } +/* start-sanitize-r5900 */ case MxSA: { if (insn->flags & TO) @@ -3936,19 +4289,16 @@ build_instruction (doisa, features, mips16, insn) printf(" definition on page B-113 */\n"); printf(" signed64 t = ((unsigned64)HI_UW(0) << 32) | (unsigned64)LO_UW(0);\n"); printf(" signed64 u = ((unsigned64)HI_UW(2) << 32) | (unsigned64)LO_UW(2);\n"); - printf(" signed64 x000000007FFFFFFF = LSMASK64 (31);\n"); - printf(" signed64 x0000000080000000 = x000000007FFFFFFF + 1;\n"); - printf(" signed64 minus0000000080000000 = -x0000000080000000;\n"); - printf(" if ( t > x000000007FFFFFFF )\n"); - printf(" GPR_SD(destreg,0) = x000000007FFFFFFF;\n"); - printf(" else if ( t < minus0000000080000000 )\n"); - printf(" GPR_SD(destreg,0) = minus0000000080000000;\n"); + printf(" if ( t > SIGNED64 (0x000000007FFFFFFF) )\n"); + printf(" GPR_SD(destreg,0) = SIGNED64 (0x000000007FFFFFFF);\n"); + printf(" else if ( t < - SIGNED64 (0x0000000080000000) )\n"); + printf(" GPR_SD(destreg,0) = - SIGNED64 (0x0000000080000000);\n"); printf(" else\n"); printf(" GPR_SD(destreg,0) = t;\n"); - printf(" if ( u > x000000007FFFFFFF )\n"); - printf(" GPR_SD(destreg,1) = x000000007FFFFFFF;\n"); - printf(" else if ( u < minus0000000080000000 )\n"); - printf(" GPR_SD(destreg,1) = minus0000000080000000;\n"); + printf(" if ( u > SIGNED64 (0x000000007FFFFFFF) )\n"); + printf(" GPR_SD(destreg,1) = SIGNED64 (0x000000007FFFFFFF);\n"); + printf(" else if ( u < - SIGNED64 (0x0000000080000000) )\n"); + printf(" GPR_SD(destreg,1) = - SIGNED64 (0x0000000080000000);\n"); printf(" else\n"); printf(" GPR_SD(destreg,1) = u;\n"); printf(" }\n"); @@ -4117,10 +4467,14 @@ struct architectures { }; 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_TX19}, /* Toshiba TX19 */ + {"1900",ARCH_R3900}, /* Toshiba R1900 (TX19) */ /* end-sanitize-tx19 */ - {"4100",ARCH_VR4100}, /* NEC MIPS VR4100 */ /* start-sanitize-r5900 */ {"5900",ARCH_R5900}, /* end-sanitize-r5900 */ @@ -4211,6 +4565,7 @@ main(argc,argv) {"fast", 0,0,'f'}, {"help", 0,0,'h'}, {"warnings",0,0,'w'}, + {"igen", 0,0,'i'}, {0, 0,0,0} }; @@ -4227,6 +4582,10 @@ main(argc,argv) 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: @@ -4485,10 +4844,3 @@ my_strtoul(nptr, endptr, base) /*---------------------------------------------------------------------------*/ /*> EOF gencode.c <*/ - - - - - - -