mirror of https://github.com/mgba-emu/mgba.git
ARM9: Implement SMUL<x><y>
This commit is contained in:
parent
4778dc41c8
commit
3f27b09ec1
|
@ -192,6 +192,10 @@ enum ARMMnemonic {
|
||||||
ARM_MN_SMLABT,
|
ARM_MN_SMLABT,
|
||||||
ARM_MN_SMLATB,
|
ARM_MN_SMLATB,
|
||||||
ARM_MN_SMLATT,
|
ARM_MN_SMLATT,
|
||||||
|
ARM_MN_SMULBB,
|
||||||
|
ARM_MN_SMULBT,
|
||||||
|
ARM_MN_SMULTB,
|
||||||
|
ARM_MN_SMULTT,
|
||||||
ARM_MN_SMLAL,
|
ARM_MN_SMLAL,
|
||||||
ARM_MN_SMULL,
|
ARM_MN_SMULL,
|
||||||
ARM_MN_STC,
|
ARM_MN_STC,
|
||||||
|
|
|
@ -155,13 +155,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, ILL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
||||||
|
MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMULBB), 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, SMULTB), DECLARE_INSTRUCTION_ARM(EMITTER, ILL), V >= 5), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
|
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \
|
||||||
|
MIN_V(DECLARE_INSTRUCTION_ARM(EMITTER, SMULBT), 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, SMULTT), 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, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \
|
DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \
|
||||||
DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \
|
DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \
|
||||||
|
|
|
@ -315,6 +315,10 @@ DEFINE_MULTIPLY_DECODER_EX_ARM(SMLABB, SMLABB, 0, ARM_OPERAND_REGISTER_4)
|
||||||
DEFINE_MULTIPLY_DECODER_EX_ARM(SMLABT, SMLABT, 0, ARM_OPERAND_REGISTER_4)
|
DEFINE_MULTIPLY_DECODER_EX_ARM(SMLABT, SMLABT, 0, ARM_OPERAND_REGISTER_4)
|
||||||
DEFINE_MULTIPLY_DECODER_EX_ARM(SMLATB, SMLATB, 0, ARM_OPERAND_REGISTER_4)
|
DEFINE_MULTIPLY_DECODER_EX_ARM(SMLATB, SMLATB, 0, ARM_OPERAND_REGISTER_4)
|
||||||
DEFINE_MULTIPLY_DECODER_EX_ARM(SMLATT, SMLATT, 0, ARM_OPERAND_REGISTER_4)
|
DEFINE_MULTIPLY_DECODER_EX_ARM(SMLATT, SMLATT, 0, ARM_OPERAND_REGISTER_4)
|
||||||
|
DEFINE_MULTIPLY_DECODER_EX_ARM(SMULBB, SMULBB, 0, 0)
|
||||||
|
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)
|
||||||
|
|
||||||
// Begin load/store definitions
|
// Begin load/store definitions
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,10 @@ static const char* _armMnemonicStrings[] = {
|
||||||
"smlabt",
|
"smlabt",
|
||||||
"smlatb",
|
"smlatb",
|
||||||
"smlatt",
|
"smlatt",
|
||||||
|
"smulbb",
|
||||||
|
"smulbt",
|
||||||
|
"smultb",
|
||||||
|
"smultt",
|
||||||
"smlal",
|
"smlal",
|
||||||
"smull",
|
"smull",
|
||||||
"stc",
|
"stc",
|
||||||
|
|
|
@ -361,6 +361,7 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
int rs = (opcode >> 8) & 0xF; \
|
int rs = (opcode >> 8) & 0xF; \
|
||||||
int rn = (opcode >> 12) & 0xF; \
|
int rn = (opcode >> 12) & 0xF; \
|
||||||
int rm = opcode & 0xF; \
|
int rm = opcode & 0xF; \
|
||||||
|
UNUSED(rn); \
|
||||||
if (rd == ARM_PC) { \
|
if (rd == ARM_PC) { \
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
|
@ -368,12 +369,26 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
int32_t x; \
|
int32_t x; \
|
||||||
int32_t y; \
|
int32_t y; \
|
||||||
BODY; \
|
BODY; \
|
||||||
int32_t dn = cpu->gprs[rn]; \
|
|
||||||
int32_t d = x * y; \
|
|
||||||
cpu->gprs[rd] = d + dn; \
|
|
||||||
cpu->cpsr.q = cpu->cpsr.q || ARM_V_ADDITION(d, dn, cpu->gprs[rd]); \
|
|
||||||
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32)
|
currentCycles += cpu->memory.activeNonseqCycles32 - cpu->memory.activeSeqCycles32)
|
||||||
|
|
||||||
|
#define DEFINE_MULTIPLY_INSTRUCTION_XY_ARM(NAME, BODY) \
|
||||||
|
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(NAME ## BB, \
|
||||||
|
x = ARM_SXT_16(cpu->gprs[rm]); \
|
||||||
|
y = ARM_SXT_16(cpu->gprs[rs]); \
|
||||||
|
BODY) \
|
||||||
|
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(NAME ## BT, \
|
||||||
|
x = ARM_SXT_16(cpu->gprs[rm]); \
|
||||||
|
y = ARM_SXT_16(cpu->gprs[rs] >> 16); \
|
||||||
|
BODY) \
|
||||||
|
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(NAME ## TB, \
|
||||||
|
x = ARM_SXT_16(cpu->gprs[rm] >> 16); \
|
||||||
|
y = ARM_SXT_16(cpu->gprs[rs]); \
|
||||||
|
BODY) \
|
||||||
|
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(NAME ## TT, \
|
||||||
|
x = ARM_SXT_16(cpu->gprs[rm] >> 16); \
|
||||||
|
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; \
|
||||||
|
@ -541,21 +556,13 @@ DEFINE_MULTIPLY_INSTRUCTION_2_ARM(SMLAL,
|
||||||
cpu->gprs[rdHi] = cpu->gprs[rdHi] + (d >> 32) + ARM_CARRY_FROM(dm, dn, cpu->gprs[rd]);,
|
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)
|
ARM_NEUTRAL_HI_S(cpu->gprs[rd], cpu->gprs[rdHi]), 3)
|
||||||
|
|
||||||
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(SMLABB,
|
DEFINE_MULTIPLY_INSTRUCTION_XY_ARM(SMLA,
|
||||||
x = ARM_SXT_16(cpu->gprs[rm]);
|
int32_t dn = cpu->gprs[rn]; \
|
||||||
y = ARM_SXT_16(cpu->gprs[rs]);)
|
int32_t d = x * y; \
|
||||||
|
cpu->gprs[rd] = d + dn; \
|
||||||
|
cpu->cpsr.q = cpu->cpsr.q || ARM_V_ADDITION(d, dn, cpu->gprs[rd]);)
|
||||||
|
|
||||||
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(SMLABT,
|
DEFINE_MULTIPLY_INSTRUCTION_XY_ARM(SMUL, cpu->gprs[rd] = x * y;)
|
||||||
x = ARM_SXT_16(cpu->gprs[rm]);
|
|
||||||
y = ARM_SXT_16(cpu->gprs[rs] >> 16);)
|
|
||||||
|
|
||||||
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(SMLATB,
|
|
||||||
x = ARM_SXT_16(cpu->gprs[rm] >> 16);
|
|
||||||
y = ARM_SXT_16(cpu->gprs[rs]);)
|
|
||||||
|
|
||||||
DEFINE_MULTIPLY_INSTRUCTION_3_ARM(SMLATT,
|
|
||||||
x = ARM_SXT_16(cpu->gprs[rm] >> 16);
|
|
||||||
y = ARM_SXT_16(cpu->gprs[rs] >> 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]);
|
||||||
|
|
Loading…
Reference in New Issue