mirror of https://github.com/mgba-emu/mgba.git
ARM: Unify barrel shifter instructions
This commit is contained in:
parent
fff6f5890b
commit
dd053a05fe
|
@ -16,21 +16,21 @@
|
||||||
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I))
|
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I))
|
||||||
|
|
||||||
#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4) \
|
#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4) \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, EX2), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, EX2), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, EX3), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, EX3), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
|
DECLARE_INSTRUCTION_ARM(EMITTER, ALU), \
|
||||||
DECLARE_INSTRUCTION_ARM(EMITTER, EX4)
|
DECLARE_INSTRUCTION_ARM(EMITTER, EX4)
|
||||||
|
|
||||||
#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W) \
|
#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W) \
|
||||||
|
|
|
@ -9,9 +9,22 @@
|
||||||
#include <mgba/internal/arm/emitter-arm.h>
|
#include <mgba/internal/arm/emitter-arm.h>
|
||||||
#include <mgba/internal/arm/isa-inlines.h>
|
#include <mgba/internal/arm/isa-inlines.h>
|
||||||
|
|
||||||
#define ADDR_MODE_1_SHIFT(OP) \
|
#define ADDR_MODE_1_SHIFT \
|
||||||
info->op3.reg = opcode & 0x0000000F; \
|
info->op3.reg = opcode & 0x0000000F; \
|
||||||
info->op3.shifterOp = ARM_SHIFT_ ## OP; \
|
switch (opcode & 0x00000060) { \
|
||||||
|
case 0x00000000: \
|
||||||
|
info->op3.shifterOp = ARM_SHIFT_LSL; \
|
||||||
|
break; \
|
||||||
|
case 0x00000020: \
|
||||||
|
info->op3.shifterOp = ARM_SHIFT_LSR; \
|
||||||
|
break; \
|
||||||
|
case 0x00000040: \
|
||||||
|
info->op3.shifterOp = ARM_SHIFT_ASR; \
|
||||||
|
break; \
|
||||||
|
case 0x00000060: \
|
||||||
|
info->op3.shifterOp = ARM_SHIFT_ROR; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
info->operandFormat |= ARM_OPERAND_REGISTER_3; \
|
info->operandFormat |= ARM_OPERAND_REGISTER_3; \
|
||||||
if (opcode & 0x00000010) { \
|
if (opcode & 0x00000010) { \
|
||||||
info->op3.shifterReg = (opcode >> 8) & 0xF; \
|
info->op3.shifterReg = (opcode >> 8) & 0xF; \
|
||||||
|
@ -20,21 +33,14 @@
|
||||||
} else { \
|
} else { \
|
||||||
info->op3.shifterImm = (opcode >> 7) & 0x1F; \
|
info->op3.shifterImm = (opcode >> 7) & 0x1F; \
|
||||||
info->operandFormat |= ARM_OPERAND_SHIFT_IMMEDIATE_3; \
|
info->operandFormat |= ARM_OPERAND_SHIFT_IMMEDIATE_3; \
|
||||||
}
|
|
||||||
|
|
||||||
#define ADDR_MODE_1_LSL \
|
|
||||||
ADDR_MODE_1_SHIFT(LSL) \
|
|
||||||
if (!info->op3.shifterImm) { \
|
if (!info->op3.shifterImm) { \
|
||||||
|
if (info->op3.shifterOp == ARM_SHIFT_LSL) { \
|
||||||
info->operandFormat &= ~ARM_OPERAND_SHIFT_IMMEDIATE_3; \
|
info->operandFormat &= ~ARM_OPERAND_SHIFT_IMMEDIATE_3; \
|
||||||
info->op3.shifterOp = ARM_SHIFT_NONE; \
|
info->op3.shifterOp = ARM_SHIFT_NONE; \
|
||||||
}
|
} else if (info->op3.shifterOp == ARM_SHIFT_ROR) { \
|
||||||
|
|
||||||
#define ADDR_MODE_1_LSR ADDR_MODE_1_SHIFT(LSR)
|
|
||||||
#define ADDR_MODE_1_ASR ADDR_MODE_1_SHIFT(ASR)
|
|
||||||
#define ADDR_MODE_1_ROR \
|
|
||||||
ADDR_MODE_1_SHIFT(ROR) \
|
|
||||||
if (!info->op3.shifterImm) { \
|
|
||||||
info->op3.shifterOp = ARM_SHIFT_RRX; \
|
info->op3.shifterOp = ARM_SHIFT_RRX; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADDR_MODE_1_IMM \
|
#define ADDR_MODE_1_IMM \
|
||||||
|
@ -114,22 +120,13 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
#define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED) \
|
#define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED) \
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 0, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
DEFINE_ALU_DECODER_EX_ARM(NAME, NAME, 0, ADDR_MODE_1_SHIFT, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
DEFINE_ALU_DECODER_EX_ARM(NAME ## S, NAME, 1, ADDR_MODE_1_SHIFT, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 0, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 0, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 0, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 0, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 0, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED) \
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## SI, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED)
|
DEFINE_ALU_DECODER_EX_ARM(NAME ## SI, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED)
|
||||||
|
|
||||||
#define DEFINE_ALU_DECODER_S_ONLY_ARM(NAME) \
|
#define DEFINE_ALU_DECODER_S_ONLY_ARM(NAME) \
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_NONE, 1) \
|
DEFINE_ALU_DECODER_EX_ARM(NAME, NAME, 1, ADDR_MODE_1_SHIFT, ARM_OPERAND_NONE, 1) \
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_NONE, 1) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_NONE, 1) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_NONE, 1) \
|
|
||||||
DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_NONE, 1)
|
DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_NONE, 1)
|
||||||
|
|
||||||
#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED) \
|
#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED) \
|
||||||
|
|
|
@ -14,24 +14,30 @@
|
||||||
#define PSR_STATE_MASK 0x00000020
|
#define PSR_STATE_MASK 0x00000020
|
||||||
|
|
||||||
// Addressing mode 1
|
// Addressing mode 1
|
||||||
static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
|
static void _shift(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
int rm = opcode & 0x0000000F;
|
int rm = opcode & 0x0000000F;
|
||||||
|
|
||||||
if (opcode & 0x00000010) {
|
if (opcode & 0x00000010) {
|
||||||
int rs = (opcode >> 8) & 0x0000000F;
|
|
||||||
++cpu->cycles;
|
++cpu->cycles;
|
||||||
int shift = cpu->gprs[rs];
|
int rs = (opcode >> 8) & 0x0000000F;
|
||||||
|
uint8_t shift = cpu->gprs[rs];
|
||||||
if (rs == ARM_PC) {
|
if (rs == ARM_PC) {
|
||||||
shift += 4;
|
shift += 4;
|
||||||
}
|
}
|
||||||
shift &= 0xFF;
|
uint32_t shiftVal = cpu->gprs[rm];
|
||||||
int32_t shiftVal = cpu->gprs[rm];
|
|
||||||
if (rm == ARM_PC) {
|
if (rm == ARM_PC) {
|
||||||
shiftVal += 4;
|
shiftVal += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shift) {
|
if (!shift) {
|
||||||
cpu->shifterOperand = shiftVal;
|
cpu->shifterOperand = shiftVal;
|
||||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||||
} else if (shift < 32) {
|
return;
|
||||||
|
}
|
||||||
|
switch (opcode & 0x00000060) {
|
||||||
|
// LSL
|
||||||
|
case 0x00000000:
|
||||||
|
if (shift < 32) {
|
||||||
cpu->shifterOperand = shiftVal << shift;
|
cpu->shifterOperand = shiftVal << shift;
|
||||||
cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;
|
cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;
|
||||||
} else if (shift == 32) {
|
} else if (shift == 32) {
|
||||||
|
@ -41,36 +47,10 @@ static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
cpu->shifterOperand = 0;
|
cpu->shifterOperand = 0;
|
||||||
cpu->shifterCarryOut = 0;
|
cpu->shifterCarryOut = 0;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
int immediate = (opcode & 0x00000F80) >> 7;
|
// LSR
|
||||||
if (!immediate) {
|
case 0x00000020:
|
||||||
cpu->shifterOperand = cpu->gprs[rm];
|
if (shift < 32) {
|
||||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
|
||||||
} else {
|
|
||||||
cpu->shifterOperand = cpu->gprs[rm] << immediate;
|
|
||||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _shiftLSR(struct ARMCore* cpu, uint32_t opcode) {
|
|
||||||
int rm = opcode & 0x0000000F;
|
|
||||||
if (opcode & 0x00000010) {
|
|
||||||
int rs = (opcode >> 8) & 0x0000000F;
|
|
||||||
++cpu->cycles;
|
|
||||||
int shift = cpu->gprs[rs];
|
|
||||||
if (rs == ARM_PC) {
|
|
||||||
shift += 4;
|
|
||||||
}
|
|
||||||
shift &= 0xFF;
|
|
||||||
uint32_t shiftVal = cpu->gprs[rm];
|
|
||||||
if (rm == ARM_PC) {
|
|
||||||
shiftVal += 4;
|
|
||||||
}
|
|
||||||
if (!shift) {
|
|
||||||
cpu->shifterOperand = shiftVal;
|
|
||||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
|
||||||
} else if (shift < 32) {
|
|
||||||
cpu->shifterOperand = shiftVal >> shift;
|
cpu->shifterOperand = shiftVal >> shift;
|
||||||
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
||||||
} else if (shift == 32) {
|
} else if (shift == 32) {
|
||||||
|
@ -80,38 +60,12 @@ static inline void _shiftLSR(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
cpu->shifterOperand = 0;
|
cpu->shifterOperand = 0;
|
||||||
cpu->shifterCarryOut = 0;
|
cpu->shifterCarryOut = 0;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
int immediate = (opcode & 0x00000F80) >> 7;
|
// ASR
|
||||||
if (immediate) {
|
case 0x00000040:
|
||||||
cpu->shifterOperand = ((uint32_t) cpu->gprs[rm]) >> immediate;
|
if (shift < 32) {
|
||||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
cpu->shifterOperand = (int32_t) shiftVal >> shift;
|
||||||
} else {
|
cpu->shifterCarryOut = ((int32_t) shiftVal >> (shift - 1)) & 1;
|
||||||
cpu->shifterOperand = 0;
|
|
||||||
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) {
|
|
||||||
int rm = opcode & 0x0000000F;
|
|
||||||
if (opcode & 0x00000010) {
|
|
||||||
int rs = (opcode >> 8) & 0x0000000F;
|
|
||||||
++cpu->cycles;
|
|
||||||
int shift = cpu->gprs[rs];
|
|
||||||
if (rs == ARM_PC) {
|
|
||||||
shift += 4;
|
|
||||||
}
|
|
||||||
shift &= 0xFF;
|
|
||||||
int shiftVal = cpu->gprs[rm];
|
|
||||||
if (rm == ARM_PC) {
|
|
||||||
shiftVal += 4;
|
|
||||||
}
|
|
||||||
if (!shift) {
|
|
||||||
cpu->shifterOperand = shiftVal;
|
|
||||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
|
||||||
} else if (shift < 32) {
|
|
||||||
cpu->shifterOperand = shiftVal >> shift;
|
|
||||||
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
|
|
||||||
} else if (cpu->gprs[rm] >> 31) {
|
} else if (cpu->gprs[rm] >> 31) {
|
||||||
cpu->shifterOperand = 0xFFFFFFFF;
|
cpu->shifterOperand = 0xFFFFFFFF;
|
||||||
cpu->shifterCarryOut = 1;
|
cpu->shifterCarryOut = 1;
|
||||||
|
@ -119,8 +73,46 @@ static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
cpu->shifterOperand = 0;
|
cpu->shifterOperand = 0;
|
||||||
cpu->shifterCarryOut = 0;
|
cpu->shifterCarryOut = 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
// ROR
|
||||||
|
case 0x00000060:
|
||||||
|
{
|
||||||
|
int rotate = shift & 0x1F;
|
||||||
|
if (rotate) {
|
||||||
|
cpu->shifterOperand = ROR(shiftVal, rotate);
|
||||||
|
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
|
||||||
|
} else {
|
||||||
|
cpu->shifterOperand = shiftVal;
|
||||||
|
cpu->shifterCarryOut = ARM_SIGN(shiftVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int immediate = (opcode & 0x00000F80) >> 7;
|
int immediate = (opcode & 0x00000F80) >> 7;
|
||||||
|
switch (opcode & 0x00000060) {
|
||||||
|
// LSL
|
||||||
|
case 0x00000000:
|
||||||
|
if (!immediate) {
|
||||||
|
cpu->shifterOperand = cpu->gprs[rm];
|
||||||
|
cpu->shifterCarryOut = cpu->cpsr.c;
|
||||||
|
} else {
|
||||||
|
cpu->shifterOperand = cpu->gprs[rm] << immediate;
|
||||||
|
cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// LSR
|
||||||
|
case 0x00000020:
|
||||||
|
if (immediate) {
|
||||||
|
cpu->shifterOperand = ((uint32_t) cpu->gprs[rm]) >> immediate;
|
||||||
|
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||||
|
} else {
|
||||||
|
cpu->shifterOperand = 0;
|
||||||
|
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// ASR
|
||||||
|
case 0x00000040:
|
||||||
if (immediate) {
|
if (immediate) {
|
||||||
cpu->shifterOperand = cpu->gprs[rm] >> immediate;
|
cpu->shifterOperand = cpu->gprs[rm] >> immediate;
|
||||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||||
|
@ -128,36 +120,9 @@ static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
|
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
|
||||||
cpu->shifterOperand = cpu->shifterCarryOut;
|
cpu->shifterOperand = cpu->shifterCarryOut;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
}
|
// ROR
|
||||||
|
case 0x00000060:
|
||||||
static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
|
|
||||||
int rm = opcode & 0x0000000F;
|
|
||||||
if (opcode & 0x00000010) {
|
|
||||||
int rs = (opcode >> 8) & 0x0000000F;
|
|
||||||
++cpu->cycles;
|
|
||||||
int shift = cpu->gprs[rs];
|
|
||||||
if (rs == ARM_PC) {
|
|
||||||
shift += 4;
|
|
||||||
}
|
|
||||||
shift &= 0xFF;
|
|
||||||
int shiftVal = cpu->gprs[rm];
|
|
||||||
if (rm == ARM_PC) {
|
|
||||||
shiftVal += 4;
|
|
||||||
}
|
|
||||||
int rotate = shift & 0x1F;
|
|
||||||
if (!shift) {
|
|
||||||
cpu->shifterOperand = shiftVal;
|
|
||||||
cpu->shifterCarryOut = cpu->cpsr.c;
|
|
||||||
} else if (rotate) {
|
|
||||||
cpu->shifterOperand = ROR(shiftVal, rotate);
|
|
||||||
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
|
|
||||||
} else {
|
|
||||||
cpu->shifterOperand = shiftVal;
|
|
||||||
cpu->shifterCarryOut = ARM_SIGN(shiftVal);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int immediate = (opcode & 0x00000F80) >> 7;
|
|
||||||
if (immediate) {
|
if (immediate) {
|
||||||
cpu->shifterOperand = ROR(cpu->gprs[rm], immediate);
|
cpu->shifterOperand = ROR(cpu->gprs[rm], immediate);
|
||||||
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
|
||||||
|
@ -166,6 +131,8 @@ static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
|
||||||
cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
|
cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
|
||||||
cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001;
|
cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,22 +285,13 @@ ATTRIBUTE_NOINLINE static void _neutralS(struct ARMCore* cpu, int32_t d) {
|
||||||
})
|
})
|
||||||
|
|
||||||
#define DEFINE_ALU_INSTRUCTION_ARM(NAME, S_BODY, BODY) \
|
#define DEFINE_ALU_INSTRUCTION_ARM(NAME, S_BODY, BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSL, , _shiftLSL, BODY) \
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, , _shift, BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_LSL, S_BODY, _shiftLSL, BODY) \
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S, S_BODY, _shift, BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSR, , _shiftLSR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_LSR, S_BODY, _shiftLSR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ASR, , _shiftASR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_ASR, S_BODY, _shiftASR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ROR, , _shiftROR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_ROR, S_BODY, _shiftROR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, , _immediate, BODY) \
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, , _immediate, BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## SI, S_BODY, _immediate, BODY)
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## SI, S_BODY, _immediate, BODY)
|
||||||
|
|
||||||
#define DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(NAME, S_BODY, BODY) \
|
#define DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(NAME, S_BODY, BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSL, S_BODY, _shiftLSL, BODY) \
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME, S_BODY, _shift, BODY) \
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSR, S_BODY, _shiftLSR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ASR, S_BODY, _shiftASR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ROR, S_BODY, _shiftROR, BODY) \
|
|
||||||
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, S_BODY, _immediate, BODY)
|
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, S_BODY, _immediate, BODY)
|
||||||
|
|
||||||
#define DEFINE_MULTIPLY_INSTRUCTION_EX_ARM(NAME, BODY, S_BODY) \
|
#define DEFINE_MULTIPLY_INSTRUCTION_EX_ARM(NAME, BODY, S_BODY) \
|
||||||
|
|
Loading…
Reference in New Issue