]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - sim/d10v/simops.c
Add DM (bit 4) to PSW. See 7-1 for more info.
[thirdparty/binutils-gdb.git] / sim / d10v / simops.c
index 222d2d4f67654429ff66398846996854c464d42c..b085c148c715c18c54935d451fb9f24b1814987f 100644 (file)
@@ -1352,13 +1352,17 @@ OP_1A00 ()
 void
 OP_3A00 ()
 {
-  int64 tmp;
+  uint64 tmp;
+  uint32 src1;
+  uint32 src2;
 
   trace_input ("macu", OP_ACCUM, OP_REG, OP_REG);
-  tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]);
+  src1 = (uint16) State.regs[OP[1]];
+  src2 = (uint16) State.regs[OP[2]];
+  tmp = src1 * src2;
   if (State.FX)
-    tmp = SEXT40( (tmp << 1) & MASK40);
-  State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) + tmp) & MASK40;
+    tmp = (tmp << 1);
+  State.a[OP[0]] = (State.a[OP[0]] + tmp) & MASK40;
   trace_output (OP_ACCUM);
 }
 
@@ -1514,14 +1518,18 @@ OP_1800 ()
 void
 OP_3800 ()
 {
-  int64 tmp;
+  uint64 tmp;
+  uint32 src1;
+  uint32 src2;
 
   trace_input ("msbu", OP_ACCUM, OP_REG, OP_REG);
-  tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]);
+  src1 = (uint16) State.regs[OP[1]];
+  src2 = (uint16) State.regs[OP[2]];
+  tmp = src1 * src2;
   if (State.FX)
-    tmp = SEXT40( (tmp << 1) & MASK40);
+    tmp = (tmp << 1);
 
-  State.a[OP[0]] = (SEXT40 (State.a[OP[0]]) - tmp) & MASK40;
+  State.a[OP[0]] = (State.a[OP[0]] - tmp) & MASK40;
   trace_output (OP_ACCUM);
 }
 
@@ -1573,11 +1581,14 @@ OP_1C00 ()
 void
 OP_3C00 ()
 {
-  int64 tmp;
+  uint64 tmp;
+  uint32 src1;
+  uint32 src2;
 
   trace_input ("mulxu", OP_ACCUM_OUTPUT, OP_REG, OP_REG);
-  tmp = SEXT40 (State.regs[OP[1]] * State.regs[OP[2]]);
-
+  src1 = (uint16) State.regs[OP[1]];
+  src2 = (uint16) State.regs[OP[2]];
+  tmp = src1 * src2;
   if (State.FX)
     tmp <<= 1;
 
@@ -1700,6 +1711,7 @@ OP_5200 ()
       if (State.SM) PSW |= 0x8000;
       if (State.EA) PSW |= 0x2000;
       if (State.DB) PSW |= 0x1000;
+      if (State.DM) PSW |= 0x800;
       if (State.IE) PSW |= 0x400;
       if (State.RP) PSW |= 0x200;
       if (State.MD) PSW |= 0x100;
@@ -1756,6 +1768,7 @@ OP_5600 ()
       State.SM = (PSW & 0x8000) ? 1 : 0;
       State.EA = (PSW & 0x2000) ? 1 : 0;
       State.DB = (PSW & 0x1000) ? 1 : 0;
+      State.DM = (PSW & 0x800) ? 1 : 0;
       State.IE = (PSW & 0x400) ? 1 : 0;
       State.RP = (PSW & 0x200) ? 1 : 0;
       State.MD = (PSW & 0x100) ? 1 : 0;
@@ -1901,18 +1914,20 @@ OP_5201 ()
     }
 
   State.F1 = State.F0;
+  tmp = SEXT56 ((State.a[0] << 16) | (State.a[1] & 0xffff));
   if (shift >=0)
-    tmp = ((State.a[0] << 16) | (State.a[1] & 0xffff)) << shift;
+    tmp <<= shift;
   else
-    tmp = ((State.a[0] << 16) | (State.a[1] & 0xffff)) >> -shift;
-  tmp = ( SEXT60(tmp) + 0x8000 ) >> 16;
-  if (tmp > MAX32)
+    tmp >>= -shift;
+  tmp += 0x8000;
+  tmp >>= 16; /* look at bits 0:43 */
+  if (tmp > SEXT44 (SIGNED64 (0x0007fffffff)))
     {
       State.regs[OP[0]] = 0x7fff;
       State.regs[OP[0]+1] = 0xffff;
       State.F0 = 1;
     } 
-  else if (tmp < MIN32)
+  else if (tmp < SEXT44 (SIGNED64 (0xfff80000000)))
     {
       State.regs[OP[0]] = 0x8000;
       State.regs[OP[0]+1] = 0;
@@ -2418,8 +2433,10 @@ OP_0 ()
   uint16 tmp;
 
   trace_input ("sub", OP_REG, OP_REG, OP_VOID);
+  /* see ../common/sim-alu.h for a more extensive discussion on how to
+     compute the carry/overflow bits. */
   tmp = State.regs[OP[0]] - State.regs[OP[1]];
-  State.C = (tmp > State.regs[OP[0]]);
+  State.C = ((uint16) State.regs[OP[0]] >= (uint16) State.regs[OP[1]]);
   State.regs[OP[0]] = tmp;
   trace_output (OP_REG);
 }
@@ -2483,7 +2500,7 @@ OP_1000 ()
   /* see ../common/sim-alu.h for a more extensive discussion on how to
      compute the carry/overflow bits */
   tmp = a - b;
-  State.C = (a < b);
+  State.C = (a >= b);
   State.regs[OP[0]] = (tmp >> 16) & 0xffff;
   State.regs[OP[0]+1] = tmp & 0xffff;
   trace_output (OP_DREG);
@@ -2585,7 +2602,8 @@ OP_1 ()
 
   trace_input ("subi", OP_REG, OP_CONSTANT16, OP_VOID);
   /* see ../common/sim-alu.h for a more extensive discussion on how to
-     compute the carry/overflow bits */
+     compute the carry/overflow bits. */
+  /* since OP[1] is never <= 0, -OP[1] == ~OP[1]+1 can never overflow */
   tmp = ((unsigned)(unsigned16) State.regs[OP[0]]
         + (unsigned)(unsigned16) ( - OP[1]));
   State.C = (tmp >= (1 << 16));