]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/mn10300/op_utils.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / mn10300 / op_utils.c
diff --git a/sim/mn10300/op_utils.c b/sim/mn10300/op_utils.c
new file mode 100644 (file)
index 0000000..0a966ed
--- /dev/null
@@ -0,0 +1,227 @@
+#include "sim-main.h"
+#include "targ-vals.h"
+
+#ifdef HAVE_UTIME_H
+#include <utime.h>
+#endif
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#include <sys/stat.h>
+#include <sys/times.h>
+#include <sys/time.h>
+
+
+
+#define REG0(X) ((X) & 0x3)
+#define REG1(X) (((X) & 0xc) >> 2)
+#define REG0_4(X) (((X) & 0x30) >> 4)
+#define REG0_8(X) (((X) & 0x300) >> 8)
+#define REG1_8(X) (((X) & 0xc00) >> 10)
+#define REG0_16(X) (((X) & 0x30000) >> 16)
+#define REG1_16(X) (((X) & 0xc0000) >> 18)
+
+
+INLINE_SIM_MAIN (void)
+genericAdd(unsigned long source, unsigned long destReg)
+{
+  int z, c, n, v;
+  unsigned long dest, sum;
+
+  dest = State.regs[destReg];
+  sum = source + dest;
+  State.regs[destReg] = sum;
+
+  z = (sum == 0);
+  n = (sum & 0x80000000);
+  c = (sum < source) || (sum < dest);
+  v = ((dest & 0x80000000) == (source & 0x80000000)
+       && (dest & 0x80000000) != (sum & 0x80000000));
+
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
+         | (c ? PSW_C : 0) | (v ? PSW_V : 0));
+}
+
+
+
+
+INLINE_SIM_MAIN (void)
+genericSub(unsigned long source, unsigned long destReg)
+{
+  int z, c, n, v;
+  unsigned long dest, difference;
+
+  dest = State.regs[destReg];
+  difference = dest - source;
+  State.regs[destReg] = difference;
+
+  z = (difference == 0);
+  n = (difference & 0x80000000);
+  c = (source > dest);
+  v = ((dest & 0x80000000) != (source & 0x80000000)
+       && (dest & 0x80000000) != (difference & 0x80000000));
+
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
+         | (c ? PSW_C : 0) | (v ? PSW_V : 0));
+}
+
+INLINE_SIM_MAIN (void)
+genericCmp(unsigned long leftOpnd, unsigned long rightOpnd)
+{
+  int z, c, n, v;
+  unsigned long value;
+
+  value = rightOpnd - leftOpnd;
+
+  z = (value == 0);
+  n = (value & 0x80000000);
+  c = (leftOpnd > rightOpnd);
+  v = ((rightOpnd & 0x80000000) != (leftOpnd & 0x80000000)
+       && (rightOpnd & 0x80000000) != (value & 0x80000000));
+
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= ((z ? PSW_Z : 0) | ( n ? PSW_N : 0)
+         | (c ? PSW_C : 0) | (v ? PSW_V : 0));
+}
+
+
+INLINE_SIM_MAIN (void)
+genericOr(unsigned long source, unsigned long destReg)
+{
+  int n, z;
+
+  State.regs[destReg] |= source;
+  z = (State.regs[destReg] == 0);
+  n = (State.regs[destReg] & 0x80000000) != 0;
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
+}
+
+
+INLINE_SIM_MAIN (void)
+genericXor(unsigned long source, unsigned long destReg)
+{
+  int n, z;
+
+  State.regs[destReg] ^= source;
+  z = (State.regs[destReg] == 0);
+  n = (State.regs[destReg] & 0x80000000) != 0;
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= ((z ? PSW_Z : 0) | (n ? PSW_N : 0));
+}
+
+
+INLINE_SIM_MAIN (void)
+genericBtst(unsigned long leftOpnd, unsigned long rightOpnd)
+{
+  unsigned long temp;
+  int z, n;
+
+  temp = rightOpnd;
+  temp &= leftOpnd;
+  n = (temp & 0x80000000) != 0;
+  z = (temp == 0);
+  PSW &= ~(PSW_Z | PSW_N | PSW_C | PSW_V);
+  PSW |= (z ? PSW_Z : 0) | (n ? PSW_N : 0);
+}
+
+/* Read/write functions for system call interface.  */
+INLINE_SIM_MAIN (int)
+syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
+                 unsigned long taddr, char *buf, int bytes)
+{
+  SIM_DESC sd = (SIM_DESC) sc->p1;
+  sim_cpu *cpu = STATE_CPU(sd, 0);
+
+  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
+}
+
+INLINE_SIM_MAIN (int)
+syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
+                  unsigned long taddr, const char *buf, int bytes)
+{
+  SIM_DESC sd = (SIM_DESC) sc->p1;
+  sim_cpu *cpu = STATE_CPU(sd, 0);
+
+  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
+}
+
+
+/* syscall */
+INLINE_SIM_MAIN (void)
+do_syscall ()
+{
+
+  /* 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   (State.regs[0])
+
+/* Parameters.  */
+#define PARM1   (State.regs[1])
+#define PARM2   (load_word (State.regs[REG_SP] + 12))
+#define PARM3   (load_word (State.regs[REG_SP] + 16))
+
+/* 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)
+
+  if ( FUNC == TARGET_SYS_exit )
+    {
+      /* EXIT - caller can look in PARM1 to work out the reason */
+      if (PARM1 == 0xdead)
+       State.exception = SIGABRT;
+      else
+       {
+         sim_engine_halt (simulator, STATE_CPU (simulator, 0), NULL, PC,
+                          sim_exited, PARM1);
+         State.exception = SIGQUIT;
+       }
+      State.exited = 1;
+    }
+  else
+    {
+      CB_SYSCALL syscall;
+
+      CB_SYSCALL_INIT (&syscall);
+      syscall.arg1 = PARM1;
+      syscall.arg2 = PARM2;
+      syscall.arg3 = PARM3;
+      syscall.func = FUNC;
+      syscall.p1 = (PTR) simulator;
+      syscall.read_mem = syscall_read_mem;
+      syscall.write_mem = syscall_write_mem;
+      cb_syscall (STATE_CALLBACK (simulator), &syscall);
+      RETERR = syscall.errcode;
+      RETVAL = syscall.result;
+    }
+
+
+  errno = save_errno;
+}
+