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);
}
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);
}
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;
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;
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;
}
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;
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);
}
/* 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);
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));