aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRSDuck <rsduck@users.noreply.github.com>2020-07-25 22:08:43 +0200
committerRSDuck <rsduck@users.noreply.github.com>2020-07-25 22:08:43 +0200
commit887ad27ed88fa3cd12ab14a8fe1c0c5bc63f37fb (patch)
treea7b1cddbfb6cc2d9316893b678e559cd08315e95 /src
parent8b83611d32e14cab123051dc347646d9ec7caa1b (diff)
implement carry setting ALU op with imm
Diffstat (limited to 'src')
-rw-r--r--src/ARMInterpreter_ALU.cpp9
-rw-r--r--src/ARMJIT_A64/ARMJIT_ALU.cpp13
-rw-r--r--src/ARMJIT_x64/ARMJIT_ALU.cpp20
-rw-r--r--src/ARM_InstrInfo.cpp15
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)