mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-28 06:41:47 +00:00
- implement emitter functions for LKP_R, META, CLSS, LO, LO_R, LP, LP_R, SO, SO_R, SP, SP_R
- add emit code for throwing exceptions on null pointers
This commit is contained in:
parent
999b3833ff
commit
ccd2f58fb4
1 changed files with 158 additions and 72 deletions
|
@ -34,7 +34,6 @@
|
||||||
#define ASSERTKS(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstS)
|
#define ASSERTKS(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstS)
|
||||||
|
|
||||||
// [pbeta] TODO: VM aborts
|
// [pbeta] TODO: VM aborts
|
||||||
#define NULL_POINTER_CHECK(a,o,x)
|
|
||||||
#define BINARY_OP_INT(op,out,r,l) \
|
#define BINARY_OP_INT(op,out,r,l) \
|
||||||
{ \
|
{ \
|
||||||
auto tmp = cc.newInt32(); \
|
auto tmp = cc.newInt32(); \
|
||||||
|
@ -145,10 +144,10 @@ private:
|
||||||
EMIT_OP(LK_R);
|
EMIT_OP(LK_R);
|
||||||
EMIT_OP(LKF_R);
|
EMIT_OP(LKF_R);
|
||||||
// EMIT_OP(LKS_R);
|
// EMIT_OP(LKS_R);
|
||||||
// EMIT_OP(LKP_R);
|
EMIT_OP(LKP_R);
|
||||||
// EMIT_OP(LFP);
|
// EMIT_OP(LFP);
|
||||||
// EMIT_OP(META);
|
EMIT_OP(META);
|
||||||
// EMIT_OP(CLSS);
|
EMIT_OP(CLSS);
|
||||||
EMIT_OP(LB);
|
EMIT_OP(LB);
|
||||||
EMIT_OP(LB_R);
|
EMIT_OP(LB_R);
|
||||||
EMIT_OP(LH);
|
EMIT_OP(LH);
|
||||||
|
@ -165,10 +164,10 @@ private:
|
||||||
EMIT_OP(LDP_R);
|
EMIT_OP(LDP_R);
|
||||||
// EMIT_OP(LS);
|
// EMIT_OP(LS);
|
||||||
// EMIT_OP(LS_R);
|
// EMIT_OP(LS_R);
|
||||||
// EMIT_OP(LO);
|
EMIT_OP(LO);
|
||||||
// EMIT_OP(LO_R);
|
EMIT_OP(LO_R);
|
||||||
// EMIT_OP(LP);
|
EMIT_OP(LP);
|
||||||
// EMIT_OP(LP_R);
|
EMIT_OP(LP_R);
|
||||||
EMIT_OP(LV2);
|
EMIT_OP(LV2);
|
||||||
EMIT_OP(LV2_R);
|
EMIT_OP(LV2_R);
|
||||||
EMIT_OP(LV3);
|
EMIT_OP(LV3);
|
||||||
|
@ -188,10 +187,10 @@ private:
|
||||||
EMIT_OP(SDP_R);
|
EMIT_OP(SDP_R);
|
||||||
//EMIT_OP(SS);
|
//EMIT_OP(SS);
|
||||||
//EMIT_OP(SS_R);
|
//EMIT_OP(SS_R);
|
||||||
//EMIT_OP(SO);
|
EMIT_OP(SO);
|
||||||
//EMIT_OP(SO_R);
|
EMIT_OP(SO_R);
|
||||||
//EMIT_OP(SP);
|
EMIT_OP(SP);
|
||||||
//EMIT_OP(SP_R);
|
EMIT_OP(SP_R);
|
||||||
EMIT_OP(SV2);
|
EMIT_OP(SV2);
|
||||||
EMIT_OP(SV2_R);
|
EMIT_OP(SV2_R);
|
||||||
EMIT_OP(SV3);
|
EMIT_OP(SV3);
|
||||||
|
@ -386,122 +385,146 @@ private:
|
||||||
|
|
||||||
void EmitLK_R()
|
void EmitLK_R()
|
||||||
{
|
{
|
||||||
cc.mov(regD[a], asmjit::x86::ptr(ToMemAddress(konstd), regD[B], 2, C * 4));
|
cc.mov(regD[a], asmjit::x86::ptr(ToMemAddress(konstd), regD[B], 2, C * sizeof(int32_t)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLKF_R()
|
void EmitLKF_R()
|
||||||
{
|
{
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, ToMemAddress(konstf + BC));
|
cc.mov(tmp, ToMemAddress(konstf + BC));
|
||||||
cc.movsd(regF[a], asmjit::x86::qword_ptr(tmp, regD[B], 3, C * 8));
|
cc.movsd(regF[a], asmjit::x86::qword_ptr(tmp, regD[B], 3, C * sizeof(double)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void EmitLKS_R() // load string constant indexed
|
//void EmitLKS_R() { } // load string constant indexed
|
||||||
|
|
||||||
|
void EmitLKP_R()
|
||||||
{
|
{
|
||||||
//cc.mov(regS[a], konsts[regD[B] + C]);
|
cc.mov(regA[a], asmjit::x86::ptr(ToMemAddress(konsta), regD[B], 2, C * sizeof(void*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLKP_R() // load pointer constant indexed
|
/*void EmitLFP() // load frame pointer
|
||||||
{
|
|
||||||
//cc.mov(b, regD[B] + C);
|
|
||||||
//cc.mov(regA[a], konsta[b].v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitLFP() // load frame pointer
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitMETA() // load a class's meta data address
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitCLSS() // load a class's descriptor address
|
|
||||||
{
|
{
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
void EmitMETA()
|
||||||
|
{
|
||||||
|
typedef void*(*FuncPtr)(void*);
|
||||||
|
|
||||||
|
auto label = cc.newLabel();
|
||||||
|
cc.test(regA[B], regA[B]);
|
||||||
|
cc.jne(label);
|
||||||
|
EmitThrowException(X_READ_NIL);
|
||||||
|
cc.bind(label);
|
||||||
|
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(static_cast<FuncPtr>([](void *o) -> void*
|
||||||
|
{
|
||||||
|
return static_cast<DObject*>(o)->GetClass();
|
||||||
|
}))), asmjit::FuncSignature1<void*, void*>());
|
||||||
|
call->setRet(0, regA[a]);
|
||||||
|
call->setArg(0, regA[B]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitCLSS()
|
||||||
|
{
|
||||||
|
typedef void*(*FuncPtr)(void*);
|
||||||
|
|
||||||
|
auto label = cc.newLabel();
|
||||||
|
cc.test(regA[B], regA[B]);
|
||||||
|
cc.jne(label);
|
||||||
|
EmitThrowException(X_READ_NIL);
|
||||||
|
cc.bind(label);
|
||||||
|
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(static_cast<FuncPtr>([](void *o) -> void*
|
||||||
|
{
|
||||||
|
return static_cast<DObject*>(o)->GetClass()->Meta;
|
||||||
|
}))), asmjit::FuncSignature1<void*, void*>());
|
||||||
|
call->setRet(0, regA[a]);
|
||||||
|
call->setArg(0, regA[B]);
|
||||||
|
}
|
||||||
|
|
||||||
// Load from memory. rA = *(rB + rkC)
|
// Load from memory. rA = *(rB + rkC)
|
||||||
|
|
||||||
void EmitLB()
|
void EmitLB()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movsx(regD[a], asmjit::x86::byte_ptr(PB, KC));
|
cc.movsx(regD[a], asmjit::x86::byte_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLB_R()
|
void EmitLB_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movsx(regD[a], asmjit::x86::byte_ptr(PB, RC));
|
cc.movsx(regD[a], asmjit::x86::byte_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLH()
|
void EmitLH()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movsx(regD[a], asmjit::x86::word_ptr(PB, KC));
|
cc.movsx(regD[a], asmjit::x86::word_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLH_R()
|
void EmitLH_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movsx(regD[a], asmjit::x86::word_ptr(PB, RC));
|
cc.movsx(regD[a], asmjit::x86::word_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLW()
|
void EmitLW()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.mov(regD[a], asmjit::x86::dword_ptr(PB, KC));
|
cc.mov(regD[a], asmjit::x86::dword_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLW_R()
|
void EmitLW_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.mov(regD[a], asmjit::x86::dword_ptr(PB, RC));
|
cc.mov(regD[a], asmjit::x86::dword_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLBU()
|
void EmitLBU()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.mov(regD[a], asmjit::x86::byte_ptr(PB, KC));
|
cc.mov(regD[a], asmjit::x86::byte_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLBU_R()
|
void EmitLBU_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.mov(regD[a], asmjit::x86::byte_ptr(PB, RC));
|
cc.mov(regD[a], asmjit::x86::byte_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLHU()
|
void EmitLHU()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.mov(regD[a], asmjit::x86::word_ptr(PB, KC));
|
cc.mov(regD[a], asmjit::x86::word_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLHU_R()
|
void EmitLHU_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.mov(regD[a], asmjit::x86::word_ptr(PB, RC));
|
cc.mov(regD[a], asmjit::x86::word_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLSP()
|
void EmitLSP()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movss(regF[a], asmjit::x86::dword_ptr(PB, KC));
|
cc.movss(regF[a], asmjit::x86::dword_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLSP_R()
|
void EmitLSP_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movss(regF[a], asmjit::x86::dword_ptr(PB, RC));
|
cc.movss(regF[a], asmjit::x86::dword_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLDP()
|
void EmitLDP()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movsd(regF[a], asmjit::x86::qword_ptr(PB, KC));
|
cc.movsd(regF[a], asmjit::x86::qword_ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLDP_R()
|
void EmitLDP_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
cc.movsd(regF[a], asmjit::x86::qword_ptr(PB, RC));
|
cc.movsd(regF[a], asmjit::x86::qword_ptr(PB, RC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,27 +534,57 @@ private:
|
||||||
|
|
||||||
void EmitLS_R()
|
void EmitLS_R()
|
||||||
{
|
{
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void EmitLO() // load object
|
void EmitLO()
|
||||||
{
|
{
|
||||||
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
|
|
||||||
|
auto ptr = cc.newIntPtr();
|
||||||
|
cc.mov(ptr, asmjit::x86::ptr(PB, KC));
|
||||||
|
|
||||||
|
typedef void*(*FuncPtr)(void*);
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(static_cast<FuncPtr>([](void *ptr) -> void*
|
||||||
|
{
|
||||||
|
DObject *p = static_cast<DObject *>(ptr);
|
||||||
|
return GC::ReadBarrier(p);
|
||||||
|
}))), asmjit::FuncSignature1<void*, void*>());
|
||||||
|
call->setRet(0, regA[a]);
|
||||||
|
call->setArg(0, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLO_R()
|
void EmitLO_R()
|
||||||
{
|
{
|
||||||
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
|
|
||||||
|
auto ptr = cc.newIntPtr();
|
||||||
|
cc.mov(ptr, asmjit::x86::ptr(PB, RC));
|
||||||
|
|
||||||
|
typedef void*(*FuncPtr)(void*);
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(static_cast<FuncPtr>([](void *ptr) -> void*
|
||||||
|
{
|
||||||
|
DObject *p = static_cast<DObject *>(ptr);
|
||||||
|
return GC::ReadBarrier(p);
|
||||||
|
}))), asmjit::FuncSignature1<void*, void*>());
|
||||||
|
call->setRet(0, regA[a]);
|
||||||
|
call->setArg(0, ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLP() // load pointer
|
void EmitLP()
|
||||||
{
|
{
|
||||||
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
|
cc.mov(regA[a], asmjit::x86::ptr(PB, KC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitLP_R()
|
void EmitLP_R()
|
||||||
{
|
{
|
||||||
}*/
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
|
cc.mov(regA[a], asmjit::x86::ptr(PB, RC));
|
||||||
|
}
|
||||||
|
|
||||||
void EmitLV2()
|
void EmitLV2()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, KC);
|
cc.add(tmp, KC);
|
||||||
|
@ -541,7 +594,7 @@ private:
|
||||||
|
|
||||||
void EmitLV2_R()
|
void EmitLV2_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, RC);
|
cc.add(tmp, RC);
|
||||||
|
@ -551,7 +604,7 @@ private:
|
||||||
|
|
||||||
void EmitLV3()
|
void EmitLV3()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, KC);
|
cc.add(tmp, KC);
|
||||||
|
@ -562,7 +615,7 @@ private:
|
||||||
|
|
||||||
void EmitLV3_R()
|
void EmitLV3_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, RC);
|
cc.add(tmp, RC);
|
||||||
|
@ -581,7 +634,7 @@ private:
|
||||||
|
|
||||||
void EmitLBIT() // rA = !!(*rB & C) -- *rB is a byte
|
void EmitLBIT() // rA = !!(*rB & C) -- *rB is a byte
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, 0, X_READ_NIL);
|
EmitNullPointerThrow(B, X_READ_NIL);
|
||||||
auto tmp = cc.newInt8();
|
auto tmp = cc.newInt8();
|
||||||
cc.mov(regD[a], PB);
|
cc.mov(regD[a], PB);
|
||||||
cc.and_(regD[a], C);
|
cc.and_(regD[a], C);
|
||||||
|
@ -594,74 +647,98 @@ private:
|
||||||
|
|
||||||
void EmitSB()
|
void EmitSB()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PA, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.mov(asmjit::x86::byte_ptr(PA, KC), regD[B].r8Lo());
|
cc.mov(asmjit::x86::byte_ptr(PA, KC), regD[B].r8Lo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSB_R()
|
void EmitSB_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PA, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.mov(asmjit::x86::byte_ptr(PA, RC), regD[B].r8Lo());
|
cc.mov(asmjit::x86::byte_ptr(PA, RC), regD[B].r8Lo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSH()
|
void EmitSH()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PA, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.mov(asmjit::x86::word_ptr(PA, KC), regD[B].r16());
|
cc.mov(asmjit::x86::word_ptr(PA, KC), regD[B].r16());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSH_R()
|
void EmitSH_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PA, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.mov(asmjit::x86::word_ptr(PA, RC), regD[B].r16());
|
cc.mov(asmjit::x86::word_ptr(PA, RC), regD[B].r16());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSW()
|
void EmitSW()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PA, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.mov(asmjit::x86::dword_ptr(PA, KC), regD[B]);
|
cc.mov(asmjit::x86::dword_ptr(PA, KC), regD[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSW_R()
|
void EmitSW_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PA, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.mov(asmjit::x86::dword_ptr(PA, RC), regD[B]);
|
cc.mov(asmjit::x86::dword_ptr(PA, RC), regD[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSSP()
|
void EmitSSP()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.movss(asmjit::x86::dword_ptr(PA, KC), regF[B]);
|
cc.movss(asmjit::x86::dword_ptr(PA, KC), regF[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSSP_R()
|
void EmitSSP_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.movss(asmjit::x86::dword_ptr(PA, RC), regF[B]);
|
cc.movss(asmjit::x86::dword_ptr(PA, RC), regF[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSDP()
|
void EmitSDP()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.movsd(asmjit::x86::qword_ptr(PA, KC), regF[B]);
|
cc.movsd(asmjit::x86::qword_ptr(PA, KC), regF[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitSDP_R()
|
void EmitSDP_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(A, X_WRITE_NIL);
|
||||||
cc.movsd(asmjit::x86::qword_ptr(PA, RC), regF[B]);
|
cc.movsd(asmjit::x86::qword_ptr(PA, RC), regF[B]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void EmitSS() {} // store string
|
//void EmitSS() {} // store string
|
||||||
//void EmitSS_R() {}
|
//void EmitSS_R() {}
|
||||||
//void EmitSO() {} // store object pointer with write barrier (only needed for non thinkers and non types)
|
|
||||||
//void EmitSO_R() {}
|
void EmitSO()
|
||||||
//void EmitSP() {} // store pointer
|
{
|
||||||
//void EmitSP_R() {}
|
cc.mov(asmjit::x86::ptr(PA, KC), regA[B]);
|
||||||
|
|
||||||
|
typedef void(*FuncPtr)(DObject*);
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(static_cast<FuncPtr>(GC::WriteBarrier))), asmjit::FuncSignature1<void, void*>());
|
||||||
|
call->setArg(0, regA[B]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSO_R()
|
||||||
|
{
|
||||||
|
cc.mov(asmjit::x86::ptr(PA, RC), regA[B]);
|
||||||
|
|
||||||
|
typedef void(*FuncPtr)(DObject*);
|
||||||
|
auto call = cc.call(ToMemAddress(reinterpret_cast<const void*>(static_cast<FuncPtr>(GC::WriteBarrier))), asmjit::FuncSignature1<void, void*>());
|
||||||
|
call->setArg(0, regA[B]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSP()
|
||||||
|
{
|
||||||
|
cc.mov(asmjit::x86::ptr(PA, KC), regA[B]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmitSP_R()
|
||||||
|
{
|
||||||
|
cc.mov(asmjit::x86::ptr(PA, RC), regA[B]);
|
||||||
|
}
|
||||||
|
|
||||||
void EmitSV2()
|
void EmitSV2()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(B, X_WRITE_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, KC);
|
cc.add(tmp, KC);
|
||||||
|
@ -671,7 +748,7 @@ private:
|
||||||
|
|
||||||
void EmitSV2_R()
|
void EmitSV2_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(B, X_WRITE_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, RC);
|
cc.add(tmp, RC);
|
||||||
|
@ -681,7 +758,7 @@ private:
|
||||||
|
|
||||||
void EmitSV3()
|
void EmitSV3()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, KC, X_WRITE_NIL);
|
EmitNullPointerThrow(B, X_WRITE_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, KC);
|
cc.add(tmp, KC);
|
||||||
|
@ -692,7 +769,7 @@ private:
|
||||||
|
|
||||||
void EmitSV3_R()
|
void EmitSV3_R()
|
||||||
{
|
{
|
||||||
NULL_POINTER_CHECK(PB, RC, X_WRITE_NIL);
|
EmitNullPointerThrow(B, X_WRITE_NIL);
|
||||||
auto tmp = cc.newIntPtr();
|
auto tmp = cc.newIntPtr();
|
||||||
cc.mov(tmp, PB);
|
cc.mov(tmp, PB);
|
||||||
cc.add(tmp, RC);
|
cc.add(tmp, RC);
|
||||||
|
@ -2488,6 +2565,15 @@ private:
|
||||||
call->setArg(0, b);
|
call->setArg(0, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmitNullPointerThrow(int index, EVMAbortException reason)
|
||||||
|
{
|
||||||
|
auto label = cc.newLabel();
|
||||||
|
cc.test(regA[index], regA[index]);
|
||||||
|
cc.jne(label);
|
||||||
|
EmitThrowException(reason);
|
||||||
|
cc.bind(label);
|
||||||
|
}
|
||||||
|
|
||||||
void EmitThrowException(EVMAbortException reason)
|
void EmitThrowException(EVMAbortException reason)
|
||||||
{
|
{
|
||||||
using namespace asmjit;
|
using namespace asmjit;
|
||||||
|
|
Loading…
Reference in a new issue