Sanity clause
[deliverable/binutils-gdb.git] / sim / mips / gencode.c
index 2f8e60e9ec97c91337f68c38b09da09740398a1f..928b88e37997f50a07ddb17d10cbf5a3204ae9e0 100644 (file)
 #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 */
@@ -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)
@@ -476,6 +480,10 @@ typedef struct instruction {
 #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. */
@@ -484,6 +492,9 @@ typedef struct instruction {
 /* 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 */                      \
@@ -512,6 +523,9 @@ typedef struct instruction {
 
 #define G5 (0                                         \
             | ARCH_R3900                              \
+            /* start-sanitize-tx49 */                 \
+            | ARCH_R4900                              \
+            /* end-sanitize-tx49 */                   \
             /* start-sanitize-r5900 */                \
             | ARCH_R5900                              \
             /* end-sanitize-r5900 */                  \
@@ -519,7 +533,27 @@ typedef struct instruction {
 
 #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 */
@@ -545,7 +579,7 @@ struct instruction MIPS_DECODE[] = {
  {"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)},
@@ -584,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)},
@@ -667,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)},
@@ -807,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 */
@@ -823,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)},
@@ -941,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 },
@@ -962,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
@@ -985,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;
   }
@@ -1008,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;
   }
@@ -1032,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;
   }
@@ -1055,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;
   }
@@ -1078,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;
   }
@@ -1101,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;
   }
@@ -1124,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;
   }
@@ -1364,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
@@ -1559,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);
@@ -1659,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");
@@ -1753,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","<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
@@ -1882,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;
@@ -1892,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);
      }
@@ -1982,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
@@ -2013,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
@@ -2039,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)
        {
@@ -2089,7 +2376,7 @@ process_instructions(doarch,features)
        case RR:
         {
           int minor;
-
+          
           minor = bitmap_val (bitmap, 0, 5);
           if (minor != 0)
             num = 50 + minor;
@@ -2105,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);
 
@@ -2124,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 ;
 }
 
@@ -2183,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))
@@ -2195,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
@@ -2214,9 +2527,6 @@ build_instruction (doisa, features, mips16, insn)
      {
      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");
@@ -2265,9 +2575,6 @@ build_instruction (doisa, features, mips16, insn)
       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) {
@@ -2384,14 +2691,8 @@ build_instruction (doisa, features, mips16, insn)
        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");
@@ -2418,6 +2719,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);
@@ -2477,15 +2782,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");
@@ -2496,13 +2801,10 @@ build_instruction (doisa, features, mips16, insn)
      /* 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 */
@@ -2519,7 +2821,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");
@@ -2580,7 +2882,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");
      }
@@ -2636,24 +2938,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") ;
       }
 
@@ -2680,11 +2984,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));
@@ -2693,7 +3000,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) {
@@ -2779,16 +3086,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");
@@ -2801,14 +3111,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:
@@ -2898,10 +3216,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)
@@ -2964,8 +3285,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");
@@ -3022,7 +3343,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) {
@@ -3041,14 +3362,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");
@@ -3155,7 +3476,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:
@@ -3247,7 +3570,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");
@@ -3308,7 +3636,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");
@@ -4126,6 +4454,9 @@ 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_R3900},   /* Toshiba R1900 (TX19) */
   /* end-sanitize-tx19  */
@@ -4219,6 +4550,7 @@ main(argc,argv)
       {"fast",    0,0,'f'},
       {"help",    0,0,'h'},
       {"warnings",0,0,'w'},
+      {"igen",    0,0,'i'},
       {0,         0,0,0}
     };
    
@@ -4235,6 +4567,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:
@@ -4493,10 +4829,3 @@ my_strtoul(nptr, endptr, base)
 /*---------------------------------------------------------------------------*/
 
 /*> EOF gencode.c <*/
-
-
-
-
-
-
-
This page took 0.038355 seconds and 4 git commands to generate.