Core: Clean up brace/body placements for JitIL
This commit is contained in:
parent
b005ba2797
commit
d694637938
File diff suppressed because it is too large
Load Diff
|
@ -174,8 +174,12 @@ namespace JitILProfiler
|
|||
u64 codeHash;
|
||||
u64 totalElapsed;
|
||||
u64 numberOfCalls;
|
||||
Block() : index(0), codeHash(0), totalElapsed(0), numberOfCalls(0) { }
|
||||
|
||||
Block() : index(0), codeHash(0), totalElapsed(0), numberOfCalls(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<Block> blocks;
|
||||
static u32 blockIndex;
|
||||
static u64 beginTime;
|
||||
|
@ -188,6 +192,7 @@ namespace JitILProfiler
|
|||
block.codeHash = codeHash;
|
||||
return block;
|
||||
}
|
||||
|
||||
// These functions need to be static because they are called with
|
||||
// ABI_CallFunction().
|
||||
static void Begin(u32 index)
|
||||
|
@ -195,6 +200,7 @@ namespace JitILProfiler
|
|||
blockIndex = index;
|
||||
beginTime = __rdtsc();
|
||||
}
|
||||
|
||||
static void End()
|
||||
{
|
||||
const u64 endTime = __rdtsc();
|
||||
|
@ -203,6 +209,7 @@ namespace JitILProfiler
|
|||
block.totalElapsed += duration;
|
||||
++block.numberOfCalls;
|
||||
}
|
||||
|
||||
struct JitILProfilerFinalizer
|
||||
{
|
||||
virtual ~JitILProfilerFinalizer()
|
||||
|
@ -221,11 +228,13 @@ namespace JitILProfiler
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<JitILProfilerFinalizer> finalizer;
|
||||
static void Init()
|
||||
{
|
||||
finalizer = std::make_unique<JitILProfilerFinalizer>();
|
||||
}
|
||||
|
||||
static void Shutdown()
|
||||
{
|
||||
finalizer.reset();
|
||||
|
@ -246,10 +255,14 @@ void JitIL::Init()
|
|||
else
|
||||
{
|
||||
if (!Core::g_CoreStartupParameter.bJITBlockLinking)
|
||||
{
|
||||
jo.enableBlocklink = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Speed boost, but not 100% safe
|
||||
jo.enableBlocklink = !Core::g_CoreStartupParameter.bMMU;
|
||||
}
|
||||
}
|
||||
|
||||
jo.fpAccurateFcmp = false;
|
||||
|
@ -268,7 +281,8 @@ void JitIL::Init()
|
|||
code_block.m_gpa = &js.gpa;
|
||||
code_block.m_fpa = &js.fpa;
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||
{
|
||||
JitILProfiler::Init();
|
||||
}
|
||||
}
|
||||
|
@ -282,7 +296,8 @@ void JitIL::ClearCache()
|
|||
|
||||
void JitIL::Shutdown()
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||
{
|
||||
JitILProfiler::Shutdown();
|
||||
}
|
||||
|
||||
|
@ -352,11 +367,14 @@ static void ImHere()
|
|||
PowerPC::ppcState.gpr[5], PowerPC::ppcState.gpr[6]);
|
||||
f.Flush();
|
||||
}
|
||||
if (been_here.find(PC) != been_here.end()) {
|
||||
|
||||
if (been_here.find(PC) != been_here.end())
|
||||
{
|
||||
been_here.find(PC)->second++;
|
||||
if ((been_here.find(PC)->second) & 1023)
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(DYNA_REC, "I'm here - PC = %08x , LR = %08x", PC, LR);
|
||||
been_here[PC] = 1;
|
||||
}
|
||||
|
@ -376,7 +394,8 @@ void JitIL::Cleanup()
|
|||
void JitIL::WriteExit(u32 destination)
|
||||
{
|
||||
Cleanup();
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||
{
|
||||
ABI_CallFunction((void *)JitILProfiler::End);
|
||||
}
|
||||
SUB(32, M(&PowerPC::ppcState.downcount), Imm32(js.downcountAmount));
|
||||
|
@ -408,7 +427,8 @@ void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
|
|||
{
|
||||
MOV(32, M(&PC), arg);
|
||||
Cleanup();
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||
{
|
||||
ABI_CallFunction((void *)JitILProfiler::End);
|
||||
}
|
||||
SUB(32, M(&PowerPC::ppcState.downcount), Imm32(js.downcountAmount));
|
||||
|
@ -420,7 +440,8 @@ void JitIL::WriteRfiExitDestInOpArg(const Gen::OpArg& arg)
|
|||
MOV(32, M(&PC), arg);
|
||||
MOV(32, M(&NPC), arg);
|
||||
Cleanup();
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||
{
|
||||
ABI_CallFunction((void *)JitILProfiler::End);
|
||||
}
|
||||
ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
|
||||
|
@ -431,7 +452,8 @@ void JitIL::WriteRfiExitDestInOpArg(const Gen::OpArg& arg)
|
|||
void JitIL::WriteExceptionExit()
|
||||
{
|
||||
Cleanup();
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling) {
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling)
|
||||
{
|
||||
ABI_CallFunction((void *)JitILProfiler::End);
|
||||
}
|
||||
MOV(32, R(EAX), M(&PC));
|
||||
|
@ -554,7 +576,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||
|
||||
u64 codeHash = -1;
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILTimeProfiling ||
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILOutputIR)
|
||||
SConfig::GetInstance().m_LocalCoreStartupParameter.bJITILOutputIR)
|
||||
{
|
||||
// For profiling and IR Writer
|
||||
for (u32 i = 0; i < code_block.m_num_instructions; i++)
|
||||
|
@ -577,7 +599,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
|||
|
||||
js.downcountAmount = 0;
|
||||
if (!Core::g_CoreStartupParameter.bEnableDebugging)
|
||||
js.downcountAmount += PatchEngine::GetSpeedhackCycles(code_block.m_address);
|
||||
js.downcountAmount += PatchEngine::GetSpeedhackCycles(code_block.m_address);
|
||||
|
||||
// Translate instructions
|
||||
for (u32 i = 0; i < code_block.m_num_instructions; i++)
|
||||
|
|
|
@ -67,19 +67,22 @@ public:
|
|||
bool IsInCodeSpace(u8 *ptr) override { return IsInSpace(ptr); }
|
||||
|
||||
void ClearCache() override;
|
||||
const u8 *GetDispatcher() {
|
||||
const u8 *GetDispatcher()
|
||||
{
|
||||
return asm_routines.dispatcher; // asm_routines.dispatcher
|
||||
}
|
||||
const CommonAsmRoutines *GetAsmRoutines() override {
|
||||
|
||||
const CommonAsmRoutines *GetAsmRoutines() override
|
||||
{
|
||||
return &asm_routines;
|
||||
}
|
||||
|
||||
const char *GetName() override {
|
||||
const char *GetName() override
|
||||
{
|
||||
return "JIT64IL";
|
||||
}
|
||||
|
||||
// Run!
|
||||
|
||||
void Run() override;
|
||||
void SingleStep() override;
|
||||
|
||||
|
|
|
@ -376,15 +376,19 @@ void CompileInstruction(PPCAnalyst::CodeOp & op)
|
|||
JitIL *jitil = (JitIL *)jit;
|
||||
(jitil->*dynaOpTable[op.inst.OPCD])(op.inst);
|
||||
GekkoOPInfo *info = op.opinfo;
|
||||
if (info) {
|
||||
if (info)
|
||||
{
|
||||
#ifdef OPLOG
|
||||
if (!strcmp(info->opname, OP_TO_LOG)){ ///"mcrfs"
|
||||
if (!strcmp(info->opname, OP_TO_LOG)) // "mcrfs"
|
||||
{
|
||||
rsplocations.push_back(jit.js.compilerPC);
|
||||
}
|
||||
#endif
|
||||
info->compileCount++;
|
||||
info->lastUse = jit->js.compilerPC;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("Tried to compile illegal (or unknown) instruction %08x, at %08x", op.inst.hex, jit->js.compilerPC);
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,8 +8,11 @@
|
|||
|
||||
#include "Common/x64Emitter.h"
|
||||
|
||||
namespace IREmitter {
|
||||
enum Opcode {
|
||||
namespace IREmitter
|
||||
{
|
||||
|
||||
enum Opcode
|
||||
{
|
||||
Nop = 0,
|
||||
|
||||
// "Zero-operand" operators
|
||||
|
@ -177,46 +180,57 @@ enum Opcode {
|
|||
typedef unsigned Inst;
|
||||
typedef Inst* InstLoc;
|
||||
|
||||
unsigned inline getOpcode(Inst i) {
|
||||
unsigned inline getOpcode(Inst i)
|
||||
{
|
||||
return i & 255;
|
||||
}
|
||||
|
||||
unsigned inline isImm(Inst i) {
|
||||
unsigned inline isImm(Inst i)
|
||||
{
|
||||
return getOpcode(i) >= CInt16 && getOpcode(i) <= CInt32;
|
||||
}
|
||||
|
||||
unsigned inline isICmp(Inst i) {
|
||||
unsigned inline isICmp(Inst i)
|
||||
{
|
||||
return getOpcode(i) >= ICmpEq && getOpcode(i) <= ICmpSle;
|
||||
}
|
||||
|
||||
unsigned inline isFResult(Inst i) {
|
||||
unsigned inline isFResult(Inst i)
|
||||
{
|
||||
return getOpcode(i) > FResult_Start &&
|
||||
getOpcode(i) < FResult_End;
|
||||
}
|
||||
|
||||
InstLoc inline getOp1(InstLoc i) {
|
||||
InstLoc inline getOp1(InstLoc i)
|
||||
{
|
||||
i = i - 1 - ((*i >> 8) & 255);
|
||||
if (getOpcode(*i) == Tramp) {
|
||||
|
||||
if (getOpcode(*i) == Tramp)
|
||||
{
|
||||
i = i - 1 - (*i >> 8);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
InstLoc inline getOp2(InstLoc i) {
|
||||
InstLoc inline getOp2(InstLoc i)
|
||||
{
|
||||
i = i - 1 - ((*i >> 16) & 255);
|
||||
if (getOpcode(*i) == Tramp) {
|
||||
|
||||
if (getOpcode(*i) == Tramp)
|
||||
{
|
||||
i = i - 1 - (*i >> 8);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
class IRBuilder {
|
||||
class IRBuilder
|
||||
{
|
||||
private:
|
||||
InstLoc EmitZeroOp(unsigned Opcode, unsigned extra);
|
||||
InstLoc EmitUOp(unsigned OpCode, InstLoc Op1,
|
||||
unsigned extra = 0);
|
||||
InstLoc EmitBiOp(unsigned OpCode, InstLoc Op1, InstLoc Op2,
|
||||
unsigned extra = 0);
|
||||
InstLoc EmitUOp(unsigned OpCode, InstLoc Op1, unsigned extra = 0);
|
||||
InstLoc EmitBiOp(unsigned OpCode, InstLoc Op1, InstLoc Op2, unsigned extra = 0);
|
||||
|
||||
InstLoc FoldAdd(InstLoc Op1, InstLoc Op2);
|
||||
InstLoc FoldSub(InstLoc Op1, InstLoc Op2);
|
||||
|
@ -238,316 +252,515 @@ private:
|
|||
InstLoc FoldFallBackToInterpreter(InstLoc Op1, InstLoc Op2);
|
||||
|
||||
InstLoc FoldZeroOp(unsigned Opcode, unsigned extra);
|
||||
InstLoc FoldUOp(unsigned OpCode, InstLoc Op1,
|
||||
unsigned extra = 0);
|
||||
InstLoc FoldBiOp(unsigned OpCode, InstLoc Op1, InstLoc Op2,
|
||||
unsigned extra = 0);
|
||||
InstLoc FoldUOp(unsigned OpCode, InstLoc Op1, unsigned extra = 0);
|
||||
InstLoc FoldBiOp(unsigned OpCode, InstLoc Op1, InstLoc Op2, unsigned extra = 0);
|
||||
|
||||
unsigned ComputeKnownZeroBits(InstLoc I) const;
|
||||
|
||||
public:
|
||||
InstLoc EmitIntConst(unsigned value) { return EmitIntConst64(value); }
|
||||
InstLoc EmitIntConst64(u64 value);
|
||||
InstLoc EmitStoreLink(InstLoc val) {
|
||||
|
||||
InstLoc EmitStoreLink(InstLoc val)
|
||||
{
|
||||
return FoldUOp(StoreLink, val);
|
||||
}
|
||||
InstLoc EmitBranchUncond(InstLoc val) {
|
||||
|
||||
InstLoc EmitBranchUncond(InstLoc val)
|
||||
{
|
||||
return FoldUOp(BranchUncond, val);
|
||||
}
|
||||
InstLoc EmitBranchCond(InstLoc check, InstLoc dest) {
|
||||
|
||||
InstLoc EmitBranchCond(InstLoc check, InstLoc dest)
|
||||
{
|
||||
return FoldBiOp(BranchCond, check, dest);
|
||||
}
|
||||
InstLoc EmitIdleBranch(InstLoc check, InstLoc dest) {
|
||||
|
||||
InstLoc EmitIdleBranch(InstLoc check, InstLoc dest)
|
||||
{
|
||||
return FoldBiOp(IdleBranch, check, dest);
|
||||
}
|
||||
InstLoc EmitLoadCR(unsigned crreg) {
|
||||
|
||||
InstLoc EmitLoadCR(unsigned crreg)
|
||||
{
|
||||
return FoldZeroOp(LoadCR, crreg);
|
||||
}
|
||||
InstLoc EmitStoreCR(InstLoc value, unsigned crreg) {
|
||||
|
||||
InstLoc EmitStoreCR(InstLoc value, unsigned crreg)
|
||||
{
|
||||
return FoldUOp(StoreCR, value, crreg);
|
||||
}
|
||||
InstLoc EmitLoadLink() {
|
||||
|
||||
InstLoc EmitLoadLink()
|
||||
{
|
||||
return FoldZeroOp(LoadLink, 0);
|
||||
}
|
||||
InstLoc EmitLoadMSR() {
|
||||
|
||||
InstLoc EmitLoadMSR()
|
||||
{
|
||||
return FoldZeroOp(LoadMSR, 0);
|
||||
}
|
||||
InstLoc EmitStoreMSR(InstLoc val, InstLoc pc) {
|
||||
|
||||
InstLoc EmitStoreMSR(InstLoc val, InstLoc pc)
|
||||
{
|
||||
return FoldBiOp(StoreMSR, val, pc);
|
||||
}
|
||||
InstLoc EmitStoreFPRF(InstLoc value) {
|
||||
|
||||
InstLoc EmitStoreFPRF(InstLoc value)
|
||||
{
|
||||
return FoldUOp(StoreFPRF, value);
|
||||
}
|
||||
InstLoc EmitLoadGReg(unsigned reg) {
|
||||
|
||||
InstLoc EmitLoadGReg(unsigned reg)
|
||||
{
|
||||
return FoldZeroOp(LoadGReg, reg);
|
||||
}
|
||||
InstLoc EmitStoreGReg(InstLoc value, unsigned reg) {
|
||||
|
||||
InstLoc EmitStoreGReg(InstLoc value, unsigned reg)
|
||||
{
|
||||
return FoldUOp(StoreGReg, value, reg);
|
||||
}
|
||||
InstLoc EmitNot(InstLoc op1) {
|
||||
|
||||
InstLoc EmitNot(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(Not, op1);
|
||||
}
|
||||
InstLoc EmitAnd(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitAnd(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(And, op1, op2);
|
||||
}
|
||||
InstLoc EmitXor(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitXor(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Xor, op1, op2);
|
||||
}
|
||||
InstLoc EmitSub(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitSub(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Sub, op1, op2);
|
||||
}
|
||||
InstLoc EmitOr(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitOr(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Or, op1, op2);
|
||||
}
|
||||
InstLoc EmitAdd(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitAdd(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Add, op1, op2);
|
||||
}
|
||||
InstLoc EmitMul(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitMul(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Mul, op1, op2);
|
||||
}
|
||||
InstLoc EmitMulHighUnsigned(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitMulHighUnsigned(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(MulHighUnsigned, op1, op2);
|
||||
}
|
||||
InstLoc EmitRol(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitRol(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Rol, op1, op2);
|
||||
}
|
||||
InstLoc EmitShl(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitShl(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Shl, op1, op2);
|
||||
}
|
||||
InstLoc EmitShrl(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitShrl(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Shrl, op1, op2);
|
||||
}
|
||||
InstLoc EmitSarl(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitSarl(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Sarl, op1, op2);
|
||||
}
|
||||
InstLoc EmitLoadCTR() {
|
||||
|
||||
InstLoc EmitLoadCTR()
|
||||
{
|
||||
return FoldZeroOp(LoadCTR, 0);
|
||||
}
|
||||
InstLoc EmitStoreCTR(InstLoc op1) {
|
||||
|
||||
InstLoc EmitStoreCTR(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(StoreCTR, op1);
|
||||
}
|
||||
InstLoc EmitICmpEq(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpEq(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpEq, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpNe(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpNe(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpNe, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpUgt(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpUgt(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpUgt, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpUlt(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpUlt(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpUlt, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpSgt(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpSgt(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpSgt, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpSlt(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpSlt(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpSlt, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpSge(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpSge(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpSge, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpSle(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpSle(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpSle, op1, op2);
|
||||
}
|
||||
InstLoc EmitLoad8(InstLoc op1) {
|
||||
|
||||
InstLoc EmitLoad8(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(Load8, op1);
|
||||
}
|
||||
InstLoc EmitLoad16(InstLoc op1) {
|
||||
|
||||
InstLoc EmitLoad16(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(Load16, op1);
|
||||
}
|
||||
InstLoc EmitLoad32(InstLoc op1) {
|
||||
|
||||
InstLoc EmitLoad32(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(Load32, op1);
|
||||
}
|
||||
InstLoc EmitStore8(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitStore8(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Store8, op1, op2);
|
||||
}
|
||||
InstLoc EmitStore16(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitStore16(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Store16, op1, op2);
|
||||
}
|
||||
InstLoc EmitStore32(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitStore32(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(Store32, op1, op2);
|
||||
}
|
||||
InstLoc EmitSExt16(InstLoc op1) {
|
||||
|
||||
InstLoc EmitSExt16(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(SExt16, op1);
|
||||
}
|
||||
InstLoc EmitSExt8(InstLoc op1) {
|
||||
|
||||
InstLoc EmitSExt8(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(SExt8, op1);
|
||||
}
|
||||
InstLoc EmitCntlzw(InstLoc op1) {
|
||||
|
||||
InstLoc EmitCntlzw(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(Cntlzw, op1);
|
||||
}
|
||||
InstLoc EmitICmpCRSigned(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpCRSigned(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpCRSigned, op1, op2);
|
||||
}
|
||||
InstLoc EmitICmpCRUnsigned(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitICmpCRUnsigned(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(ICmpCRUnsigned, op1, op2);
|
||||
}
|
||||
InstLoc EmitConvertFromFastCR(InstLoc op1) {
|
||||
|
||||
InstLoc EmitConvertFromFastCR(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(ConvertFromFastCR, op1);
|
||||
}
|
||||
InstLoc EmitConvertToFastCR(InstLoc op1) {
|
||||
|
||||
InstLoc EmitConvertToFastCR(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(ConvertToFastCR, op1);
|
||||
}
|
||||
InstLoc EmitFastCRSOSet(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFastCRSOSet(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FastCRSOSet, op1);
|
||||
}
|
||||
InstLoc EmitFastCREQSet(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFastCREQSet(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FastCREQSet, op1);
|
||||
}
|
||||
InstLoc EmitFastCRLTSet(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFastCRLTSet(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FastCRLTSet, op1);
|
||||
}
|
||||
InstLoc EmitFastCRGTSet(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFastCRGTSet(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FastCRGTSet, op1);
|
||||
}
|
||||
InstLoc EmitFallBackToInterpreter(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFallBackToInterpreter(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FallBackToInterpreter, op1, op2);
|
||||
}
|
||||
InstLoc EmitInterpreterBranch() {
|
||||
|
||||
InstLoc EmitInterpreterBranch()
|
||||
{
|
||||
return FoldZeroOp(InterpreterBranch, 0);
|
||||
}
|
||||
InstLoc EmitLoadCarry() {
|
||||
|
||||
InstLoc EmitLoadCarry()
|
||||
{
|
||||
return FoldZeroOp(LoadCarry, 0);
|
||||
}
|
||||
InstLoc EmitStoreCarry(InstLoc op1) {
|
||||
|
||||
InstLoc EmitStoreCarry(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(StoreCarry, op1);
|
||||
}
|
||||
InstLoc EmitSystemCall(InstLoc pc) {
|
||||
|
||||
InstLoc EmitSystemCall(InstLoc pc)
|
||||
{
|
||||
return FoldUOp(SystemCall, pc);
|
||||
}
|
||||
InstLoc EmitFPExceptionCheck(InstLoc pc) {
|
||||
|
||||
InstLoc EmitFPExceptionCheck(InstLoc pc)
|
||||
{
|
||||
return EmitUOp(FPExceptionCheck, pc);
|
||||
}
|
||||
InstLoc EmitDSIExceptionCheck(InstLoc pc) {
|
||||
|
||||
InstLoc EmitDSIExceptionCheck(InstLoc pc)
|
||||
{
|
||||
return EmitUOp(DSIExceptionCheck, pc);
|
||||
}
|
||||
InstLoc EmitISIException(InstLoc dest) {
|
||||
|
||||
InstLoc EmitISIException(InstLoc dest)
|
||||
{
|
||||
return EmitUOp(ISIException, dest);
|
||||
}
|
||||
InstLoc EmitExtExceptionCheck(InstLoc pc) {
|
||||
|
||||
InstLoc EmitExtExceptionCheck(InstLoc pc)
|
||||
{
|
||||
return EmitUOp(ExtExceptionCheck, pc);
|
||||
}
|
||||
InstLoc EmitBreakPointCheck(InstLoc pc) {
|
||||
|
||||
InstLoc EmitBreakPointCheck(InstLoc pc)
|
||||
{
|
||||
return EmitUOp(BreakPointCheck, pc);
|
||||
}
|
||||
InstLoc EmitRFIExit() {
|
||||
|
||||
InstLoc EmitRFIExit()
|
||||
{
|
||||
return FoldZeroOp(RFIExit, 0);
|
||||
}
|
||||
InstLoc EmitShortIdleLoop(InstLoc pc) {
|
||||
|
||||
InstLoc EmitShortIdleLoop(InstLoc pc)
|
||||
{
|
||||
return FoldUOp(ShortIdleLoop, pc);
|
||||
}
|
||||
InstLoc EmitLoadSingle(InstLoc addr) {
|
||||
|
||||
InstLoc EmitLoadSingle(InstLoc addr)
|
||||
{
|
||||
return FoldUOp(LoadSingle, addr);
|
||||
}
|
||||
InstLoc EmitLoadDouble(InstLoc addr) {
|
||||
|
||||
InstLoc EmitLoadDouble(InstLoc addr)
|
||||
{
|
||||
return FoldUOp(LoadDouble, addr);
|
||||
}
|
||||
InstLoc EmitLoadPaired(InstLoc addr, unsigned quantReg) {
|
||||
|
||||
InstLoc EmitLoadPaired(InstLoc addr, unsigned quantReg)
|
||||
{
|
||||
return FoldUOp(LoadPaired, addr, quantReg);
|
||||
}
|
||||
InstLoc EmitStoreSingle(InstLoc value, InstLoc addr) {
|
||||
|
||||
InstLoc EmitStoreSingle(InstLoc value, InstLoc addr)
|
||||
{
|
||||
return FoldBiOp(StoreSingle, value, addr);
|
||||
}
|
||||
InstLoc EmitStoreDouble(InstLoc value, InstLoc addr) {
|
||||
|
||||
InstLoc EmitStoreDouble(InstLoc value, InstLoc addr)
|
||||
{
|
||||
return FoldBiOp(StoreDouble, value, addr);
|
||||
}
|
||||
InstLoc EmitStorePaired(InstLoc value, InstLoc addr, unsigned quantReg) {
|
||||
|
||||
InstLoc EmitStorePaired(InstLoc value, InstLoc addr, unsigned quantReg)
|
||||
{
|
||||
return FoldBiOp(StorePaired, value, addr, quantReg);
|
||||
}
|
||||
InstLoc EmitLoadFReg(unsigned freg) {
|
||||
|
||||
InstLoc EmitLoadFReg(unsigned freg)
|
||||
{
|
||||
return FoldZeroOp(LoadFReg, freg);
|
||||
}
|
||||
InstLoc EmitLoadFRegDENToZero(unsigned freg) {
|
||||
|
||||
InstLoc EmitLoadFRegDENToZero(unsigned freg)
|
||||
{
|
||||
return FoldZeroOp(LoadFRegDENToZero, freg);
|
||||
}
|
||||
InstLoc EmitStoreFReg(InstLoc val, unsigned freg) {
|
||||
|
||||
InstLoc EmitStoreFReg(InstLoc val, unsigned freg)
|
||||
{
|
||||
return FoldUOp(StoreFReg, val, freg);
|
||||
}
|
||||
InstLoc EmitDupSingleToMReg(InstLoc val) {
|
||||
|
||||
InstLoc EmitDupSingleToMReg(InstLoc val)
|
||||
{
|
||||
return FoldUOp(DupSingleToMReg, val);
|
||||
}
|
||||
InstLoc EmitDupSingleToPacked(InstLoc val) {
|
||||
|
||||
InstLoc EmitDupSingleToPacked(InstLoc val)
|
||||
{
|
||||
return FoldUOp(DupSingleToPacked, val);
|
||||
}
|
||||
InstLoc EmitInsertDoubleInMReg(InstLoc val, InstLoc reg) {
|
||||
|
||||
InstLoc EmitInsertDoubleInMReg(InstLoc val, InstLoc reg)
|
||||
{
|
||||
return FoldBiOp(InsertDoubleInMReg, val, reg);
|
||||
}
|
||||
InstLoc EmitExpandPackedToMReg(InstLoc val) {
|
||||
|
||||
InstLoc EmitExpandPackedToMReg(InstLoc val)
|
||||
{
|
||||
return FoldUOp(ExpandPackedToMReg, val);
|
||||
}
|
||||
InstLoc EmitCompactMRegToPacked(InstLoc val) {
|
||||
|
||||
InstLoc EmitCompactMRegToPacked(InstLoc val)
|
||||
{
|
||||
return FoldUOp(CompactMRegToPacked, val);
|
||||
}
|
||||
InstLoc EmitFSMul(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFSMul(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FSMul, op1, op2);
|
||||
}
|
||||
InstLoc EmitFSAdd(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFSAdd(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FSAdd, op1, op2);
|
||||
}
|
||||
InstLoc EmitFSSub(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFSSub(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FSSub, op1, op2);
|
||||
}
|
||||
InstLoc EmitFSNeg(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFSNeg(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FSNeg, op1);
|
||||
}
|
||||
InstLoc EmitFDMul(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFDMul(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FDMul, op1, op2);
|
||||
}
|
||||
InstLoc EmitFDAdd(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFDAdd(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FDAdd, op1, op2);
|
||||
}
|
||||
InstLoc EmitFDSub(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFDSub(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FDSub, op1, op2);
|
||||
}
|
||||
InstLoc EmitFDNeg(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFDNeg(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FDNeg, op1);
|
||||
}
|
||||
InstLoc EmitFPAdd(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPAdd(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPAdd, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPMul(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPMul(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPMul, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPSub(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPSub(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPSub, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPMerge00(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPMerge00(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPMerge00, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPMerge01(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPMerge01(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPMerge01, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPMerge10(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPMerge10(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPMerge10, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPMerge11(InstLoc op1, InstLoc op2) {
|
||||
|
||||
InstLoc EmitFPMerge11(InstLoc op1, InstLoc op2)
|
||||
{
|
||||
return FoldBiOp(FPMerge11, op1, op2);
|
||||
}
|
||||
InstLoc EmitFPDup0(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFPDup0(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FPDup0, op1);
|
||||
}
|
||||
InstLoc EmitFPDup1(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFPDup1(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FPDup1, op1);
|
||||
}
|
||||
InstLoc EmitFPNeg(InstLoc op1) {
|
||||
|
||||
InstLoc EmitFPNeg(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(FPNeg, op1);
|
||||
}
|
||||
InstLoc EmitDoubleToSingle(InstLoc op1) {
|
||||
|
||||
InstLoc EmitDoubleToSingle(InstLoc op1)
|
||||
{
|
||||
return FoldUOp(DoubleToSingle, op1);
|
||||
}
|
||||
InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2, int ordered) {
|
||||
|
||||
InstLoc EmitFDCmpCR(InstLoc op1, InstLoc op2, int ordered)
|
||||
{
|
||||
return FoldBiOp(FDCmpCR, op1, op2, ordered);
|
||||
}
|
||||
InstLoc EmitLoadGQR(unsigned gqr) {
|
||||
|
||||
InstLoc EmitLoadGQR(unsigned gqr)
|
||||
{
|
||||
return FoldZeroOp(LoadGQR, gqr);
|
||||
}
|
||||
InstLoc EmitStoreGQR(InstLoc op1, unsigned gqr) {
|
||||
|
||||
InstLoc EmitStoreGQR(InstLoc op1, unsigned gqr)
|
||||
{
|
||||
return FoldUOp(StoreGQR, op1, gqr);
|
||||
}
|
||||
InstLoc EmitStoreSRR(InstLoc op1, unsigned srr) {
|
||||
|
||||
InstLoc EmitStoreSRR(InstLoc op1, unsigned srr)
|
||||
{
|
||||
return FoldUOp(StoreSRR, op1, srr);
|
||||
}
|
||||
|
||||
InstLoc EmitINT3()
|
||||
{
|
||||
return FoldZeroOp(Int3, 0);
|
||||
|
@ -566,28 +779,38 @@ public:
|
|||
bool IsMarkUsed(InstLoc I) const;
|
||||
void WriteToFile(u64 codeHash);
|
||||
|
||||
void Reset() {
|
||||
void Reset()
|
||||
{
|
||||
InstList.clear();
|
||||
InstList.reserve(100000);
|
||||
MarkUsed.clear();
|
||||
MarkUsed.reserve(100000);
|
||||
for (unsigned i = 0; i < 32; i++) {
|
||||
|
||||
for (unsigned i = 0; i < 32; i++)
|
||||
{
|
||||
GRegCache[i] = nullptr;
|
||||
GRegCacheStore[i] = nullptr;
|
||||
FRegCache[i] = nullptr;
|
||||
FRegCacheStore[i] = nullptr;
|
||||
}
|
||||
|
||||
CarryCache = nullptr;
|
||||
CarryCacheStore = nullptr;
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
|
||||
for (unsigned i = 0; i < 8; i++)
|
||||
{
|
||||
CRCache[i] = nullptr;
|
||||
CRCacheStore[i] = nullptr;
|
||||
}
|
||||
|
||||
CTRCache = nullptr;
|
||||
CTRCacheStore = nullptr;
|
||||
}
|
||||
|
||||
IRBuilder() { Reset(); }
|
||||
IRBuilder()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
private:
|
||||
IRBuilder(IRBuilder&); // DO NOT IMPLEMENT
|
||||
|
|
|
@ -43,7 +43,8 @@ void JitILBase::bx(UGeckoInstruction inst)
|
|||
// If this is not the last instruction of a block,
|
||||
// we will skip the rest process.
|
||||
// Because PPCAnalyst::Flatten() merged the blocks.
|
||||
if (!js.isLastInstruction) {
|
||||
if (!js.isLastInstruction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -53,7 +54,8 @@ void JitILBase::bx(UGeckoInstruction inst)
|
|||
else
|
||||
destination = js.compilerPC + SignExt26(inst.LI << 2);
|
||||
|
||||
if (destination == js.compilerPC) {
|
||||
if (destination == js.compilerPC)
|
||||
{
|
||||
ibuild.EmitShortIdleLoop(ibuild.EmitIntConst(js.compilerPC));
|
||||
return;
|
||||
}
|
||||
|
@ -85,36 +87,40 @@ static IREmitter::InstLoc EmitCRTest(IREmitter::IRBuilder& ibuild, UGeckoInstruc
|
|||
return CRTest;
|
||||
}
|
||||
|
||||
static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruction inst) {
|
||||
static IREmitter::InstLoc TestBranch(IREmitter::IRBuilder& ibuild, UGeckoInstruction inst)
|
||||
{
|
||||
IREmitter::InstLoc CRTest = nullptr, CTRTest = nullptr;
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
{
|
||||
CRTest = EmitCRTest(ibuild, inst);
|
||||
}
|
||||
|
||||
if ((inst.BO & 4) == 0) {
|
||||
if ((inst.BO & 4) == 0)
|
||||
{
|
||||
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||
c = ibuild.EmitSub(c, ibuild.EmitIntConst(1));
|
||||
ibuild.EmitStoreCTR(c);
|
||||
if (inst.BO & 2) {
|
||||
CTRTest = ibuild.EmitICmpEq(c,
|
||||
ibuild.EmitIntConst(0));
|
||||
} else {
|
||||
|
||||
if (inst.BO & 2)
|
||||
CTRTest = ibuild.EmitICmpEq(c, ibuild.EmitIntConst(0));
|
||||
else
|
||||
CTRTest = c;
|
||||
}
|
||||
}
|
||||
|
||||
IREmitter::InstLoc Test = CRTest;
|
||||
if (CTRTest) {
|
||||
if (CTRTest)
|
||||
{
|
||||
if (Test)
|
||||
Test = ibuild.EmitAnd(Test, CTRTest);
|
||||
else
|
||||
Test = CTRTest;
|
||||
}
|
||||
|
||||
if (!Test) {
|
||||
if (!Test)
|
||||
{
|
||||
Test = ibuild.EmitIntConst(1);
|
||||
}
|
||||
|
||||
return Test;
|
||||
}
|
||||
|
||||
|
@ -122,8 +128,7 @@ void JitILBase::bcx(UGeckoInstruction inst)
|
|||
{
|
||||
NORMALBRANCH_START
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(
|
||||
ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
||||
IREmitter::InstLoc Test = TestBranch(ibuild, inst);
|
||||
|
||||
|
@ -134,11 +139,11 @@ void JitILBase::bcx(UGeckoInstruction inst)
|
|||
destination = js.compilerPC + SignExt16(inst.BD << 2);
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle &&
|
||||
inst.hex == 0x4182fff8 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
|
||||
(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
|
||||
)
|
||||
inst.hex == 0x4182fff8 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 8) & 0xFFFF0000) == 0x800D0000 &&
|
||||
(Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x28000000 ||
|
||||
(SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC - 4) == 0x2C000000))
|
||||
)
|
||||
{
|
||||
ibuild.EmitIdleBranch(Test, ibuild.EmitIntConst(destination));
|
||||
}
|
||||
|
@ -152,11 +157,13 @@ void JitILBase::bcx(UGeckoInstruction inst)
|
|||
void JitILBase::bcctrx(UGeckoInstruction inst)
|
||||
{
|
||||
NORMALBRANCH_START
|
||||
if ((inst.BO & 4) == 0) {
|
||||
if ((inst.BO & 4) == 0)
|
||||
{
|
||||
IREmitter::InstLoc c = ibuild.EmitLoadCTR();
|
||||
c = ibuild.EmitSub(c, ibuild.EmitIntConst(1));
|
||||
ibuild.EmitStoreCTR(c);
|
||||
}
|
||||
|
||||
IREmitter::InstLoc test;
|
||||
if ((inst.BO & 16) == 0) // Test a CR bit
|
||||
{
|
||||
|
@ -181,16 +188,19 @@ void JitILBase::bclrx(UGeckoInstruction inst)
|
|||
NORMALBRANCH_START
|
||||
|
||||
if (!js.isLastInstruction &&
|
||||
(inst.BO & (1 << 4)) && (inst.BO & (1 << 2))) {
|
||||
(inst.BO & (1 << 4)) && (inst.BO & (1 << 2)))
|
||||
{
|
||||
if (inst.LK)
|
||||
ibuild.EmitStoreLink(ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
return;
|
||||
}
|
||||
|
||||
if (inst.hex == 0x4e800020) {
|
||||
if (inst.hex == 0x4e800020)
|
||||
{
|
||||
ibuild.EmitBranchUncond(ibuild.EmitLoadLink());
|
||||
return;
|
||||
}
|
||||
|
||||
IREmitter::InstLoc test = TestBranch(ibuild, inst);
|
||||
test = ibuild.EmitICmpEq(test, ibuild.EmitIntConst(0));
|
||||
ibuild.EmitBranchCond(test, ibuild.EmitIntConst(js.compilerPC + 4));
|
||||
|
|
|
@ -30,10 +30,13 @@ void JitILBase::fp_arith_s(UGeckoInstruction inst)
|
|||
_assert_msg_(DYNA_REC, 0, "fp_arith_s WTF!!!");
|
||||
}
|
||||
|
||||
if (inst.OPCD == 59) {
|
||||
if (inst.OPCD == 59)
|
||||
{
|
||||
val = ibuild.EmitDoubleToSingle(val);
|
||||
val = ibuild.EmitDupSingleToMReg(val);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
val = ibuild.EmitInsertDoubleInMReg(val, ibuild.EmitLoadFReg(inst.FD));
|
||||
}
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
|
@ -50,18 +53,25 @@ void JitILBase::fmaddXX(UGeckoInstruction inst)
|
|||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadFReg(inst.FA);
|
||||
val = ibuild.EmitFDMul(val, ibuild.EmitLoadFReg(inst.FC));
|
||||
|
||||
if (inst.SUBOP5 & 1)
|
||||
val = ibuild.EmitFDAdd(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
else
|
||||
val = ibuild.EmitFDSub(val, ibuild.EmitLoadFReg(inst.FB));
|
||||
|
||||
if (inst.SUBOP5 & 2)
|
||||
val = ibuild.EmitFDNeg(val);
|
||||
if (inst.OPCD == 59) {
|
||||
|
||||
if (inst.OPCD == 59)
|
||||
{
|
||||
val = ibuild.EmitDoubleToSingle(val);
|
||||
val = ibuild.EmitDupSingleToMReg(val);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
val = ibuild.EmitInsertDoubleInMReg(val, ibuild.EmitLoadFReg(inst.FD));
|
||||
}
|
||||
|
||||
ibuild.EmitStoreFReg(val, inst.FD);
|
||||
}
|
||||
|
||||
|
@ -97,7 +107,8 @@ void JitILBase::fsign(UGeckoInstruction inst)
|
|||
FALLBACK_IF(true);
|
||||
|
||||
// TODO
|
||||
switch (inst.SUBOP10) {
|
||||
switch (inst.SUBOP10)
|
||||
{
|
||||
case 40: // fnegx
|
||||
break;
|
||||
case 264: // fabsx
|
||||
|
|
|
@ -198,7 +198,7 @@ void JitILBase::subfic(UGeckoInstruction inst)
|
|||
JITDISABLE(bJITIntegerOff);
|
||||
IREmitter::InstLoc nota, lhs, val, test;
|
||||
nota = ibuild.EmitXor(ibuild.EmitLoadGReg(inst.RA),
|
||||
ibuild.EmitIntConst(-1));
|
||||
ibuild.EmitIntConst(-1));
|
||||
|
||||
if (inst.SIMM_16 == -1)
|
||||
{
|
||||
|
@ -220,7 +220,10 @@ void JitILBase::subfcx(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
if (inst.OE) PanicAlert("OE: subfcx");
|
||||
|
||||
if (inst.OE)
|
||||
PanicAlert("OE: subfcx");
|
||||
|
||||
IREmitter::InstLoc val, test, lhs, rhs;
|
||||
lhs = ibuild.EmitLoadGReg(inst.RB);
|
||||
rhs = ibuild.EmitLoadGReg(inst.RA);
|
||||
|
@ -229,6 +232,7 @@ void JitILBase::subfcx(UGeckoInstruction inst)
|
|||
test = ibuild.EmitICmpEq(rhs, ibuild.EmitIntConst(0));
|
||||
test = ibuild.EmitOr(test, ibuild.EmitICmpUgt(lhs, val));
|
||||
ibuild.EmitStoreCarry(test);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -237,7 +241,10 @@ void JitILBase::subfex(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
if (inst.OE) PanicAlert("OE: subfex");
|
||||
|
||||
if (inst.OE)
|
||||
PanicAlert("OE: subfex");
|
||||
|
||||
IREmitter::InstLoc val, test, lhs, rhs, carry;
|
||||
rhs = ibuild.EmitLoadGReg(inst.RA);
|
||||
carry = ibuild.EmitLoadCarry();
|
||||
|
@ -250,6 +257,7 @@ void JitILBase::subfex(UGeckoInstruction inst)
|
|||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
test = ibuild.EmitOr(test, ibuild.EmitICmpUgt(lhs, val));
|
||||
ibuild.EmitStoreCarry(test);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -258,10 +266,14 @@ void JitILBase::subfx(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
if (inst.OE) PanicAlert("OE: subfx");
|
||||
|
||||
if (inst.OE)
|
||||
PanicAlert("OE: subfx");
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RB);
|
||||
val = ibuild.EmitSub(val, ibuild.EmitLoadGReg(inst.RA));
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -282,6 +294,7 @@ void JitILBase::mullwx(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RB);
|
||||
val = ibuild.EmitMul(ibuild.EmitLoadGReg(inst.RA), val);
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -295,6 +308,7 @@ void JitILBase::mulhwux(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc b = ibuild.EmitLoadGReg(inst.RB);
|
||||
IREmitter::InstLoc d = ibuild.EmitMulHighUnsigned(a, b);
|
||||
ibuild.EmitStoreGReg(d, inst.RD);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, d);
|
||||
}
|
||||
|
@ -326,7 +340,9 @@ void JitILBase::divwux(UGeckoInstruction inst)
|
|||
MOV(32, gpr.R(d), R(EAX));
|
||||
gpr.UnlockAll();
|
||||
gpr.UnlockAllX();
|
||||
if (inst.Rc) {
|
||||
|
||||
if (inst.Rc)
|
||||
{
|
||||
CALL((u8*)asm_routines.computeRc);
|
||||
}
|
||||
#endif
|
||||
|
@ -339,6 +355,7 @@ void JitILBase::addx(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RB);
|
||||
val = ibuild.EmitAdd(ibuild.EmitLoadGReg(inst.RA), val);
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -347,12 +364,12 @@ void JitILBase::addzex(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
IREmitter::InstLoc lhs = ibuild.EmitLoadGReg(inst.RA),
|
||||
val, newcarry;
|
||||
IREmitter::InstLoc lhs = ibuild.EmitLoadGReg(inst.RA), val, newcarry;
|
||||
val = ibuild.EmitAdd(lhs, ibuild.EmitLoadCarry());
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
newcarry = ibuild.EmitICmpUlt(val, lhs);
|
||||
ibuild.EmitStoreCarry(newcarry);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -375,7 +392,9 @@ void JitILBase::addex(UGeckoInstruction inst)
|
|||
ibuild.EmitStoreGReg(abc, inst.RD);
|
||||
ibuild.EmitStoreCarry(new_carry);
|
||||
|
||||
if (inst.OE) PanicAlert("OE: addex");
|
||||
if (inst.OE)
|
||||
PanicAlert("OE: addex");
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, abc);
|
||||
}
|
||||
|
@ -389,6 +408,7 @@ void JitILBase::rlwinmx(UGeckoInstruction inst)
|
|||
val = ibuild.EmitRol(val, ibuild.EmitIntConst(inst.SH));
|
||||
val = ibuild.EmitAnd(val, ibuild.EmitIntConst(mask));
|
||||
ibuild.EmitStoreGReg(val, inst.RA);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -406,6 +426,7 @@ void JitILBase::rlwimix(UGeckoInstruction inst)
|
|||
ival = ibuild.EmitAnd(ival, ibuild.EmitIntConst(~mask));
|
||||
val = ibuild.EmitOr(ival, val);
|
||||
ibuild.EmitStoreGReg(val, inst.RA);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -419,6 +440,7 @@ void JitILBase::rlwnmx(UGeckoInstruction inst)
|
|||
val = ibuild.EmitRol(val, ibuild.EmitLoadGReg(inst.RB));
|
||||
val = ibuild.EmitAnd(val, ibuild.EmitIntConst(mask));
|
||||
ibuild.EmitStoreGReg(val, inst.RA);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -430,6 +452,7 @@ void JitILBase::negx(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RA);
|
||||
val = ibuild.EmitSub(ibuild.EmitIntConst(0), val);
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -438,9 +461,11 @@ void JitILBase::srwx(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS),
|
||||
samt = ibuild.EmitLoadGReg(inst.RB),
|
||||
corr;
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
|
||||
IREmitter::InstLoc samt = ibuild.EmitLoadGReg(inst.RB);
|
||||
IREmitter::InstLoc corr;
|
||||
|
||||
// FIXME: We can do better with a cmov
|
||||
// FIXME: We can do better on 64-bit
|
||||
val = ibuild.EmitShrl(val, samt);
|
||||
|
@ -449,6 +474,7 @@ void JitILBase::srwx(UGeckoInstruction inst)
|
|||
corr = ibuild.EmitXor(corr, ibuild.EmitIntConst(-1));
|
||||
val = ibuild.EmitAnd(corr, val);
|
||||
ibuild.EmitStoreGReg(val, inst.RA);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -457,9 +483,11 @@ void JitILBase::slwx(UGeckoInstruction inst)
|
|||
{
|
||||
INSTRUCTION_START
|
||||
JITDISABLE(bJITIntegerOff);
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS),
|
||||
samt = ibuild.EmitLoadGReg(inst.RB),
|
||||
corr;
|
||||
|
||||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
|
||||
IREmitter::InstLoc samt = ibuild.EmitLoadGReg(inst.RB);
|
||||
IREmitter::InstLoc corr;
|
||||
|
||||
// FIXME: We can do better with a cmov
|
||||
// FIXME: We can do better on 64-bit
|
||||
val = ibuild.EmitShl(val, samt);
|
||||
|
@ -468,6 +496,7 @@ void JitILBase::slwx(UGeckoInstruction inst)
|
|||
corr = ibuild.EmitXor(corr, ibuild.EmitIntConst(-1));
|
||||
val = ibuild.EmitAnd(corr, val);
|
||||
ibuild.EmitStoreGReg(val, inst.RA);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
@ -524,6 +553,7 @@ void JitILBase::cntlzwx(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc val = ibuild.EmitLoadGReg(inst.RS);
|
||||
val = ibuild.EmitCntlzw(val);
|
||||
ibuild.EmitStoreGReg(val, inst.RA);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(ibuild, val);
|
||||
}
|
||||
|
|
|
@ -35,11 +35,21 @@ void JitILBase::lXz(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc val;
|
||||
switch (inst.OPCD & ~0x1)
|
||||
{
|
||||
case 32: val = ibuild.EmitLoad32(addr); break; //lwz
|
||||
case 40: val = ibuild.EmitLoad16(addr); break; //lhz
|
||||
case 34: val = ibuild.EmitLoad8(addr); break; //lbz
|
||||
default: PanicAlert("lXz: invalid access size"); val = nullptr; break;
|
||||
case 32: // lwz
|
||||
val = ibuild.EmitLoad32(addr);
|
||||
break;
|
||||
case 40: // lhz
|
||||
val = ibuild.EmitLoad16(addr);
|
||||
break;
|
||||
case 34: // lbz
|
||||
val = ibuild.EmitLoad8(addr);
|
||||
break;
|
||||
default:
|
||||
PanicAlert("lXz: invalid access size");
|
||||
val = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
}
|
||||
|
||||
|
@ -87,10 +97,17 @@ void JitILBase::lXzx(UGeckoInstruction inst)
|
|||
IREmitter::InstLoc val;
|
||||
switch (inst.SUBOP10 & ~32)
|
||||
{
|
||||
default: PanicAlert("lXzx: invalid access size");
|
||||
case 23: val = ibuild.EmitLoad32(addr); break; //lwzx
|
||||
case 279: val = ibuild.EmitLoad16(addr); break; //lhzx
|
||||
case 87: val = ibuild.EmitLoad8(addr); break; //lbzx
|
||||
default:
|
||||
PanicAlert("lXzx: invalid access size");
|
||||
case 23: // lwzx
|
||||
val = ibuild.EmitLoad32(addr);
|
||||
break;
|
||||
case 279: // lhzx
|
||||
val = ibuild.EmitLoad16(addr);
|
||||
break;
|
||||
case 87: // lbzx
|
||||
val = ibuild.EmitLoad8(addr);
|
||||
break;
|
||||
}
|
||||
ibuild.EmitStoreGReg(val, inst.RD);
|
||||
}
|
||||
|
@ -115,7 +132,10 @@ void JitILBase::dcbz(UGeckoInstruction inst)
|
|||
// TODO!
|
||||
#if 0
|
||||
if (Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
|
||||
{Default(inst); return;} // turn off from debugger
|
||||
{
|
||||
Default(inst);
|
||||
return;
|
||||
}
|
||||
INSTRUCTION_START;
|
||||
MOV(32, R(EAX), gpr.R(inst.RB));
|
||||
if (inst.RA)
|
||||
|
@ -149,10 +169,18 @@ void JitILBase::stX(UGeckoInstruction inst)
|
|||
|
||||
switch (inst.OPCD & ~1)
|
||||
{
|
||||
case 36: ibuild.EmitStore32(value, addr); break; //stw
|
||||
case 44: ibuild.EmitStore16(value, addr); break; //sth
|
||||
case 38: ibuild.EmitStore8(value, addr); break; //stb
|
||||
default: _assert_msg_(DYNA_REC, 0, "AWETKLJASDLKF"); return;
|
||||
case 36: // stw
|
||||
ibuild.EmitStore32(value, addr);
|
||||
break;
|
||||
case 44: // sth
|
||||
ibuild.EmitStore16(value, addr);
|
||||
break;
|
||||
case 38: // stb
|
||||
ibuild.EmitStore8(value, addr);
|
||||
break;
|
||||
default:
|
||||
_assert_msg_(DYNA_REC, 0, "AWETKLJASDLKF");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,10 +200,18 @@ void JitILBase::stXx(UGeckoInstruction inst)
|
|||
|
||||
switch (inst.SUBOP10 & ~32)
|
||||
{
|
||||
case 151: ibuild.EmitStore32(value, addr); break; //stw
|
||||
case 407: ibuild.EmitStore16(value, addr); break; //sth
|
||||
case 215: ibuild.EmitStore8(value, addr); break; //stb
|
||||
default: _assert_msg_(DYNA_REC, 0, "AWETKLJASDLKF"); return;
|
||||
case 151: // stw
|
||||
ibuild.EmitStore32(value, addr);
|
||||
break;
|
||||
case 407: // sth
|
||||
ibuild.EmitStore16(value, addr);
|
||||
break;
|
||||
case 215: // stb
|
||||
ibuild.EmitStore8(value, addr);
|
||||
break;
|
||||
default:
|
||||
_assert_msg_(DYNA_REC, 0, "AWETKLJASDLKF");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,8 @@ void JitILBase::ps_maddXX(UGeckoInstruction inst)
|
|||
|
||||
switch (inst.SUBOP5)
|
||||
{
|
||||
case 14: {//madds0
|
||||
case 14: // madds0
|
||||
{
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
op2 = ibuild.EmitFPDup0(op2);
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
|
@ -137,7 +138,8 @@ void JitILBase::ps_maddXX(UGeckoInstruction inst)
|
|||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 15: {//madds1
|
||||
case 15: // madds1
|
||||
{
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
op2 = ibuild.EmitFPDup1(op2);
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
|
@ -145,21 +147,24 @@ void JitILBase::ps_maddXX(UGeckoInstruction inst)
|
|||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 28: {//msub
|
||||
case 28: // msub
|
||||
{
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPSub(val, op3);
|
||||
break;
|
||||
}
|
||||
case 29: {//madd
|
||||
case 29: // madd
|
||||
{
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
val = ibuild.EmitFPAdd(val, op3);
|
||||
break;
|
||||
}
|
||||
case 30: {//nmsub
|
||||
case 30: // nmsub
|
||||
{
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
|
@ -167,7 +172,8 @@ void JitILBase::ps_maddXX(UGeckoInstruction inst)
|
|||
val = ibuild.EmitFPNeg(val);
|
||||
break;
|
||||
}
|
||||
case 31: {//nmadd
|
||||
case 31: // nmadd
|
||||
{
|
||||
op2 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FC));
|
||||
val = ibuild.EmitFPMul(val, op2);
|
||||
op3 = ibuild.EmitCompactMRegToPacked(ibuild.EmitLoadFReg(inst.FB));
|
||||
|
|
|
@ -170,42 +170,35 @@ void JitILBase::crXX(UGeckoInstruction inst)
|
|||
|
||||
// Compute combined bit
|
||||
const unsigned subop = inst.SUBOP10;
|
||||
switch (subop) {
|
||||
case 257:
|
||||
// crand
|
||||
switch (subop)
|
||||
{
|
||||
case 257: // crand
|
||||
eax = ibuild.EmitAnd(eax, ecx);
|
||||
break;
|
||||
case 129:
|
||||
// crandc
|
||||
case 129: // crandc
|
||||
ecx = ibuild.EmitNot(ecx);
|
||||
eax = ibuild.EmitAnd(eax, ecx);
|
||||
break;
|
||||
case 289:
|
||||
// creqv
|
||||
case 289: // creqv
|
||||
eax = ibuild.EmitXor(eax, ecx);
|
||||
eax = ibuild.EmitNot(eax);
|
||||
break;
|
||||
case 225:
|
||||
// crnand
|
||||
case 225: // crnand
|
||||
eax = ibuild.EmitAnd(eax, ecx);
|
||||
eax = ibuild.EmitNot(eax);
|
||||
break;
|
||||
case 33:
|
||||
// crnor
|
||||
case 33: // crnor
|
||||
eax = ibuild.EmitOr(eax, ecx);
|
||||
eax = ibuild.EmitNot(eax);
|
||||
break;
|
||||
case 449:
|
||||
// cror
|
||||
case 449: // cror
|
||||
eax = ibuild.EmitOr(eax, ecx);
|
||||
break;
|
||||
case 417:
|
||||
// crorc
|
||||
case 417: // crorc
|
||||
ecx = ibuild.EmitNot(ecx);
|
||||
eax = ibuild.EmitOr(eax, ecx);
|
||||
break;
|
||||
case 193:
|
||||
// crxor
|
||||
case 193: // crxor
|
||||
eax = ibuild.EmitXor(eax, ecx);
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue