Implement 32 bit MIPS16 instructions listed in m16.igen.
[deliverable/binutils-gdb.git] / sim / mips / gencode.c
index 6c4e4ef625a2c9fb3ce6beb0c666e6ea60cc062b..44fac70846184ae1f6075dee127455a43d10f3a8 100644 (file)
@@ -480,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. */
@@ -488,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 */                      \
@@ -516,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 */                  \
@@ -523,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 */
@@ -588,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)},
@@ -671,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)},
@@ -811,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 */
@@ -827,7 +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",  T3,"000000????????????????????001110",SPECIAL,SDBBP,    (NOARG)},
+ {"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)},
@@ -946,7 +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",  T3, "11100??????00001",  RR,      SDBBP,   NOARG },
+{"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 },
@@ -1570,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
@@ -1765,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);
@@ -1865,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");
@@ -2461,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))
@@ -2473,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
@@ -2664,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" : ""));
        }
@@ -2759,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");
@@ -2784,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 */
@@ -2801,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");
@@ -2862,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");
      }
@@ -2928,16 +2963,16 @@ build_instruction (doisa, features, mips16, insn)
       }
 
       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") ;
       }
 
@@ -2980,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) {
@@ -3265,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");
@@ -3323,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) {
@@ -3342,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");
@@ -3456,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:
@@ -3548,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");
@@ -3609,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");
@@ -4427,6 +4469,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  */
This page took 0.028307 seconds and 4 git commands to generate.