From 70ee56c585016f0b3b24814af61c458e8c7def4f Mon Sep 17 00:00:00 2001
From: Andrew Cagney <cagney@redhat.com>
Date: Mon, 1 Dec 1997 06:27:02 +0000
Subject: [PATCH] Rework sim/common/sim-alu.h to differentiate between direcct
 subtraction (involves borrow) and negated addition (involves carry). Update
 d30v so that it uses this method.  Add more tests.

---
 sim/d10v/ChangeLog | 24 ++++++++++++++++++++++++
 sim/d10v/simops.c  | 27 ++++++++++++++++-----------
 2 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/sim/d10v/ChangeLog b/sim/d10v/ChangeLog
index a967c78c85..d80707c763 100644
--- a/sim/d10v/ChangeLog
+++ b/sim/d10v/ChangeLog
@@ -1,3 +1,27 @@
+Thu Nov 27 15:30:01 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+	* simops.c (OP_1000): Compute carry by comparing inputs.
+
+Mon Nov 17 20:57:21 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+	* simops.c (OP_1): Use 32 bit unsigned arithmetic for subtract,
+ 	carry indicated by value > 0xffff.
+
+Fri Nov 14 12:51:20 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+	* interp.c (sim_resume): Don't set up SIGINT handler using signal,
+ 	handled by client.
+	(sim_resume): Fix race condition of a direct assignment to
+ 	stop_simulator, conditionally call sim_stop.
+	(sim_stop_reason): Check stop_simulator returning SIGINT.  Clear
+ 	stop_simulator ready for next sim_resume call.
+	(sim_ctrl_c): Delete function.
+
+Thu Nov 13 19:29:34 1997  Andrew Cagney  <cagney@b1.cygnus.com>
+
+	* interp.c (sim_resume): For "REP", only check/update the PC when
+ 	a branch instruction has not been executed.
+
 Mon Nov 10 17:50:18 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
 	* simops.c (OP_4201): "rachi". Sign extend bit 40 of ACC.  Sign
diff --git a/sim/d10v/simops.c b/sim/d10v/simops.c
index df0f82642b..222d2d4f67 100644
--- a/sim/d10v/simops.c
+++ b/sim/d10v/simops.c
@@ -1931,23 +1931,23 @@ OP_5201 ()
 void
 OP_4201 ()
 {
-  int64 tmp;
+  signed64 tmp;
   int shift = SEXT3 (OP[2]);
 
   trace_input ("rachi", OP_REG_OUTPUT, OP_ACCUM, OP_CONSTANT3);
   State.F1 = State.F0;
   if (shift >=0)
-    tmp = SEXT44 (State.a[OP[1]]) << shift;
+    tmp = SEXT40 (State.a[OP[1]]) << shift;
   else
-    tmp = SEXT44 (State.a[OP[1]]) >> -shift;
+    tmp = SEXT40 (State.a[OP[1]]) >> -shift;
   tmp += 0x8000;
 
-  if (tmp > MAX32)
+  if (tmp > SEXT44 (SIGNED64 (0x0007fffffff)))
     {
       State.regs[OP[0]] = 0x7fff;
       State.F0 = 1;
     }
-  else if (tmp < 0xfff80000000LL)
+  else if (tmp < SEXT44 (SIGNED64 (0xfff80000000)))
     {
       State.regs[OP[0]] = 0x8000;
       State.F0 = 1;
@@ -2480,8 +2480,10 @@ OP_1000 ()
   trace_input ("sub2w", OP_DREG, OP_DREG, OP_VOID);
   a = (uint32)((State.regs[OP[0]] << 16) | State.regs[OP[0]+1]);
   b = (uint32)((State.regs[OP[1]] << 16) | State.regs[OP[1]+1]);
-  tmp = a-b;
-  State.C = (tmp > a);
+  /* 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.regs[OP[0]] = (tmp >> 16) & 0xffff;
   State.regs[OP[0]+1] = tmp & 0xffff;
   trace_output (OP_DREG);
@@ -2577,14 +2579,17 @@ OP_17001002 ()
 void
 OP_1 ()
 {
-  uint16 tmp;
+  unsigned tmp;
   if (OP[1] == 0)
     OP[1] = 16;
 
   trace_input ("subi", OP_REG, OP_CONSTANT16, OP_VOID);
-  tmp = State.regs[OP[0]] - OP[1];
-  State.C = (tmp > State.regs[OP[0]]);
-  State.regs[OP[0]] = tmp;  
+  /* see ../common/sim-alu.h for a more extensive discussion on how to
+     compute the carry/overflow bits */
+  tmp = ((unsigned)(unsigned16) State.regs[OP[0]]
+	 + (unsigned)(unsigned16) ( - OP[1]));
+  State.C = (tmp >= (1 << 16));
+  State.regs[OP[0]] = tmp;
   trace_output (OP_REG);
 }