CPU: Restrict allowed opcodes in INC/DEC Grp4

Only FE /0 (INC r/m8) and FE /1 (DEC r/m8) are valid instructions in
INC/DEC Grp 4. All other ModR/M opcode bits are reserved and should
throw #UD.
This commit is contained in:
snow flurry
2025-12-14 15:49:20 -08:00
parent a1b1515661
commit ca9eb9acb9

View File

@@ -56,16 +56,23 @@ opINCDEC_b_a16(uint32_t fetchdat)
if (cpu_state.abrt)
return 1;
if (rmdat & 0x38) {
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
} else {
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
switch (rmdat & 0x38) {
case 0: /* INC r/m8 */
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
break;
case 0x8: /* DEC r/m8 */
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
break;
default:
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0);
@@ -83,16 +90,23 @@ opINCDEC_b_a32(uint32_t fetchdat)
if (cpu_state.abrt)
return 1;
if (rmdat & 0x38) {
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
} else {
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
switch (rmdat & 0x38) {
case 0: /* INC r/m8 */
seteab(temp + 1);
if (cpu_state.abrt)
return 1;
setadd8nc(temp, 1);
break;
case 0x8: /* DEC r/m8 */
seteab(temp - 1);
if (cpu_state.abrt)
return 1;
setsub8nc(temp, 1);
break;
default:
cpu_state.pc = cpu_state.oldpc;
x86illegal();
break;
}
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1);