Get configure to define RETSIGTYPE
[deliverable/binutils-gdb.git] / sim / d10v / simops.c
index e547f9bcd32db9bfa5863cd6eac9fbbd9b5096f1..3c4a0af7dc9a62aae5fa31fce5e52625b3f7d847 100644 (file)
@@ -1,13 +1,18 @@
+#include "config.h"
+
 #include <signal.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#endif
 
 #include "d10v_sim.h"
 #include "simops.h"
 #include "sys/syscall.h"
-#include "bfd.h"
+
+extern char *strrchr ();
 
 enum op_types {
   OP_VOID,
@@ -50,12 +55,6 @@ static void trace_output_func PARAMS ((enum op_types result));
 
 #define trace_output(result) do { if (d10v_debug) trace_output_func (result); } while (0)
 
-static int init_text_p = 0;
-static asection *text;
-static bfd_vma text_start;
-static bfd_vma text_end;
-extern bfd *exec_bfd;
-
 #ifndef SIZE_INSTRUCTION
 #define SIZE_INSTRUCTION 8
 #endif
@@ -94,7 +93,6 @@ trace_input_func (name, in1, in2, in3)
   char *p;
   long tmp;
   char *type;
-  asection *s;
   const char *filename;
   const char *functionname;
   unsigned int linenumber;
@@ -111,6 +109,10 @@ trace_input_func (name, in1, in2, in3)
     case INS_RIGHT:            type = " R"; break;
     case INS_LEFT_PARALLEL:    type = "*L"; break;
     case INS_RIGHT_PARALLEL:   type = "*R"; break;
+    case INS_LEFT_COND_TEST:   type = "?L"; break;
+    case INS_RIGHT_COND_TEST:  type = "?R"; break;
+    case INS_LEFT_COND_EXE:    type = "&L"; break;
+    case INS_RIGHT_COND_EXE:   type = "&R"; break;
     case INS_LONG:             type = " B"; break;
     }
 
@@ -123,21 +125,8 @@ trace_input_func (name, in1, in2, in3)
 
   else
     {
-      if (!init_text_p)
-       {
-         init_text_p = 1;
-         for (s = exec_bfd->sections; s; s = s->next)
-           if (strcmp (bfd_get_section_name (exec_bfd, s), ".text") == 0)
-             {
-               text = s;
-               text_start = bfd_get_section_vma (exec_bfd, s);
-               text_end = text_start + bfd_section_size (exec_bfd, s);
-               break;
-             }
-       }
-
       buf[0] = '\0';
-      byte_pc = (bfd_vma)PC << 2;
+      byte_pc = decode_pc ();
       if (text && byte_pc >= text_start && byte_pc < text_end)
        {
          filename = (const char *)0;
@@ -165,7 +154,7 @@ trace_input_func (name, in1, in2, in3)
                }
              else if (filename)
                {
-                 char *q = (char *) strrchr (filename, '/');
+                 char *q = strrchr (filename, '/');
                  sprintf (p, "%s ", (q) ? q+1 : filename);
                  p += strlen (p);
                }
@@ -196,6 +185,7 @@ trace_input_func (name, in1, in2, in3)
        case OP_R2:
        case OP_R3:
        case OP_R4:
+       case OP_R2R3:
          break;
 
        case OP_REG:
@@ -406,9 +396,19 @@ trace_input_func (name, in1, in2, in3)
              (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
                                                 (uint16)State.regs[4]);
              break;
+
+           case OP_R2R3:
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)State.regs[2]);
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)State.regs[3]);
+             i++;
+             break;
            }
        }
     }
+
+  (*d10v_callback->flush_stdout) (d10v_callback);
 }
 
 static void
@@ -486,6 +486,8 @@ trace_output_func (result)
          break;
        }
     }
+
+  (*d10v_callback->flush_stdout) (d10v_callback);
 }
 
 #else
@@ -603,15 +605,12 @@ void
 OP_1200 ()
 {
   uint32 tmp;
-  uint32 tmp1 = (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1];
-  uint32 tmp2 = (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1];
+  uint32 a = (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1];
+  uint32 b = (State.regs[OP[1]]) << 16 | State.regs[OP[1]+1];
 
   trace_input ("add2w", OP_DREG, OP_DREG, OP_VOID);
-  tmp = tmp1 + tmp2;
-  if ( (tmp < tmp1) || (tmp < tmp2) )
-    State.C = 1;
-  else
-    State.C = 0;
+  tmp = a + b;
+  State.C = (tmp < a);
   State.regs[OP[0]] = tmp >> 16;
   State.regs[OP[0]+1] = tmp & 0xFFFF;
   trace_output (OP_DREG);
@@ -621,14 +620,11 @@ OP_1200 ()
 void
 OP_1000000 ()
 {
-  uint16 tmp = State.regs[OP[0]];
-  State.regs[OP[0]] = State.regs[OP[1]] + OP[2];
+  uint16 tmp = State.regs[OP[1]];
+  State.regs[OP[0]] = tmp + OP[2];
 
   trace_input ("add3", OP_REG_OUTPUT, OP_REG, OP_CONSTANT16);
-  if ( tmp > State.regs[OP[0]])
-    State.C = 1;
-  else
-    State.C = 0;
+  State.C = (State.regs[OP[0]] < tmp);
   trace_output (OP_REG);
 }
 
@@ -725,12 +721,10 @@ OP_201 ()
   uint tmp = State.regs[OP[0]];
   if (OP[1] == 0)
     OP[1] = 16;
+
   trace_input ("addi", OP_REG, OP_CONSTANT16, OP_VOID);
   State.regs[OP[0]] += OP[1];
-  if (tmp > State.regs[OP[0]])
-    State.C = 1;
-  else
-    State.C = 0;
+  State.C = (State.regs[OP[0]] < tmp);
   trace_output (OP_REG);
 }
 
@@ -767,7 +761,7 @@ OP_4900 ()
 {
   trace_input ("bl.s", OP_CONSTANT8, OP_R2, OP_R3);
   State.regs[13] = PC+1;
-  PC += SEXT8 (OP[0]);
+  JMP( PC + SEXT8 (OP[0]));
   trace_output (OP_VOID);
 }
 
@@ -777,7 +771,7 @@ OP_24800000 ()
 {
   trace_input ("bl.l", OP_CONSTANT16, OP_R2, OP_R3);
   State.regs[13] = PC+1;
-  PC += OP[0];
+  JMP (PC + OP[0]);
   trace_output (OP_VOID);
 }
 
@@ -795,7 +789,7 @@ void
 OP_4800 ()
 {
   trace_input ("bra.s", OP_CONSTANT8, OP_VOID, OP_VOID);
-  PC += SEXT8 (OP[0]);
+  JMP (PC + SEXT8 (OP[0]));
   trace_output (OP_VOID);
 }
 
@@ -804,7 +798,7 @@ void
 OP_24000000 ()
 {
   trace_input ("bra.l", OP_CONSTANT16, OP_VOID, OP_VOID);
-  PC += OP[0];
+  JMP (PC + OP[0]);
   trace_output (OP_VOID);
 }
 
@@ -814,7 +808,7 @@ OP_4A00 ()
 {
   trace_input ("brf0f.s", OP_CONSTANT8, OP_VOID, OP_VOID);
   if (State.F0 == 0)
-    PC += SEXT8 (OP[0]);
+    JMP (PC + SEXT8 (OP[0]));
   trace_output (OP_FLAG);
 }
 
@@ -824,7 +818,7 @@ OP_25000000 ()
 {
   trace_input ("brf0f.l", OP_CONSTANT16, OP_VOID, OP_VOID);
   if (State.F0 == 0)
-    PC += OP[0];
+    JMP (PC + OP[0]);
   trace_output (OP_FLAG);
 }
 
@@ -834,7 +828,7 @@ OP_4B00 ()
 {
   trace_input ("brf0t.s", OP_CONSTANT8, OP_VOID, OP_VOID);
   if (State.F0)
-    PC += SEXT8 (OP[0]);
+    JMP (PC + SEXT8 (OP[0]));
   trace_output (OP_FLAG);
 }
 
@@ -844,7 +838,7 @@ OP_25800000 ()
 {
   trace_input ("brf0t.l", OP_CONSTANT16, OP_VOID, OP_VOID);
   if (State.F0)
-    PC += OP[0];
+    JMP (PC + OP[0]);
   trace_output (OP_FLAG);
 }
 
@@ -912,7 +906,7 @@ OP_1403 ()
 {
   trace_input ("cmpeq", OP_ACCUM, OP_ACCUM, OP_VOID);
   State.F1 = State.F0;
-  State.F0 = (State.a[OP[0]] == State.a[OP[1]]) ? 1 : 0;
+  State.F0 = ((State.a[OP[0]] & MASK40) == (State.a[OP[1]] & MASK40)) ? 1 : 0;
   trace_output (OP_FLAG);
 }
 
@@ -1130,10 +1124,9 @@ OP_15002A02 ()
   int i;
 
   trace_input ("exp", OP_REG_OUTPUT, OP_ACCUM, OP_VOID);
-  if (SEXT40(State.a[OP[1]]) >= 0)
-    tmp = State.a[OP[1]];
-  else
-    tmp = ~(State.a[OP[1]]);
+  tmp = SEXT40(State.a[OP[1]]);
+  if (tmp < 0)
+    tmp = ~tmp & MASK40;
   
   foo = 0x4000000000LL;
   for (i=1;i<25;i++)
@@ -1156,7 +1149,7 @@ OP_4D00 ()
 {
   trace_input ("jl", OP_REG, OP_R2, OP_R3);
   State.regs[13] = PC+1;
-  PC = State.regs[OP[0]]; 
+  JMP (State.regs[OP[0]]);
   trace_output (OP_VOID);
 }
 
@@ -1168,7 +1161,7 @@ OP_4C00 ()
               (OP[0] == 13) ? OP_R2 : OP_VOID,
               (OP[0] == 13) ? OP_R3 : OP_VOID);
 
-  PC = State.regs[OP[0]]; 
+  JMP (State.regs[OP[0]]);
   trace_output (OP_VOID);
 }
 
@@ -1186,6 +1179,12 @@ void
 OP_6401 ()
 {
   trace_input ("ld", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
+  if ( OP[1] == 15 )
+    {
+      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+      State.exception = SIGILL;
+      return;
+    }
   State.regs[OP[0]] = RW (State.regs[OP[1]]);
   INC_ADDR(State.regs[OP[1]],-2);
   trace_output (OP_REG);
@@ -1227,6 +1226,12 @@ OP_6601 ()
 {
   uint16 addr = State.regs[OP[1]];
   trace_input ("ld2w", OP_REG_OUTPUT, OP_POSTDEC, OP_VOID);
+  if ( OP[1] == 15 )
+    {
+      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+      State.exception = SIGILL;
+      return;
+    }
   State.regs[OP[0]] = RW (addr);
   State.regs[OP[0]+1] = RW (addr+2);
   INC_ADDR(State.regs[OP[1]],-4);
@@ -1261,8 +1266,7 @@ void
 OP_38000000 ()
 {
   trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF2, OP_VOID);
-  State.regs[OP[0]] = RB (OP[1] + State.regs[OP[2]]);
-  SEXT8 (State.regs[OP[0]]);
+  State.regs[OP[0]] = SEXT8 (RB (OP[1] + State.regs[OP[2]]));
   trace_output (OP_REG);
 }
 
@@ -1271,8 +1275,7 @@ void
 OP_7000 ()
 {
   trace_input ("ldb", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
-  State.regs[OP[0]] = RB (State.regs[OP[1]]);
-  SEXT8 (State.regs[OP[0]]);
+  State.regs[OP[0]] = SEXT8 (RB (State.regs[OP[1]]));
   trace_output (OP_REG);
 }
 
@@ -1289,7 +1292,7 @@ OP_4001 ()
 void
 OP_20000000 ()
 {
-  trace_input ("ldi.s", OP_REG_OUTPUT, OP_CONSTANT16, OP_VOID);
+  trace_input ("ldi.l", OP_REG_OUTPUT, OP_CONSTANT16, OP_VOID);
   State.regs[OP[0]] = OP[1];
   trace_output (OP_REG);
 }
@@ -1627,9 +1630,9 @@ OP_3E00 ()
 void
 OP_3E01 ()
 {
-  trace_input ("mv2wtac", OP_ACCUM_OUTPUT, OP_DREG, OP_VOID);
+  trace_input ("mv2wtac", OP_DREG, OP_ACCUM_OUTPUT, OP_VOID);
   State.a[OP[1]] = (SEXT16 (State.regs[OP[0]]) << 16 | State.regs[OP[0]+1]) & MASK40;
-  trace_output (OP_ACCUM);
+  trace_output (OP_ACCUM_REVERSE);
 }
 
 /* mvac */
@@ -1830,12 +1833,40 @@ void
 OP_5E00 ()
 {
   trace_input ("nop", OP_VOID, OP_VOID, OP_VOID);
-  trace_output (OP_VOID);
 
-  if (State.ins_type == INS_LEFT || State.ins_type == INS_LEFT_PARALLEL)
-    left_nops++;
-  else
-    right_nops++;
+  ins_type_counters[ (int)State.ins_type ]--;  /* don't count nops as normal instructions */
+  switch (State.ins_type)
+    {
+    default:
+      ins_type_counters[ (int)INS_UNKNOWN ]++;
+      break;
+
+    case INS_LEFT_PARALLEL:
+      /* Don't count a parallel op that includes a NOP as a true parallel op */
+      ins_type_counters[ (int)INS_RIGHT_PARALLEL ]--;
+      ins_type_counters[ (int)INS_RIGHT ]++;
+      ins_type_counters[ (int)INS_LEFT_NOPS ]++;
+      break;
+
+    case INS_LEFT:
+    case INS_LEFT_COND_EXE:
+      ins_type_counters[ (int)INS_LEFT_NOPS ]++;
+      break;
+
+    case INS_RIGHT_PARALLEL:
+      /* Don't count a parallel op that includes a NOP as a true parallel op */
+      ins_type_counters[ (int)INS_LEFT_PARALLEL ]--;
+      ins_type_counters[ (int)INS_LEFT ]++;
+      ins_type_counters[ (int)INS_RIGHT_NOPS ]++;
+      break;
+
+    case INS_RIGHT:
+    case INS_RIGHT_COND_EXE:
+      ins_type_counters[ (int)INS_RIGHT_NOPS ]++;
+      break;
+    }
+
+  trace_output (OP_VOID);
 }
 
 /* not */
@@ -2129,8 +2160,6 @@ OP_3201 ()
 void
 OP_460B ()
 {
-  uint16 tmp;
-
   trace_input ("slx", OP_REG, OP_FLAG, OP_VOID);
   State.regs[OP[0]] = (State.regs[OP[0]] << 1) | State.F0;
   trace_output (OP_REG);
@@ -2151,7 +2180,7 @@ OP_3400 ()
 {
   trace_input ("sra", OP_ACCUM, OP_REG, OP_VOID);
   if ((State.regs[OP[1]] & 31) <= 16)
-    State.a[OP[0]] >>= (State.regs[OP[1]] & 31);
+    State.a[OP[0]] = (SEXT40(State.a[OP[0]]) >> (State.regs[OP[1]] & 31)) & MASK40;
   else
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31);
@@ -2179,7 +2208,7 @@ OP_3401 ()
     OP[1] = 16;
 
   trace_input ("srai", OP_ACCUM, OP_CONSTANT16, OP_VOID);
-  State.a[OP[0]] >>= OP[1];
+  State.a[OP[0]] = (SEXT40(State.a[OP[0]]) >> OP[1]) & MASK40;
   trace_output (OP_ACCUM);
 }
 
@@ -2198,7 +2227,7 @@ OP_3000 ()
 {
   trace_input ("srl", OP_ACCUM, OP_REG, OP_VOID);
   if ((State.regs[OP[1]] & 31) <= 16)
-    State.a[OP[0]] >>= (State.regs[OP[1]] & 31);
+    State.a[OP[0]] = (uint64)((State.a[OP[0]] & MASK40) >> (State.regs[OP[1]] & 31));
   else
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: shift value %d too large.\n", State.regs[OP[1]] & 31);
@@ -2226,7 +2255,7 @@ OP_3001 ()
     OP[1] = 16;
 
   trace_input ("srli", OP_ACCUM, OP_CONSTANT16, OP_VOID);
-  State.a[OP[0]] >>= OP[1];
+  State.a[OP[0]] = (uint64)(State.a[OP[0]] & MASK40) >> OP[1];
   trace_output (OP_ACCUM);
 }
 
@@ -2291,6 +2320,12 @@ void
 OP_6C01 ()
 {
   trace_input ("st", OP_REG, OP_POSTDEC, OP_VOID);
+  if ( OP[1] == 15 )
+    {
+      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+      State.exception = SIGILL;
+      return;
+    }
   SW (State.regs[OP[1]], State.regs[OP[0]]);
   INC_ADDR (State.regs[OP[1]],-2);
   trace_output (OP_VOID);
@@ -2338,6 +2373,12 @@ void
 OP_6A01 ()
 {
   trace_input ("st2w", OP_DREG, OP_POSTDEC, OP_VOID);
+  if ( OP[1] == 15 )
+    {
+      (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot post-decrement register r15 (SP).\n");
+      State.exception = SIGILL;
+      return;
+    }
   SW (State.regs[OP[1]],   State.regs[OP[0]]);
   SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]);
   INC_ADDR (State.regs[OP[1]],4);
@@ -2386,12 +2427,12 @@ OP_5FE0 ()
 void
 OP_0 ()
 {
-  int32 tmp;
+  uint16 tmp;
 
   trace_input ("sub", OP_REG, OP_REG, OP_VOID);
-  tmp = (int16)State.regs[OP[0]]- (int16)State.regs[OP[1]];
-  State.C = (tmp & 0xffff0000) ? 1 : 0;
-  State.regs[OP[0]] = tmp & 0xffff;
+  tmp = State.regs[OP[0]] - State.regs[OP[1]];
+  State.C = (tmp > State.regs[OP[0]]);
+  State.regs[OP[0]] = tmp;
   trace_output (OP_REG);
 }
 
@@ -2446,14 +2487,13 @@ OP_1003 ()
 void
 OP_1000 ()
 {
-  int64 tmp;
-  int32 a,b;
+  uint32 tmp,a,b;
 
   trace_input ("sub2w", OP_DREG, OP_DREG, OP_VOID);
-  a = (int32)((State.regs[OP[0]] << 16) | State.regs[OP[0]+1]);
-  b = (int32)((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]);
+  a = (uint32)((State.regs[OP[0]] << 16) | State.regs[OP[0]+1]);
+  b = (uint32)((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]);
   tmp = a-b;
-  State.C = (tmp & 0xffffffff00000000LL) ? 1 : 0;  
+  State.C = (tmp > a);
   State.regs[OP[0]] = (tmp >> 16) & 0xffff;
   State.regs[OP[0]+1] = tmp & 0xffff;
   trace_output (OP_DREG);
@@ -2549,14 +2589,14 @@ OP_17001002 ()
 void
 OP_1 ()
 {
-  int32 tmp;
+  uint16 tmp;
   if (OP[1] == 0)
     OP[1] = 16;
 
   trace_input ("subi", OP_REG, OP_CONSTANT16, OP_VOID);
-  tmp = (int16)State.regs[OP[0]] - OP[1];
-  State.C = (tmp & 0xffff0000) ? 1 : 0;
-  State.regs[OP[0]] = tmp & 0xffff;  
+  tmp = State.regs[OP[0]] - OP[1];
+  State.C = (tmp > State.regs[OP[0]]);
+  State.regs[OP[0]] = tmp;  
   trace_output (OP_REG);
 }
 
@@ -2595,18 +2635,18 @@ OP_5F00 ()
 
       for (i = 0; i < 2; i++)
        (*d10v_callback->printf_filtered) (d10v_callback, " %.2x%.8lx",
-                                          ((int)(State.a[OP[i]] >> 32) & 0xff),
-                                          ((unsigned long)State.a[OP[i]]) & 0xffffffff);
+                                          ((int)(State.a[i] >> 32) & 0xff),
+                                          ((unsigned long)State.a[i]) & 0xffffffff);
 
       (*d10v_callback->printf_filtered) (d10v_callback, "  %d  %d %d\n",
                                         State.F0 != 0, State.F1 != 0, State.C != 0);
+      (*d10v_callback->flush_stdout) (d10v_callback);
       break;
 #endif
 
     case 0:
       /* Trap 0 is used for simulating low-level I/O */
       {
-       int save_errno = errno; 
        errno = 0;
 
 /* Registers passed to trap 0 */
@@ -2626,7 +2666,7 @@ OP_5F00 ()
 
 /* Turn a pointer in a register into a pointer into real memory. */
 
-#define MEMPTR(x) ((char *)((x) + State.imem))
+#define MEMPTR(x) ((char *)(dmem_addr(x)))
 
        switch (FUNC)
          {
@@ -2760,6 +2800,7 @@ OP_5F00 ()
                  {
                    trace_output (OP_VOID);
                    (*d10v_callback->printf_filtered) (d10v_callback, "Unknown signal %d\n", PARM2);
+                   (*d10v_callback->flush_stdout) (d10v_callback);
                    State.exception = SIGILL;
                  }
                else
@@ -2942,7 +2983,7 @@ OP_5F00 ()
     case 1:
       /* Trap 1 prints a string */
       {
-       char *fstr = State.regs[2] + State.imem;
+       char *fstr = dmem_addr(State.regs[2]);
        fputs (fstr, stdout);
        break;
       }
@@ -2950,11 +2991,12 @@ OP_5F00 ()
     case 2:
       /* Trap 2 calls printf */
       {
-       char *fstr = State.regs[2] + State.imem;
+       char *fstr = dmem_addr(State.regs[2]);
        (*d10v_callback->printf_filtered) (d10v_callback, fstr,
                                           (int16)State.regs[3],
                                           (int16)State.regs[4],
                                           (int16)State.regs[5]);
+       (*d10v_callback->flush_stdout) (d10v_callback);
        break;
       }
 
This page took 0.033161 seconds and 4 git commands to generate.