ARM9: Implemented SMLAW<y> and SMULW<y> (#609)
Gericom fnouwt2@gmail.com
Tue, 11 Apr 2017 22:39:43 +0200
6 files changed,
38 insertions(+),
8 deletions(-)
M
CHANGES
→
CHANGES
@@ -12,6 +12,7 @@ - DS GX: Reset polygon attributes between buffer swaps
Misc: - DS: Set boot complete bit in RAM on boot (fixes mgba.io/i/576, mgba.io/i/580, mgba.io/i/586) - DS Memory: Ensure DS9 I/O is 8-byte aligned + - ARM9: Implement SMLAW and SMULW - Qt: Add .nds files to the extension list in Info.plist 0.6.0: (Future)
M
include/mgba/internal/arm/decoder.h
→
include/mgba/internal/arm/decoder.h
@@ -190,14 +190,18 @@ ARM_MN_RSC,
ARM_MN_SBC, ARM_MN_SMLABB, ARM_MN_SMLABT, + ARM_MN_SMLAL, ARM_MN_SMLATB, ARM_MN_SMLATT, + ARM_MN_SMLAWB, + ARM_MN_SMLAWT, ARM_MN_SMULBB, ARM_MN_SMULBT, + ARM_MN_SMULL, ARM_MN_SMULTB, ARM_MN_SMULTT, - ARM_MN_SMLAL, - ARM_MN_SMULL, + ARM_MN_SMULWB, + ARM_MN_SMULWT, ARM_MN_STC, ARM_MN_STM, ARM_MN_STR,
M
include/mgba/internal/arm/emitter-arm.h
→
include/mgba/internal/arm/emitter-arm.h
@@ -143,13 +143,13 @@ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMLAWB), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMULWB), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \ DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMLAWT), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ + MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMULWT), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \ DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \ DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \ DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \
M
src/arm/decoder-arm.c
→
src/arm/decoder-arm.c
@@ -320,6 +320,11 @@ DEFINE_MULTIPLY_DECODER_EX_ARM(SMULBT, SMULBT, 0, 0)
DEFINE_MULTIPLY_DECODER_EX_ARM(SMULTB, SMULTB, 0, 0) DEFINE_MULTIPLY_DECODER_EX_ARM(SMULTT, SMULTT, 0, 0) +DEFINE_MULTIPLY_DECODER_EX_ARM(SMLAWB, SMLAWB, 0, ARM_OPERAND_REGISTER_4) +DEFINE_MULTIPLY_DECODER_EX_ARM(SMLAWT, SMLAWT, 0, ARM_OPERAND_REGISTER_4) +DEFINE_MULTIPLY_DECODER_EX_ARM(SMULWB, SMULWB, 0, 0) +DEFINE_MULTIPLY_DECODER_EX_ARM(SMULWT, SMULWT, 0, 0) + // Begin load/store definitions DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD)
M
src/arm/decoder.c
→
src/arm/decoder.c
@@ -278,14 +278,18 @@ "rsc",
"sbc", "smlabb", "smlabt", + "smlal", "smlatb", "smlatt", + "smlawb", + "smlawt", "smulbb", "smulbt", + "smull", "smultb", "smultt", - "smlal", - "smull", + "smulwb", + "smulwt", "stc", "stm", "str",
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -401,6 +401,14 @@ x = ARM_SXT_16(cpu->gprs[rm] >> 16); \
y = ARM_SXT_16(cpu->gprs[rs] >> 16); \ BODY) +#define DEFINE_MULTIPLY_INSTRUCTION_WY_ARM(NAME, BODY) \ + DEFINE_MULTIPLY_INSTRUCTION_3_ARM(NAME ## B, \ + y = ARM_SXT_16(cpu->gprs[rs]); \ + BODY) \ + DEFINE_MULTIPLY_INSTRUCTION_3_ARM(NAME ## T, \ + y = ARM_SXT_16(cpu->gprs[rs] >> 16); \ + BODY) \ + #define DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, BODY) \ DEFINE_INSTRUCTION_ARM(NAME, \ uint32_t address; \@@ -575,6 +583,14 @@ cpu->gprs[rd] = d + dn; \
cpu->cpsr.q = cpu->cpsr.q || ARM_V_ADDITION(d, dn, cpu->gprs[rd]);) DEFINE_MULTIPLY_INSTRUCTION_XY_ARM(SMUL, cpu->gprs[rd] = x * y;) + +DEFINE_MULTIPLY_INSTRUCTION_WY_ARM(SMLAW, + int32_t dn = cpu->gprs[rn]; \ + int32_t d = (((int64_t) cpu->gprs[rm]) * ((int64_t) y)) >> 16; \ + cpu->gprs[rd] = d + dn; \ + cpu->cpsr.q = cpu->cpsr.q || ARM_V_ADDITION(d, dn, cpu->gprs[rd]);) + +DEFINE_MULTIPLY_INSTRUCTION_WY_ARM(SMULW, cpu->gprs[rd] = (((int64_t) cpu->gprs[rm]) * ((int64_t) y)) >> 16;) DEFINE_MULTIPLY_INSTRUCTION_2_ARM(SMULL, int64_t d = ((int64_t) cpu->gprs[rm]) * ((int64_t) cpu->gprs[rs]);