jit: fix thumb hi reg alu and mcr halt

+ mcr/mrc aren't always, msr_imm is never unk on ARM7
This commit is contained in:
RSDuck 2019-07-21 17:28:16 +02:00
parent 9d180c7bbc
commit 4a0f6b3b4b
5 changed files with 45 additions and 16 deletions

View File

@ -174,7 +174,7 @@ CompiledBlock CompileBlock(ARM* cpu)
instrs[i].Info = ARMInstrInfo::Decode(thumb, cpu->Num, instrs[i].Instr); instrs[i].Info = ARMInstrInfo::Decode(thumb, cpu->Num, instrs[i].Instr);
i++; 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); CompiledBlock block = compiler->CompileBlock(cpu, instrs, i);

View File

@ -663,7 +663,7 @@ void Compiler::T_Comp_ALU_HiReg()
switch (op) switch (op)
{ {
case 0x0: // ADD case 0x0: // ADD
Comp_ArithTriOp(&Compiler::ADD, rdMapped, rdMapped, rs, false, opSymmetric|opRetriveCV); Comp_ArithTriOp(&Compiler::ADD, rdMapped, rdMapped, rs, false, opSymmetric);
break; break;
case 0x1: // CMP case 0x1: // CMP
Comp_CmpOp(2, rdMapped, rs, false); Comp_CmpOp(2, rdMapped, rs, false);
@ -671,8 +671,6 @@ void Compiler::T_Comp_ALU_HiReg()
case 0x2: // MOV case 0x2: // MOV
if (rdMapped != rs) if (rdMapped != rs)
MOV(32, rdMapped, rs); MOV(32, rdMapped, rs);
TEST(32, rdMapped, rdMapped);
Comp_RetriveFlags(false, false, false);
break; break;
} }

View File

@ -235,17 +235,24 @@ void Compiler::T_Comp_B()
void Compiler::T_Comp_BranchXchangeReg() void Compiler::T_Comp_BranchXchangeReg()
{ {
bool link = CurInstr.Instr & (1 << 7); bool link = CurInstr.Instr & (1 << 7);
if (link && Num == 1)
if (link)
{
if (Num == 1)
{ {
printf("BLX unsupported on ARM7!!!\n"); printf("BLX unsupported on ARM7!!!\n");
return; return;
} }
MOV(32, R(RSCRATCH), MapReg(CurInstr.A_Reg(3)));
OpArg rn = MapReg(CurInstr.A_Reg(3));
if (link)
MOV(32, MapReg(14), Imm32(R15 - 1)); MOV(32, MapReg(14), Imm32(R15 - 1));
Comp_JumpTo(RSCRATCH);
}
else
{
OpArg rn = MapReg(CurInstr.A_Reg(3));
Comp_JumpTo(rn.GetSimpleReg()); Comp_JumpTo(rn.GetSimpleReg());
} }
}
void Compiler::T_Comp_BL_LONG_1() void Compiler::T_Comp_BL_LONG_1()
{ {

View File

@ -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_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_UNK = A_BranchAlways | A_Link | ak(ak_UNK);
const u32 A_MSR_IMM = A_UnkOnARM7 | ak(ak_MSR_IMM); const u32 A_MSR_IMM = ak(ak_MSR_IMM);
const u32 A_MSR_REG = A_Read0 | A_UnkOnARM7 | ak(ak_MSR_REG); const u32 A_MSR_REG = A_Read0 | ak(ak_MSR_REG);
const u32 A_MRS = A_Write12 | A_UnkOnARM7 | ak(ak_MRS); const u32 A_MRS = A_Write12 | ak(ak_MRS);
const u32 A_MCR = A_Read12 | A_UnkOnARM7 | ak(ak_MCR); const u32 A_MCR = A_Read12 | ak(ak_MCR);
const u32 A_MRC = A_Write12 | A_UnkOnARM7 | ak(ak_MRC); const u32 A_MRC = A_Write12 | ak(ak_MRC);
const u32 A_SVC = A_BranchAlways | A_Link | ak(ak_SVC); const u32 A_SVC = A_BranchAlways | A_Link | ak(ak_SVC);
// THUMB // THUMB
@ -310,6 +310,7 @@ Info Decode(bool thumb, u32 num, u32 instr)
res.DstRegs |= 1 << 15; res.DstRegs |= 1 << 15;
res.Kind = (data >> 16) & 0x3F; res.Kind = (data >> 16) & 0x3F;
res.EndBlock = res.Branches();
return res; return res;
} }
@ -324,6 +325,26 @@ Info Decode(bool thumb, u32 num, u32 instr)
res.Kind = (data >> 13) & 0x1FF; 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) if (data & A_Read0)
res.SrcRegs |= 1 << (instr & 0xF); res.SrcRegs |= 1 << (instr & 0xF);
if (data & A_Read16) if (data & A_Read16)
@ -361,6 +382,8 @@ Info Decode(bool thumb, u32 num, u32 instr)
if (res.Kind == ak_LDM) if (res.Kind == ak_LDM)
res.DstRegs |= instr & (1 << 15); // this is right res.DstRegs |= instr & (1 << 15); // this is right
res.EndBlock |= res.Branches();
return res; return res;
} }
} }

View File

@ -220,6 +220,7 @@ struct Info
u16 DstRegs, SrcRegs; u16 DstRegs, SrcRegs;
u16 Kind; u16 Kind;
bool EndBlock;
bool Branches() bool Branches()
{ {
return DstRegs & (1 << 15); return DstRegs & (1 << 15);