diff options
author | RSDuck <rsduck@users.noreply.github.com> | 2020-07-25 22:08:43 +0200 |
---|---|---|
committer | RSDuck <rsduck@users.noreply.github.com> | 2020-07-25 22:08:43 +0200 |
commit | 887ad27ed88fa3cd12ab14a8fe1c0c5bc63f37fb (patch) | |
tree | a7b1cddbfb6cc2d9316893b678e559cd08315e95 /src | |
parent | 8b83611d32e14cab123051dc347646d9ec7caa1b (diff) |
implement carry setting ALU op with imm
Diffstat (limited to 'src')
-rw-r--r-- | src/ARMInterpreter_ALU.cpp | 9 | ||||
-rw-r--r-- | src/ARMJIT_A64/ARMJIT_ALU.cpp | 13 | ||||
-rw-r--r-- | src/ARMJIT_x64/ARMJIT_ALU.cpp | 20 | ||||
-rw-r--r-- | src/ARM_InstrInfo.cpp | 15 |
4 files changed, 46 insertions, 11 deletions
diff --git a/src/ARMInterpreter_ALU.cpp b/src/ARMInterpreter_ALU.cpp index 2d185b5..2095432 100644 --- a/src/ARMInterpreter_ALU.cpp +++ b/src/ARMInterpreter_ALU.cpp @@ -126,6 +126,11 @@ namespace ARMInterpreter #define A_CALC_OP2_IMM \ 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) \ u32 b = cpu->R[cpu->CurInstr&0xF]; \ 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) \ { \ - A_CALC_OP2_IMM \ + A_CALC_OP2_IMM##s \ A_##x##_S(0) \ } \ 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) \ { \ - A_CALC_OP2_IMM \ + A_CALC_OP2_IMM##s \ A_##x(0) \ } \ void A_##x##_REG_LSL_IMM(ARM* cpu) \ diff --git a/src/ARMJIT_A64/ARMJIT_ALU.cpp b/src/ARMJIT_A64/ARMJIT_ALU.cpp index 5f021a0..26a89cb 100644 --- a/src/ARMJIT_A64/ARMJIT_ALU.cpp +++ b/src/ARMJIT_A64/ARMJIT_ALU.cpp @@ -434,6 +434,19 @@ void Compiler::A_Comp_GetOp2(bool S, Op2& op2) if (CurInstr.Instr & (1 << 25)) { 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)); } else diff --git a/src/ARMJIT_x64/ARMJIT_ALU.cpp b/src/ARMJIT_x64/ARMJIT_ALU.cpp index 43b94b6..57a38c4 100644 --- a/src/ARMJIT_x64/ARMJIT_ALU.cpp +++ b/src/ARMJIT_x64/ARMJIT_ALU.cpp @@ -103,16 +103,30 @@ void Compiler::Comp_CmpOp(int op, Gen::OpArg rn, Gen::OpArg op2, bool carryUsed) // also calculates cycles OpArg Compiler::A_Comp_GetALUOp2(bool S, bool& carryUsed) { + S = S && (CurInstr.SetFlags & 0x2); + if (CurInstr.Instr & (1 << 25)) { Comp_AddCycles_C(); + + u32 shift = (CurInstr.Instr >> 7) & 0x1E; + u32 imm = ROR(CurInstr.Instr & 0xFF, shift); + 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 { - S = S && (CurInstr.SetFlags & 0x2); - int op = (CurInstr.Instr >> 5) & 0x3; if (CurInstr.Instr & (1 << 4)) { diff --git a/src/ARM_InstrInfo.cpp b/src/ARM_InstrInfo.cpp index ccec951..74a5f87 100644 --- a/src/ARM_InstrInfo.cpp +++ b/src/ARM_InstrInfo.cpp @@ -7,7 +7,7 @@ namespace ARMInstrInfo { -#define ak(x) ((x) << 22) +#define ak(x) ((x) << 23) enum { A_Read0 = 1 << 0, @@ -37,9 +37,10 @@ enum { A_RRXReadC = 1 << 17, A_StaticShiftSetC = 1 << 18, A_SetC = 1 << 19, + A_SetCImm = 1 << 20, - A_WriteMem = 1 << 20, - A_LoadMem = 1 << 21 + A_WriteMem = 1 << 21, + A_LoadMem = 1 << 22 }; #define A_BIOP A_Read16 @@ -52,7 +53,7 @@ enum { #define A_ARITH_SHIFT_REG A_SetCV #define A_LOGIC_SHIFT_REG A_SetMaybeC #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) \ 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) data = A_UNK; - res.Kind = (data >> 22) & 0x1FF; + res.Kind = (data >> 23) & 0x1FF; 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; if ((data & A_RRXReadC) && !((instr >> 7) & 0x1F)) 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; if (data & A_WriteMem) |