diff options
author | RSDuck <rsduck@users.noreply.github.com> | 2019-07-21 17:28:16 +0200 |
---|---|---|
committer | RSDuck <rsduck@users.noreply.github.com> | 2020-04-26 13:03:10 +0200 |
commit | 4a0f6b3b4bd60815d0c8259e4ec2a944bfb716be (patch) | |
tree | 9a07ecd2ec19263e9f49c1fd9ccbd2b2d0d31f7c | |
parent | 9d180c7bbc8ccb3459ab2ab14dd2adc7a0f71cf3 (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.cpp | 2 | ||||
-rw-r--r-- | src/ARMJIT_x64/ARMJIT_ALU.cpp | 4 | ||||
-rw-r--r-- | src/ARMJIT_x64/ARMJIT_Branch.cpp | 21 | ||||
-rw-r--r-- | src/ARM_InstrInfo.cpp | 33 | ||||
-rw-r--r-- | src/ARM_InstrInfo.h | 1 |
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); |