mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
Merge pull request #571 from Gutawer/asmjit
Added OP_MOVES, OP_CONCAT, OP_LENS, OP_CMPS
This commit is contained in:
commit
2ea97bac6d
5 changed files with 81 additions and 10 deletions
|
@ -154,14 +154,10 @@ bool JitCompiler::CanJit(VMScriptFunction *sfunc)
|
||||||
case OP_LFP:
|
case OP_LFP:
|
||||||
case OP_LCS_R:
|
case OP_LCS_R:
|
||||||
case OP_SS_R:
|
case OP_SS_R:
|
||||||
case OP_MOVES:
|
|
||||||
case OP_IJMP:
|
case OP_IJMP:
|
||||||
case OP_CALL: // this one is implemented but crashes currently
|
case OP_CALL: // this one is implemented but crashes currently
|
||||||
case OP_TAIL:
|
case OP_TAIL:
|
||||||
case OP_TAIL_K:
|
case OP_TAIL_K:
|
||||||
case OP_CONCAT:
|
|
||||||
case OP_LENS:
|
|
||||||
case OP_CMPS:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,6 +413,20 @@ asmjit::X86Xmm JitCompiler::CheckRegF(int r0, int r1, int r2, int r3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmjit::X86Gp JitCompiler::CheckRegS(int r0, int r1)
|
||||||
|
{
|
||||||
|
if (r0 != r1)
|
||||||
|
{
|
||||||
|
return regS[r0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto copy = cc.newIntPtr();
|
||||||
|
cc.mov(copy, regS[r0]);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
asmjit::X86Gp JitCompiler::CheckRegA(int r0, int r1)
|
asmjit::X86Gp JitCompiler::CheckRegA(int r0, int r1)
|
||||||
{
|
{
|
||||||
if (r0 != r1)
|
if (r0 != r1)
|
||||||
|
|
|
@ -6,17 +6,71 @@
|
||||||
|
|
||||||
void JitCompiler::EmitCONCAT()
|
void JitCompiler::EmitCONCAT()
|
||||||
{
|
{
|
||||||
I_FatalError("EmitCONCAT not implemented\n");
|
auto rc = CheckRegS(C, A);
|
||||||
|
auto concatLambda = [](FString* to, FString* first, FString* second) -> void {
|
||||||
|
*to = *first + *second;
|
||||||
|
};
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<void(*)(FString*, FString*, FString*)>(concatLambda))),
|
||||||
|
asmjit::FuncSignature3<void, FString*, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
|
||||||
|
call->setArg(0, regS[A]);
|
||||||
|
call->setArg(1, regS[B]);
|
||||||
|
call->setArg(2, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitLENS()
|
void JitCompiler::EmitLENS()
|
||||||
{
|
{
|
||||||
I_FatalError("EmitLENS not implemented\n");
|
auto lenLambda = [](FString* str) -> int {
|
||||||
|
return static_cast<int>(str->Len());
|
||||||
|
};
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<int(*)(FString*)>(lenLambda))),
|
||||||
|
asmjit::FuncSignature1<int, FString*>(asmjit::CallConv::kIdHostCDecl));
|
||||||
|
call->setRet(0, regD[A]);
|
||||||
|
call->setArg(0, regS[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitCMPS()
|
void JitCompiler::EmitCMPS()
|
||||||
{
|
{
|
||||||
I_FatalError("EmitCMPS not implemented\n");
|
EmitComparisonOpcode([&](bool check, asmjit::Label& fail, asmjit::Label& success) {
|
||||||
|
auto compareNoCaseLambda = [](FString* first, FString* second) -> int {
|
||||||
|
return first->CompareNoCase(*second);
|
||||||
|
};
|
||||||
|
auto compareLambda = [](FString* first, FString* second) -> int {
|
||||||
|
return first->Compare(*second);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto call =
|
||||||
|
static_cast<bool>(A & CMP_APPROX) ?
|
||||||
|
cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<int(*)(FString*, FString*)>(compareNoCaseLambda))),
|
||||||
|
asmjit::FuncSignature2<int, FString*, FString*>(asmjit::CallConv::kIdHostCDecl)) :
|
||||||
|
cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<int(*)(FString*, FString*)>(compareLambda))),
|
||||||
|
asmjit::FuncSignature2<int, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
|
||||||
|
|
||||||
|
auto result = cc.newInt32();
|
||||||
|
call->setRet(0, result);
|
||||||
|
|
||||||
|
if (static_cast<bool>(A & CMP_BK)) call->setArg(0, asmjit::imm_ptr(&konsts[B]));
|
||||||
|
else call->setArg(0, regS[B]);
|
||||||
|
|
||||||
|
if (static_cast<bool>(A & CMP_CK)) call->setArg(1, asmjit::imm_ptr(&konsts[C]));
|
||||||
|
else call->setArg(1, regS[C]);
|
||||||
|
|
||||||
|
int method = A & CMP_METHOD_MASK;
|
||||||
|
if (method == CMP_EQ) {
|
||||||
|
cc.test(result, result);
|
||||||
|
if (check) cc.jz(fail);
|
||||||
|
else cc.jnz(fail);
|
||||||
|
}
|
||||||
|
else if (method == CMP_LT) {
|
||||||
|
cc.cmp(result, 0);
|
||||||
|
if (check) cc.jl(fail);
|
||||||
|
else cc.jnl(fail);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cc.cmp(result, 0);
|
||||||
|
if (check) cc.jle(fail);
|
||||||
|
else cc.jnle(fail);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -12,7 +12,13 @@ void JitCompiler::EmitMOVEF()
|
||||||
|
|
||||||
void JitCompiler::EmitMOVES()
|
void JitCompiler::EmitMOVES()
|
||||||
{
|
{
|
||||||
I_FatalError("EmitMOVES not implemented\n");
|
auto loadLambda = [](FString* to, FString* from) -> void {
|
||||||
|
*to = *from;
|
||||||
|
};
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<void*>(static_cast<void(*)(FString*, FString*)>(loadLambda))),
|
||||||
|
asmjit::FuncSignature2<void, FString*, FString*>(asmjit::CallConv::kIdHostCDecl));
|
||||||
|
call->setArg(0, regS[A]);
|
||||||
|
call->setArg(1, regS[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitCompiler::EmitMOVEA()
|
void JitCompiler::EmitMOVEA()
|
||||||
|
|
|
@ -63,7 +63,7 @@ void JitCompiler::EmitSDP_R()
|
||||||
|
|
||||||
void JitCompiler::EmitSS()
|
void JitCompiler::EmitSS()
|
||||||
{
|
{
|
||||||
EmitNullPointerThrow(B, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
auto ptr = cc.newIntPtr();
|
auto ptr = cc.newIntPtr();
|
||||||
cc.mov(ptr, regA[A]);
|
cc.mov(ptr, regA[A]);
|
||||||
cc.add(ptr, konstd[C]);
|
cc.add(ptr, konstd[C]);
|
||||||
|
@ -78,7 +78,7 @@ void JitCompiler::EmitSS()
|
||||||
|
|
||||||
void JitCompiler::EmitSS_R()
|
void JitCompiler::EmitSS_R()
|
||||||
{
|
{
|
||||||
EmitNullPointerThrow(B, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
auto ptr = cc.newIntPtr();
|
auto ptr = cc.newIntPtr();
|
||||||
cc.mov(ptr, regA[A]);
|
cc.mov(ptr, regA[A]);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
|
|
|
@ -80,6 +80,7 @@ private:
|
||||||
asmjit::X86Xmm CheckRegF(int r0, int r1);
|
asmjit::X86Xmm CheckRegF(int r0, int r1);
|
||||||
asmjit::X86Xmm CheckRegF(int r0, int r1, int r2);
|
asmjit::X86Xmm CheckRegF(int r0, int r1, int r2);
|
||||||
asmjit::X86Xmm CheckRegF(int r0, int r1, int r2, int r3);
|
asmjit::X86Xmm CheckRegF(int r0, int r1, int r2, int r3);
|
||||||
|
asmjit::X86Gp CheckRegS(int r0, int r1);
|
||||||
asmjit::X86Gp CheckRegA(int r0, int r1);
|
asmjit::X86Gp CheckRegA(int r0, int r1);
|
||||||
|
|
||||||
asmjit::X86Compiler cc;
|
asmjit::X86Compiler cc;
|
||||||
|
|
Loading…
Reference in a new issue