]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/d10v/simops.c
Fix tracing for st2w
[thirdparty/binutils-gdb.git] / sim / d10v / simops.c
index 1af4e09a70672a5b71690e06e85de0eed0d450d8..a59f475103695091ab4b2cdade7a2ea68502fb04 100644 (file)
@@ -7,6 +7,7 @@
 #include "d10v_sim.h"
 #include "simops.h"
 #include "sys/syscall.h"
+#include "bfd.h"
 
 enum op_types {
   OP_VOID,
@@ -23,37 +24,62 @@ enum op_types {
   OP_FLAG,
   OP_FLAG_OUTPUT,
   OP_CONSTANT16,
+  OP_CONSTANT8,
   OP_CONSTANT3,
   OP_CONSTANT4,
   OP_MEMREF,
   OP_MEMREF2,
   OP_POSTDEC,
   OP_POSTINC,
-  OP_PREDEC
+  OP_PREDEC,
+  OP_R2,
+  OP_R3
 };
 
 #ifdef DEBUG
-static void trace_input PARAMS ((char *name,
-                                enum op_types in1,
-                                enum op_types in2,
-                                enum op_types in3));
+static void trace_input_func PARAMS ((char *name,
+                                     enum op_types in1,
+                                     enum op_types in2,
+                                     enum op_types in3));
 
-static void trace_output PARAMS ((enum op_types result));
+#define trace_input(name, in1, in2, in3) do { if (d10v_debug) trace_input_func (name, in1, in2, in3); } while (0)
+
+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 10
+#define SIZE_INSTRUCTION 8
 #endif
 
 #ifndef SIZE_OPERANDS
-#define SIZE_OPERANDS 24
+#define SIZE_OPERANDS 18
 #endif
 
 #ifndef SIZE_VALUES
 #define SIZE_VALUES 13
 #endif
 
+#ifndef SIZE_LOCATION
+#define SIZE_LOCATION 20
+#endif
+
+#ifndef SIZE_PC
+#define SIZE_PC 6
+#endif
+
+#ifndef SIZE_LINE_NUMBER
+#define SIZE_LINE_NUMBER 4
+#endif
+
 static void
-trace_input (name, in1, in2, in3)
+trace_input_func (name, in1, in2, in3)
      char *name;
      enum op_types in1;
      enum op_types in2;
@@ -62,10 +88,15 @@ trace_input (name, in1, in2, in3)
   char *comma;
   enum op_types in[3];
   int i;
-  char buf[80];
+  char buf[1024];
   char *p;
   long tmp;
   char *type;
+  asection *s;
+  const char *filename;
+  const char *functionname;
+  unsigned int linenumber;
+  bfd_vma byte_pc;
 
   if ((d10v_debug & DEBUG_TRACE) == 0)
     return;
@@ -81,10 +112,74 @@ trace_input (name, in1, in2, in3)
     case INS_LONG:             type = " B"; break;
     }
 
-  (*d10v_callback->printf_filtered) (d10v_callback,
-                                    "0x%.6x %s:  %-*s",
-                                    (unsigned)PC, type,
-                                    SIZE_INSTRUCTION, name);
+  if ((d10v_debug & DEBUG_LINE_NUMBER) == 0)
+    (*d10v_callback->printf_filtered) (d10v_callback,
+                                      "0x%.*x %s: %-*s ",
+                                      SIZE_PC, (unsigned)PC,
+                                      type,
+                                      SIZE_INSTRUCTION, name);
+
+  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;
+      if (text && byte_pc >= text_start && byte_pc < text_end)
+       {
+         filename = (const char *)0;
+         functionname = (const char *)0;
+         linenumber = 0;
+         if (bfd_find_nearest_line (exec_bfd, text, (struct symbol_cache_entry **)0, byte_pc - text_start,
+                                    &filename, &functionname, &linenumber))
+           {
+             p = buf;
+             if (linenumber)
+               {
+                 sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, linenumber);
+                 p += strlen (p);
+               }
+             else
+               {
+                 sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
+                 p += SIZE_LINE_NUMBER+2;
+               }
+
+             if (functionname)
+               {
+                 sprintf (p, "%s ", functionname);
+                 p += strlen (p);
+               }
+             else if (filename)
+               {
+                 char *q = (char *) strrchr (filename, '/');
+                 sprintf (p, "%s ", (q) ? q+1 : filename);
+                 p += strlen (p);
+               }
+
+             if (*p == ' ')
+               *p = '\0';
+           }
+       }
+
+      (*d10v_callback->printf_filtered) (d10v_callback,
+                                        "0x%.*x %s: %-*.*s %-*s ",
+                                        SIZE_PC, (unsigned)PC,
+                                        type,
+                                        SIZE_LOCATION, SIZE_LOCATION, buf,
+                                        SIZE_INSTRUCTION, name);
+    }
 
   in[0] = in1;
   in[1] = in2;
@@ -96,6 +191,8 @@ trace_input (name, in1, in2, in3)
       switch (in[i])
        {
        case OP_VOID:
+       case OP_R2:
+       case OP_R3:
          break;
 
        case OP_REG:
@@ -129,6 +226,12 @@ trace_input (name, in1, in2, in3)
          comma = ",";
          break;
 
+       case OP_CONSTANT8:
+         sprintf (p, "%s%d", comma, SEXT8(OP[i]));
+         p += strlen (p);
+         comma = ",";
+         break;
+
        case OP_CONSTANT4:
          sprintf (p, "%s%d", comma, SEXT4(OP[i]));
          p += strlen (p);
@@ -254,6 +357,11 @@ trace_input (name, in1, in2, in3)
                                                 (uint16)SEXT4(OP[i]));
              break;
 
+           case OP_CONSTANT8:
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)SEXT8(OP[i]));
+             break;
+
            case OP_CONSTANT3:
              (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
                                                 (uint16)SEXT3(OP[i]));
@@ -280,13 +388,23 @@ trace_input (name, in1, in2, in3)
              (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
                                                 (uint16)State.regs[OP[++i]]);
              break;
+
+           case OP_R2:
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)State.regs[2]);
+             break;
+
+           case OP_R3:
+             (*d10v_callback->printf_filtered) (d10v_callback, "%*s0x%.4x", SIZE_VALUES-6, "",
+                                                (uint16)State.regs[3]);
+             break;
            }
        }
     }
 }
 
 static void
-trace_output (result)
+trace_output_func (result)
      enum op_types result;
 {
   if ((d10v_debug & (DEBUG_TRACE | DEBUG_VALUES)) == (DEBUG_TRACE | DEBUG_VALUES))
@@ -584,10 +702,15 @@ OP_17001202 ()
 void
 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;
   trace_output (OP_REG);
 }
 
@@ -622,7 +745,7 @@ OP_C01 ()
 void
 OP_4900 ()
 {
-  trace_input ("bl.s", OP_CONSTANT16, OP_VOID, OP_VOID);
+  trace_input ("bl.s", OP_CONSTANT8, OP_R2, OP_R3);
   State.regs[13] = PC+1;
   PC += SEXT8 (OP[0]);
   trace_output (OP_VOID);
@@ -632,7 +755,7 @@ OP_4900 ()
 void
 OP_24800000 ()
 {
-  trace_input ("bl.l", OP_CONSTANT16, OP_VOID, OP_VOID);
+  trace_input ("bl.l", OP_CONSTANT16, OP_R2, OP_R3);
   State.regs[13] = PC+1;
   PC += OP[0];
   trace_output (OP_VOID);
@@ -651,7 +774,7 @@ OP_A01 ()
 void
 OP_4800 ()
 {
-  trace_input ("bra.s", OP_CONSTANT16, OP_VOID, OP_VOID);
+  trace_input ("bra.s", OP_CONSTANT8, OP_VOID, OP_VOID);
   PC += SEXT8 (OP[0]);
   trace_output (OP_VOID);
 }
@@ -669,7 +792,7 @@ OP_24000000 ()
 void
 OP_4A00 ()
 {
-  trace_input ("brf0f.s", OP_CONSTANT16, OP_VOID, OP_VOID);
+  trace_input ("brf0f.s", OP_CONSTANT8, OP_VOID, OP_VOID);
   if (State.F0 == 0)
     PC += SEXT8 (OP[0]);
   trace_output (OP_FLAG);
@@ -689,7 +812,7 @@ OP_25000000 ()
 void
 OP_4B00 ()
 {
-  trace_input ("brf0t.s", OP_CONSTANT16, OP_VOID, OP_VOID);
+  trace_input ("brf0t.s", OP_CONSTANT8, OP_VOID, OP_VOID);
   if (State.F0)
     PC += SEXT8 (OP[0]);
   trace_output (OP_FLAG);
@@ -777,9 +900,9 @@ OP_1403 ()
 void
 OP_401 ()
 {
-  trace_input ("cmpeqi.s", OP_REG, OP_CONSTANT16, OP_VOID);
+  trace_input ("cmpeqi.s", OP_REG, OP_CONSTANT4, OP_VOID);
   State.F1 = State.F0;
-  State.F0 = (State.regs[OP[0]] == SEXT4(OP[1])) ? 1 : 0;  
+  State.F0 = (State.regs[OP[0]] == (reg_t)SEXT4(OP[1])) ? 1 : 0;  
   trace_output (OP_FLAG);
 }
 
@@ -789,7 +912,7 @@ OP_2000000 ()
 {
   trace_input ("cmpeqi.l", OP_REG, OP_CONSTANT16, OP_VOID);
   State.F1 = State.F0;
-  State.F0 = (State.regs[OP[0]] == OP[1]) ? 1 : 0;  
+  State.F0 = (State.regs[OP[0]] == (reg_t)OP[1]) ? 1 : 0;  
   trace_output (OP_FLAG);
 }
 
@@ -799,7 +922,7 @@ OP_601 ()
 {
   trace_input ("cmpi.s", OP_REG, OP_CONSTANT4, OP_VOID);
   State.F1 = State.F0;
-  State.F0 = ((int16)(State.regs[OP[0]]) < SEXT4(OP[1])) ? 1 : 0;  
+  State.F0 = ((int16)(State.regs[OP[0]]) < (int16)SEXT4(OP[1])) ? 1 : 0;  
   trace_output (OP_FLAG);
 }
 
@@ -829,7 +952,7 @@ OP_23000000 ()
 {
   trace_input ("cmpui", OP_REG, OP_CONSTANT16, OP_VOID);
   State.F1 = State.F0;
-  State.F0 = (State.regs[OP[0]] < OP[1]) ? 1 : 0;  
+  State.F0 = (State.regs[OP[0]] < (reg_t)OP[1]) ? 1 : 0;  
   trace_output (OP_FLAG);
 }
 
@@ -860,7 +983,7 @@ OP_4E09 ()
 void
 OP_5F20 ()
 {
-  d10v_callback->printf_filtered(d10v_callback, "***** DBT *****  PC=%x\n",PC);
+  /* d10v_callback->printf_filtered(d10v_callback, "***** DBT *****  PC=%x\n",PC); */
   State.exception = SIGTRAP;
 }
 
@@ -1011,7 +1134,7 @@ OP_15002A02 ()
 void
 OP_4D00 ()
 {
-  trace_input ("jl", OP_REG, OP_VOID, OP_VOID);
+  trace_input ("jl", OP_REG, OP_R2, OP_R3);
   State.regs[13] = PC+1;
   PC = State.regs[OP[0]]; 
   trace_output (OP_VOID);
@@ -1021,7 +1144,10 @@ OP_4D00 ()
 void
 OP_4C00 ()
 {
-  trace_input ("jmp", OP_REG, OP_VOID, OP_VOID);
+  trace_input ("jmp", OP_REG,
+              (OP[0] == 13) ? OP_R2 : OP_VOID,
+              (OP[0] == 13) ? OP_R3 : OP_VOID);
+
   PC = State.regs[OP[0]]; 
   trace_output (OP_VOID);
 }
@@ -1100,7 +1226,7 @@ OP_6201 ()
 void
 OP_6200 ()
 {
-  trace_input ("ld", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
+  trace_input ("ld2w", OP_REG_OUTPUT, OP_MEMREF, OP_VOID);
   State.regs[OP[0]] = RW (State.regs[OP[1]]);
   State.regs[OP[0]+1] = RW (State.regs[OP[1]]+2);
   trace_output (OP_REG);
@@ -2160,7 +2286,7 @@ OP_35000000 ()
 void
 OP_6A00 ()
 {
-  trace_input ("st2w", OP_REG, OP_MEMREF, OP_VOID);
+  trace_input ("st2w", OP_DREG, OP_MEMREF, OP_VOID);
   SW (State.regs[OP[1]],   State.regs[OP[0]]);
   SW (State.regs[OP[1]]+2, State.regs[OP[0]+1]);
   trace_output (OP_VOID);
@@ -2170,7 +2296,7 @@ OP_6A00 ()
 void
 OP_6E1F ()
 {
-  trace_input ("st2w", OP_REG, OP_PREDEC, OP_VOID);
+  trace_input ("st2w", OP_DREG, OP_PREDEC, OP_VOID);
   if ( OP[1] != 15 )
     {
       (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: cannot pre-decrement any registers but r15 (SP).\n");
@@ -2187,7 +2313,7 @@ OP_6E1F ()
 void
 OP_6A01 ()
 {
-  trace_input ("st2w", OP_REG, OP_POSTDEC, OP_VOID);
+  trace_input ("st2w", OP_DREG, OP_POSTDEC, OP_VOID);
   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);
@@ -2198,7 +2324,7 @@ OP_6A01 ()
 void
 OP_6E01 ()
 {
-  trace_input ("st2w", OP_REG, OP_POSTINC, OP_VOID);
+  trace_input ("st2w", OP_DREG, OP_POSTINC, OP_VOID);
   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);
@@ -2228,7 +2354,7 @@ void
 OP_5FE0 ()
 {
   trace_input ("stop", OP_VOID, OP_VOID, OP_VOID);
-  State.exception = SIGQUIT;
+  State.exception = SIG_D10V_STOP;
   trace_output (OP_VOID);
 }
 
@@ -2414,14 +2540,44 @@ OP_1 ()
 void
 OP_5F00 ()
 {
-  trace_input ("trap", OP_CONSTANT16, OP_REG, OP_VOID);
+  trace_input ("trap", OP_CONSTANT4, OP_VOID, OP_VOID);
   trace_output (OP_VOID);
   
   switch (OP[0])
     {
     default:
+#if 0
       (*d10v_callback->printf_filtered) (d10v_callback, "Unknown trap code %d\n", OP[0]);
       State.exception = SIGILL;
+#else
+      /* Use any other traps for batch debugging. */
+      {
+       int i;
+       static int first_time = 1;
+
+       if (first_time)
+         {
+           first_time = 0;
+           (*d10v_callback->printf_filtered) (d10v_callback, "Trap  #     PC ");
+           for (i = 0; i < 16; i++)
+             (*d10v_callback->printf_filtered) (d10v_callback, "  %sr%d", (i > 9) ? "" : " ", i);
+           (*d10v_callback->printf_filtered) (d10v_callback, "         a0         a1 f0 f1 c\n");
+         }
+
+      (*d10v_callback->printf_filtered) (d10v_callback, "Trap %2d 0x%.4x:", (int)OP[0], (int)PC);
+
+      for (i = 0; i < 16; i++)
+       (*d10v_callback->printf_filtered) (d10v_callback, " %.4x", (int) State.regs[i]);
+
+      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);
+
+      (*d10v_callback->printf_filtered) (d10v_callback, "  %d  %d %d\n",
+                                        State.F0 != 0, State.F1 != 0, State.C != 0);
+      break;
+#endif
 
     case 0:
       /* Trap 0 is used for simulating low-level I/O */
@@ -2431,15 +2587,18 @@ OP_5F00 ()
 
 /* Registers passed to trap 0 */
 
-#define FUNC   State.regs[2]   /* function number, return value */
-#define PARM1  State.regs[3]   /* optional parm 1 */
-#define PARM2  State.regs[4]   /* optional parm 2 */
-#define PARM3  State.regs[5]   /* optional parm 3 */
+#define FUNC   State.regs[6]   /* function number */
+#define PARM1  State.regs[2]   /* optional parm 1 */
+#define PARM2  State.regs[3]   /* optional parm 2 */
+#define PARM3  State.regs[4]   /* optional parm 3 */
+#define PARM4  State.regs[5]   /* optional parm 3 */
 
 /* Registers set by trap 0 */
 
-#define RETVAL State.regs[2]   /* return value */
-#define RETERR State.regs[3]   /* return error code */
+#define RETVAL State.regs[2]           /* return value */
+#define RETVAL_HIGH State.regs[2]      /* return value */
+#define RETVAL_LOW  State.regs[3]      /* return value */
+#define RETERR State.regs[4]           /* return error code */
 
 /* Turn a pointer in a register into a pointer into real memory. */
 
@@ -2448,23 +2607,16 @@ OP_5F00 ()
        switch (FUNC)
          {
 #if !defined(__GO32__) && !defined(_WIN32)
-#ifdef SYS_fork
          case SYS_fork:
            RETVAL = fork ();
            break;
-#endif
-#ifdef SYS_execve
          case SYS_execve:
            RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
                             (char **)MEMPTR (PARM3));
            break;
-#endif
-#ifdef SYS_execv
          case SYS_execv:
            RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
            break;
-#endif
-#ifdef SYS_pipe
          case SYS_pipe:
            {
              reg_t buf;
@@ -2477,8 +2629,6 @@ OP_5F00 ()
              SW (buf, host_fd[1]);
            }
          break;
-#endif
-#ifdef SYS_wait
          case SYS_wait:
            {
              int status;
@@ -2488,15 +2638,10 @@ OP_5F00 ()
            }
          break;
 #endif
-#endif
-
-#ifdef SYS_read
          case SYS_read:
            RETVAL = d10v_callback->read (d10v_callback, PARM1, MEMPTR (PARM2),
                                          PARM3);
            break;
-#endif
-#ifdef SYS_write
          case SYS_write:
            if (PARM1 == 1)
              RETVAL = (int)d10v_callback->write_stdout (d10v_callback,
@@ -2505,31 +2650,25 @@ OP_5F00 ()
              RETVAL = (int)d10v_callback->write (d10v_callback, PARM1,
                                                  MEMPTR (PARM2), PARM3);
            break;
-#endif
-#ifdef SYS_lseek
          case SYS_lseek:
-           RETVAL = d10v_callback->lseek (d10v_callback, PARM1, PARM2, PARM3);
+           {
+             unsigned long ret = d10v_callback->lseek (d10v_callback, PARM1,
+                       (((unsigned long)PARM2) << 16) || (unsigned long)PARM3,
+                       PARM4);
+             RETVAL_HIGH = ret >> 16;
+             RETVAL_LOW  = ret & 0xffff;
+           }
            break;
-#endif
-#ifdef SYS_close
          case SYS_close:
            RETVAL = d10v_callback->close (d10v_callback, PARM1);
            break;
-#endif
-#ifdef SYS_open
          case SYS_open:
            RETVAL = d10v_callback->open (d10v_callback, MEMPTR (PARM1), PARM2);
            break;
-#endif
-#ifdef SYS_exit
          case SYS_exit:
-           /* EXIT - caller can look in PARM1 to work out the 
-              reason */
-           State.exception = SIGQUIT;
+           State.exception = SIG_D10V_EXIT;
            break;
-#endif
 
-#ifdef SYS_stat
          case SYS_stat:
            /* stat system call */
            {
@@ -2556,30 +2695,22 @@ OP_5F00 ()
              SLW (buf+36, host_stat.st_ctime);
            }
            break;
-#endif
 
-#ifdef SYS_chown
          case SYS_chown:
            RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
            break;
-#endif
-#ifdef SYS_chmod
          case SYS_chmod:
            RETVAL = chmod (MEMPTR (PARM1), PARM2);
            break;
-#endif
-#ifdef SYS_utime
          case SYS_utime:
            /* Cast the second argument to void *, to avoid type mismatch
               if a prototype is present.  */
            RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2));
            break;
-#endif
          default:
            abort ();
          }
-       RETERR = errno;
-       errno = save_errno;
+       RETERR = d10v_callback->get_errno(d10v_callback);
        break;
       }
 
@@ -2606,6 +2737,7 @@ OP_5F00 ()
       /* Trap 3 writes a character */
       putchar (State.regs[2]);
       break;
+      }
     }
 }