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
1 changed files with 20 additions and 19 deletions
|
@ -2220,30 +2220,31 @@ t_stat sim_instr(void)
|
||||||
cpu_set_v_flag(0);
|
cpu_set_v_flag(0);
|
||||||
break;
|
break;
|
||||||
case CMPW:
|
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:
|
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:
|
case CMPB:
|
||||||
a = cpu_read_op(src1);
|
a = cpu_read_op(src1);
|
||||||
b = cpu_read_op(src2);
|
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_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);
|
cpu_set_v_flag(0);
|
||||||
break;
|
break;
|
||||||
case DECW:
|
case DECW:
|
||||||
|
|
Loading…
Add table
Reference in a new issue