- embed and use asmjit to JIT ZScript VM functions
This commit is contained in:
parent
19a5a2fd2b
commit
cbb945d8a7
79 changed files with 50124 additions and 2 deletions
209
asmjit/asmjit/base/operand.cpp
Normal file
209
asmjit/asmjit/base/operand.cpp
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
// [AsmJit]
|
||||
// Complete x86/x64 JIT and Remote Assembler for C++.
|
||||
//
|
||||
// [License]
|
||||
// Zlib - See LICENSE.md file in the package.
|
||||
|
||||
// [Export]
|
||||
#define ASMJIT_EXPORTS
|
||||
|
||||
// [Dependencies]
|
||||
#include "../base/operand.h"
|
||||
|
||||
// [Api-Begin]
|
||||
#include "../asmjit_apibegin.h"
|
||||
|
||||
namespace asmjit {
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::TypeId]
|
||||
// ============================================================================
|
||||
|
||||
template<int ID>
|
||||
struct TypeIdSizeOf_T {
|
||||
enum {
|
||||
kValue = (ID == TypeId::kI8 ) ? 1 :
|
||||
(ID == TypeId::kU8 ) ? 1 :
|
||||
(ID == TypeId::kI16 ) ? 2 :
|
||||
(ID == TypeId::kU16 ) ? 2 :
|
||||
(ID == TypeId::kI32 ) ? 4 :
|
||||
(ID == TypeId::kU32 ) ? 4 :
|
||||
(ID == TypeId::kI64 ) ? 8 :
|
||||
(ID == TypeId::kU64 ) ? 8 :
|
||||
(ID == TypeId::kF32 ) ? 4 :
|
||||
(ID == TypeId::kF64 ) ? 8 :
|
||||
(ID == TypeId::kF80 ) ? 10 :
|
||||
(ID == TypeId::kMask8 ) ? 1 :
|
||||
(ID == TypeId::kMask16) ? 2 :
|
||||
(ID == TypeId::kMask32) ? 4 :
|
||||
(ID == TypeId::kMask64) ? 8 :
|
||||
(ID == TypeId::kMmx32 ) ? 4 :
|
||||
(ID == TypeId::kMmx64 ) ? 8 :
|
||||
(ID >= TypeId::_kVec32Start && ID <= TypeId::_kVec32End ) ? 4 :
|
||||
(ID >= TypeId::_kVec64Start && ID <= TypeId::_kVec64End ) ? 8 :
|
||||
(ID >= TypeId::_kVec128Start && ID <= TypeId::_kVec128End) ? 16 :
|
||||
(ID >= TypeId::_kVec256Start && ID <= TypeId::_kVec256End) ? 32 :
|
||||
(ID >= TypeId::_kVec512Start && ID <= TypeId::_kVec512End) ? 64 : 0
|
||||
};
|
||||
};
|
||||
|
||||
template<int ID>
|
||||
struct TypeIdElementOf_T {
|
||||
enum {
|
||||
kValue = (ID == TypeId::kMask8 ) ? TypeId::kU8 :
|
||||
(ID == TypeId::kMask16) ? TypeId::kU16 :
|
||||
(ID == TypeId::kMask32) ? TypeId::kU32 :
|
||||
(ID == TypeId::kMask64) ? TypeId::kU64 :
|
||||
(ID == TypeId::kMmx32 ) ? TypeId::kI32 :
|
||||
(ID == TypeId::kMmx64 ) ? TypeId::kI64 :
|
||||
(ID >= TypeId::kI8 && ID <= TypeId::kF80 ) ? ID :
|
||||
(ID >= TypeId::_kVec32Start && ID <= TypeId::_kVec32End ) ? ID - TypeId::_kVec32Start + TypeId::kI8 :
|
||||
(ID >= TypeId::_kVec64Start && ID <= TypeId::_kVec64End ) ? ID - TypeId::_kVec64Start + TypeId::kI8 :
|
||||
(ID >= TypeId::_kVec128Start && ID <= TypeId::_kVec128End) ? ID - TypeId::_kVec128Start + TypeId::kI8 :
|
||||
(ID >= TypeId::_kVec256Start && ID <= TypeId::_kVec256End) ? ID - TypeId::_kVec256Start + TypeId::kI8 :
|
||||
(ID >= TypeId::_kVec512Start && ID <= TypeId::_kVec512End) ? ID - TypeId::_kVec512Start + TypeId::kI8 : 0
|
||||
};
|
||||
};
|
||||
|
||||
#define R(TMPL, I) TMPL<I + 0>::kValue, TMPL<I + 1>::kValue, \
|
||||
TMPL<I + 2>::kValue, TMPL<I + 3>::kValue, \
|
||||
TMPL<I + 4>::kValue, TMPL<I + 5>::kValue, \
|
||||
TMPL<I + 6>::kValue, TMPL<I + 7>::kValue, \
|
||||
TMPL<I + 8>::kValue, TMPL<I + 9>::kValue, \
|
||||
TMPL<I + 10>::kValue, TMPL<I + 11>::kValue, \
|
||||
TMPL<I + 12>::kValue, TMPL<I + 13>::kValue, \
|
||||
TMPL<I + 14>::kValue, TMPL<I + 15>::kValue
|
||||
ASMJIT_API const TypeId::Info TypeId::_info = {
|
||||
// SizeOf[128]
|
||||
{
|
||||
R(TypeIdSizeOf_T, 0), R(TypeIdSizeOf_T, 16),
|
||||
R(TypeIdSizeOf_T, 32), R(TypeIdSizeOf_T, 48),
|
||||
R(TypeIdSizeOf_T, 64), R(TypeIdSizeOf_T, 80),
|
||||
R(TypeIdSizeOf_T, 96), R(TypeIdSizeOf_T, 112)
|
||||
},
|
||||
|
||||
// ElementOf[128]
|
||||
{
|
||||
R(TypeIdElementOf_T, 0), R(TypeIdElementOf_T, 16),
|
||||
R(TypeIdElementOf_T, 32), R(TypeIdElementOf_T, 48),
|
||||
R(TypeIdElementOf_T, 64), R(TypeIdElementOf_T, 80),
|
||||
R(TypeIdElementOf_T, 96), R(TypeIdElementOf_T, 112)
|
||||
}
|
||||
};
|
||||
#undef R
|
||||
|
||||
// ============================================================================
|
||||
// [asmjit::Operand - Test]
|
||||
// ============================================================================
|
||||
|
||||
#if defined(ASMJIT_TEST)
|
||||
UNIT(base_operand) {
|
||||
INFO("Checking operand sizes");
|
||||
EXPECT(sizeof(Operand) == 16);
|
||||
EXPECT(sizeof(Reg) == 16);
|
||||
EXPECT(sizeof(Mem) == 16);
|
||||
EXPECT(sizeof(Imm) == 16);
|
||||
EXPECT(sizeof(Label) == 16);
|
||||
|
||||
INFO("Checking basic functionality of Operand");
|
||||
Operand a, b;
|
||||
Operand dummy;
|
||||
|
||||
EXPECT(a.isNone() == true);
|
||||
EXPECT(a.isReg() == false);
|
||||
EXPECT(a.isMem() == false);
|
||||
EXPECT(a.isImm() == false);
|
||||
EXPECT(a.isLabel() == false);
|
||||
EXPECT(a == b);
|
||||
|
||||
EXPECT(a._any.reserved8_4 == 0, "Default constructed Operand should zero its 'reserved8_4' field");
|
||||
EXPECT(a._any.reserved12_4 == 0, "Default constructed Operand should zero its 'reserved12_4' field");
|
||||
|
||||
INFO("Checking basic functionality of Label");
|
||||
Label label;
|
||||
EXPECT(label.isValid() == false);
|
||||
EXPECT(label.getId() == 0);
|
||||
|
||||
INFO("Checking basic functionality of Reg");
|
||||
EXPECT(Reg().isValid() == false,
|
||||
"Default constructed Reg() should not be valid");
|
||||
EXPECT(Reg()._any.reserved8_4 == 0,
|
||||
"A default constructed Reg() should zero its 'reserved8_4' field");
|
||||
EXPECT(Reg()._any.reserved12_4 == 0,
|
||||
"A default constructed Reg() should zero its 'reserved12_4' field");
|
||||
|
||||
EXPECT(Reg().isReg() == false,
|
||||
"Default constructed register should not isReg()");
|
||||
EXPECT(dummy.as<Reg>().isValid() == false,
|
||||
"Default constructed Operand casted to Reg should not be valid");
|
||||
|
||||
// Create some register (not specific to any architecture).
|
||||
uint32_t rSig = Operand::kOpReg | (1 << Operand::kSignatureRegTypeShift) |
|
||||
(2 << Operand::kSignatureRegKindShift) |
|
||||
(8 << Operand::kSignatureSizeShift ) ;
|
||||
Reg r1(Reg::fromSignature(rSig, 5));
|
||||
|
||||
EXPECT(r1.isValid() == true);
|
||||
EXPECT(r1.isReg() == true);
|
||||
EXPECT(r1.isReg(1) == true);
|
||||
EXPECT(r1.isPhysReg() == true);
|
||||
EXPECT(r1.isVirtReg() == false);
|
||||
EXPECT(r1.getSignature() == rSig);
|
||||
EXPECT(r1.getType() == 1);
|
||||
EXPECT(r1.getKind() == 2);
|
||||
EXPECT(r1.getSize() == 8);
|
||||
EXPECT(r1.getId() == 5);
|
||||
EXPECT(r1.isReg(1, 5) == true); // RegType and Id.
|
||||
|
||||
EXPECT(r1._any.reserved8_4 == 0, "Reg should have 'reserved8_4' zero");
|
||||
EXPECT(r1._any.reserved12_4 == 0, "Reg should have 'reserved12_4' zero");
|
||||
|
||||
// The same type of register having different id.
|
||||
Reg r2(r1, 6);
|
||||
EXPECT(r2.isValid() == true);
|
||||
EXPECT(r2.isReg() == true);
|
||||
EXPECT(r2.isReg(1) == true);
|
||||
EXPECT(r2.isPhysReg() == true);
|
||||
EXPECT(r2.isVirtReg() == false);
|
||||
EXPECT(r2.getSignature() == rSig);
|
||||
EXPECT(r2.getType() == r1.getType());
|
||||
EXPECT(r2.getKind() == r1.getKind());
|
||||
EXPECT(r2.getSize() == r1.getSize());
|
||||
EXPECT(r2.getId() == 6);
|
||||
EXPECT(r2.isReg(1, 6) == true);
|
||||
|
||||
r1.reset();
|
||||
EXPECT(!r1.isValid(),
|
||||
"Reset register should not be valid");
|
||||
EXPECT(!r1.isReg(),
|
||||
"Reset register should not isReg()");
|
||||
|
||||
INFO("Checking basic functionality of Mem");
|
||||
Mem m;
|
||||
EXPECT(m.isMem() , "Default constructed Mem() should isMem()");
|
||||
EXPECT(m == Mem() , "Two default constructed Mem() operands should be equal");
|
||||
EXPECT(m.hasBase() == false , "Default constructed Mem() should not have base specified");
|
||||
EXPECT(m.hasIndex() == false , "Default constructed Mem() should not have index specified");
|
||||
EXPECT(m.has64BitOffset() == true , "Default constructed Mem() should report 64-bit offset");
|
||||
EXPECT(m.getOffset() == 0 , "Default constructed Mem() should have be zero offset / address");
|
||||
|
||||
m.setOffset(-1);
|
||||
EXPECT(m.getOffsetLo32() == -1 , "Memory operand must hold a 32-bit offset");
|
||||
EXPECT(m.getOffset() == -1 , "32-bit offset must be sign extended to 64 bits");
|
||||
|
||||
int64_t x = int64_t(ASMJIT_UINT64_C(0xFF00FF0000000001));
|
||||
m.setOffset(x);
|
||||
EXPECT(m.getOffset() == x , "Memory operand must hold a 64-bit offset");
|
||||
EXPECT(m.getOffsetLo32() == 1 , "Memory operand must return correct low offset DWORD");
|
||||
EXPECT(m.getOffsetHi32() == 0xFF00FF00, "Memory operand must return correct high offset DWORD");
|
||||
|
||||
INFO("Checking basic functionality of Imm");
|
||||
EXPECT(Imm(-1).getInt64() == int64_t(-1),
|
||||
"Immediate values should by default sign-extend to 64-bits");
|
||||
}
|
||||
#endif // ASMJIT_TEST
|
||||
|
||||
} // asmjit namespace
|
||||
|
||||
// [Api-End]
|
||||
#include "../asmjit_apiend.h"
|
||||
Loading…
Add table
Add a link
Reference in a new issue