diff --git a/src/asmjit/base/vmem.cpp b/src/asmjit/base/vmem.cpp index bbfd03c..31a9f50 100644 --- a/src/asmjit/base/vmem.cpp +++ b/src/asmjit/base/vmem.cpp @@ -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 diff --git a/src/asmjit/base/zone.cpp b/src/asmjit/base/zone.cpp index 8b18175..3a0e19c 100644 --- a/src/asmjit/base/zone.cpp +++ b/src/asmjit/base/zone.cpp @@ -29,7 +29,7 @@ static const Zone::Block Zone_zeroBlock = { // ============================================================================ Zone::Zone(size_t blockSize) { - _blocks = const_cast(&Zone_zeroBlock); + _block = const_cast(&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_zeroBlock); + _block = const_cast(&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(_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(next->data); } @@ -120,7 +120,7 @@ void* Zone::_alloc(size_t size) { } } - _blocks = newBlock; + _block = newBlock; return static_cast(newBlock->data); } diff --git a/src/asmjit/base/zone.h b/src/asmjit/base/zone.h index f78be2d..b55ac9b 100644 --- a/src/asmjit/base/zone.h +++ b/src/asmjit/base/zone.h @@ -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; }; diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp index faa1b75..c22f289 100644 --- a/src/asmjit/x86/x86assembler.cpp +++ b/src/asmjit/x86/x86assembler.cpp @@ -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; diff --git a/src/asmjit/x86/x86assembler.h b/src/asmjit/x86/x86assembler.h index d6146a4..93d2e28 100644 --- a/src/asmjit/x86/x86assembler.h +++ b/src/asmjit/x86/x86assembler.h @@ -869,7 +869,7 @@ struct X86X64Assembler : public BaseAssembler { ASMJIT_ASSERT(dst.getRegIndex() == 0); Imm imm(static_cast((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((intptr_t)dst)); - return emit(kInstMovptr, imm, src); + return emit(kInstMovPtr, imm, src); } //! Move data after dwapping bytes (SSE3 - Atom). diff --git a/src/asmjit/x86/x86compiler.h b/src/asmjit/x86/x86compiler.h index a9079de..f14c0c1 100644 --- a/src/asmjit/x86/x86compiler.h +++ b/src/asmjit/x86/x86compiler.h @@ -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((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((intptr_t)dst)); - return emit(kInstMovptr, imm, src); + return emit(kInstMovPtr, imm, src); } //! Move data after swapping bytes (SSE3 - Atom). diff --git a/src/asmjit/x86/x86context.cpp b/src/asmjit/x86/x86context.cpp index 71f9e1e..9886dee 100644 --- a/src/asmjit/x86/x86context.cpp +++ b/src/asmjit/x86/x86context.cpp @@ -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: diff --git a/src/asmjit/x86/x86inst.cpp b/src/asmjit/x86/x86inst.cpp index 5f45a3f..d2cf363 100644 --- a/src/asmjit/x86/x86inst.cpp +++ b/src/asmjit/x86/x86inst.cpp @@ -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(static_cast(a[i])) - + static_cast(static_cast(b[i])) ; + if (c != 0) + return c; + } + + return static_cast(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((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((size_t)(cur - _instInfo)); + } + } + + return kInstNone; +} + } // x86x64 namespace } // asmjit namespace diff --git a/src/asmjit/x86/x86inst.h b/src/asmjit/x86/x86inst.h index f237ad8..3bbbe39 100644 --- a/src/asmjit/x86/x86inst.h +++ b/src/asmjit/x86/x86inst.h @@ -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 diff --git a/src/asmjit/x86/x86util.cpp b/src/asmjit/x86/x86util.cpp index c8dcf13..12fe100 100644 --- a/src/asmjit/x86/x86util.cpp +++ b/src/asmjit/x86/x86util.cpp @@ -21,7 +21,7 @@ namespace asmjit { namespace x86x64 { // ============================================================================ -// [asmjit::x86x64::Cond] +// [asmjit::x86x64::Condition Codes] // ============================================================================ #define CC_TO_INST(_Inst_) { \ diff --git a/src/asmjit/x86/x86util.h b/src/asmjit/x86/x86util.h index f3f21be..24583d9 100644 --- a/src/asmjit/x86/x86util.h +++ b/src/asmjit/x86/x86util.h @@ -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. diff --git a/tools/src-gendefs.js b/tools/src-gendefs.js index c2d4476..3724f8f 100644 --- a/tools/src-gendefs.js +++ b/tools/src-gendefs.js @@ -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" } ]);