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);
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);

View File

@ -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;
}

View File

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

View File

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