diff options
-rw-r--r-- | sim/sh/ChangeLog | 21 | ||||
-rw-r--r-- | sim/sh/interp.c | 96 |
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 |