mirror of
https://github.com/open-simh/simh.git
synced 2026-01-14 07:40:35 +00:00
3b2: CMP{W|H|B} instruction fix
The WE32100 supports expanded datatypes for its opcodes, allowing an
opcode to override the default size (byte/halfword/word) expected by the
instruction. For example:
CMPH &0x10000,{uword}-8(%fp)
Without the {uword} marker, this instruction would only compare the
lower 2 bytes of -8(%fp) against the lower two bytes of the constant
value 0x10000, since the CMPH instruction compares halfwords. However,
with the {uword} marker, the CMPH instruction promotes the opcode from a
halfword to an unsigned word, sign extending if appropriate.
The CMP{W|H|B} instruction implementation in the 3B2 simulator was
ignoring any expanded type markers on its opcodes when checking whether
to set the "N" (negative) bit in the PSW, leading to a failure in
compiling GCC. This fix causes the instruction to honor the expanded
datatype in this case.
This commit is contained in:
parent
e4e7071b6a
commit
731d99cf65
@ -2220,30 +2220,31 @@ t_stat sim_instr(void)
|
||||
cpu_set_v_flag(0);
|
||||
break;
|
||||
case CMPW:
|
||||
a = cpu_read_op(src1);
|
||||
b = cpu_read_op(src2);
|
||||
|
||||
cpu_set_z_flag((uint32)b == (uint32)a);
|
||||
cpu_set_n_flag((int32)b < (int32)a);
|
||||
cpu_set_c_flag((uint32)b < (uint32)a);
|
||||
cpu_set_v_flag(0);
|
||||
break;
|
||||
case CMPH:
|
||||
a = cpu_read_op(src1);
|
||||
b = cpu_read_op(src2);
|
||||
|
||||
cpu_set_z_flag((uint16)b == (uint16)a);
|
||||
cpu_set_n_flag((int16)b < (int16)a);
|
||||
cpu_set_c_flag((uint16)b < (uint16)a);
|
||||
cpu_set_v_flag(0);
|
||||
break;
|
||||
case CMPB:
|
||||
a = cpu_read_op(src1);
|
||||
b = cpu_read_op(src2);
|
||||
|
||||
cpu_set_z_flag((uint8)b == (uint8)a);
|
||||
cpu_set_n_flag((int8)b < (int8)a);
|
||||
cpu_set_c_flag((uint8)b < (uint8)a);
|
||||
switch(op_type(src2)) {
|
||||
case WD:
|
||||
case UW:
|
||||
cpu_set_n_flag((int32)b < (int32)a);
|
||||
break;
|
||||
case HW:
|
||||
case UH:
|
||||
cpu_set_n_flag((int16)b < (int16)a);
|
||||
break;
|
||||
case BT:
|
||||
case SB:
|
||||
cpu_set_n_flag((int8)b < (int8)a);
|
||||
break;
|
||||
default:
|
||||
/* Unreachable */
|
||||
break;
|
||||
}
|
||||
|
||||
cpu_set_z_flag(b == a);
|
||||
cpu_set_c_flag(b < a);
|
||||
cpu_set_v_flag(0);
|
||||
break;
|
||||
case DECW:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user