aboutsummaryrefslogtreecommitdiff
path: root/sim
diff options
context:
space:
mode:
Diffstat (limited to 'sim')
-rw-r--r--sim/sh/ChangeLog21
-rw-r--r--sim/sh/interp.c96
2 files changed, 76 insertions, 41 deletions
diff --git a/sim/sh/ChangeLog b/sim/sh/ChangeLog
index 3dd94dd..39bc83f 100644
--- a/sim/sh/ChangeLog
+++ b/sim/sh/ChangeLog
@@ -1,6 +1,23 @@
-Thu Jan 19 05:50:50 1995 Torbjorn Granlund <tege@rtl.cygnus.com>
+Sun Jan 22 13:55:36 1995 Torbjorn Granlund <tege@rtl.cygnus.com>
- * gecode.c (op_tab): Replace code for ADDC and SUBC.
+ * gencode.c (op_tab): Make MAC.W call macw, not abort.
+ * interp.c (macw): New function.
+ (S): New #define.
+
+Sat Jan 21 15:52:30 1995 Torbjorn Granlund <tege@rtl.cygnus.com>
+
+ * gencode.c (op_tab): New code for ADDV and SUBV.
+ Make MAC.L abort sicne it is not implemented.
+
+ * interp.c (dmul): Handle the signed case by adjusting after unsigned multiply.
+ Get rid of __GNUC__ conditional.
+
+aThu Jan 19 05:50:50 1995 Torbjorn Granlund <tege@rtl.cygnus.com>
+
+ * gencode.c (op_tab): Also replace NEGC, and try again with SUBC.
+ Change ADDC for symmetry.
+
+ * gencode.c (op_tab): Replace code for ADDC and SUBC.
Mon Jan 9 15:43:53 1995 Stu Grossman (grossman@cygnus.com)
diff --git a/sim/sh/interp.c b/sim/sh/interp.c
index d6a528d..38a1d26 100644
--- a/sim/sh/interp.c
+++ b/sim/sh/interp.c
@@ -44,6 +44,7 @@
#define MACL saved_state.asregs.macl
#define M saved_state.asregs.sr.bits.m
#define Q saved_state.asregs.sr.bits.q
+#define S saved_state.asregs.sr.bits.s
#define GET_SR() (saved_state.asregs.sr.bits.t = T, saved_state.asregs.sr.word)
#define SET_SR(x) {saved_state.asregs.sr.word = (x); T =saved_state.asregs.sr.bits.t;}
@@ -80,11 +81,7 @@ int valid[16];
#define UNDEF(x)
#endif
-#ifdef __GNUC__
-#define INLINE inline
-#else
-#define INLINE
-#endif
+static int IOMEM PARAMS ((int addr, int write, int value));
/* These variables are at file scope so that functions other than
sim_resume can use the fetch/store macros */
@@ -703,49 +700,70 @@ dmul (sign, rm, rn)
unsigned long temp0, temp1, temp2, temp3;
unsigned long Res2, Res1, Res0;
-
- if (!sign)
+ RnL = rn & 0xffff;
+ RnH = (rn >> 16) & 0xffff;
+ RmL = rm & 0xffff;
+ RmH = (rm >> 16) & 0xffff;
+ temp0 = RmL * RnL;
+ temp1 = RmH * RnL;
+ temp2 = RmL * RnH;
+ temp3 = RmH * RnH;
+ Res2 = 0;
+ Res1 = temp1 + temp2;
+ if (Res1 < temp1)
+ Res2 += 0x00010000;
+ temp1 = (Res1 << 16) & 0xffff0000;
+ Res0 = temp0 + temp1;
+ if (Res0 < temp0)
+ Res2 += 1;
+ Res2 += ((Res1 >> 16) & 0xffff) + temp3;
+
+ if (sign)
{
+ if (rn & 0x80000000)
+ Res2 -= rm;
+ if (rm & 0x80000000)
+ Res2 -= rn;
+ }
- RnL = rn & 0xffff;
- RnH = (rn >> 16) & 0xffff;
- RmL = rm & 0xffff;
- RmH = (rm >> 16) & 0xffff;
- temp0 = RmL * RnL;
- temp1 = RmH * RnL;
- temp2 = RmL * RnH;
- temp3 = RmH * RnH;
- Res2 = 0;
- Res1 = temp1 + temp2;
- if (Res1 < temp1)
- Res2 += 0x00010000;
- temp1 = (Res1 << 16) & 0xffff0000;
- Res0 = temp0 + temp1;
- if (Res0 < temp0)
- Res2 += 1;
- Res2 += ((Res1 >> 16) & 0xffff) + temp3;
- MACH = Res2;
- MACL = Res0;
+ MACH = Res2;
+ MACL = Res0;
+}
- }
+static void
+macw (regs, memory, n, m)
+ int *regs;
+ unsigned char *memory;
+ int m, n;
+{
+ long tempm, tempn;
+ long prod, macl, sum;
+ tempm=RSWAT(regs[m]); regs[m]+=2;
+ tempn=RSWAT(regs[n]); regs[n]+=2;
+
+ macl = MACL;
+ prod = (long)(short) tempm * (long)(short) tempn;
+ sum = prod + macl;
+ if (S)
+ {
+ if ((~(prod ^ macl) & (sum ^ prod)) < 0)
+ {
+ /* MACH's lsb is a sticky overflow bit. */
+ MACH |= 1;
+ /* Store the smallest negative number in MACL if prod is
+ negative, and the largest positive number otherwise. */
+ sum = 0x7fffffff + (prod < 0);
+ }
+ }
else
{
-#ifdef __GNUC__
- long long res;
- long long a = rn;
- long long b = rm;
- res = a * b;
- MACH = res >> 32;
- MACL = res & 0xffffffff;
-#else
- abort ();
-#endif
+ /* Add to MACH the sign extended product, and carry from low sum. */
+ MACH += (-(prod < 0)) + ((unsigned long) sum < prod);
}
-
+ MACL = sum;
}
-
/* Set the memory size to the power of two provided. */
void