aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRSDuck <rsduck@users.noreply.github.com>2019-07-21 17:28:16 +0200
committerRSDuck <rsduck@users.noreply.github.com>2020-04-26 13:03:10 +0200
commit4a0f6b3b4bd60815d0c8259e4ec2a944bfb716be (patch)
tree9a07ecd2ec19263e9f49c1fd9ccbd2b2d0d31f7c
parent9d180c7bbc8ccb3459ab2ab14dd2adc7a0f71cf3 (diff)
jit: fix thumb hi reg alu and mcr halt
+ mcr/mrc aren't always, msr_imm is never unk on ARM7
-rw-r--r--src/ARMJIT.cpp2
-rw-r--r--src/ARMJIT_x64/ARMJIT_ALU.cpp4
-rw-r--r--src/ARMJIT_x64/ARMJIT_Branch.cpp21
-rw-r--r--src/ARM_InstrInfo.cpp33
-rw-r--r--src/ARM_InstrInfo.h1
5 files changed, 45 insertions, 16 deletions
diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp
index aad14c0..6948eee 100644
--- a/src/ARMJIT.cpp
+++ b/src/ARMJIT.cpp
@@ -174,7 +174,7 @@ CompiledBlock CompileBlock(ARM* cpu)
instrs[i].Info = ARMInstrInfo::Decode(thumb, cpu->Num, instrs[i].Instr);
i++;
- } while(!instrs[i - 1].Info.Branches() && i < Config::JIT_MaxBlockSize);
+ } while(!instrs[i - 1].Info.EndBlock && i < Config::JIT_MaxBlockSize);
CompiledBlock block = compiler->CompileBlock(cpu, instrs, i);
diff --git a/src/ARMJIT_x64/ARMJIT_ALU.cpp b/src/ARMJIT_x64/ARMJIT_ALU.cpp
index 013f54c..bdf06f7 100644
--- a/src/ARMJIT_x64/ARMJIT_ALU.cpp
+++ b/src/ARMJIT_x64/ARMJIT_ALU.cpp
@@ -663,7 +663,7 @@ void Compiler::T_Comp_ALU_HiReg()
switch (op)
{
case 0x0: // ADD
- Comp_ArithTriOp(&Compiler::ADD, rdMapped, rdMapped, rs, false, opSymmetric|opRetriveCV);
+ Comp_ArithTriOp(&Compiler::ADD, rdMapped, rdMapped, rs, false, opSymmetric);
break;
case 0x1: // CMP
Comp_CmpOp(2, rdMapped, rs, false);
@@ -671,8 +671,6 @@ void Compiler::T_Comp_ALU_HiReg()
case 0x2: // MOV
if (rdMapped != rs)
MOV(32, rdMapped, rs);
- TEST(32, rdMapped, rdMapped);
- Comp_RetriveFlags(false, false, false);
break;
}
diff --git a/src/ARMJIT_x64/ARMJIT_Branch.cpp b/src/ARMJIT_x64/ARMJIT_Branch.cpp
index 6ae4aad..9d4c1e2 100644
--- a/src/ARMJIT_x64/ARMJIT_Branch.cpp
+++ b/src/ARMJIT_x64/ARMJIT_Branch.cpp
@@ -235,16 +235,23 @@ void Compiler::T_Comp_B()
void Compiler::T_Comp_BranchXchangeReg()
{
bool link = CurInstr.Instr & (1 << 7);
- if (link && Num == 1)
- {
- printf("BLX unsupported on ARM7!!!\n");
- return;
- }
- OpArg rn = MapReg(CurInstr.A_Reg(3));
if (link)
+ {
+ if (Num == 1)
+ {
+ printf("BLX unsupported on ARM7!!!\n");
+ return;
+ }
+ MOV(32, R(RSCRATCH), MapReg(CurInstr.A_Reg(3)));
MOV(32, MapReg(14), Imm32(R15 - 1));
- Comp_JumpTo(rn.GetSimpleReg());
+ Comp_JumpTo(RSCRATCH);
+ }
+ else
+ {
+ OpArg rn = MapReg(CurInstr.A_Reg(3));
+ Comp_JumpTo(rn.GetSimpleReg());
+ }
}
void Compiler::T_Comp_BL_LONG_1()
diff --git a/src/ARM_InstrInfo.cpp b/src/ARM_InstrInfo.cpp
index 5db2471..b70c8dc 100644
--- a/src/ARM_InstrInfo.cpp
+++ b/src/ARM_InstrInfo.cpp
@@ -152,11 +152,11 @@ const u32 A_BX = A_BranchAlways | A_Read0 | ak(ak_BX);
const u32 A_BLX_REG = A_BranchAlways | A_Link | A_Read0 | ak(ak_BLX_REG);
const u32 A_UNK = A_BranchAlways | A_Link | ak(ak_UNK);
-const u32 A_MSR_IMM = A_UnkOnARM7 | ak(ak_MSR_IMM);
-const u32 A_MSR_REG = A_Read0 | A_UnkOnARM7 | ak(ak_MSR_REG);
-const u32 A_MRS = A_Write12 | A_UnkOnARM7 | ak(ak_MRS);
-const u32 A_MCR = A_Read12 | A_UnkOnARM7 | ak(ak_MCR);
-const u32 A_MRC = A_Write12 | A_UnkOnARM7 | ak(ak_MRC);
+const u32 A_MSR_IMM = ak(ak_MSR_IMM);
+const u32 A_MSR_REG = A_Read0 | ak(ak_MSR_REG);
+const u32 A_MRS = A_Write12 | ak(ak_MRS);
+const u32 A_MCR = A_Read12 | ak(ak_MCR);
+const u32 A_MRC = A_Write12 | ak(ak_MRC);
const u32 A_SVC = A_BranchAlways | A_Link | ak(ak_SVC);
// THUMB
@@ -310,6 +310,7 @@ Info Decode(bool thumb, u32 num, u32 instr)
res.DstRegs |= 1 << 15;
res.Kind = (data >> 16) & 0x3F;
+ res.EndBlock = res.Branches();
return res;
}
@@ -324,6 +325,26 @@ Info Decode(bool thumb, u32 num, u32 instr)
res.Kind = (data >> 13) & 0x1FF;
+ if (res.Kind == ak_MCR)
+ {
+ u32 cn = (instr >> 16) & 0xF;
+ u32 cm = instr & 0xF;
+ u32 cpinfo = (instr >> 5) & 0x7;
+ u32 id = (cn<<8)|(cm<<4)|cpinfo;
+ if (id == 0x704 || id == 0x782)
+ res.EndBlock |= true;
+ }
+ if (res.Kind == ak_MCR || res.Kind == ak_MRC)
+ {
+ u32 cp = ((instr >> 8) & 0xF);
+ if ((num == 0 && cp != 15) || (num == 1 && cp != 14))
+ {
+ printf("happens\n");
+ data = A_UNK;
+ res.Kind = ak_UNK;
+ }
+ }
+
if (data & A_Read0)
res.SrcRegs |= 1 << (instr & 0xF);
if (data & A_Read16)
@@ -361,6 +382,8 @@ Info Decode(bool thumb, u32 num, u32 instr)
if (res.Kind == ak_LDM)
res.DstRegs |= instr & (1 << 15); // this is right
+ res.EndBlock |= res.Branches();
+
return res;
}
}
diff --git a/src/ARM_InstrInfo.h b/src/ARM_InstrInfo.h
index 51dcfa2..4fe9b10 100644
--- a/src/ARM_InstrInfo.h
+++ b/src/ARM_InstrInfo.h
@@ -220,6 +220,7 @@ struct Info
u16 DstRegs, SrcRegs;
u16 Kind;
+ bool EndBlock;
bool Branches()
{
return DstRegs & (1 << 15);