Minor changes.

Added possibility to get x86/x64 instruction id by name.
This commit is contained in:
kobalicek
2014-05-30 14:49:22 +02:00
parent 5869dc4736
commit cc2909f0db
12 changed files with 254 additions and 157 deletions

View File

@@ -45,7 +45,7 @@
// - Keep implementation simple and easy to follow.
//
// Implementation is based on bit arrays and binary trees. Bit arrays contain
// information related to allocated and unused blocks of memory. The size of
// information related to allocated and unused blocks of memory. The size of
// a block is described by `MemNode::density`. Count of blocks is stored in
// `MemNode::blocks`. For example if density is 64 and count of blocks is 20,
// memory node contains 64*20 bytes of memory and smallest possible allocation

View File

@@ -29,7 +29,7 @@ static const Zone::Block Zone_zeroBlock = {
// ============================================================================
Zone::Zone(size_t blockSize) {
_blocks = const_cast<Zone::Block*>(&Zone_zeroBlock);
_block = const_cast<Zone::Block*>(&Zone_zeroBlock);
_blockSize = blockSize;
}
@@ -42,7 +42,7 @@ Zone::~Zone() {
// ============================================================================
void Zone::clear() {
Block* cur = _blocks;
Block* cur = _block;
// Can't be altered.
if (cur == &Zone_zeroBlock)
@@ -52,11 +52,11 @@ void Zone::clear() {
cur = cur->prev;
cur->pos = cur->data;
_blocks = cur;
_block = cur;
}
void Zone::reset() {
Block* cur = _blocks;
Block* cur = _block;
// Can't be altered.
if (cur == &Zone_zeroBlock)
@@ -68,7 +68,7 @@ void Zone::reset() {
cur = prev;
} while (cur != NULL);
_blocks = const_cast<Zone::Block*>(&Zone_zeroBlock);
_block = const_cast<Zone::Block*>(&Zone_zeroBlock);
}
// ============================================================================
@@ -76,7 +76,7 @@ void Zone::reset() {
// ============================================================================
void* Zone::_alloc(size_t size) {
Block* curBlock = _blocks;
Block* curBlock = _block;
size_t blockSize = IntUtil::iMax<size_t>(_blockSize, size);
// The `_alloc()` method can only be called if there is not enough space
@@ -90,7 +90,7 @@ void* Zone::_alloc(size_t size) {
Block* next = curBlock->next;
if (next != NULL && next->getBlockSize() >= size) {
next->pos = next->data + size;
_blocks = next;
_block = next;
return static_cast<void*>(next->data);
}
@@ -120,7 +120,7 @@ void* Zone::_alloc(size_t size) {
}
}
_blocks = newBlock;
_block = newBlock;
return static_cast<void*>(newBlock->data);
}

View File

@@ -158,7 +158,7 @@ struct Zone {
//! zone.reset();
//! ~~~
ASMJIT_INLINE void* alloc(size_t size) {
Block* cur = _blocks;
Block* cur = _block;
uint8_t* ptr = cur->pos;
size_t remainingBytes = (size_t)(cur->end - ptr);
@@ -206,7 +206,7 @@ struct Zone {
// --------------------------------------------------------------------------
//! The current block.
Block* _blocks;
Block* _block;
//! Default block size.
size_t _blockSize;
};

View File

@@ -352,7 +352,7 @@ Error X86X64Assembler::_align(uint32_t mode, uint32_t offset) {
if (getRemainingSpace() < i)
ASMJIT_PROPAGATE_ERROR(_grow(i));
uint8_t* cursor = getCursor();
uint8_t alignPattern = 0xCC;

View File

@@ -869,7 +869,7 @@ struct X86X64Assembler : public BaseAssembler {
ASMJIT_ASSERT(dst.getRegIndex() == 0);
Imm imm(static_cast<int64_t>((intptr_t)src));
return emit(kInstMovptr, dst, imm);
return emit(kInstMovPtr, dst, imm);
}
//! Move (absolute address in immediate <- AL|AX|EAX|RAX).
@@ -877,7 +877,7 @@ struct X86X64Assembler : public BaseAssembler {
ASMJIT_ASSERT(src.getRegIndex() == 0);
Imm imm(static_cast<int64_t>((intptr_t)dst));
return emit(kInstMovptr, imm, src);
return emit(kInstMovPtr, imm, src);
}
//! Move data after dwapping bytes (SSE3 - Atom).

View File

@@ -1873,12 +1873,12 @@ struct X86X64Compiler : public BaseCompiler {
//! Move (AL|AX|EAX|RAX <- absolute address in immediate).
ASMJIT_INLINE InstNode* mov_ptr(const GpVar& dst, void* src) {
Imm imm(static_cast<int64_t>((intptr_t)src));
return emit(kInstMovptr, dst, imm);
return emit(kInstMovPtr, dst, imm);
}
//! Move (absolute address in immediate <- AL|AX|EAX|RAX).
ASMJIT_INLINE InstNode* mov_ptr(void* dst, const GpVar& src) {
Imm imm(static_cast<int64_t>((intptr_t)dst));
return emit(kInstMovptr, imm, src);
return emit(kInstMovPtr, imm, src);
}
//! Move data after swapping bytes (SSE3 - Atom).

View File

@@ -260,7 +260,7 @@ static ASMJIT_INLINE const X86X64SpecialInst* X86X64SpecialInst_get(uint32_t cod
case kInstMul:
return x86SpecialInstMul;
case kInstMovptr:
case kInstMovPtr:
return x86SpecialInstMovPtr;
case kInstLahf:
@@ -5450,7 +5450,7 @@ static ASMJIT_INLINE Error X86X64Context_serialize(X86X64Context* self, X86X64As
o0 = &opList[2];
break;
case kInstMovptr:
case kInstMovPtr:
break;
case kInstLahf:

View File

@@ -309,6 +309,7 @@ const char _instName[] =
"minsd\0"
"minss\0"
"monitor\0"
"mov_ptr\0"
"mov\0"
"movapd\0"
"movaps\0"
@@ -332,7 +333,6 @@ const char _instName[] =
"movntpd\0"
"movntps\0"
"movntq\0"
"mov_ptr\0"
"movq\0"
"movq2dq\0"
"movsd\0"
@@ -700,14 +700,14 @@ const char _instName[] =
"vfmaddps\0"
"vfmaddsd\0"
"vfmaddss\0"
"vfmaddsubpd\0"
"vfmaddsubps\0"
"vfmaddsub132pd\0"
"vfmaddsub132ps\0"
"vfmaddsub213pd\0"
"vfmaddsub213ps\0"
"vfmaddsub231pd\0"
"vfmaddsub231ps\0"
"vfmaddsubpd\0"
"vfmaddsubps\0"
"vfmsub132pd\0"
"vfmsub132ps\0"
"vfmsub132sd\0"
@@ -908,8 +908,8 @@ const char _instName[] =
"vphaddwq\0"
"vphminposuw\0"
"vphsubbw\0"
"vphsubdq\0"
"vphsubd\0"
"vphsubdq\0"
"vphsubsw\0"
"vphsubw\0"
"vphsubwd\0"
@@ -1059,6 +1059,41 @@ const char _instName[] =
"xorpd\0"
"xorps\0";
enum kInstAlphaIndex {
kInstAlphaIndexFirst = 'a',
kInstAlphaIndexLast = 'z',
kInstAlphaIndexInvalid = 0xFFFF
};
static const uint16_t _instAlphaIndex[26] = {
kInstAdc,
kInstBextr,
kInstCall,
kInstDaa,
kInstEmms,
kInstF2xm1,
0xFFFF,
kInstHaddpd,
kInstIdiv,
kInstJa,
0xFFFF,
kInstLahf,
kInstMaskmovdqu,
kInstNeg,
kInstOr,
kInstPabsb,
0xFFFF,
kInstRcl,
kInstSahf,
kInstTest,
kInstUcomisd,
kInstVaddpd,
kInstWrfsbase,
kInstXadd,
0xFFFF,
0xFFFF
};
enum kInstData_NameIndex {
kInstNone_NameIndex = 0,
kInstAdc_NameIndex = 1,
@@ -1341,30 +1376,30 @@ enum kInstData_NameIndex {
kInstMinsd_NameIndex = 1746,
kInstMinss_NameIndex = 1752,
kInstMonitor_NameIndex = 1758,
kInstMov_NameIndex = 1766,
kInstMovapd_NameIndex = 1770,
kInstMovaps_NameIndex = 1777,
kInstMovbe_NameIndex = 1784,
kInstMovd_NameIndex = 1790,
kInstMovddup_NameIndex = 1795,
kInstMovdq2q_NameIndex = 1803,
kInstMovdqa_NameIndex = 1811,
kInstMovdqu_NameIndex = 1818,
kInstMovhlps_NameIndex = 1825,
kInstMovhpd_NameIndex = 1833,
kInstMovhps_NameIndex = 1840,
kInstMovlhps_NameIndex = 1847,
kInstMovlpd_NameIndex = 1855,
kInstMovlps_NameIndex = 1862,
kInstMovmskpd_NameIndex = 1869,
kInstMovmskps_NameIndex = 1878,
kInstMovntdq_NameIndex = 1887,
kInstMovntdqa_NameIndex = 1895,
kInstMovnti_NameIndex = 1904,
kInstMovntpd_NameIndex = 1911,
kInstMovntps_NameIndex = 1919,
kInstMovntq_NameIndex = 1927,
kInstMovptr_NameIndex = 1934,
kInstMovPtr_NameIndex = 1766,
kInstMov_NameIndex = 1774,
kInstMovapd_NameIndex = 1778,
kInstMovaps_NameIndex = 1785,
kInstMovbe_NameIndex = 1792,
kInstMovd_NameIndex = 1798,
kInstMovddup_NameIndex = 1803,
kInstMovdq2q_NameIndex = 1811,
kInstMovdqa_NameIndex = 1819,
kInstMovdqu_NameIndex = 1826,
kInstMovhlps_NameIndex = 1833,
kInstMovhpd_NameIndex = 1841,
kInstMovhps_NameIndex = 1848,
kInstMovlhps_NameIndex = 1855,
kInstMovlpd_NameIndex = 1863,
kInstMovlps_NameIndex = 1870,
kInstMovmskpd_NameIndex = 1877,
kInstMovmskps_NameIndex = 1886,
kInstMovntdq_NameIndex = 1895,
kInstMovntdqa_NameIndex = 1903,
kInstMovnti_NameIndex = 1912,
kInstMovntpd_NameIndex = 1919,
kInstMovntps_NameIndex = 1927,
kInstMovntq_NameIndex = 1935,
kInstMovq_NameIndex = 1942,
kInstMovq2dq_NameIndex = 1947,
kInstMovsd_NameIndex = 1955,
@@ -1732,14 +1767,14 @@ enum kInstData_NameIndex {
kInstVfmaddps_NameIndex = 4775,
kInstVfmaddsd_NameIndex = 4784,
kInstVfmaddss_NameIndex = 4793,
kInstVfmaddsubpd_NameIndex = 4802,
kInstVfmaddsubps_NameIndex = 4814,
kInstVfmaddsub132pd_NameIndex = 4826,
kInstVfmaddsub132ps_NameIndex = 4841,
kInstVfmaddsub213pd_NameIndex = 4856,
kInstVfmaddsub213ps_NameIndex = 4871,
kInstVfmaddsub231pd_NameIndex = 4886,
kInstVfmaddsub231ps_NameIndex = 4901,
kInstVfmaddsub132pd_NameIndex = 4802,
kInstVfmaddsub132ps_NameIndex = 4817,
kInstVfmaddsub213pd_NameIndex = 4832,
kInstVfmaddsub213ps_NameIndex = 4847,
kInstVfmaddsub231pd_NameIndex = 4862,
kInstVfmaddsub231ps_NameIndex = 4877,
kInstVfmaddsubpd_NameIndex = 4892,
kInstVfmaddsubps_NameIndex = 4904,
kInstVfmsub132pd_NameIndex = 4916,
kInstVfmsub132ps_NameIndex = 4928,
kInstVfmsub132sd_NameIndex = 4940,
@@ -1940,8 +1975,8 @@ enum kInstData_NameIndex {
kInstVphaddwq_NameIndex = 6842,
kInstVphminposuw_NameIndex = 6851,
kInstVphsubbw_NameIndex = 6863,
kInstVphsubdq_NameIndex = 6872,
kInstVphsubd_NameIndex = 6881,
kInstVphsubd_NameIndex = 6872,
kInstVphsubdq_NameIndex = 6880,
kInstVphsubsw_NameIndex = 6889,
kInstVphsubw_NameIndex = 6898,
kInstVphsubwd_NameIndex = 6906,
@@ -2417,6 +2452,7 @@ const InstInfo _instInfo[] = {
INST(kInstMinsd , "minsd" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F20F00(5D,U) , U ),
INST(kInstMinss , "minss" , G(ExtRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_F30F00(5D,U) , U ),
INST(kInstMonitor , "monitor" , G(X86Op) , F(None)|F(Special) , 0 , U , U , U , U , O_000F01(C8,U) , U ),
INST(kInstMovPtr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , O_000000(A0,U) , O_000000(A2,U) ),
INST(kInstMov , "mov" , G(X86Mov) , F(Move) , 0 , O(GqdwbMem) , O(GqdwbMem)|O(Imm) , U , U , U , U ),
INST(kInstMovapd , "movapd" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_660F00(28,U) , O_660F00(29,U) ),
INST(kInstMovaps , "movaps" , G(ExtMov) , F(Move) , 16, O(XmmMem) , O(XmmMem) , U , U , O_000F00(28,U) , O_000F00(29,U) ),
@@ -2440,7 +2476,6 @@ const InstInfo _instInfo[] = {
INST(kInstMovntpd , "movntpd" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , U , O_660F00(2B,U) ),
INST(kInstMovntps , "movntps" , G(ExtMov) , F(Move) , 16, O(Mem) , O(Xmm) , U , U , U , O_000F00(2B,U) ),
INST(kInstMovntq , "movntq" , G(ExtMov) , F(Move) , 8 , O(Mem) , O(Mm) , U , U , U , O_000F00(E7,U) ),
INST(kInstMovptr , "mov_ptr" , G(X86MovPtr) , F(Move)|F(Special) , 0 , O(Gqdwb) , O(Imm) , U , U , O_000000(A0,U) , O_000000(A2,U) ),
INST(kInstMovq , "movq" , G(ExtMovQ) , F(Move) , 16, O(Gq)|O(MmXmmMem) , O(Gq)|O(MmXmmMem) , U , U , U , U ),
INST(kInstMovq2dq , "movq2dq" , G(ExtRm) , F(Move) , 16, O(Xmm) , O(Mm) , U , U , O_F30F00(D6,U) , U ),
INST(kInstMovsd , "movsd" , G(ExtMov) , F(Move)|F(ZeroIfMem) , 8 , O(XmmMem) , O(XmmMem) , U , U , O_F20F00(10,U) , O_F20F00(11,U) ),
@@ -2808,14 +2843,14 @@ const InstInfo _instInfo[] = {
INST(kInstVfmaddps , "vfmaddps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(68,U) , U ),
INST(kInstVfmaddsd , "vfmaddsd" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(6B,U) , U ),
INST(kInstVfmaddss , "vfmaddss" , G(Fma4) , F(None) , 0 , O(Xmm) , O(Xmm) , O(XmmMem) , O(XmmMem) , O_660F3A(6A,U) , U ),
INST(kInstVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5D,U) , U ),
INST(kInstVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5C,U) , U ),
INST(kInstVfmaddsub132pd , "vfmaddsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(96,U) , U ),
INST(kInstVfmaddsub132ps , "vfmaddsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(96,U) , U ),
INST(kInstVfmaddsub213pd , "vfmaddsub213pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A6,U) , U ),
INST(kInstVfmaddsub213ps , "vfmaddsub213ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(A6,U) , U ),
INST(kInstVfmaddsub231pd , "vfmaddsub231pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B6,U) , U ),
INST(kInstVfmaddsub231ps , "vfmaddsub231ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(B6,U) , U ),
INST(kInstVfmaddsubpd , "vfmaddsubpd" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5D,U) , U ),
INST(kInstVfmaddsubps , "vfmaddsubps" , G(Fma4_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , O(XmmYmmMem) , O_660F3A(5C,U) , U ),
INST(kInstVfmsub132pd , "vfmsub132pd" , G(AvxRvm_P) , F(None) |F(W), 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9A,U) , U ),
INST(kInstVfmsub132ps , "vfmsub132ps" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(9A,U) , U ),
INST(kInstVfmsub132sd , "vfmsub132sd" , G(AvxRvm) , F(None) |F(W), 0 , O(Xmm) , O(Xmm) , O(XmmMem) , U , O_660F38(9B,U) , U ),
@@ -3016,8 +3051,8 @@ const InstInfo _instInfo[] = {
INST(kInstVphaddwq , "vphaddwq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(C7,U) , U ),
INST(kInstVphminposuw , "vphminposuw" , G(AvxRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_660F38(41,U) , U ),
INST(kInstVphsubbw , "vphsubbw" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E1,U) , U ),
INST(kInstVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E3,U) , U ),
INST(kInstVphsubd , "vphsubd" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(06,U) , U ),
INST(kInstVphsubdq , "vphsubdq" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E3,U) , U ),
INST(kInstVphsubsw , "vphsubsw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(07,U) , U ),
INST(kInstVphsubw , "vphsubw" , G(AvxRvm_P) , F(None) , 0 , O(XmmYmm) , O(XmmYmm) , O(XmmYmmMem) , U , O_660F38(05,U) , U ),
INST(kInstVphsubwd , "vphsubwd" , G(XopRm) , F(None) , 0 , O(Xmm) , O(XmmMem) , U , U , O_00_M09(E2,U) , U ),
@@ -3208,6 +3243,87 @@ const InstInfo _instInfo[] = {
#undef INST
// ============================================================================
// [asmjit::x86x64::X86Util]
// ============================================================================
// Compare two instruction names.
//
// `a` is null terminated instruction name from `_instName[]` table.
// `b` is non-null terminated instruction name passed to `getInstIdByName()`.
static ASMJIT_INLINE int X86InstUtil_cmpName(const char* a, const char* b, size_t len) {
for (size_t i = 0; i < len; i++) {
int c = static_cast<int>(static_cast<uint8_t>(a[i])) -
static_cast<int>(static_cast<uint8_t>(b[i])) ;
if (c != 0)
return c;
}
return static_cast<int>(a[len]);
}
uint32_t X86InstUtil::getInstIdByName(const char* name, size_t len) {
if (name == NULL)
return kInstNone;
if (len == kInvalidIndex)
len = ::strlen(name);
if (len == 0)
return kInstNone;
uint32_t prefix = name[0] - kInstAlphaIndexFirst;
if (prefix > kInstAlphaIndexLast - kInstAlphaIndexFirst)
return kInstNone;
uint32_t index = _instAlphaIndex[prefix];
if (index == kInstAlphaIndexInvalid)
return kInstNone;
const InstInfo* base = _instInfo + index;
const InstInfo* end = _instInfo + _kInstCount;
// Handle instructions starting with 'j' specially. `jcc` instruction breaks
// the sorting, because of the suffixes (it's considered as one instruction),
// so basically `jecxz` and `jmp` are stored after all `jcc` instructions.
bool linearSearch = prefix == ('j' - kInstAlphaIndexFirst);
while (++prefix <= kInstAlphaIndexLast - kInstAlphaIndexFirst) {
index = _instAlphaIndex[prefix];
if (index == kInstAlphaIndexInvalid)
continue;
end = _instInfo + index;
break;
}
if (linearSearch) {
while (base != end) {
if (X86InstUtil_cmpName(base->getName(), name, len) == 0)
return static_cast<uint32_t>((size_t)(base - _instInfo));
base++;
}
}
else {
for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
const InstInfo* cur = base + (lim >> 1);
int result = X86InstUtil_cmpName(cur->getName(), name, len);
if (result < 0) {
base = cur + 1;
lim--;
continue;
}
if (result > 0)
continue;
return static_cast<uint32_t>((size_t)(cur - _instInfo));
}
}
return kInstNone;
}
} // x86x64 namespace
} // asmjit namespace

View File

@@ -334,6 +334,7 @@ ASMJIT_ENUM(kInstCode) {
kInstMinsd, // SSE2
kInstMinss, // SSE
kInstMonitor, // SSE3
kInstMovPtr, // X86/X64
kInstMov, // X86/X64
kInstMovapd, // SSE2
kInstMovaps, // SSE
@@ -357,7 +358,6 @@ ASMJIT_ENUM(kInstCode) {
kInstMovntpd, // SSE2
kInstMovntps, // SSE
kInstMovntq, // MMX-Ext
kInstMovptr, // X86/X64
kInstMovq, // MMX/SSE/SSE2
kInstMovq2dq, // SSE2
kInstMovsd, // SSE2
@@ -745,14 +745,14 @@ ASMJIT_ENUM(kInstCode) {
kInstVfmsub231ps, // FMA3
kInstVfmsub231sd, // FMA3
kInstVfmsub231ss, // FMA3
kInstVfmsubaddpd, // FMA4
kInstVfmsubaddps, // FMA4
kInstVfmsubadd132pd, // FMA3
kInstVfmsubadd132ps, // FMA3
kInstVfmsubadd213pd, // FMA3
kInstVfmsubadd213ps, // FMA3
kInstVfmsubadd231pd, // FMA3
kInstVfmsubadd231ps, // FMA3
kInstVfmsubaddpd, // FMA4
kInstVfmsubaddps, // FMA4
kInstVfmsubpd, // FMA4
kInstVfmsubps, // FMA4
kInstVfmsubsd, // FMA4
@@ -933,8 +933,8 @@ ASMJIT_ENUM(kInstCode) {
kInstVphaddwq, // XOP
kInstVphminposuw, // AVX
kInstVphsubbw, // XOP
kInstVphsubdq, // XOP
kInstVphsubd, // AVX2
kInstVphsubdq, // XOP
kInstVphsubsw, // AVX2
kInstVphsubw, // AVX2
kInstVphsubwd, // XOP
@@ -1405,15 +1405,15 @@ ASMJIT_ENUM(kInstOpCode) {
//! X86/X64 instruction type flags.
ASMJIT_ENUM(kInstFlags) {
//! No flags.
kInstFlagNone = 0x0000,
kInstFlagNone = 0x0000,
//! Instruction is a control-flow instruction.
//!
//! Control flow instructions are jmp, jcc, call and ret.
kInstFlagFlow = 0x0001,
kInstFlagFlow = 0x0001,
//! Instruction is a compare/test like instruction.
kInstFlagTest = 0x0002,
kInstFlagTest = 0x0002,
//! Instruction is a move like instruction.
//!
@@ -1428,64 +1428,64 @@ ASMJIT_ENUM(kInstFlags) {
//! There are some MOV instructions that do only a partial move (for example
//! 'cvtsi2ss'), register allocator has to know the variable size and use
//! the flag accordingly to it.
kInstFlagMove = 0x0004,
kInstFlagMove = 0x0004,
//! Instruction is an exchange like instruction.
//!
//! Exchange instruction typically overwrite first and second operand. So
//! far only the instructions 'xchg' and 'xadd' are considered.
kInstFlagXchg = 0x0008,
kInstFlagXchg = 0x0008,
//! Instruction accesses Fp register(s).
kInstFlagFp = 0x0010,
kInstFlagFp = 0x0010,
//! Instruction can be prefixed by using the LOCK prefix.
kInstFlagLock = 0x0020,
kInstFlagLock = 0x0020,
//! Instruction is special, this is for `BaseCompiler`.
kInstFlagSpecial = 0x0040,
kInstFlagSpecial = 0x0040,
//! Instruction always performs memory access.
//!
//! This flag is always combined with `kInstFlagSpecial` and signalizes
//! that there is an implicit address which is accessed (usually EDI/RDI or
//! ESI/EDI).
kInstFlagSpecialMem = 0x0080,
kInstFlagSpecialMem = 0x0080,
//! Instruction memory operand can refer to 16-bit address (used by FPU).
kInstFlagMem2 = 0x0100,
kInstFlagMem2 = 0x0100,
//! Instruction memory operand can refer to 32-bit address (used by FPU).
kInstFlagMem4 = 0x0200,
kInstFlagMem4 = 0x0200,
//! Instruction memory operand can refer to 64-bit address (used by FPU).
kInstFlagMem8 = 0x0400,
kInstFlagMem8 = 0x0400,
//! Instruction memory operand can refer to 80-bit address (used by FPU).
kInstFlagMem10 = 0x0800,
kInstFlagMem10 = 0x0800,
//! \internal
//!
//! Combination of `kInstFlagMem2` and `kInstFlagMem4`.
kInstFlagMem2_4 = kInstFlagMem2 | kInstFlagMem4,
kInstFlagMem2_4 = kInstFlagMem2 | kInstFlagMem4,
//! \internal
//!
//! Combination of `kInstFlagMem2`, `kInstFlagMem4` and `kInstFlagMem8`.
kInstFlagMem2_4_8 = kInstFlagMem2_4 | kInstFlagMem8,
kInstFlagMem2_4_8 = kInstFlagMem2_4 | kInstFlagMem8,
//! \internal
//!
//! Combination of `kInstFlagMem4` and `kInstFlagMem8`.
kInstFlagMem4_8 = kInstFlagMem4 | kInstFlagMem8,
kInstFlagMem4_8 = kInstFlagMem4 | kInstFlagMem8,
//! \internal
//!
//! Combination of `kInstFlagMem4`, `kInstFlagMem8` and `kInstFlagMem10`.
kInstFlagMem4_8_10 = kInstFlagMem4_8 | kInstFlagMem10,
kInstFlagMem4_8_10 = kInstFlagMem4_8 | kInstFlagMem10,
//! Zeroes the rest of the register if the source operand is memory.
kInstFlagZeroIfMem = 0x1000,
kInstFlagZeroIfMem = 0x1000,
//! REX.W/VEX.W by default.
kInstFlagW = 0x8000
kInstFlagW = 0x8000
};
// ============================================================================
@@ -1823,6 +1823,15 @@ struct InstInfo {
uint32_t _opCode[2];
};
// ============================================================================
// [asmjit::x86x64::X86InstUtil]
// ============================================================================
struct X86InstUtil {
ASMJIT_API static uint32_t getInstIdByName(
const char* name, size_t len = kInvalidIndex);
};
//! \}
} // x64 namespace

View File

@@ -21,7 +21,7 @@ namespace asmjit {
namespace x86x64 {
// ============================================================================
// [asmjit::x86x64::Cond]
// [asmjit::x86x64::Condition Codes]
// ============================================================================
#define CC_TO_INST(_Inst_) { \

View File

@@ -302,6 +302,10 @@ struct RegMask {
//! X86/X64 utilities.
struct X86Util {
// --------------------------------------------------------------------------
// [Condition Codes]
// --------------------------------------------------------------------------
//! Corresponds to transposing the operands of a comparison.
static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) {
ASMJIT_ASSERT(cond < ASMJIT_ARRAY_SIZE(_reverseCond));
@@ -335,12 +339,20 @@ struct X86Util {
return _condToSetcc[cond];
}
// --------------------------------------------------------------------------
// [Registers]
// --------------------------------------------------------------------------
//! Get whether the `op` operand is Gpb-Lo or Gpb-Hi register.
static ASMJIT_INLINE bool isGpbRegOp(const Operand& op) {
const uint32_t mask = IntUtil::pack32_2x8_1x16(0xFF, 0xFF, ~(kRegTypePatchedGpbHi << 8) & 0xFF00);
return (op._packed[0].u32[0] & mask) == IntUtil::pack32_2x8_1x16(kOperandTypeReg, 1, 0x0000);
}
// --------------------------------------------------------------------------
// [Immediates]
// --------------------------------------------------------------------------
//! Pack a shuffle constant to be used with multimedia instrutions (2 values).
//!
//! \param x First component position, number at interval [0, 1] inclusive.

View File

@@ -47,25 +47,6 @@ var inject = function(s, start, end, code) {
// SuffixIndex - Index to a suffix string.
var Database = (function() {
function bestSuffix(s, suffixes) {
var best = -1;
for (var i = 0; i < suffixes.length; i++) {
var suffix = suffixes[i];
var si = s.lastIndexOf(suffix);
if (si === -1 || si + suffix.length != s.length)
continue;
if (best !== -1 && suffix.length < suffixes[best].length)
continue;
best = i;
}
return best;
}
var IndexedString = function() {
this.array = [];
this.index = 0;
@@ -106,13 +87,10 @@ var Database = (function() {
return this.index;
};
var Database = function(suffixes) {
var Database = function() {
this.map = {};
this.suffixes = suffixes;
this.alphabetical = new Array(26);
this.fullString = new IndexedString();
this.prefixString = new IndexedString();
this.suffixString = new IndexedString();
};
Database.prototype.add = function(name, id) {
@@ -120,41 +98,29 @@ var Database = (function() {
id: id,
fullIndex: 0,
prefixIndex: 0,
suffixIndex: 0,
hasV: 0
};
};
Database.prototype.index = function() {
var map = this.map;
var suffixes = this.suffixes;
for (var i = 0; i < suffixes.length; i++) {
this.suffixString.add(suffixes[i]);
}
var alphabetical = this.alphabetical;
for (var name in map) {
var inst = map[name];
var si = bestSuffix(name, suffixes);
inst.fullIndex = this.fullString.add(name);
var aIndex = name.charCodeAt(0) - 'a'.charCodeAt(0);
if (aIndex < 0 || aIndex >= 26)
throw new Error("Alphabetical index error");
if (alphabetical[aIndex] === undefined)
alphabetical[aIndex] = inst.id;
if (name.indexOf("v") === 0) {
inst.hasV = 1;
name = name.substr(1);
}
if (si !== -1) {
var suffix = suffixes[si];
var prefix = name.substr(0, name.length - suffix.length);
inst.prefixIndex = this.prefixString.add(prefix);
inst.suffixIndex = this.suffixString.add(suffix);
}
else {
inst.prefixIndex = this.prefixString.add(name);
inst.suffixIndex = this.suffixString.add("");
}
}
};
@@ -165,7 +131,7 @@ var Database = (function() {
// [Generate]
// ----------------------------------------------------------------------------
var generate = function(fileName, arch, suffixes) {
var generate = function(fileName, arch) {
var oldData = fs.readFileSync(fileName, "utf8").replace(/\r\n/g, "\n");
var data = oldData;
@@ -174,7 +140,7 @@ var generate = function(fileName, arch, suffixes) {
var Arch = uppercaseFirst(arch);
// Create database.
var db = new Database(suffixes);
var db = new Database();
var re = new RegExp("INST\\(([A-Za-z0-9_]+)\\s*,\\s*\\\"([A-Za-z0-9_ ]*)\\\"", "g");
while (m = re.exec(data)) {
@@ -186,8 +152,6 @@ var generate = function(fileName, arch, suffixes) {
db.index();
console.log("Full size: " + db.fullString.getSize());
console.log("Prefix size: " + db.prefixString.getSize());
console.log("Suffix size: " + db.suffixString.getSize());
// Generate InstName[] string.
code += "const char _instName[] =\n";
@@ -197,14 +161,32 @@ var generate = function(fileName, arch, suffixes) {
}
code = code.substr(code, code.length - 1) + ";\n\n";
// Generate AlphaIndex.
code += "enum kInstAlphaIndex {\n";
code += " kInstAlphaIndexFirst = 'a',\n";
code += " kInstAlphaIndexLast = 'z',\n";
code += " kInstAlphaIndexInvalid = 0xFFFF\n";
code += "};\n";
code += "\n";
// Generate NameIndex.
code += "static const uint16_t _instAlphaIndex[26] = {\n";
for (var i = 0; i < db.alphabetical.length; i++) {
var id = db.alphabetical[i];
code += " " + (id === undefined ? "0xFFFF" : id);
if (i !== db.alphabetical.length - 1)
code += ",";
code += "\n";
}
code += "};\n\n";
code += "enum kInstData_NameIndex {\n";
for (var k in db.map) {
var inst = db.map[k];
code += " " + inst.id + "_NameIndex = " + inst.fullIndex + ",\n";
}
code = code.substr(code, code.length - 2) + "\n};\n";
// Inject.
data = inject(data, injectStartMarker, injectEndMarker, code);
@@ -219,35 +201,13 @@ var generate = function(fileName, arch, suffixes) {
var main = function(files) {
files.forEach(function(file) {
generate(file.name, file.arch, file.suffixes);
generate(file.name, file.arch);
});
};
main([
{
name: "../src/asmjit/x86/x86inst.cpp",
arch: "x86",
suffixes: [
"a", "ae",
"b", "bd", "be", "bq", "bw",
"c",
"d", "dq", "dqa", "dqu", "dw",
"e",
"f128",
"g", "ge",
"hpd", "hps",
"i", "i128", "ip",
"l", "last", "ld", "le", "lpd", "lps", "lw",
"na", "nae", "nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", "np", "ns", "nz",
"o",
"p", "pd", "pe", "ph", "pi", "po", "pp", "ps",
"q",
"r",
"s", "sb", "sd", "si", "sq", "ss", "sw",
"usb", "usw",
"vpd", "vps",
"w", "wb", "wd", "wq",
"z"
]
arch: "x86"
}
]);