mirror of https://github.com/mgba-emu/mgba.git
ARM9: Implemented SMLAW<y> and SMULW<y> (#609)
This commit is contained in:
parent
1cab37cac2
commit
5108ebefa2
1
CHANGES
1
CHANGES
|
@ -12,6 +12,7 @@ Bugfixes:
|
||||||
Misc:
|
Misc:
|
||||||
- DS: Set boot complete bit in RAM on boot (fixes mgba.io/i/576, mgba.io/i/580, mgba.io/i/586)
|
- 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
|
- 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
|
- Qt: Add .nds files to the extension list in Info.plist
|
||||||
|
|
||||||
0.6.0: (Future)
|
0.6.0: (Future)
|
||||||
|
|
|
@ -190,14 +190,18 @@ enum ARMMnemonic {
|
||||||
ARM_MN_SBC,
|
ARM_MN_SBC,
|
||||||
ARM_MN_SMLABB,
|
ARM_MN_SMLABB,
|
||||||
ARM_MN_SMLABT,
|
ARM_MN_SMLABT,
|
||||||
|
ARM_MN_SMLAL,
|
||||||
ARM_MN_SMLATB,
|
ARM_MN_SMLATB,
|
||||||
ARM_MN_SMLATT,
|
ARM_MN_SMLATT,
|
||||||
|
ARM_MN_SMLAWB,
|
||||||
|
ARM_MN_SMLAWT,
|
||||||
ARM_MN_SMULBB,
|
ARM_MN_SMULBB,
|
||||||
ARM_MN_SMULBT,
|
ARM_MN_SMULBT,
|
||||||
|
ARM_MN_SMULL,
|
||||||
ARM_MN_SMULTB,
|
ARM_MN_SMULTB,
|
||||||
ARM_MN_SMULTT,
|
ARM_MN_SMULTT,
|
||||||
ARM_MN_SMLAL,
|
ARM_MN_SMULWB,
|
||||||
ARM_MN_SMULL,
|
ARM_MN_SMULWT,
|
||||||
ARM_MN_STC,
|
ARM_MN_STC,
|
||||||
ARM_MN_STM,
|
ARM_MN_STM,
|
||||||
ARM_MN_STR,
|
ARM_MN_STR,
|
||||||
|
|
|
@ -143,13 +143,13 @@
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \
|
||||||
|
MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMLAWB), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMULWB), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \
|
||||||
|
MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMLAWT), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
||||||
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_INSTRUCTION_ARM(EMITTER, ILL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
||||||
DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \
|
DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \
|
||||||
|
|
|
@ -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(SMULTB, SMULTB, 0, 0)
|
||||||
DEFINE_MULTIPLY_DECODER_EX_ARM(SMULTT, SMULTT, 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
|
// Begin load/store definitions
|
||||||
|
|
||||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD)
|
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD)
|
||||||
|
|
|
@ -278,14 +278,18 @@ static const char* _armMnemonicStrings[] = {
|
||||||
"sbc",
|
"sbc",
|
||||||
"smlabb",
|
"smlabb",
|
||||||
"smlabt",
|
"smlabt",
|
||||||
|
"smlal",
|
||||||
"smlatb",
|
"smlatb",
|
||||||
"smlatt",
|
"smlatt",
|
||||||
|
"smlawb",
|
||||||
|
"smlawt",
|
||||||
"smulbb",
|
"smulbb",
|
||||||
"smulbt",
|
"smulbt",
|
||||||
|
"smull",
|
||||||
"smultb",
|
"smultb",
|
||||||
"smultt",
|
"smultt",
|
||||||
"smlal",
|
"smulwb",
|
||||||
"smull",
|
"smulwt",
|
||||||
"stc",
|
"stc",
|
||||||
"stm",
|
"stm",
|
||||||
"str",
|
"str",
|
||||||
|
|
|
@ -401,6 +401,14 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
y = ARM_SXT_16(cpu->gprs[rs] >> 16); \
|
y = ARM_SXT_16(cpu->gprs[rs] >> 16); \
|
||||||
BODY)
|
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 DEFINE_LOAD_STORE_INSTRUCTION_EX_ARM(NAME, ADDRESS, WRITEBACK, BODY) \
|
||||||
DEFINE_INSTRUCTION_ARM(NAME, \
|
DEFINE_INSTRUCTION_ARM(NAME, \
|
||||||
uint32_t address; \
|
uint32_t address; \
|
||||||
|
@ -576,6 +584,14 @@ DEFINE_MULTIPLY_INSTRUCTION_XY_ARM(SMLA,
|
||||||
|
|
||||||
DEFINE_MULTIPLY_INSTRUCTION_XY_ARM(SMUL, cpu->gprs[rd] = x * y;)
|
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,
|
DEFINE_MULTIPLY_INSTRUCTION_2_ARM(SMULL,
|
||||||
int64_t d = ((int64_t) cpu->gprs[rm]) * ((int64_t) cpu->gprs[rs]);
|
int64_t d = ((int64_t) cpu->gprs[rm]) * ((int64_t) cpu->gprs[rs]);
|
||||||
cpu->gprs[rd] = d;
|
cpu->gprs[rd] = d;
|
||||||
|
|
Loading…
Reference in New Issue