* simops.c: Don't lose the upper 24 bits of the return
authorJeff Law <law@redhat.com>
Wed, 27 Nov 1996 18:36:54 +0000 (18:36 +0000)
committerJeff Law <law@redhat.com>
Wed, 27 Nov 1996 18:36:54 +0000 (18:36 +0000)
        pointer in "call" and "calls" instructions.  Rough cut
        at emulated system calls.

sim/mn10300/ChangeLog
sim/mn10300/simops.c

index 007623213a63510e312d3064a7d1993ec5d46af9..0212fc89c599e79fb74c7fa97b5d5b8ed97283c9 100644 (file)
@@ -1,5 +1,9 @@
 Wed Nov 27 09:20:42 1996  Jeffrey A Law  (law@cygnus.com)
 
+       * simops.c: Don't lose the upper 24 bits of the return
+       pointer in "call" and "calls" instructions.  Rough cut
+       at emulated system calls.
+
        * simops.c: Implement the remaining 5, 6 and 7 byte instructions.
 
        * simops.c: Implement remaining 4 byte instructions.
index fae759923e6e7d554966f9ddc997b9993b84d6f5..a57c81caeda3427fa9524e5ae38994848655ec18 100644 (file)
@@ -2367,9 +2367,9 @@ void OP_CD000000 ()
   sp = State.regs[REG_SP];
   next_pc = State.pc + 2;
   State.mem[sp] = next_pc & 0xff;
-  State.mem[sp+1] = next_pc & 0xff00;
-  State.mem[sp+2] = next_pc & 0xff0000;
-  State.mem[sp+3] = next_pc & 0xff000000;
+  State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+  State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+  State.mem[sp+3] = (next_pc & 0xff000000) >> 24;
 
   mask = insn & 0xff;
 
@@ -2432,9 +2432,9 @@ void OP_DD000000 ()
   sp = State.regs[REG_SP];
   next_pc = State.pc + 2;
   State.mem[sp] = next_pc & 0xff;
-  State.mem[sp+1] = next_pc & 0xff00;
-  State.mem[sp+2] = next_pc & 0xff0000;
-  State.mem[sp+3] = next_pc & 0xff000000;
+  State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+  State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+  State.mem[sp+3] = (next_pc & 0xff000000) >> 24;
 
   mask = (extension & 0xff00) >> 8;
 
@@ -2496,9 +2496,9 @@ void OP_F0F0 ()
   sp = State.regs[REG_SP];
   next_pc = State.pc + 2;
   State.mem[sp] = next_pc & 0xff;
-  State.mem[sp+1] = next_pc & 0xff00;
-  State.mem[sp+2] = next_pc & 0xff0000;
-  State.mem[sp+3] = next_pc & 0xff000000;
+  State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+  State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+  State.mem[sp+3] = (next_pc & 0xff000000) >> 24;
   State.regs[REG_MDR] = next_pc;
   State.pc = State.regs[REG_A0 + (insn & 0x3)] - 2;
 }
@@ -2511,9 +2511,9 @@ void OP_FAFF0000 ()
   sp = State.regs[REG_SP];
   next_pc = State.pc + 4;
   State.mem[sp] = next_pc & 0xff;
-  State.mem[sp+1] = next_pc & 0xff00;
-  State.mem[sp+2] = next_pc & 0xff0000;
-  State.mem[sp+3] = next_pc & 0xff000000;
+  State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+  State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+  State.mem[sp+3] = (next_pc & 0xff000000) >> 24;
   State.regs[REG_MDR] = next_pc;
   State.pc += SEXT16 (insn & 0xffff) - 4;
 }
@@ -2526,9 +2526,9 @@ void OP_FCFF0000 ()
   sp = State.regs[REG_SP];
   next_pc = State.pc + 6;
   State.mem[sp] = next_pc & 0xff;
-  State.mem[sp+1] = next_pc & 0xff00;
-  State.mem[sp+2] = next_pc & 0xff0000;
-  State.mem[sp+3] = next_pc & 0xff000000;
+  State.mem[sp+1] = (next_pc & 0xff00) >> 8;
+  State.mem[sp+2] = (next_pc & 0xff0000) >> 16;
+  State.mem[sp+3] = (next_pc & 0xff000000) >> 24;
   State.regs[REG_MDR] = next_pc;
   State.pc += (((insn & 0xffff) << 16) | extension) - 6;
 }
@@ -2668,7 +2668,141 @@ void OP_F0FD ()
 /* trap */
 void OP_F0FE ()
 {
- abort ();
+  /* We use this for simulated system calls; we may need to change
+     it to a reserved instruction if we conflict with uses at
+     Matsushita.  */
+  int save_errno = errno;      
+  errno = 0;
+
+/* Registers passed to trap 0 */
+
+/* Function number.  */
+#define FUNC   (load_mem (State.regs[REG_SP] + 4, 4))
+
+/* Parameters.  */
+#define PARM1   (load_mem (State.regs[REG_SP] + 8, 4))
+#define PARM2   (load_mem (State.regs[REG_SP] + 12, 4))
+#define PARM3   (load_mem (State.regs[REG_SP] + 16, 4))
+
+/* Registers set by trap 0 */
+
+#define RETVAL State.regs[0]   /* return value */
+#define RETERR State.regs[1]   /* return error code */
+
+/* Turn a pointer in a register into a pointer into real memory. */
+
+#define MEMPTR(x) (State.mem + x)
+
+  switch (FUNC)
+    {
+#if !defined(__GO32__) && !defined(_WIN32)
+      case SYS_fork:
+      RETVAL = fork ();
+      break;
+    case SYS_execve:
+      RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
+                      (char **)MEMPTR (PARM3));
+      break;
+    case SYS_execv:
+      RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
+      break;
+#endif
+
+    case SYS_read:
+      RETVAL = mn10300_callback->read (mn10300_callback, PARM1,
+                                   MEMPTR (PARM2), PARM3);
+      break;
+    case SYS_write:
+      if (PARM1 == 1)
+       RETVAL = (int)mn10300_callback->write_stdout (mn10300_callback,
+                                                  MEMPTR (PARM2), PARM3);
+      else
+       RETVAL = (int)mn10300_callback->write (mn10300_callback, PARM1,
+                                           MEMPTR (PARM2), PARM3);
+      break;
+    case SYS_lseek:
+      RETVAL = mn10300_callback->lseek (mn10300_callback, PARM1, PARM2, PARM3);
+      break;
+    case SYS_close:
+      RETVAL = mn10300_callback->close (mn10300_callback, PARM1);
+      break;
+    case SYS_open:
+      RETVAL = mn10300_callback->open (mn10300_callback, MEMPTR (PARM1), PARM2);
+      break;
+    case SYS_exit:
+      /* EXIT - caller can look in PARM1 to work out the 
+        reason */
+      if (PARM1 == 0xdead || PARM1 == 0x1)
+       State.exception = SIGABRT;
+      else
+       State.exception = SIGQUIT;
+      break;
+
+    case SYS_stat:     /* added at hmsi */
+      /* stat system call */
+      {
+       struct stat host_stat;
+       reg_t buf;
+
+       RETVAL = stat (MEMPTR (PARM1), &host_stat);
+       
+       buf = PARM2;
+
+       /* 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);
+      }
+      break;
+
+    case SYS_chown:
+      RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
+      break;
+    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.  */
+      RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2));
+      break;
+    default:
+      abort ();
+    }
+  RETERR = errno;
+  errno = save_errno;
 }
 
 /* rtm */