mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 05:10:15 +00:00
JitX64: Implement immediate data processing instructions
This commit is contained in:
parent
a80f9d8a66
commit
52558ae8be
@ -24,6 +24,7 @@ void JitX64::CondManager::CompileCond(const ConditionCode new_cond) {
|
||||
|
||||
if (current_cond != ConditionCode::AL && current_cond != ConditionCode::NV) {
|
||||
jit->reg_alloc.FlushEverything();
|
||||
jit->reg_alloc.AssertNoLocked();
|
||||
ASSERT(current_cond_fixup.ptr);
|
||||
jit->code->SetJumpTarget(current_cond_fixup);
|
||||
current_cond_fixup.ptr = nullptr;
|
||||
@ -123,6 +124,7 @@ void JitX64::CondManager::CompileCond(const ConditionCode new_cond) {
|
||||
}
|
||||
|
||||
jit->reg_alloc.FlushEverything();
|
||||
jit->reg_alloc.AssertNoLocked();
|
||||
this->current_cond_fixup = jit->code->J_CC(cc, true);
|
||||
}
|
||||
|
||||
|
@ -10,48 +10,41 @@ namespace JitX64 {
|
||||
|
||||
using namespace Gen;
|
||||
|
||||
void JitX64::ADC_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
void JitX64::CompileDataProcessingHelper(ArmReg Rn_index, ArmReg Rd_index, std::function<void(X64Reg)> body) {
|
||||
// The major consideration is if Rn and/or Rd == R15.
|
||||
|
||||
if (Rd_index == 15) {
|
||||
X64Reg Rd = reg_alloc.AllocAndLockTemp();
|
||||
reg_alloc.LockArm(Rn_index);
|
||||
|
||||
if (Rn_index == 15) {
|
||||
// TODO: In this case we can actually calculat the final result.
|
||||
// We can also use CompileJumpToBB instead of having to use CompileReturnToDispatch.
|
||||
code->MOV(32, R(Rd), Imm32(GetReg15Value()));
|
||||
} else {
|
||||
code->MOV(32, R(Rd), reg_alloc.ArmR(Rd_index));
|
||||
code->MOV(32, R(Rd), reg_alloc.ArmR(Rn_index));
|
||||
}
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->ADC(32, R(Rd), Imm32(immediate));
|
||||
|
||||
body(Rd);
|
||||
|
||||
reg_alloc.UnlockArm(Rn_index);
|
||||
|
||||
if (S)
|
||||
UNIMPLEMENTED();
|
||||
|
||||
code->MOV(32, MJitStateArmPC(), R(Rd));
|
||||
reg_alloc.UnlockTemp(Rd);
|
||||
current.arm_pc += GetInstSize();
|
||||
CompileReturnToDispatch();
|
||||
return;
|
||||
} else if (Rn_index == 15) {
|
||||
X64Reg Rd = reg_alloc.BindNoLoadAndLockArm(Rd_index);
|
||||
reg_alloc.MarkDirty(Rd_index);
|
||||
|
||||
code->MOV(32, R(Rd), Imm32(GetReg15Value()));
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->ADC(32, R(Rd), Imm32(immediate));
|
||||
|
||||
body(Rd);
|
||||
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
} else if (Rn_index == Rd_index) {
|
||||
X64Reg Rd = reg_alloc.BindAndLockArm(Rd_index);
|
||||
reg_alloc.MarkDirty(Rd_index);
|
||||
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->ADC(32, R(Rd), Imm32(immediate));
|
||||
body(Rd);
|
||||
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
} else {
|
||||
@ -60,67 +53,471 @@ void JitX64::ADC_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int ro
|
||||
reg_alloc.LockArm(Rn_index);
|
||||
|
||||
code->MOV(32, R(Rd), reg_alloc.ArmR(Rn_index));
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->ADC(32, R(Rd), Imm32(immediate));
|
||||
|
||||
body(Rd);
|
||||
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
reg_alloc.UnlockArm(Rn_index);
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::CompileDataProcessingHelper_Reverse(ArmReg Rn_index, ArmReg Rd_index, std::function<void(X64Reg)> body) {
|
||||
// The major consideration is if Rn and/or Rd == R15.
|
||||
|
||||
if (Rd_index != Rn_index) {
|
||||
|
||||
X64Reg Rd = INVALID_REG;
|
||||
|
||||
if (Rd_index == 15) {
|
||||
Rd = reg_alloc.AllocAndLockTemp();
|
||||
} else {
|
||||
Rd = reg_alloc.BindNoLoadAndLockArm(Rd_index);
|
||||
reg_alloc.MarkDirty(Rd_index);
|
||||
}
|
||||
|
||||
body(Rd);
|
||||
|
||||
if (Rd_index == 15) {
|
||||
code->MOV(32, MJitStateArmPC(), R(Rd));
|
||||
reg_alloc.UnlockTemp(Rd);
|
||||
} else {
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
X64Reg tmp = reg_alloc.AllocAndLockTemp();
|
||||
|
||||
body(tmp);
|
||||
|
||||
// TODO: Efficiency: Could implement this as a register rebind instead of needing to MOV.
|
||||
reg_alloc.LockArm(Rd_index);
|
||||
code->MOV(32, reg_alloc.ArmR(Rd_index), R(tmp));
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
reg_alloc.UnlockTemp(tmp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::ADC_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->ADC(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZVCN();
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::ADD_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->ADD(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZVCN();
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::AND_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->AND(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::BIC_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->AND(32, R(Rd), Imm32(~immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::CMN_imm(Cond cond, ArmReg Rn_index, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMP_imm(Cond cond, ArmReg Rn_index, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
|
||||
void JitX64::EOR_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->XOR(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::MOV_imm(Cond cond, bool S, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
if (Rd_index != 15) {
|
||||
reg_alloc.LockArm(Rd_index);
|
||||
code->MOV(32, reg_alloc.ArmR(Rd_index), Imm32(immediate));
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
} else {
|
||||
code->MOV(32, MJitStateArmPC(), Imm32(immediate));
|
||||
}
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
reg_alloc.LockArm(Rd_index);
|
||||
code->CMP(32, reg_alloc.ArmR(Rd_index), Imm32(0));
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::MVN_imm(Cond cond, bool S, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
if (Rd_index != 15) {
|
||||
reg_alloc.LockArm(Rd_index);
|
||||
code->MOV(32, reg_alloc.ArmR(Rd_index), Imm32(~immediate));
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
} else {
|
||||
code->MOV(32, MJitStateArmPC(), Imm32(~immediate));
|
||||
}
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
reg_alloc.LockArm(Rd_index);
|
||||
code->CMP(32, reg_alloc.ArmR(Rd_index), Imm32(0));
|
||||
reg_alloc.UnlockArm(Rd_index);
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::ORR_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->OR(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::RSB_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper_Reverse(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->MOV(32, R(Rd), Imm32(immediate));
|
||||
|
||||
if (Rn_index == 15) {
|
||||
code->SUB(32, R(Rd), Imm32(GetReg15Value()));
|
||||
} else {
|
||||
reg_alloc.LockArm(Rn_index);
|
||||
code->SUB(32, R(Rd), reg_alloc.ArmR(Rn_index));
|
||||
reg_alloc.UnlockArm(Rn_index);
|
||||
}
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZVN();
|
||||
UpdateFlagsC_complement();
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::RSC_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper_Reverse(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->MOV(32, R(Rd), Imm32(immediate));
|
||||
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->CMC();
|
||||
|
||||
if (Rn_index == 15) {
|
||||
code->SBB(32, R(Rd), Imm32(GetReg15Value()));
|
||||
} else {
|
||||
reg_alloc.LockArm(Rn_index);
|
||||
code->SBB(32, R(Rd), reg_alloc.ArmR(Rn_index));
|
||||
reg_alloc.UnlockArm(Rn_index);
|
||||
}
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZVN();
|
||||
UpdateFlagsC_complement();
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::SBC_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->BT(32, MJitStateCFlag(), Imm8(0));
|
||||
code->CMC();
|
||||
code->SBB(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZVN();
|
||||
UpdateFlagsC_complement();
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::SUB_imm(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
CompileDataProcessingHelper(Rn_index, Rd_index, [&](X64Reg Rd) {
|
||||
code->SUB(32, R(Rd), Imm32(immediate));
|
||||
});
|
||||
|
||||
if (S) {
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZVN();
|
||||
UpdateFlagsC_complement();
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
if (Rd_index == 15) {
|
||||
CompileReturnToDispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void JitX64::TEQ_imm(Cond cond, ArmReg Rn_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
X64Reg Rn = reg_alloc.AllocAndLockTemp();
|
||||
|
||||
if (Rn_index == 15) {
|
||||
code->MOV(32, R(Rn), Imm32(GetReg15Value()));
|
||||
} else {
|
||||
reg_alloc.LockArm(Rn_index);
|
||||
code->MOV(32, R(Rn), reg_alloc.ArmR(Rn_index));
|
||||
reg_alloc.UnlockArm(Rn_index);
|
||||
}
|
||||
|
||||
code->XOR(32, R(Rn), Imm32(immediate));
|
||||
|
||||
reg_alloc.UnlockTemp(Rn);
|
||||
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
}
|
||||
|
||||
void JitX64::ADC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADD_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADD_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADD_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::AND_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::AND_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::AND_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::BIC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::BIC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::BIC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMN_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMN_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMN_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMP_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMP_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMP_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::EOR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::EOR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::EOR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MOV_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::MOV_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MOV_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MVN_imm(Cond cond, bool S, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::MVN_reg(Cond cond, bool S, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MVN_rsr(Cond cond, bool S, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ORR_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::ORR_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ORR_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SBC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::SBC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SBC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SUB_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::SUB_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SUB_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TEQ_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::TEQ_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TEQ_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TST_imm(Cond cond, ArmReg Rn, int rotate, ArmImm8 imm8) { CompileInterpretInstruction(); }
|
||||
void JitX64::TST_reg(Cond cond, ArmReg Rn, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TST_rsr(Cond cond, ArmReg Rn, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TST_imm(Cond cond, ArmReg Rn_index, int rotate, ArmImm8 imm8) {
|
||||
cond_manager.CompileCond((ConditionCode)cond);
|
||||
|
||||
u32 immediate = _rotr(imm8, rotate * 2);
|
||||
|
||||
X64Reg Rn;
|
||||
|
||||
if (Rn_index == 15) {
|
||||
Rn = reg_alloc.AllocAndLockTemp();
|
||||
code->MOV(32, R(Rn), Imm32(GetReg15Value()));
|
||||
} else {
|
||||
Rn = reg_alloc.BindAndLockArm(Rn_index);
|
||||
}
|
||||
|
||||
code->TEST(32, R(Rn), Imm32(immediate));
|
||||
|
||||
if (Rn_index == 15) {
|
||||
reg_alloc.UnlockTemp(Rn);
|
||||
} else {
|
||||
reg_alloc.UnlockArm(Rn_index);
|
||||
}
|
||||
|
||||
cond_manager.FlagsDirty();
|
||||
UpdateFlagsZN();
|
||||
if (rotate != 0) {
|
||||
code->MOV(32, MJitStateCFlag(), Imm32(immediate & 0x80000000 ? 1 : 0));
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoLocked();
|
||||
|
||||
current.arm_pc += GetInstSize();
|
||||
}
|
||||
|
||||
void JitX64::ADC_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADC_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADD_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ADD_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::AND_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::AND_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::BIC_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::BIC_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMN_reg(Cond cond, ArmReg Rn_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMN_rsr(Cond cond, ArmReg Rn_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMP_reg(Cond cond, ArmReg Rn_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::CMP_rsr(Cond cond, ArmReg Rn_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::EOR_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::EOR_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MOV_reg(Cond cond, bool S, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MOV_rsr(Cond cond, bool S, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MVN_reg(Cond cond, bool S, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::MVN_rsr(Cond cond, bool S, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ORR_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::ORR_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSB_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSB_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSC_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::RSC_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SBC_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SBC_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SUB_reg(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::SUB_rsr(Cond cond, bool S, ArmReg Rn_index, ArmReg Rd_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TEQ_reg(Cond cond, ArmReg Rn_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TEQ_rsr(Cond cond, ArmReg Rn_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TST_reg(Cond cond, ArmReg Rn_index, ArmImm5 imm5, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
void JitX64::TST_rsr(Cond cond, ArmReg Rn_index, ArmReg Rs, ShiftType shift, ArmReg Rm) { CompileInterpretInstruction(); }
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
|
||||
struct BlockOfCode : Gen::XCodeBlock {
|
||||
BlockOfCode() {
|
||||
AllocCodeSpace(1024 * 1024 * 1024);
|
||||
AllocCodeSpace(128 * 1024 * 1024);
|
||||
}
|
||||
};
|
||||
|
||||
@ -222,4 +222,10 @@ void ARM_Jit::ClearCache() {
|
||||
state->cpu_state.instruction_cache.clear();
|
||||
}
|
||||
|
||||
void ARM_Jit::FastClearCache() {
|
||||
compiler.ClearCache();
|
||||
block_of_code.ResetCodePtr();
|
||||
state->cpu_state.instruction_cache.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
void ExecuteInstructions(int num_instructions) override;
|
||||
|
||||
void ClearCache() override;
|
||||
void FastClearCache();
|
||||
|
||||
private:
|
||||
bool reschedule;
|
||||
|
@ -106,6 +106,11 @@ private:
|
||||
code->SETcc(Gen::CC_S, MJitStateNFlag());
|
||||
}
|
||||
|
||||
FORCE_INLINE void UpdateFlagsZN() {
|
||||
code->SETcc(Gen::CC_Z, MJitStateZFlag());
|
||||
code->SETcc(Gen::CC_S, MJitStateNFlag());
|
||||
}
|
||||
|
||||
FORCE_INLINE void UpdateFlagsC_complement() {
|
||||
code->SETcc(Gen::CC_NC, MJitStateCFlag());
|
||||
}
|
||||
@ -151,6 +156,8 @@ private:
|
||||
virtual void STC() override;
|
||||
|
||||
// Data processing instructions
|
||||
void CompileDataProcessingHelper(ArmReg Rn_index, ArmReg Rd_index, std::function<void(Gen::X64Reg)> body);
|
||||
void CompileDataProcessingHelper_Reverse(ArmReg Rn_index, ArmReg Rd_index, std::function<void(Gen::X64Reg)> body);
|
||||
virtual void ADC_imm(Cond cond, bool S, ArmReg Rn, ArmReg Rd, int rotate, ArmImm8 imm8) override;
|
||||
virtual void ADC_reg(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmImm5 imm5, ShiftType shift, ArmReg Rm) override;
|
||||
virtual void ADC_rsr(Cond cond, bool S, ArmReg Rn, ArmReg Rd, ArmReg Rs, ShiftType shift, ArmReg Rm) override;
|
||||
|
@ -71,11 +71,16 @@ void RegAlloc::FlushX64(Gen::X64Reg x64_reg) {
|
||||
|
||||
switch (state.state) {
|
||||
case X64State::State::Free:
|
||||
case X64State::State::CleanArmReg:
|
||||
case X64State::State::MemoryMap:
|
||||
case X64State::State::Temp:
|
||||
state.state = X64State::State::Free;
|
||||
break;
|
||||
case X64State::State::CleanArmReg: {
|
||||
state.state = X64State::State::Free;
|
||||
ArmState& arm_state = arm_gpr[state.arm_reg];
|
||||
arm_state.location = MJitStateCpuReg(state.arm_reg);
|
||||
break;
|
||||
}
|
||||
case X64State::State::DirtyArmReg:
|
||||
FlushArm(state.arm_reg);
|
||||
break;
|
||||
@ -92,14 +97,18 @@ void RegAlloc::LockX64(Gen::X64Reg x64_reg) {
|
||||
X64State& x64_state = x64_gpr[x64_reg_to_index.at(x64_reg)];
|
||||
|
||||
ASSERT(!x64_state.locked);
|
||||
ASSERT(x64_state.state == X64State::State::Free);
|
||||
x64_state.locked = true;
|
||||
x64_state.state = X64State::State::UserManuallyLocked;
|
||||
}
|
||||
|
||||
void RegAlloc::UnlockX64(Gen::X64Reg x64_reg) {
|
||||
X64State& x64_state = x64_gpr[x64_reg_to_index.at(x64_reg)];
|
||||
|
||||
ASSERT(x64_state.locked);
|
||||
ASSERT(x64_state.state == X64State::State::UserManuallyLocked);
|
||||
x64_state.locked = false;
|
||||
x64_state.state = X64State::State::Free;
|
||||
}
|
||||
|
||||
void RegAlloc::FlushArm(ArmReg arm_reg) {
|
||||
@ -300,6 +309,23 @@ void RegAlloc::UnlockMemoryMap(Gen::X64Reg x64_reg) {
|
||||
x64_state.locked = false;
|
||||
}
|
||||
|
||||
void RegAlloc::AssertNoLocked() {
|
||||
for (ArmReg arm_reg = 0; arm_reg < arm_gpr.size(); arm_reg++) {
|
||||
ArmState& arm_state = arm_gpr[arm_reg];
|
||||
ASSERT(!arm_state.locked);
|
||||
if (arm_state.location.IsSimpleReg()) {
|
||||
X64State& x64_state = x64_gpr[x64_reg_to_index.at(arm_state.location.GetSimpleReg())];
|
||||
ASSERT(x64_state.state == X64State::State::CleanArmReg || x64_state.state == X64State::State::DirtyArmReg);
|
||||
ASSERT(x64_state.arm_reg == arm_reg);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i : x64_reg_to_index) {
|
||||
X64State& x64_state = x64_gpr[i.second];
|
||||
ASSERT(!x64_state.locked);
|
||||
}
|
||||
}
|
||||
|
||||
Gen::X64Reg RegAlloc::AllocReg() {
|
||||
// TODO: This is terrible.
|
||||
|
||||
|
@ -32,7 +32,8 @@ private:
|
||||
Temp,
|
||||
DirtyArmReg,
|
||||
CleanArmReg,
|
||||
MemoryMap
|
||||
MemoryMap,
|
||||
UserManuallyLocked
|
||||
};
|
||||
|
||||
bool locked;
|
||||
@ -92,6 +93,8 @@ public:
|
||||
/// Returns the register in which the JitState pointer is stored.
|
||||
Gen::X64Reg JitStateReg();
|
||||
|
||||
void AssertNoLocked();
|
||||
|
||||
private:
|
||||
/// INTERNAL: Allocates a register that is free. Flushes registers that are not locked if necessary.
|
||||
Gen::X64Reg AllocReg();
|
||||
|
@ -39,6 +39,56 @@ std::pair<u32, u32> FromBitString(const char* str) {
|
||||
}
|
||||
|
||||
TEST_CASE("Fuzz ARM data processing instructions", "[JitX64]") {
|
||||
const std::array<std::pair<u32, u32>, 48> instructions = {{
|
||||
FromBitString("cccc0010101Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000101Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000101Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010100Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000100Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000100Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010000Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000000Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000000Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011110Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001110Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001110Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc00110111nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010111nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010111nnnn0000ssss0rr1mmmm"),
|
||||
FromBitString("cccc00110101nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010101nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010101nnnn0000ssss0rr1mmmm"),
|
||||
FromBitString("cccc0010001Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000001Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000001Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011101S0000ddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001101S0000ddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001101S0000ddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011111S0000ddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001111S0000ddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001111S0000ddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011100Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001100Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001100Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010011Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000011Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000011Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010111Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000111Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000111Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010110Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000110Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000110Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010010Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000010Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000010Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc00110011nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010011nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010011nnnn0000ssss0rr1mmmm"),
|
||||
FromBitString("cccc00110001nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010001nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010001nnnn0000ssss0rr1mmmm"),
|
||||
}};
|
||||
|
||||
// Init core
|
||||
Core::Init();
|
||||
@ -62,12 +112,12 @@ TEST_CASE("Fuzz ARM data processing instructions", "[JitX64]") {
|
||||
JitX64::ARM_Jit jit(PrivilegeMode::USER32MODE);
|
||||
ARM_DynCom interp(PrivilegeMode::USER32MODE);
|
||||
SCOPE_EXIT({
|
||||
jit.ClearCache();
|
||||
jit.FastClearCache();
|
||||
interp.ClearCache();
|
||||
});
|
||||
|
||||
for (int run_number = 0; run_number < 10000; run_number++) {
|
||||
jit.ClearCache();
|
||||
jit.FastClearCache();
|
||||
interp.ClearCache();
|
||||
|
||||
u32 initial_regs[15];
|
||||
@ -87,57 +137,6 @@ TEST_CASE("Fuzz ARM data processing instructions", "[JitX64]") {
|
||||
constexpr int NUM_INST = 5;
|
||||
|
||||
for (int i = 0; i < NUM_INST; i++) {
|
||||
const std::array<std::pair<u32, u32>, 48> instructions = {{
|
||||
FromBitString("cccc0010101Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000101Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000101Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010100Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000100Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000100Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010000Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000000Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000000Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011110Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001110Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001110Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc00110111nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010111nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010111nnnn0000ssss0rr1mmmm"),
|
||||
FromBitString("cccc00110101nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010101nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010101nnnn0000ssss0rr1mmmm"),
|
||||
FromBitString("cccc0010001Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000001Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000001Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011101S0000ddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001101S0000ddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001101S0000ddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011111S0000ddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001111S0000ddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001111S0000ddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0011100Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0001100Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0001100Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010011Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000011Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000011Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010111Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000111Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000111Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010110Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000110Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000110Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc0010010Snnnnddddrrrrvvvvvvvv"),
|
||||
FromBitString("cccc0000010Snnnnddddvvvvvrr0mmmm"),
|
||||
FromBitString("cccc0000010Snnnnddddssss0rr1mmmm"),
|
||||
FromBitString("cccc00110011nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010011nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010011nnnn0000ssss0rr1mmmm"),
|
||||
FromBitString("cccc00110001nnnn0000rrrrvvvvvvvv"),
|
||||
FromBitString("cccc00010001nnnn0000vvvvvrr0mmmm"),
|
||||
FromBitString("cccc00010001nnnn0000ssss0rr1mmmm"),
|
||||
}};
|
||||
|
||||
size_t inst_index = rand_int(0, instructions.size() - 1);
|
||||
u32 cond = rand_int(0x0, 0xE);
|
||||
u32 Rn = rand_int(0, 15);
|
||||
@ -197,5 +196,7 @@ TEST_CASE("Fuzz ARM data processing instructions", "[JitX64]") {
|
||||
|
||||
FAIL();
|
||||
}
|
||||
|
||||
if (run_number % 100 == 0) printf("%i\r", run_number);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user