diff --git a/src/arm/isa-arm.c b/src/arm/isa-arm.c index dfbd3852a..5a9d85b7d 100644 --- a/src/arm/isa-arm.c +++ b/src/arm/isa-arm.c @@ -416,6 +416,7 @@ void ARMStep(struct ARMCore* cpu) { int rs = (opcode >> 8) & 0xF; \ int rm = opcode & 0xF; \ UNUSED(rdHi); \ + ARM_WAIT_MUL(cpu->gprs[rs]); \ BODY; \ S_BODY; \ if (rd == ARM_PC) { \ diff --git a/src/arm/isa-inlines.h b/src/arm/isa-inlines.h index c2167a5cc..0e837712f 100644 --- a/src/arm/isa-inlines.h +++ b/src/arm/isa-inlines.h @@ -52,6 +52,17 @@ #define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))) && (ARM_SIGN((N) ^ (D)))) #define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D)))) +#define ARM_WAIT_MUL(R) \ + if ((R & 0xFFFFFF00) == 0xFFFFFF00 || !(R & 0xFFFFFF00)) { \ + cpu->cycles += 1; \ + } else if ((R & 0xFFFF0000) == 0xFFFF0000 || !(R & 0xFFFF0000)) { \ + cpu->cycles += 2; \ + } else if ((R & 0xFF000000) == 0xFF000000 || !(R & 0xFF000000)) { \ + cpu->cycles += 3; \ + } else { \ + cpu->cycles += 4; \ + } + #define ARM_STUB cpu->board->hitStub(cpu->board, opcode) #define ARM_WRITE_PC \ diff --git a/src/arm/isa-thumb.c b/src/arm/isa-thumb.c index 2f5a8ecc1..5f8b4cf8a 100644 --- a/src/arm/isa-thumb.c +++ b/src/arm/isa-thumb.c @@ -275,7 +275,7 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(NEG, THUMB_SUBTRACTION(cpu->gprs[rd], 0, cp DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(CMP2, int32_t aluOut = cpu->gprs[rd] - cpu->gprs[rn]; THUMB_SUBTRACTION_S(cpu->gprs[rd], cpu->gprs[rn], aluOut)) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(CMN, int32_t aluOut = cpu->gprs[rd] + cpu->gprs[rn]; THUMB_ADDITION_S(cpu->gprs[rd], cpu->gprs[rn], aluOut)) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ORR, cpu->gprs[rd] = cpu->gprs[rd] | cpu->gprs[rn]; THUMB_NEUTRAL_S( , , cpu->gprs[rd])) -DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(MUL, cpu->gprs[rd] *= cpu->gprs[rn]; THUMB_NEUTRAL_S( , , cpu->gprs[rd])) +DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(MUL, ARM_WAIT_MUL(cpu->gprs[rn]); cpu->gprs[rd] *= cpu->gprs[rn]; THUMB_NEUTRAL_S( , , cpu->gprs[rd])) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(BIC, cpu->gprs[rd] = cpu->gprs[rd] & ~cpu->gprs[rn]; THUMB_NEUTRAL_S( , , cpu->gprs[rd])) DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(MVN, cpu->gprs[rd] = ~cpu->gprs[rn]; THUMB_NEUTRAL_S( , , cpu->gprs[rd]))