c926d9f409
9357732aa v6.06 b161a3eb7 update changelog e5453b064 Merge branch 'dev' 2a265d9d9 memfd: keep file descriptor open during allocation lifetime 31ff018ed replace unsigned int with uint32_t in xbyak_util.h e427b2231 move Type into Cpu 8cf41063b refactoring Cpu 66d62968d add -cpuid to test_util cf7cb744c add comments 028112949 add detection of clzero c88007b03 update doc 4cb2e77a9 v6.052 015c27cf6 Merge branch 'dev' d808f9ecb add test of Cpu::has b48a7bb1b add operator== to Type 1a90f456c v6.051 96cb1d660 update changelog 1f5a77f56 Merge branch 'dev' 87e14f02a add test with noexception 30144f809 fix error when XBYAK_NO_EXCEPTION is defined ec15751df Merge branch 'dev' 4831b3fb3 v6.05 9ddf251f3 remove debug code 905b31bab fix typo 72d1ac118 add movdir64b a6665996b add detection of movdir64b 92ddc6dfd remove Type::operator<<() because it's ambiguous 9cdd40f5e add detection of movdiri 379f8bf37 add movdiri 0ad6db138 fix cldemote test for 32-bit 84ab46bb3 add cldemote to Cpu a84ddc12d support cldemote 3a6cc626e add clwb 38c40c02e detection of clflushopt c061ac839 avoid unnecessary replacement in readme.md 095ebbff1 extend Cpu::Type to 128 bit 3ea8e45d3 Merge branch 'dev' f7bfc2634 v6.041 ab4e52d67 update doc 2bef54399 include intrin.h on mingw 621ed0775 Merge branch 'dev' 4f5893e1e memfd_create: disable for ANDROID_API < 30 684d69db0 Merge branch 'dev' ea88b6d85 disable warning on mingw 7e8923fa5 add colon 9914216bd Merge branch 'dev' b335602ff [skip ci] tweak doc 25fbb3996 tweak doc 122054dc4 Formatted Supported OS Section d4fa7e46b Reworked Authors Section 9e4b64a74 Adjusted Spacing ff9fdb45f Use Github Sponsor Widget 893b31d46 Added Quicklinks 2d2adf78b Added License Badge 335b5941b Formatted Header 70603addf Moved Install / Usage Into Dedicated Files 1659d28fe Moved History Into Dedicated File fb953284b Merge branch 'dev' dbd96b277 add news 898c354e6 v6.04 f8e2ad1e9 add waitpkg detection to Cpu a220fd69a add umwait 64ec053e6 add umonitor 764d54f6f add tpause c68646e8d remove warning of vc 4e8214ca2 Merge branch 'dev' 360f4b673 test badSSE only for 32-bit mode a9fddc454 fix typo of readme 250b5dc39 fix typo of readme c46e92756 Merge branch 'dev' 31b7cd350 v6.03 a2f9ed085 rename isValidXMm to isValidSSE 2bc8fcbd3 add tests to badSSE 6de93fb88 add baseSSE test e2eda384c update doc 71a7b1773 fix condition to throw error for SSE instructions when using XMM16-XMM31 615b665cc sample/memfd shows /proc/self/maps 2861517f2 add memfd sample 507b0285e apt update at first 452c07f77 typedef for no-MmapAllocator 8af6e2026 minimize diff 0af3b5d07 Allocator: take optional name parameter and use it with memfd a67e24505 Merge branch 'dev' b3892c15e Merge pull request #138 from Tachi107/make-cxx-cpp-ld-flags b4eddaced build(make): honour CXXFLAGS, CPPFLAGS and LDFLAGS fbe60e590 test generates only a.asm 0a4a7571d Merge branch 'patch-1' of https://github.com/Tachi107/xbyak into Tachi107-patch-1 55b9f131b build(make): fix clean target in test/Makefile 7aef3ff54 Merge branch 'dev' 82e0deb8a v6.02 4d9906a94 fix condition to throw error for invalid displacements c79311a51 fix test_util.cpp 9b2c175b3 Merge branch 'dev' 06d797e33 Allow parallel feature checks 2a85bba3f Merge branch 'dev' 8d5af80a6 v6.01 df39606fe update doc 08f11817c supprt retf 1abfc3465 support call(mem, T_FAR) fb158f901 support jmp(mem, T_FAR) 9be47ceb2 Merge branch 'lioncash-hlt' into dev 3162eb16f add test of hlt bb55725a9 xbyak: Add hlt opcode function 47cf85fdb fix conflict b29e471ea build(meson): fix CMake Config file include dir 2cc21925f delete the sentences translated into Japanese from COPYRIGHT dca3930de remove tabs cecd204a5 Merge pull request #129 from Tachi107/meson-cmake-config 345de8a54 build(meson): generate CMake package config files e831805cc revert change of the type of Pack::util::operator[] fc9d953e5 util::Pack has not pointer but instance of Reg64 0868c54a9 use _WIN32 instead of _MSC_VER for mingw64 894a1b14a use original uint8_t dfc079ca1 add cstrs of Xbyak::util::Pack for 11 or 12 args 06e8f531f Merge branch 'Tachi107-meson' into dev ef90b6bd2 Makefile updates the version of meson.build 0000938f5 build: add Meson support This allows Meson users to use xbyak more easly, while it also provides a pkg-config file generator, useful to Linux distributions 757e4063f v6.00 b3489f548 add vcvtusi2sh 16d9898ab add vcvtsi2sh cfc03cb8f unify T_66, T_F3, T_F2 flags 02fa7057d add vcvttph2qq 4e72a9dc4 add vcvttsh2usi 05d08e05b add vcvttsh2si 621e6548c add vcvtsh2usi 34abda5c5 extend vcvtps2ph facd622b2 add vcvtw2ph 270af1cb2 add vcvtuw2ph 17dc697cd add vcvttph2w 62f022aea vcvttph2uw 836346bfd add vcvtph2w 300edb37b add vcvtph2uw 737904b5a add vcvtuqq2ph 52b2ebf18 add vcvtqq2ph 6761f1e05 add vcvtpd2ph 03f95b7e3 add vcvtudq2ph 64430b2bb add vcvtps2phx 88e426aa4 add vcvtdq2ph bf28a94a5 add vcvttph2uqq 4c4e665d3 add vcvtph2uqq 2b0099b63 add vcvtph2qq 3ff69a474 add vcvtph2pd 678b52956 add vcvttph2udq 72a5717e4 add vcvttph2dq 524d52bf6 add vcvtph2udq d1cf4db97 add vcvtph2psx fccd2c49b add vcvtph2dq 6530f4099 refactor gen-cvt c51e16156 tweak ed9f6c72a add vcvtsh2si ac1407bd1 add vcvtss2sh 2958a19bb add vcvtsh2ss 10d683303 add vcvtsh2sd 3920c950c add vcvtsd2sh 9a1b73932 add vmovw d86e4882f vmovsh xmm, addr 61f85a204 add vmovsh 847166cef add tests of vgetmant{ph,sh} c11a21cf4 add vgetmantph 55ab361f0 add tests of vgetexp{ph,sh} 8653f4152 add vgetexpsh 697eeb627 add vgetexpph ee920a991 add vfpclasssh 7aed436e6 add vfpclassph 56dca14e4 v5.997 b3b1e4e3c fix vrndscale* to support {sae} 681077eb1 add vrndscalesh 2f14eae85 add vrndscaleph f96870a44 add vreducesh 043c94ae9 add vreduceph 37bf3bb49 add vscalefsh c16f91c59 add vscalefph 61ad45935 add vsqrtsh e00b508d5 add vsqrtph 52765d54f add vrsqrtsh 2ec6a7ab4 add vrsqrtph b1ff7891d add vrcpph, vrcpsh 4f543ca0e add vucomish 412b95f02 add vf{,c}mulcph 9fc53baed add vf{,c}maddcph 0098ce98d add vf{,n}m{sub,add}sh 849dffb10 add vfmadd, vfnmadd, vfnmsub for avx512-fp16 eadb93d0b add vfmsubaddcph 9b8802cba add vfmaddsub{132,213,231}ph ab9481b4c add vcomish cd036ea17 fix vcmpsh b494b321a vcmpsh supports ptr_b eb2d63c83 vcmpph uses T_B16 a480b3dd9 v5.996 16d18b1d4 fix v{add,sub,mul,...}{sd,ss} to support T_rd_sae etc. 66c6ca1ab support vaddsh with T_rd_sae 6333ec099 add m16bcst 84053c8e7 add vcmpph 5df23d263 move FP16 to AVX-512 d5c7336f8 fix disp scaling of v{add,sub,mul,div,max,min}sh ebf29542d add vaddsh test f29689d02 add test of vaddph 2c4b6ac16 add v{add,sub,mul,div,min,max}{ph,sh} edf3c2f6f remove mask for mmm 2c561aad6 add T_MAP5 and T_MAP6 acd360c38 add Cpu::tAVX512_FP16 1554f479c remove unused flags(tSSE4a and tSSE5) of Cpu c313a8758 update CMakeLists.txt version 740b39e24 Merge pull request #122 from abouvier/cmake 10a1e5759 v5.995 0a557a099 rename XBYAK_MEMFD_CREATE to XBYAK_USE_MEMFD 0ad9b9bbe Merge branch 'captain5050-master' into dev c7bb66383 fix for mac and enable it if XBYAK_MEMFD_CREATE is defined c1e6569f1 fix cmake config files ccd4130ec Name mmap pages on Linux with memfd_create 2fb843c32 v5.994 413a66b44 add alias of vcmpXX{ps,pd,ss,sd} for mask register 6f4f76890 v5.993 19043cb9a add test for gather/scatter b5acb1d1c gather test does not generate bad combination of regs 67ec1674a check restriction of gather/scatter regs ea9814f4f check bad reg combination of gather a34850b2d add endbr32 and endbr64 git-subtree-dir: externals/xbyak git-subtree-split: 9357732aa2aa3cf97809027596dfa5c61d1515b2
592 lines
29 KiB
Text
592 lines
29 KiB
Text
|
|
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 6.06
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎概要
|
|
|
|
これはx86, x64(AMD64, x86-64)のマシン語命令を生成するC++のクラスライブラリです。
|
|
プログラム実行時に動的にアセンブルすることが可能です。
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎特徴
|
|
|
|
・ヘッダファイルオンリー
|
|
xbyak.hをインクルードするだけですぐ利用することができます。
|
|
C++の枠組み内で閉じているため、外部アセンブラは不要です。
|
|
32bit/64bit両対応です。
|
|
対応ニーモニック:特権命令除くx86, MMX/MMX2/SSE/SSE2/SSE3/SSSE3/SSE4/FPU(一部)/AVX/AVX2/FMA/VEX-encoded GPR
|
|
|
|
・Windows Xp(32bit, 64bit), Windows 7/Linux(32bit, 64bit)/Intel Mac対応
|
|
Windows Xp, Windows 7上ではVC2008, VC2010, VC2012
|
|
Linux (kernel 3.8)上ではgcc 4.7.3, clang 3.3
|
|
Intel Mac
|
|
などで動作確認をしています。
|
|
|
|
※ and, orなどの代わりにand_, or_を使用してください。
|
|
and, orなどを使いたい場合は-fno-operator-namesをgcc/clangに指定してください。
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎準備
|
|
xbyak.h
|
|
xbyak_bin2hex.h
|
|
これらを同一のパスに入れてインクルードパスに追加してください。
|
|
|
|
Linuxではmake installで/usr/local/include/xbyakにコピーされます。
|
|
-----------------------------------------------------------------------------
|
|
◎下位互換性の破れ
|
|
* push byte, immまたはpush word, immが下位8bit, 16bitにキャストした値を使うように変更。
|
|
* (Windows) `<winsock2.h>`をincludeしなくなったので必要なら明示的にincludeしてください。
|
|
* XBYAK_USE_MMAP_ALLOCATORがデフォルトで有効になりました。従来の方式にする場合はXBYAK_DONT_USE_MMAP_ALLOCATORを定義してください。
|
|
* Xbyak::Errorの型をenumからclassに変更
|
|
** 従来のenumの値をとるにはintにキャストしてください。
|
|
* (古い)Reg32eクラスを(新しい)Reg32eとRegExpに分ける。
|
|
** (新しい)Reg32eはReg32かReg64
|
|
** (新しい)RegExpは'Reg32e + (Reg32e|Xmm|Ymm) * scale + disp'の型
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎新機能
|
|
|
|
例外なしモード追加
|
|
XBYAK_NO_EXCEPTIONを定義してコンパイルするとgcc/clangで-fno-exceptionsオプションでコンパイルできます。
|
|
エラーは例外の代わりに`Xbyak::GetError()`で通達されます。
|
|
この値が0でなければ何か問題が発生しています。
|
|
この値は自動的に変更されないので`Xbyak::ClearError()`でリセットしてください。
|
|
`CodeGenerator::reset()`は`ClearError()`を呼びます。
|
|
|
|
MmapAllocator追加
|
|
これはUnix系OSでのみの仕様です。XBYAK_USE_MMAP_ALLOCATORを使うと利用できます。
|
|
デフォルトのAllocatorはメモリ確保時にposix_memalignを使います。
|
|
この領域に対するmprotectはmap countを減らします。
|
|
map countの最大値は/proc/sys/vm/max_map_countに書かれています。
|
|
デフォルトでは3万個ほどのXbyak::CodeGeneratorインスタンスを生成するとエラーになります。
|
|
test/mprotect_test.cppで確認できます。
|
|
これを避けるためにはmmapを使うMmapAllocatorを使ってください。
|
|
|
|
|
|
AutoGrowモード追加
|
|
これはメモリ伸長を動的に行うモードです。
|
|
今まではXbyak::CodeGenerator()に渡したメモリサイズを超えると例外が発生して
|
|
いましたが、このモードでは内部でメモリを再確保して伸長します。
|
|
ただし、getCode()を呼び出す前にジャンプ命令のアドレス解決をするためにready()
|
|
関数を呼ぶ必要があります。
|
|
|
|
次のように使います。
|
|
|
|
struct Code : Xbyak::CodeGenerator {
|
|
Code()
|
|
: Xbyak::CodeGenerator(<default memory size>, Xbyak::AutoGrow)
|
|
{
|
|
...
|
|
}
|
|
};
|
|
Code c;
|
|
c.ready(); // この呼び出しを忘れてはいけない
|
|
|
|
注意1. ready()を呼んで確定するまではgetCurr()で得たポインタは無効化されている
|
|
可能性があります。getSize()でoffsetを保持しておきready()のあとにgetCode()を
|
|
呼び出してからgetCode() + offsetで新しいポインタを取得してください。
|
|
|
|
注意2. AutoGrowモードでは64bitモードの相対アドレッシング[rip]は非サポートです。
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎文法
|
|
|
|
Xbyak::CodeGeneratorクラスを継承し、そのクラスメソッド内でx86, x64アセンブラを
|
|
記述します。そのメソッドを呼び出した後、getCode()メソッドを呼び出し、その戻
|
|
り値を自分が使いたい関数ポインタに変換して利用します。アセンブルエラーは例外
|
|
により通知されます(cf. main.cpp)。
|
|
|
|
・基本的にnasmの命令で括弧をつければよいです。
|
|
|
|
mov eax, ebx --> mov(eax, ebx);
|
|
inc ecx inc(ecx);
|
|
ret --> ret();
|
|
|
|
・アドレッシング
|
|
|
|
(ptr|dword|word|byte) [base + index * (1|2|4|8) + displacement]
|
|
[rip + 32bit disp] ; x64 only
|
|
という形で指定します。サイズを指定する必要がない限りptrを使えばよいです。
|
|
|
|
セレクター(セグメントレジスタ)をサポートしました。
|
|
(注意)セグメントレジスタはOperandを継承していません。
|
|
|
|
mov eax, [fs:eax] --> putSeg(fs); mov(eax, ptr [eax]);
|
|
mov ax, cs --> mov(ax, cs);
|
|
|
|
mov eax, [ebx+ecx] --> mov (eax, ptr[ebx+ecx]);
|
|
test byte [esp], 4 --> test (byte [esp], 4);
|
|
|
|
(注意) dword, word, byteはメンバ変数です。従ってたとえばunsigned intの
|
|
つもりでdwordをtypedefしないでください。
|
|
|
|
・AVX
|
|
|
|
FMAについては簡略表記を導入するか検討中です(アイデア募集中)。
|
|
|
|
vaddps(xmm1, xmm2, xmm3); // xmm1 <- xmm2 + xmm3
|
|
vaddps(xmm2, xmm3, ptr [rax]); // メモリアクセスはptrで
|
|
|
|
vfmadd231pd(xmm1, xmm2, xmm3); // xmm1 <- (xmm2 * xmm3) + xmm1
|
|
|
|
*注意*
|
|
デスティネーションの省略形はサポートされなくなりました。
|
|
|
|
vaddps(xmm2, xmm3); // xmm2 <- xmm2 + xmm3
|
|
|
|
XBYAK_ENABLE_OMITTED_OPERANDを定義すると使えますが、将来はそれも非サポートになるでしょう。
|
|
|
|
・AVX-512
|
|
|
|
vaddpd zmm2, zmm5, zmm30 --> vaddpd(zmm2, zmm5, zmm30);
|
|
vaddpd xmm30, xmm20, [rax] --> vaddpd(xmm30, xmm20, ptr [rax]);
|
|
vaddps xmm30, xmm20, [rax] --> vaddps(xmm30, xmm20, ptr [rax]);
|
|
vaddpd zmm2{k5}, zmm4, zmm2 --> vaddpd(zmm2 | k5, zmm4, zmm2);
|
|
vaddpd zmm2{k5}{z}, zmm4, zmm2 --> vaddpd(zmm2 | k5 | T_z, zmm4, zmm2);
|
|
vaddpd zmm2{k5}{z}, zmm4, zmm2,{rd-sae} --> vaddpd(zmm2 | k5 | T_z, zmm4, zmm2 | T_rd_sae);
|
|
vaddpd(zmm2 | k5 | T_z | T_rd_sae, zmm4, zmm2); // the position of `|` is arbitrary.
|
|
vcmppd k4{k3}, zmm1, zmm2, {sae}, 5 --> vcmppd(k4 | k3, zmm1, zmm2 | T_sae, 5);
|
|
|
|
vaddpd xmm1, xmm2, [rax+256]{1to2} --> vaddpd(xmm1, xmm2, ptr_b [rax+256]);
|
|
vaddpd ymm1, ymm2, [rax+256]{1to4} --> vaddpd(ymm1, ymm2, ptr_b [rax+256]);
|
|
vaddpd zmm1, zmm2, [rax+256]{1to8} --> vaddpd(zmm1, zmm2, ptr_b [rax+256]);
|
|
vaddps zmm1, zmm2, [rax+rcx*8+8]{1to16} --> vaddps(zmm1, zmm2, ptr_b [rax+rcx*8+8]);
|
|
vmovsd [rax]{k1}, xmm4 --> vmovsd(ptr [rax] | k1, xmm4);
|
|
|
|
vcvtpd2dq xmm16, oword [eax+33] --> vcvtpd2dq(xmm16, xword [eax+33]); // use xword for m128 instead of oword
|
|
vcvtpd2dq(xmm16, ptr [eax+33]); // default xword
|
|
vcvtpd2dq xmm21, [eax+32]{1to2} --> vcvtpd2dq(xmm21, ptr_b [eax+32]);
|
|
vcvtpd2dq xmm0, yword [eax+33] --> vcvtpd2dq(xmm0, yword [eax+33]); // use yword for m256
|
|
vcvtpd2dq xmm19, [eax+32]{1to4} --> vcvtpd2dq(xmm19, yword_b [eax+32]); // use yword_b to broadcast
|
|
|
|
vfpclassps k5{k3}, zword [rax+64], 5 --> vfpclassps(k5|k3, zword [rax+64], 5); // specify m512
|
|
vfpclasspd k5{k3}, [rax+64]{1to2}, 5 --> vfpclasspd(k5|k3, xword_b [rax+64], 5); // broadcast 64-bit to 128-bit
|
|
vfpclassps k5{k3}, [rax+64]{1to4}, 5 --> vfpclassps(k5|k3, xword_b [rax+64], 5); // broadcast 64-bit to 256-bit
|
|
|
|
vpdpbusd(xm0, xm1, xm2); // default encoding is EVEX
|
|
vpdpbusd(xm0, xm1, xm2, EvexEncoding); // same as the above
|
|
vpdpbusd(xm0, xm1, xm2, VexEncoding); // VEX encoding
|
|
|
|
注意
|
|
* k1, ..., k7 は新しいopmaskレジスタです。
|
|
* z, sae, rn-sae, rd-sae, ru-sae, rz-saeの代わりにT_z, T_sae, T_rn_sae, T_rd_sae, T_ru_sae, T_rz_saeを使ってください。
|
|
* `k4 | k3`と`k3 | k4`は意味が異なります。
|
|
* {1toX}の代わりにptr_bを使ってください。Xは自動的に決まります。
|
|
* 一部の命令はメモリサイズを指定するためにxword/yword/zword(_b)を使ってください。
|
|
|
|
・ラベル
|
|
|
|
L(文字列);
|
|
で定義します。ジャンプするときはその文字列を指定します。後方参照も可能ですが、
|
|
相対アドレスが8ビットに収まらない場合はT_NEARをつけないと実行時に例外が発生
|
|
します。
|
|
mov(eax, "L2");の様にラベルが表すアドレスをmovの即値として使えます。
|
|
|
|
・hasUndefinedLabel()を呼び出して真ならジャンプ先が存在しないことを示します。
|
|
コードを見直してください。
|
|
|
|
L("L1");
|
|
jmp ("L1");
|
|
|
|
jmp ("L2");
|
|
...
|
|
少しの命令の場合。
|
|
...
|
|
L("L2");
|
|
|
|
jmp ("L3", T_NEAR);
|
|
...
|
|
沢山の命令がある場合
|
|
...
|
|
L("L3");
|
|
|
|
<応用編>
|
|
|
|
1. MASMライクな@@, @f, @bをサポート
|
|
|
|
L("@@"); // <A>
|
|
jmp("@b"); // jmp to <A>
|
|
jmp("@f"); // jmp to <B>
|
|
L("@@"); // <B>
|
|
jmp("@b"); // jmp to <B>
|
|
mov(eax, "@b");
|
|
jmp(eax); // jmp to <B>
|
|
|
|
2. ラベルの局所化
|
|
|
|
ピリオドで始まるラベルをinLocalLabel(), outLocalLabel()で挟むことで局所化できます。
|
|
inLocalLabel(), outLocalLabel()は入れ子にすることができます。
|
|
|
|
void func1()
|
|
{
|
|
inLocalLabel();
|
|
L(".lp"); // <A> ; ローカルラベル
|
|
...
|
|
jmp(".lp"); // jmpt to <A>
|
|
L("aaa"); // グローバルラベル
|
|
outLocalLabel();
|
|
}
|
|
|
|
void func2()
|
|
{
|
|
inLocalLabel();
|
|
L(".lp"); // <B> ; ローカルラベル
|
|
func1();
|
|
jmp(".lp"); // jmp to <B>
|
|
outLocalLabel();
|
|
}
|
|
|
|
上記サンプルではinLocalLabel(), outLocalLabel()が無いと、
|
|
".lp"ラベルの二重定義エラーになります。
|
|
|
|
3. 新しいLabelクラスによるジャンプ命令
|
|
|
|
ジャンプ先を文字列による指定だけでなくラベルクラスを使えるようになりました。
|
|
|
|
Label label1, label2;
|
|
L(label1);
|
|
...
|
|
jmp(label1);
|
|
...
|
|
jmp(label2);
|
|
...
|
|
L(label2);
|
|
|
|
更にラベルの割り当てを行うassignL(dstLabel, srcLabel)という命令も追加されました。
|
|
|
|
Label label2;
|
|
Label label1 = L(); // Label label1; L(label1);と同じ意味
|
|
...
|
|
jmp(label2);
|
|
...
|
|
assignL(label2, label1);
|
|
|
|
上記jmp命令はlabel1にジャンプします。
|
|
|
|
制限
|
|
* srcLabelはL()により飛び先が確定していないといけません。
|
|
* dstLabelはL()により飛び先が確定していてはいけません。
|
|
|
|
ラベルは`getAddress()`によりそのアドレスを取得できます。
|
|
未定義のときは0が返ります。
|
|
```
|
|
// not AutoGrow mode
|
|
Label label;
|
|
assert(label.getAddress(), 0);
|
|
L(label);
|
|
assert(label.getAddress(), getCurr());
|
|
```
|
|
|
|
4. farジャンプ
|
|
|
|
`jmp(mem, T_FAR)`, `call(mem, T_FAR)`, `retf()`をサポートします。
|
|
サイズを明示するために`ptr`の代わりに`word|dword|qword`を利用してください。
|
|
|
|
32bit
|
|
```
|
|
jmp(word[eax], T_FAR); // jmp m16:16(FF /5)
|
|
jmp(dword[eax], T_FAR); // jmp m16:32(FF /5)
|
|
```
|
|
|
|
64bit
|
|
```
|
|
jmp(word[rax], T_FAR); // jmp m16:16(FF /5)
|
|
jmp(dword[rax], T_FAR); // jmp m16:32(FF /5)
|
|
jmp(qword[rax], T_FAR); // jmp m16:64(REX.W FF /5)
|
|
```
|
|
|
|
・Xbyak::CodeGenerator()コンストラクタインタフェース
|
|
|
|
@param maxSize [in] コード生成最大サイズ(デフォルト4096byte)
|
|
@param userPtr [in] ユーザ指定メモリ
|
|
|
|
CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0);
|
|
|
|
デフォルトコードサイズは4096(=DEFAULT_MAX_CODE_SIZE)バイトです。
|
|
それより大きなコードを生成する場合はCodeGenerator()のコンストラクタに指定してください。
|
|
|
|
class Quantize : public Xbyak::CodeGenerator {
|
|
public:
|
|
Quantize()
|
|
: CodeGenerator(8192)
|
|
{
|
|
}
|
|
...
|
|
};
|
|
|
|
またユーザ指定メモリをコード生成最大サイズと共に指定すると、CodeGeneratorは
|
|
指定されたメモリ上にバイト列を生成します。
|
|
|
|
補助関数として指定されたアドレスの実行属性を変更するCodeArray::protect()と
|
|
与えられたポインタからアライメントされたポインタを取得するCodeArray::getAlignedAddress()
|
|
も用意しました。詳細はsample/test0.cppのuse memory allocated by userを参考に
|
|
してください。
|
|
|
|
/**
|
|
change exec permission of memory
|
|
@param addr [in] buffer address
|
|
@param size [in] buffer size
|
|
@param canExec [in] true(enable to exec), false(disable to exec)
|
|
@return true(success), false(failure)
|
|
*/
|
|
bool CodeArray::protect(const void *addr, size_t size, bool canExec);
|
|
|
|
/**
|
|
get aligned memory pointer
|
|
*/
|
|
uint8 *CodeArray::getAlignedAddress(uint8 *addr, size_t alignedSize = ALIGN_SIZE);
|
|
|
|
・read/execモード
|
|
デフォルトのCodeGeneratorはコンストラクト時にJIT用の領域をread/write/execモードに設定して利用します。
|
|
コード生成時はread/writeでコード実行時にはread/execにしたい場合、次のようにしてください。
|
|
|
|
struct Code : Xbyak::CodeGenerator {
|
|
Code()
|
|
: Xbyak::CodeGenerator(4096, Xbyak::DontUseProtect) // JIT領域をread/writeのままコード生成
|
|
{
|
|
mov(eax, 123);
|
|
ret();
|
|
}
|
|
};
|
|
|
|
Code c;
|
|
c.setProtectModeRE(); // read/execモードに変更
|
|
// JIT領域を実行
|
|
|
|
AutoGrowの場合はreadyの代わりにreadyRE()を読んでください。
|
|
|
|
struct Code : Xbyak::CodeGenerator {
|
|
Code()
|
|
: Xbyak::CodeGenerator(4096, Xbyak::AutoGrow) // JIT領域をread/writeのままコード生成
|
|
{
|
|
mov(eax, 123);
|
|
ret();
|
|
}
|
|
};
|
|
|
|
Code c;
|
|
c.readyRE(); // read/exeモードに変更
|
|
// JIT領域を実行
|
|
|
|
setProtectModeRW()を呼ぶと領域が元のread/execモードに戻ります。
|
|
|
|
|
|
その他詳細は各種サンプルを参照してください。
|
|
-----------------------------------------------------------------------------
|
|
◎マクロ
|
|
|
|
32bit環境上でコンパイルするとXBYAK32が、64bit環境上でコンパイルするとXBYAK64が
|
|
定義されます。さらに64bit環境上ではWindows(VC)ならXBYAK64_WIN、cygwin, gcc上では
|
|
XBYAK64_GCCが定義されます。
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎使用例
|
|
|
|
test0.cpp ; 簡単な例(x86, x64)
|
|
quantize.cpp ; 割り算のJITアセンブルによる量子化の高速化(x86)
|
|
calc.cpp ; 与えられた多項式をアセンブルして実行(x86, x64)
|
|
boost(http://www.boost.org/)が必要
|
|
bf.cpp ; JIT Brainfuck(x86, x64)
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎ライセンス
|
|
|
|
修正された新しいBSDライセンスに従います。
|
|
http://opensource.org/licenses/BSD-3-Clause
|
|
|
|
sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から
|
|
いただきました。
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎履歴
|
|
|
|
2022/06/01 ver 6.06 Cpu::TypeクラスのリファクタリングとXBYAK_USE_MEMFDが定義されたときのMmapAllocatorの改善
|
|
2022/05/20 ver 6.052 Cpu::operator==()を正しく定義
|
|
2022/05/13 ver 6.051 XYBAK_NO_EXCEPTIONを定義したときのCpuクラスのコンパイルエラー修正
|
|
2022/05/12 ver 6.05 movdiri, movdir64b, clwb, cldemoteを追加
|
|
2022/04/05 ver 6.04 tpause, umonitor, umwaitを追加
|
|
2022/03/08 ver 6.03 MmapAllocatorがmemfd用のユーザ定義文字列をサポート
|
|
2022/01/28 ver 6.02 dispacementの32bit範囲チェックの厳密化
|
|
2021/12/14 ver 6.01 T_FAR jump/callとretfをサポート
|
|
2021/09/14 ver 6.00 AVX512-FP16を完全サポート
|
|
2021/09/09 ver 5.997 vrndscale*を{sae}をサポートするよう修正
|
|
2021/09/03 ver 5.996 v{add,sub,mul,div,max,min}{sd,ss}をT_rd_saeなどをサポートするよう修正
|
|
2021/08/15 ver 5.995 Linux上でXBYAK_USE_MEMFDが定義されたなら/proc/self/mapsにラベル追加
|
|
2021/06/17 ver 5.994 マスクレジスタ用のvcmpXX{ps,pd,ss,sd}のalias追加
|
|
2021/06/06 ver 5.993 gather/scatterのレジスタの組み合わせの厳密なチェック
|
|
2021/05/09 ver 5.992 endbr32とendbr64のサポート
|
|
2020/11/16 ver 5.991 g++-5のC++14でconstexpr機能の抑制
|
|
2020/10/19 ver 5.99 VNNI命令サポート(Thanks to akharito)
|
|
2020/10/17 ver 5.98 [scale * reg]のサポート
|
|
2020/09/08 ver 5.97 uint32などをuint32_tに置換
|
|
2020/08/28 ver 5.95 レジスタクラスのコンストラクタがconstexprに対応(C++14以降)
|
|
2020/08/04 ver 5.941 `CodeGenerator::reset()`が`ClearError()`を呼ぶように変更
|
|
2020/07/28 ver 5.94 #include <winsock2.h>の削除 (only windows)
|
|
2020/07/21 ver 5.93 例外なしモード追加
|
|
2020/06/30 ver 5.92 Intel AMX命令サポート (Thanks to nshustrov)
|
|
2020/06/19 ver 5.913 32ビット環境でXBYAK64を定義したときのmov(r64, imm64)を修正
|
|
2020/06/19 ver 5.912 macOSの古いXcodeでもMAP_JITを有効にする(Thanks to rsdubtso)
|
|
2020/05/10 ver 5.911 Linux/macOSでXBYAK_USE_MMAP_ALLOCATORがデフォルト有効になる
|
|
2020/04/20 ver 5.91 マスクレジスタk0を受け入れる(マスクをしない)
|
|
2020/04/09 ver 5.90 kmov{b,w,d,q}がサポートされないレジスタを受けると例外を投げる
|
|
2020/02/26 ver 5.891 zm0のtype修正
|
|
2020/01/03 ver 5.89 vfpclasspdの処理エラー修正
|
|
2019/12/20 ver 5.88 Windowsでのコンパイルエラー修正
|
|
2019/12/19 ver 5.87 未定義ラベルへのjmp命令のデフォルト挙動をT_NEARにするsetDefaultJmpNEAR()を追加
|
|
2019/12/13 ver 5.86 [変更] -fno-operator-namesが指定されたときは5.84以前の挙動に戻す
|
|
2019/12/07 ver 5.85 mmapにMAP_JITフラグを追加(macOS mojave以上)
|
|
2019/11/29 ver 5.84 [変更] XBYAK_USE_OP_NAMESが定義されていない限りXBYAK_NO_OP_NAMESが定義されるように変更
|
|
2019/10/12 ver 5.83 exit(1)の除去
|
|
2019/09/23 ver 5.82 monitorx, mwaitx, clzero対応 (thanks to MagurosanTeam)
|
|
2019/09/14 ver 5.81 いくつかの一般命令をサポート
|
|
2019/08/01 ver 5.802 AVX512_BF16判定修正 (thanks to vpirogov)
|
|
2019/05/27 support vp2intersectd, vp2intersectq (not tested)
|
|
2019/05/26 ver 5.80 support vcvtne2ps2bf16, vcvtneps2bf16, vdpbf16ps
|
|
2019/04/27 ver 5.79 vcmppd/vcmppsのptr_b対応忘れ(thanks to jkopinsky)
|
|
2019/04/15 ver 5.78 Reg::changeBit()のリファクタリング(thanks to MerryMage)
|
|
2019/03/06 ver 5.77 LLCキャッシュを共有数CPU数の修整(by densamoilov)
|
|
2019/01/17 ver 5.76 Cpu::getNumCores()追加(by shelleygoel)
|
|
2018/10/31 ver 5.751 互換性のためにXbyak::CastToの復元
|
|
2018/10/29 ver 5.75 LabelManagerのデストラクタでLabelから参照を切り離す
|
|
2018/10/21 ver 5.74 RegRip +/intの形をサポート Xbyak::CastToを削除
|
|
2018/10/15 util::StackFrameでmovの代わりにpush/popを使う
|
|
2018/09/19 ver 5.73 vpslld, vpslldq, vpsllwなどの(reg, mem, imm8)に対するevexエンコーディング修整
|
|
2018/09/19 ver 5.72 fix the encoding of vinsertps for disp8N(Thanks to petercaday)
|
|
2018/08/27 ver 5.71 新しいlabelインスタンスを返すL()を追加
|
|
2018/08/27 ver 5.70 read/exec設定のためのsetProtectMode()とDontUseProtectの追加
|
|
2018/08/24 ver 5.68 indexが16以上のVSIBエンコーディングのバグ修正(thanks to petercaday)
|
|
2018/08/14 ver 5.67 Addressクラス内のmutableを削除 ; fix setCacheHierarchy for cloud vm
|
|
2018/07/26 ver 5.661 mingw64対応
|
|
2018/07/24 ver 5.66 protect()のmodeにCodeArray::PROTECT_REを追加
|
|
2018/06/26 ver 5.65 fix push(qword [mem])
|
|
2018/03/07 ver 5.64 Cpu()の中でzero divisionが出ることがあるのを修正
|
|
2018/02/14 ver 5.63 Cpu::setCacheHierarchy()の修正とclang<3.9のためのEvexModifierZero修正(thanks to mgouicem)
|
|
2018/02/13 ver 5.62 Cpu::setCacheHierarchy() by mgouicem and rsdubtso
|
|
2018/02/07 ver 5.61 vmov*がmem{k}{z}形式対応(忘れてた)
|
|
2018/01/24 ver 5.601 xword, ywordなどをXbyak::util名前空間に追加
|
|
2018/01/05 ver 5.60 Ice lake系命令対応(319433-030.pdf)
|
|
2017/08/22 ver 5.53 mpxエンコーディングバグ修正, bnd()プレフィクス追加
|
|
2017/08/18 ver 5.52 align修正(thanks to MerryMage)
|
|
2017/08/17 ver 5.51 multi-byte nop追加 align()はそれを使用する(thanks to inolen)
|
|
2017/08/08 ver 5.50 mpx追加(thanks to magurosan)
|
|
2017/08/08 ver 5.45 sha追加(thanks to magurosan)
|
|
2017/08/08 ver 5.44 prefetchw追加(thanks to rsdubtso)
|
|
2017/07/12 ver 5.432 PVS-studioの警告を減らす
|
|
2017/07/09 ver 5.431 hasRex()修正 (影響なし) (thanks to drillsar)
|
|
2017/05/14 ver 5.43 CodeGenerator::resetSize()修正(thanks to gibbed)
|
|
2017/05/13 ver 5.42 movs{b,w,d,q}追加
|
|
2017/01/26 ver 5.41 prefetcwt1追加とscale == 0対応(thanks to rsdubtso)
|
|
2016/12/14 ver 5.40 Labelが示すアドレスを取得するLabel::getAddress()追加
|
|
2016/12/07 ver 5.34 disp8N時の負のオフセット処理の修正(thanks to rsdubtso)
|
|
2016/12/06 ver 5.33 disp8N時のvpbroadcast{b,w,d,q}, vpinsr{b,w}, vpextr{b,w}のバグ修正
|
|
2016/12/01 ver 5.32 clang for Visual Studioサポートのために__xgetbv()を_xgetbv()に変更(thanks to freiro)
|
|
2016/11/27 ver 5.31 AVX512_4VNNIをAVX512_4VNNIWに変更
|
|
2016/11/27 ver 5.30 AVX512_4VNNI, AVX512_4FMAPS命令の追加(thanks to rsdubtso)
|
|
2016/11/26 ver 5.20 AVX512_4VNNIとAVX512_4FMAPSの判定追加(thanks to rsdubtso)
|
|
2016/11/20 ver 5.11 何故か消えていたvptest for ymm追加(thanks to gregory38)
|
|
2016/11/20 ver 5.10 [rip+&var]の形のアドレッシング追加
|
|
2016/09/29 ver 5.03 ERR_INVALID_OPMASK_WITH_MEMORYの判定ミス修正(thanks to PVS-Studio)
|
|
2016/08/15 ver 5.02 xbyak_bin2hex.hをincludeしない
|
|
2016/08/15 ver 5.011 gcc 5.4のバージョン取得ミスの修正
|
|
2016/08/03 ver 5.01 AVXの省略表記非サポート
|
|
2016/07/24 ver 5.00 avx-512フルサポート
|
|
2016/06/13 avx-512 opmask命令サポート
|
|
2016/05/05 ver 4.91 AVX-512命令の検出サポート
|
|
2016/03/14 ver 4.901 ready()関数にコメント加筆(thanks to skmp)
|
|
2016/02/04 ver 4.90 条件分岐命令にjcc(const void *addr);のタイプを追加
|
|
2016/01/30 ver 4.89 vpblendvbがymmレジスタをサポートしていなかった(thanks to John Funnell)
|
|
2016/01/24 ver 4.88 lea, cmovの16bitレジスタ対応(thanks to whyisthisfieldhere)
|
|
2015/08/16 ver 4.87 セグメントセレクタに対応
|
|
2015/08/16 ver 4.86 [rip + label]アドレッシングで即値を使うと壊れる(thanks to whyisthisfieldhere)
|
|
2015/08/10 ver 4.85 Address::operator==()が間違っている(thanks to inolen)
|
|
2015/07/22 ver 4.84 call()がvariadic template対応
|
|
2015/05/24 ver 4.83 mobveサポート(thanks to benvanik)
|
|
2015/05/24 ver 4.82 F16Cが使えるかどうかの判定追加
|
|
2015/04/25 ver 4.81 setSizeが例外を投げる条件を修正(thanks to whyisthisfieldhere)
|
|
2015/04/22 ver 4.80 rip相対でLabelのサポート(thanks to whyisthisfieldhere)
|
|
2015/01/28 ver 4.71 adcx, adox, cmpxchg, rdseed, stacのサポート
|
|
2014/10/14 ver 4.70 MmapAllocatorのサポート
|
|
2014/06/13 ver 4.62 VC2014で警告抑制
|
|
2014/05/30 ver 4.61 bt, bts, btr, btcのサポート
|
|
2014/05/28 ver 4.60 vcvtph2ps, vcvtps2phのサポート
|
|
2014/04/11 ver 4.52 rdrandの判定追加
|
|
2014/03/25 ver 4.51 参照されなくなったラベルの状態を削除する
|
|
2014/03/16 ver 4.50 新しいラベルクラスのサポート
|
|
2014/03/05 ver 4.40 VirtualBox上でBMI/enhanced repのサポート判定を間違うことがあるのを修正
|
|
2013/12/03 ver 4.30 Reg::cvt8(), cvt16(), cvt32()のサポート
|
|
2013/10/16 ver 4.21 ラベルでstd::stringを受け付ける。
|
|
2013/07/30 ver 4.20 [break backward compatibility] 従来のReg32eクラスをアドレッシング用のRegExpとReg32, Reg64を表すReg32eに分離
|
|
2013/07/04 ver 4.10 [break backward compatibility] Xbyak::Errorの型をenumからclassに変更
|
|
2013/06/21 ver 4.02 LABELの指すアドレスを書き込むputL(LABEL)関数の追加。
|
|
2013/06/21 ver 4.01 vpsllw, vpslld, vpsllq, vpsraw, vpsrad, vpsrlw, vpsrld, vpsrlq support (ymm, ymm, xmm)
|
|
support vpbroadcastb, vpbroadcastw, vpbroadcastd, vpbroadcastq(thanks to Gabest)
|
|
2013/05/30 ver 4.00 AVX2, VEX-encoded GPR-instructionをサポート
|
|
2013/03/27 ver 3.80 mov(reg, "label");をサポート
|
|
2013/03/13 ver 3.76 cqo, jcxz, jecxz, jrcxz追加
|
|
2013/01/15 ver 3.75 生成されたコードを修正するためにsetSize()を追加
|
|
2013/01/12 ver 3.74 CodeGenerator::reset()とAllocator::useProtect()を追加
|
|
2013/01/06 ver 3.73 可能ならunordered_mapを使う
|
|
2012/12/04 ver 3.72 eaxなどをCodeGeneratorのメンバ変数に戻す. Xbyak::util::eaxはstatic const変数
|
|
2012/11/17 ver 3.71 and_(), or_(), xor_(), not_()をXBYAK_NO_OP_NAMESが定義されていないときでも使えるようにした
|
|
2012/11/17 CodeGeneratorのeax, ecx, ptrなどのメンバ変数をstaticにし、const参照をXbyak::utilにも定義
|
|
2012/11/09 ver 3.70 and()をand_()にするためのマクロXBYAK_NO_OP_NAMESを追加(thanks to Mattias)
|
|
2012/11/01 ver 3.62 add fwait/fnwait/finit/fninit
|
|
2012/11/01 ver 3.61 add fldcw/fstcw
|
|
2012/05/03 ver 3.60 Allocatorクラスのインタフェースを変更
|
|
2012/03/23 ver 3.51 userPtrモードがバグったのを修正
|
|
2012/03/19 ver 3.50 AutoGrowモードサポート
|
|
2011/11/09 ver 3.05 rip相対の64bitサイズ以外の扱いのバグ修正 / movsxdサポート
|
|
2011/08/15 ver 3.04 add(dword [ebp-8], 0xda);などにおけるimm8の扱いのバグ修正(thanks to lolcat)
|
|
2011/06/16 ver 3.03 Macのgcc上での__GNUC_PREREQがミスってたのを修正(thanks to t_teruya)
|
|
2011/04/28 ver 3.02 Macのgcc上ではxgetbvをdisable
|
|
2011/03/24 ver 3.01 fix typo of OSXSAVE
|
|
2011/03/23 ver 3.00 vcmpeqpsなどを追加
|
|
2011/02/16 ver 2.994 beta add vmovq for 32-bit mode(I forgot it)
|
|
2011/02/16 ver 2.993 beta remove cvtReg to avoid thread unsafe
|
|
2011/02/10 ver 2.992 beta support one argument syntax for fadd like nasm
|
|
2011/02/07 ver 2.991 beta fix pextrw reg, xmm, imm(Thanks to Gabest)
|
|
2011/02/04 ver 2.99 beta support AVX
|
|
2010/12/08 ver 2.31 fix ptr [rip + 32bit offset], support rtdscp
|
|
2010/10/19 ver 2.30 support pclmulqdq, aesdec, aesdeclast, aesenc, aesenclast, aesimc, aeskeygenassist
|
|
2010/07/07 ver 2.29 fix call(<label>)
|
|
2010/06/17 ver 2.28 move some member functions to public
|
|
2010/06/01 ver 2.27 support encoding of mov(reg64, imm) like yasm(not nasm)
|
|
2010/05/24 ver 2.26 fix sub(rsp, 1000)
|
|
2010/04/26 ver 2.25 add jc/jnc(I forgot to implement them...)
|
|
2010/04/16 ver 2.24 change the prototype of rewrite() method
|
|
2010/04/15 ver 2.23 fix align() and xbyak_util.h for Mac
|
|
2010/02/16 ver 2.22 fix inLocalLabel()/outLocalLabel()
|
|
2009/12/09 ver 2.21 support cygwin(gcc 4.3.2)
|
|
2009/11/28 ver 2.20 FPUの一部命令サポート
|
|
2009/06/25 ver 2.11 64bitモードでの mov(qword[rax], imm); 修正(thanks to Martinさん)
|
|
2009/03/10 ver 2.10 jmp/call reg64の冗長なREG.W削除
|
|
2009/02/24 ver 2.09 movq reg64, mmx/xmm; movq mmx/xmm, reg64追加
|
|
2009/02/13 ver 2.08 movd(xmm7, dword[eax])が0x66を落とすバグ修正(thanks to Gabestさん)
|
|
2008/12/30 ver 2.07 call()の相対アドレスが8bit以下のときのバグ修正(thanks to katoさん)
|
|
2008/09/18 ver 2.06 @@, @f, @bとラベルの局所化機能追加(thanks to nobu-qさん)
|
|
2008/09/18 ver 2.05 ptr [rip + 32bit offset]サポート(thanks to 団子厨(Dango-Chu)さん)
|
|
2008/06/03 ver 2.04 align()のポカミス修正。mov(ptr[eax],1);などをエラーに
|
|
2008/06/02 ver 2.03 ユーザ定義メモリインタフェースサポート
|
|
2008/05/26 ver 2.02 protect()(on Linux)で不正な設定になることがあるのを修正(thanks to sinichiro_hさん)
|
|
2008/04/30 ver 2.01 cmpxchg16b, cdqe追加
|
|
2008/04/29 ver 2.00 x86/x64-64版公開
|
|
2008/04/25 ver 1.90 x64版β公開
|
|
2008/04/18 ver 1.12 コード整理
|
|
2008/04/14 ver 1.11 コード整理
|
|
2008/03/12 ver 1.10 bsf/bsr追加(忘れていた)
|
|
2008/02/14 ver 1.09 sub eax, 1234が16bitモードで出力されていたのを修正(thanks to Robertさん)
|
|
2007/11/05 ver 1.08 lock, xadd, xchg追加
|
|
2007/11/02 ver 1.07 SSSE3/SSE4対応(thanks to 団子厨(Dango-Chu)さん)
|
|
2007/09/25 ver 1.06 call((int)関数ポインタ); jmp((int)関数ポインタ);のサポート
|
|
2007/08/04 ver 1.05 細かい修正
|
|
2007/02/04 後方へのジャンプでT_NEARをつけないときに8bit相対アドレスに入らない
|
|
場合に例外が発生しないバグの修正
|
|
2007/01/21 [disp]の形のアドレス生成のバグ修正
|
|
mov (eax|ax|al, [disp]); mov([disp], eax|ax|al);の短い表現選択
|
|
2007/01/17 webページ作成
|
|
2007/01/04 公開開始
|
|
|
|
-----------------------------------------------------------------------------
|
|
◎著作権者
|
|
|
|
光成滋生(MITSUNARI Shigeo, herumi@nifty.com)
|