* simops.c (OP_10007E0): Handle SYS_times and SYS_gettimeofday.
[deliverable/binutils-gdb.git] / sim / v850 / simops.c
index 07d9ae20797e9f09b9e7c975a8a8b688c4b7aab1..c932849fa0e5892e9da4a99f8b9239e96720f88a 100644 (file)
@@ -3,6 +3,9 @@
 #include "simops.h"
 #include "sys/syscall.h"
 #include "bfd.h"
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/times.h>
 
 enum op_types {
   OP_UNKNOWN,
@@ -150,7 +153,7 @@ trace_input (name, type, size)
     case OP_IMM_REG:
     case OP_IMM_REG_CMP:
     case OP_IMM_REG_MOVE:
-      sprintf (buf, "%d,r%d", OP[1], OP[0]);
+      sprintf (buf, "%d,r%d", OP[0], OP[1]);
       break;
 
     case OP_COND_BR:
@@ -158,19 +161,19 @@ trace_input (name, type, size)
       break;
 
     case OP_LOAD16:
-      sprintf (buf, "%d[r30],r%d", SEXT7 (OP[1]) * size, OP[0]);
+      sprintf (buf, "%d[r30],r%d", OP[1] * size, OP[0]);
       break;
 
     case OP_STORE16:
-      sprintf (buf, "r%d,%d[r30]", OP[0], SEXT7 (OP[1]) * size);
+      sprintf (buf, "r%d,%d[r30]", OP[0], OP[1] * size);
       break;
 
     case OP_LOAD32:
-      sprintf (buf, "%d[r%d],r%d", SEXT16 (OP[2]), OP[0], OP[1]);
+      sprintf (buf, "%d[r%d],r%d", SEXT16 (OP[2]) & ~0x1, OP[0], OP[1]);
       break;
 
     case OP_STORE32:
-      sprintf (buf, "r%d,%d[r%d]", OP[1], SEXT16 (OP[2]), OP[0]);
+      sprintf (buf, "r%d,%d[r%d]", OP[1], SEXT16 (OP[2] & ~0x1), OP[0]);
       break;
 
     case OP_JUMP:
@@ -273,14 +276,14 @@ trace_input (name, type, size)
          break;
 
        case OP_LOAD16:
-         values[0] = SEXT7 (OP[1]) * size;
+         values[0] = OP[1] * size;
          values[1] = State.regs[30];
          num_values = 2;
          break;
 
        case OP_STORE16:
          values[0] = State.regs[OP[0]];
-         values[1] = SEXT7 (OP[1]) * size;
+         values[1] = OP[1] * size;
          values[2] = State.regs[30];
          num_values = 3;
          break;
@@ -422,9 +425,9 @@ OP_300 ()
 
   trace_input ("sld.b", OP_LOAD16, 1);
   temp = OP[1];
-  temp = SEXT7 (temp);
+  temp &= 0x7f;
   op2 = temp;
-  result = get_byte (State.mem + State.regs[30] + op2);
+  result = load_mem (State.regs[30] + op2, 1);
   State.regs[OP[0]] = SEXT8 (result);
   trace_output (OP_LOAD16);
 }
@@ -438,9 +441,9 @@ OP_400 ()
 
   trace_input ("sld.h", OP_LOAD16, 2);
   temp = OP[1];
-  temp = SEXT7 (temp);
+  temp &= 0x7f;
   op2 = temp << 1;
-  result = get_half (State.mem + State.regs[30] + op2);
+  result = load_mem (State.regs[30] + op2, 2);
   State.regs[OP[0]] = SEXT16 (result);
   trace_output (OP_LOAD16);
 }
@@ -454,9 +457,9 @@ OP_500 ()
 
   trace_input ("sld.w", OP_LOAD16, 4);
   temp = OP[1];
-  temp = SEXT7 (temp);
-  op2 = temp << 2;
-  result = get_word (State.mem + State.regs[30] + op2);
+  temp &= 0x7e;
+  op2 = temp << 1;
+  result = load_mem (State.regs[30] + op2, 4);
   State.regs[OP[0]] = result;
   trace_output (OP_LOAD16);
 }
@@ -471,9 +474,9 @@ OP_380 ()
   trace_input ("sst.b", OP_STORE16, 1);
   op0 = State.regs[OP[0]];
   temp = OP[1];
-  temp = SEXT7 (temp);
+  temp &= 0x7f;
   op1 = temp;
-  put_byte (State.mem + State.regs[30] + op1, op0);
+  store_mem (State.regs[30] + op1, 1, op0);
   trace_output (OP_STORE16);
 }
 
@@ -487,9 +490,9 @@ OP_480 ()
   trace_input ("sst.h", OP_STORE16, 2);
   op0 = State.regs[OP[0]];
   temp = OP[1];
-  temp = SEXT7 (temp);
+  temp &= 0x7f;
   op1 = temp << 1;
-  put_half (State.mem + State.regs[30] + op1, op0);
+  store_mem (State.regs[30] + op1, 2, op0);
   trace_output (OP_STORE16);
 }
 
@@ -503,9 +506,9 @@ OP_501 ()
   trace_input ("sst.w", OP_STORE16, 4);
   op0 = State.regs[OP[0]];
   temp = OP[1];
-  temp = SEXT7 (temp);
-  op1 = temp << 2;
-  put_word (State.mem + State.regs[30] + op1, op0);
+  temp &= 0x7e;
+  op1 = temp << 1;
+  store_mem (State.regs[30] + op1, 4, op0);
   trace_output (OP_STORE16);
 }
 
@@ -520,7 +523,7 @@ OP_700 ()
   op0 = State.regs[OP[0]];
   temp = SEXT16 (OP[2]);
   op2 = temp;
-  result = get_byte (State.mem + op0 + op2);
+  result = load_mem (op0 + op2, 1);
   State.regs[OP[1]] = SEXT8 (result);
   trace_output (OP_LOAD32);
 }
@@ -537,7 +540,7 @@ OP_720 ()
   temp = SEXT16 (OP[2]);
   temp &= ~0x1;
   op2 = temp;
-  result = get_half (State.mem + op0 + op2);
+  result = load_mem (op0 + op2, 2);
   State.regs[OP[1]] = SEXT16 (result);
   trace_output (OP_LOAD32);
 }
@@ -554,7 +557,7 @@ OP_10720 ()
   temp = SEXT16 (OP[2]);
   temp &= ~0x1;
   op2 = temp;
-  result = get_word (State.mem + op0 + op2);
+  result = load_mem (op0 + op2, 4);
   State.regs[OP[1]] = result;
   trace_output (OP_LOAD32);
 }
@@ -571,7 +574,7 @@ OP_740 ()
   op1 = State.regs[OP[1]];
   temp = SEXT16 (OP[2]);
   op2 = temp;
-  put_byte (State.mem + op0 + op2, op1);
+  store_mem (op0 + op2, 1, op1);
   trace_output (OP_STORE32);
 }
 
@@ -587,7 +590,7 @@ OP_760 ()
   op1 = State.regs[OP[1]];
   temp = SEXT16 (OP[2] & ~0x1);
   op2 = temp;
-  put_half (State.mem + op0 + op2, op1);
+  store_mem (op0 + op2, 2, op1);
   trace_output (OP_STORE32);
 }
 
@@ -603,7 +606,7 @@ OP_10760 ()
   op1 = State.regs[OP[1]];
   temp = SEXT16 (OP[2] & ~0x1);
   op2 = temp;
-  put_word (State.mem + op0 + op2, op1);
+  store_mem (op0 + op2, 4, op1);
   trace_output (OP_STORE32);
 }
 
@@ -1828,12 +1831,12 @@ OP_7C0 ()
   op1 = OP[1] & 0x7;
   temp = SEXT16 (OP[2]);
   op2 = temp;
-  temp = get_byte (State.mem + op0 + op2);
+  temp = load_mem (op0 + op2, 1);
   State.sregs[5] &= ~PSW_Z;
   if ((temp & (1 << op1)) == 0)
     State.sregs[5] |= PSW_Z;
   temp |= (1 << op1);
-  put_byte (State.mem + op0 + op2, temp);
+  store_mem (op0 + op2, 1, temp);
   trace_output (OP_BIT);
 }
 
@@ -1849,12 +1852,12 @@ OP_47C0 ()
   op1 = OP[1] & 0x7;
   temp = SEXT16 (OP[2]);
   op2 = temp;
-  temp = get_byte (State.mem + op0 + op2);
+  temp = load_mem (op0 + op2, 1);
   State.sregs[5] &= ~PSW_Z;
   if ((temp & (1 << op1)) == 0)
     State.sregs[5] |= PSW_Z;
   temp ^= (1 << op1);
-  put_byte (State.mem + op0 + op2, temp);
+  store_mem (op0 + op2, 1, temp);
   trace_output (OP_BIT);
 }
 
@@ -1870,12 +1873,12 @@ OP_87C0 ()
   op1 = OP[1] & 0x7;
   temp = SEXT16 (OP[2]);
   op2 = temp;
-  temp = get_byte (State.mem + op0 + op2);
+  temp = load_mem (op0 + op2, 1);
   State.sregs[5] &= ~PSW_Z;
   if ((temp & (1 << op1)) == 0)
     State.sregs[5] |= PSW_Z;
   temp &= ~(1 << op1);
-  put_byte (State.mem + op0 + op2, temp);
+  store_mem (op0 + op2, 1, temp);
   trace_output (OP_BIT);
 }
 
@@ -1891,13 +1894,21 @@ OP_C7C0 ()
   op1 = OP[1] & 0x7;
   temp = SEXT16 (OP[2]);
   op2 = temp;
-  temp = get_byte (State.mem + op0 + op2);
+  temp = load_mem (op0 + op2, 1);
   State.sregs[5] &= ~PSW_Z;
   if ((temp & (1 << op1)) == 0)
     State.sregs[5] |= PSW_Z;
   trace_output (OP_BIT);
 }
 
+/* breakpoint */
+void
+OP_FFFF ()
+{
+  State.exception = SIGTRAP;
+  PC -= 4;
+}
+
 /* di */
 void
 OP_16007E0 ()
@@ -1931,21 +1942,29 @@ OP_14007E0 ()
 {
   trace_input ("reti", OP_NONE, 0);
   trace_output (OP_NONE);
-  abort ();
+
+  if ((State.sregs[5] & (PSW_NP | PSW_EP)) == PSW_NP)
+    {                          /* Only NP is on */
+      PC = State.sregs[2] - 4; /* FEPC */
+      State.sregs[5] = State.sregs[3]; /* FEPSW */
+    }
+  else
+    {
+      PC = State.sregs[0] - 4; /* EIPC */
+      State.sregs[5] = State.sregs[1]; /* EIPSW */
+    }
 }
 
 /* trap, not supportd */
 void
 OP_10007E0 ()
 {
-  extern int errno;
-
   trace_input ("trap", OP_TRAP, 0);
   trace_output (OP_TRAP);
 
-  /* Trap 0 is used for simulating low-level I/O */
+  /* Trap 31 is used for simulating OS I/O functions */
 
-  if (OP[0] == 0)
+  if (OP[0] == 31)
     {
       int save_errno = errno;  
       errno = 0;
@@ -1964,8 +1983,7 @@ OP_10007E0 ()
 
 /* Turn a pointer in a register into a pointer into real memory. */
 
-#define MEMPTR(x) ((char *)((x) + State.mem))
-
+#define MEMPTR(x) (map (x))
 
       switch (FUNC)
        {
@@ -2035,7 +2053,6 @@ OP_10007E0 ()
            State.exception = SIGQUIT;
          break;
 
-#if 0
        case SYS_stat:  /* added at hmsi */
          /* stat system call */
          {
@@ -2046,22 +2063,19 @@ OP_10007E0 ()
 
            buf = PARM2;
 
-           /* The hard-coded offsets and sizes were determined by using
-            * the D10V compiler on a test program that used struct stat.
-            */
-           SW  (buf,    host_stat.st_dev);
-           SW  (buf+2,  host_stat.st_ino);
-           SW  (buf+4,  host_stat.st_mode);
-           SW  (buf+6,  host_stat.st_nlink);
-           SW  (buf+8,  host_stat.st_uid);
-           SW  (buf+10, host_stat.st_gid);
-           SW  (buf+12, host_stat.st_rdev);
-           SLW (buf+16, host_stat.st_size);
-           SLW (buf+20, host_stat.st_atime);
-           SLW (buf+28, host_stat.st_mtime);
-           SLW (buf+36, host_stat.st_ctime);
+           /* Just wild-assed guesses.  */
+           store_mem (buf, 2, host_stat.st_dev);
+           store_mem (buf + 2, 2, host_stat.st_ino);
+           store_mem (buf + 4, 4, host_stat.st_mode);
+           store_mem (buf + 8, 2, host_stat.st_nlink);
+           store_mem (buf + 10, 2, host_stat.st_uid);
+           store_mem (buf + 12, 2, host_stat.st_gid);
+           store_mem (buf + 14, 2, host_stat.st_rdev);
+           store_mem (buf + 16, 4, host_stat.st_size);
+           store_mem (buf + 20, 4, host_stat.st_atime);
+           store_mem (buf + 28, 4, host_stat.st_mtime);
+           store_mem (buf + 36, 4, host_stat.st_ctime);
          }
-#endif
          break;
 
        case SYS_chown:
@@ -2070,6 +2084,30 @@ OP_10007E0 ()
        case SYS_chmod:
          RETVAL = chmod (MEMPTR (PARM1), PARM2);
          break;
+       case SYS_time:
+         RETVAL = time (MEMPTR (PARM1));
+         break;
+       case SYS_times:
+         {
+           struct tms tms;
+           RETVAL = times (&tms);
+           store_mem (PARM1, 4, tms.tms_utime);
+           store_mem (PARM1 + 4, 4, tms.tms_stime);
+           store_mem (PARM1 + 8, 4, tms.tms_cutime);
+           store_mem (PARM1 + 12, 4, tms.tms_cstime);
+           break;
+         }
+       case SYS_gettimeofday:
+         {
+           struct timeval t;
+           struct timezone tz;
+           RETVAL = gettimeofday (&t, &tz);
+           store_mem (PARM1, 4, t.tv_sec);
+           store_mem (PARM1 + 4, 4, t.tv_usec);
+           store_mem (PARM2, 4, tz.tz_minuteswest);
+           store_mem (PARM2 + 4, 4, tz.tz_dsttime);
+           break;
+         }
        case SYS_utime:
          /* Cast the second argument to void *, to avoid type mismatch
             if a prototype is present.  */
@@ -2081,10 +2119,14 @@ OP_10007E0 ()
       RETERR = errno;
       errno = save_errno;
     }
-  else if (OP[0] == 1 )
-    {
-      char *fstr = State.regs[2] + State.mem;
-      puts (fstr);
+  else
+    {                          /* Trap 0 -> 30 */
+      State.sregs[0] = PC + 4; /* EIPC */
+      State.sregs[1] = State.sregs[5]; /* EIPSW */
+      State.sregs[4] &= 0xffff0000; /* Mask out EICC */
+      State.sregs[4] |= 0x40 + OP[0];  /* EICC */
+      State.sregs[5] |= PSW_EP | PSW_ID; /* Now doing exception processing */
+      PC = ((OP[0] < 0x10) ? 0x40 : 0x50) - 4;
     }
 }
 
This page took 0.028664 seconds and 4 git commands to generate.