all repos — mgba @ fbba3efb344df982f32cbf9cf3252b193263a9d3

mGBA Game Boy Advance Emulator

ARM: Fix long multiply-and-accumulate register write order (fixes #1956)
Vicki Pfau vi@endrift.com
Sat, 28 Nov 2020 21:19:34 -0800
commit

fbba3efb344df982f32cbf9cf3252b193263a9d3

parent

98799dae6d1e293a6aa255b7700c05a29e609b35

2 files changed, 11 insertions(+), 12 deletions(-)

jump to
M CHANGESCHANGES

@@ -19,6 +19,7 @@ Emulation fixes:

- ARM: Fix ALU reading PC after shifting - ARM: Fix STR storing PC after address calculation - ARM: Fix Addressing mode 1 shifter on rs == pc (fixes mgba.io/i/1926) + - ARM: Fix long multiply-and-accumulate register write order (fixes mgba.io/1/1956) - GB: Partially fix timing for skipped BIOS - GB: Downgrade DMG-only ROMs from CGB mode even without boot ROM - GB Audio: Fix serializing sweep time
M src/arm/isa-arm.csrc/arm/isa-arm.c

@@ -526,12 +526,11 @@ DEFINE_MULTIPLY_INSTRUCTION_2_ARM(MLA, cpu->gprs[rdHi] = cpu->gprs[rm] * cpu->gprs[rs] + cpu->gprs[rd], ARM_NEUTRAL_S(, , cpu->gprs[rdHi]), 2)

DEFINE_MULTIPLY_INSTRUCTION_ARM(MUL, cpu->gprs[rd] = cpu->gprs[rm] * cpu->gprs[rs], ARM_NEUTRAL_S(cpu->gprs[rm], cpu->gprs[rs], cpu->gprs[rd])) DEFINE_MULTIPLY_INSTRUCTION_2_ARM(SMLAL, - int64_t d = ((int64_t) cpu->gprs[rm]) * ((int64_t) cpu->gprs[rs]); - int32_t dm = cpu->gprs[rd]; - int32_t dn = d; - cpu->gprs[rd] = dm + dn; - cpu->gprs[rdHi] = cpu->gprs[rdHi] + (d >> 32) + ARM_CARRY_FROM(dm, dn, cpu->gprs[rd]);, - ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]), 3) + int64_t d = ((int64_t) cpu->gprs[rm]) * ((int64_t) cpu->gprs[rs]) + ((uint32_t) cpu->gprs[rd]); + int32_t dHi = cpu->gprs[rdHi] + (d >> 32); + cpu->gprs[rd] = d; + cpu->gprs[rdHi] = dHi;, + ARM_NEUTRAL_HI_S(cpu->gprs[rd], dHi), 3) DEFINE_MULTIPLY_INSTRUCTION_2_ARM(SMULL, int64_t d = ((int64_t) cpu->gprs[rm]) * ((int64_t) cpu->gprs[rs]);

@@ -540,12 +539,11 @@ cpu->gprs[rdHi] = d >> 32;,

ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]), 2) DEFINE_MULTIPLY_INSTRUCTION_2_ARM(UMLAL, - uint64_t d = ARM_UXT_64(cpu->gprs[rm]) * ARM_UXT_64(cpu->gprs[rs]); - int32_t dm = cpu->gprs[rd]; - int32_t dn = d; - cpu->gprs[rd] = dm + dn; - cpu->gprs[rdHi] = cpu->gprs[rdHi] + (d >> 32) + ARM_CARRY_FROM(dm, dn, cpu->gprs[rd]);, - ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]), 3) + uint64_t d = ARM_UXT_64(cpu->gprs[rm]) * ARM_UXT_64(cpu->gprs[rs]) + ((uint32_t) cpu->gprs[rd]); + uint32_t dHi = ((uint32_t) cpu->gprs[rdHi]) + (d >> 32); + cpu->gprs[rd] = d; + cpu->gprs[rdHi] = dHi;, + ARM_NEUTRAL_HI_S(cpu->gprs[rd], dHi), 3) DEFINE_MULTIPLY_INSTRUCTION_2_ARM(UMULL, uint64_t d = ARM_UXT_64(cpu->gprs[rm]) * ARM_UXT_64(cpu->gprs[rs]);