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:
Seth Morabito 2019-09-01 11:45:45 -07:00
parent e4e7071b6a
commit 731d99cf65

View file

@ -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);
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);
cpu_set_c_flag((uint8)b < (uint8)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: