implement carry setting ALU op with imm
This commit is contained in:
parent
8b83611d32
commit
887ad27ed8
|
@ -126,6 +126,11 @@ namespace ARMInterpreter
|
||||||
#define A_CALC_OP2_IMM \
|
#define A_CALC_OP2_IMM \
|
||||||
u32 b = ROR(cpu->CurInstr&0xFF, (cpu->CurInstr>>7)&0x1E);
|
u32 b = ROR(cpu->CurInstr&0xFF, (cpu->CurInstr>>7)&0x1E);
|
||||||
|
|
||||||
|
#define A_CALC_OP2_IMM_S \
|
||||||
|
u32 b = ROR(cpu->CurInstr&0xFF, (cpu->CurInstr>>7)&0x1E); \
|
||||||
|
if ((cpu->CurInstr>>7)&0x1E) \
|
||||||
|
cpu->SetC(b & 0x80000000);
|
||||||
|
|
||||||
#define A_CALC_OP2_REG_SHIFT_IMM(shiftop) \
|
#define A_CALC_OP2_REG_SHIFT_IMM(shiftop) \
|
||||||
u32 b = cpu->R[cpu->CurInstr&0xF]; \
|
u32 b = cpu->R[cpu->CurInstr&0xF]; \
|
||||||
u32 s = (cpu->CurInstr>>7)&0x1F; \
|
u32 s = (cpu->CurInstr>>7)&0x1F; \
|
||||||
|
@ -186,7 +191,7 @@ void A_##x##_REG_ROR_REG(ARM* cpu) \
|
||||||
} \
|
} \
|
||||||
void A_##x##_IMM_S(ARM* cpu) \
|
void A_##x##_IMM_S(ARM* cpu) \
|
||||||
{ \
|
{ \
|
||||||
A_CALC_OP2_IMM \
|
A_CALC_OP2_IMM##s \
|
||||||
A_##x##_S(0) \
|
A_##x##_S(0) \
|
||||||
} \
|
} \
|
||||||
void A_##x##_REG_LSL_IMM_S(ARM* cpu) \
|
void A_##x##_REG_LSL_IMM_S(ARM* cpu) \
|
||||||
|
@ -234,7 +239,7 @@ void A_##x##_REG_ROR_REG_S(ARM* cpu) \
|
||||||
\
|
\
|
||||||
void A_##x##_IMM(ARM* cpu) \
|
void A_##x##_IMM(ARM* cpu) \
|
||||||
{ \
|
{ \
|
||||||
A_CALC_OP2_IMM \
|
A_CALC_OP2_IMM##s \
|
||||||
A_##x(0) \
|
A_##x(0) \
|
||||||
} \
|
} \
|
||||||
void A_##x##_REG_LSL_IMM(ARM* cpu) \
|
void A_##x##_REG_LSL_IMM(ARM* cpu) \
|
||||||
|
|
|
@ -434,6 +434,19 @@ void Compiler::A_Comp_GetOp2(bool S, Op2& op2)
|
||||||
if (CurInstr.Instr & (1 << 25))
|
if (CurInstr.Instr & (1 << 25))
|
||||||
{
|
{
|
||||||
Comp_AddCycles_C();
|
Comp_AddCycles_C();
|
||||||
|
|
||||||
|
u32 shift = (CurInstr.Instr >> 7) & 0x1E;
|
||||||
|
u32 imm = ROR(CurInstr.Instr & 0xFF, shift);
|
||||||
|
|
||||||
|
if (S && shift && (CurInstr.SetFlags & 0x2))
|
||||||
|
{
|
||||||
|
CPSRDirty = true;
|
||||||
|
if (imm & 0x80000000)
|
||||||
|
ORRI2R(RCPSR, RCPSR, 1 << 29);
|
||||||
|
else
|
||||||
|
ANDI2R(RCPSR, RCPSR, ~(1 << 29));
|
||||||
|
}
|
||||||
|
|
||||||
op2 = Op2(ROR(CurInstr.Instr & 0xFF, (CurInstr.Instr >> 7) & 0x1E));
|
op2 = Op2(ROR(CurInstr.Instr & 0xFF, (CurInstr.Instr >> 7) & 0x1E));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -103,16 +103,30 @@ void Compiler::Comp_CmpOp(int op, Gen::OpArg rn, Gen::OpArg op2, bool carryUsed)
|
||||||
// also calculates cycles
|
// also calculates cycles
|
||||||
OpArg Compiler::A_Comp_GetALUOp2(bool S, bool& carryUsed)
|
OpArg Compiler::A_Comp_GetALUOp2(bool S, bool& carryUsed)
|
||||||
{
|
{
|
||||||
|
S = S && (CurInstr.SetFlags & 0x2);
|
||||||
|
|
||||||
if (CurInstr.Instr & (1 << 25))
|
if (CurInstr.Instr & (1 << 25))
|
||||||
{
|
{
|
||||||
Comp_AddCycles_C();
|
Comp_AddCycles_C();
|
||||||
|
|
||||||
|
u32 shift = (CurInstr.Instr >> 7) & 0x1E;
|
||||||
|
u32 imm = ROR(CurInstr.Instr & 0xFF, shift);
|
||||||
|
|
||||||
carryUsed = false;
|
carryUsed = false;
|
||||||
return Imm32(ROR(CurInstr.Instr & 0xFF, (CurInstr.Instr >> 7) & 0x1E));
|
if (S && shift)
|
||||||
|
{
|
||||||
|
CPSRDirty = true;
|
||||||
|
carryUsed = true;
|
||||||
|
if (imm & 0x80000000)
|
||||||
|
MOV(32, R(RSCRATCH2), Imm32(1));
|
||||||
|
else
|
||||||
|
XOR(32, R(RSCRATCH2), R(RSCRATCH2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Imm32(imm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
S = S && (CurInstr.SetFlags & 0x2);
|
|
||||||
|
|
||||||
int op = (CurInstr.Instr >> 5) & 0x3;
|
int op = (CurInstr.Instr >> 5) & 0x3;
|
||||||
if (CurInstr.Instr & (1 << 4))
|
if (CurInstr.Instr & (1 << 4))
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace ARMInstrInfo
|
namespace ARMInstrInfo
|
||||||
{
|
{
|
||||||
|
|
||||||
#define ak(x) ((x) << 22)
|
#define ak(x) ((x) << 23)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
A_Read0 = 1 << 0,
|
A_Read0 = 1 << 0,
|
||||||
|
@ -37,9 +37,10 @@ enum {
|
||||||
A_RRXReadC = 1 << 17,
|
A_RRXReadC = 1 << 17,
|
||||||
A_StaticShiftSetC = 1 << 18,
|
A_StaticShiftSetC = 1 << 18,
|
||||||
A_SetC = 1 << 19,
|
A_SetC = 1 << 19,
|
||||||
|
A_SetCImm = 1 << 20,
|
||||||
|
|
||||||
A_WriteMem = 1 << 20,
|
A_WriteMem = 1 << 21,
|
||||||
A_LoadMem = 1 << 21
|
A_LoadMem = 1 << 22
|
||||||
};
|
};
|
||||||
|
|
||||||
#define A_BIOP A_Read16
|
#define A_BIOP A_Read16
|
||||||
|
@ -52,7 +53,7 @@ enum {
|
||||||
#define A_ARITH_SHIFT_REG A_SetCV
|
#define A_ARITH_SHIFT_REG A_SetCV
|
||||||
#define A_LOGIC_SHIFT_REG A_SetMaybeC
|
#define A_LOGIC_SHIFT_REG A_SetMaybeC
|
||||||
#define A_ARITH_IMM A_SetCV
|
#define A_ARITH_IMM A_SetCV
|
||||||
#define A_LOGIC_IMM 0
|
#define A_LOGIC_IMM A_SetCImm
|
||||||
|
|
||||||
#define A_IMPLEMENT_ALU_OP(x,k,a,c) \
|
#define A_IMPLEMENT_ALU_OP(x,k,a,c) \
|
||||||
const u32 A_##x##_IMM = A_Write12 | c | A_##k | ak(ak_##x##_IMM); \
|
const u32 A_##x##_IMM = A_Write12 | c | A_##k | ak(ak_##x##_IMM); \
|
||||||
|
@ -410,7 +411,7 @@ Info Decode(bool thumb, u32 num, u32 instr)
|
||||||
if (data & A_UnkOnARM7 && num == 1)
|
if (data & A_UnkOnARM7 && num == 1)
|
||||||
data = A_UNK;
|
data = A_UNK;
|
||||||
|
|
||||||
res.Kind = (data >> 22) & 0x1FF;
|
res.Kind = (data >> 23) & 0x1FF;
|
||||||
|
|
||||||
if (res.Kind >= ak_SMLAxy && res.Kind <= ak_SMULxy && num == 1)
|
if (res.Kind >= ak_SMLAxy && res.Kind <= ak_SMULxy && num == 1)
|
||||||
{
|
{
|
||||||
|
@ -496,7 +497,9 @@ Info Decode(bool thumb, u32 num, u32 instr)
|
||||||
res.ReadFlags |= flag_C;
|
res.ReadFlags |= flag_C;
|
||||||
if ((data & A_RRXReadC) && !((instr >> 7) & 0x1F))
|
if ((data & A_RRXReadC) && !((instr >> 7) & 0x1F))
|
||||||
res.ReadFlags |= flag_C;
|
res.ReadFlags |= flag_C;
|
||||||
if ((data & A_SetC) || ((data & A_StaticShiftSetC) && ((instr >> 7) & 0x1F)))
|
if ((data & A_SetC)
|
||||||
|
|| ((data & A_StaticShiftSetC) && ((instr >> 7) & 0x1F))
|
||||||
|
|| ((data & A_SetCImm) && ((instr >> 7) & 0x1E)))
|
||||||
res.WriteFlags |= flag_C;
|
res.WriteFlags |= flag_C;
|
||||||
|
|
||||||
if (data & A_WriteMem)
|
if (data & A_WriteMem)
|
||||||
|
|
Loading…
Reference in New Issue