diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index fbbcd67..eba0ffc 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -440,6 +440,8 @@ void put() printf("void cmov%s(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | %d); }\n", p->name, p->ext); printf("void j%s(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x%02X, 0x%02X, 0x%02X); }\n", p->name, p->ext | B01110000, p->ext | B10000000, 0x0F); printf("void j%s(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x%02X, 0x%02X, 0x%02X); }\n", p->name, p->ext | B01110000, p->ext | B10000000, 0x0F); + printf("void j%s(const char *label, LabelType type = T_AUTO) { j%s(std::string(label), type); }\n", p->name, p->name); + printf("void j%s(const void *addr) { opJmpAbs(addr, T_NEAR, 0x%02X, 0x%02X, 0x%02X); }\n", p->name, p->ext | B01110000, p->ext | B10000000, 0x0F); printf("void set%s(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | %d); }\n", p->name, p->ext); } puts("#ifdef XBYAK32"); diff --git a/readme.md b/readme.md index bb5d2f0..1a08caf 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ -Xbyak 4.89 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ +Xbyak 4.90 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ ============= Abstract @@ -285,6 +285,7 @@ The header files under xbyak/ are independent of cybozulib. History ------------- +* 2016/Feb/04 ver 4.90 add jcc(const void *addr); * 2016/Jan/30 ver 4.89 vpblendvb supports ymm reg(thanks to John Funnell) * 2016/Jan/24 ver 4.88 lea, cmov supports 16-bit register(thanks to whyisthisfieldhere) * 2015/Oct/05 ver 4.87 support segment selectors diff --git a/readme.txt b/readme.txt index 8cd2e64..2af4d2f 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ - C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 4.89 + C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 4.90 ----------------------------------------------------------------------------- ◎概要 @@ -301,6 +301,7 @@ cybozulibは単体テストでのみ利用されていて、xbyak/ディレク ----------------------------------------------------------------------------- ◎履歴 +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 セグメントセレクタに対応 diff --git a/test/jmp.cpp b/test/jmp.cpp index 3e5e2a5..e15f634 100644 --- a/test/jmp.cpp +++ b/test/jmp.cpp @@ -766,6 +766,36 @@ CYBOZU_TEST_AUTO(test6) } } +CYBOZU_TEST_AUTO(test_jcc) +{ + struct A : Xbyak::CodeGenerator { + A() + { + add(eax, 5); + ret(); + } + }; + struct B : Xbyak::CodeGenerator { + B(bool grow, const void *p) : Xbyak::CodeGenerator(grow ? 0 : 4096, grow ? Xbyak::AutoGrow : 0) + { + mov(eax, 1); + add(eax, 2); + jnz(p); + } + }; + A a; + const void *p = a.getCode(); + for (int i = 0; i < 2; i++) { + bool grow = i == 1; + B b(grow, p); + if (grow) { + b.ready(); + } + int (*f)() = b.getCode(); + CYBOZU_TEST_EQUAL(f(), 8); + } +} + CYBOZU_TEST_AUTO(testNewLabel) { struct Code : Xbyak::CodeGenerator { diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index 49c8f53..5d3f33d 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -101,7 +101,7 @@ namespace Xbyak { enum { DEFAULT_MAX_CODE_SIZE = 4096, - VERSION = 0x4890 /* 0xABCD = A.BC(D) */ + VERSION = 0x4900 /* 0xABCD = A.BC(D) */ }; #ifndef MIE_INTEGER_TYPE_DEFINED @@ -1385,16 +1385,17 @@ private: labelMgr_.addUndefinedLabel(label, jmp); } } - void opJmpAbs(const void *addr, LabelType type, uint8 shortCode, uint8 longCode) + void opJmpAbs(const void *addr, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref = 0) { if (isAutoGrow()) { if (type != T_NEAR) throw Error(ERR_ONLY_T_NEAR_IS_SUPPORTED_IN_AUTO_GROW); if (size_ + 16 >= maxSize_) growMemory(); + if (longPref) db(longPref); db(longCode); dd(0); save(size_ - 4, size_t(addr) - size_, 4, inner::Labs); } else { - makeJmp(inner::VerifyInInt32(reinterpret_cast(addr) - getCurr()), type, shortCode, longCode, 0); + makeJmp(inner::VerifyInInt32(reinterpret_cast(addr) - getCurr()), type, shortCode, longCode, longPref); } } diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 068fef4..98b7dd6 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -1,4 +1,4 @@ -const char *getVersionString() const { return "4.88"; } +const char *getVersionString() const { return "4.90"; } void packssdw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x6B); } void packsswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x63); } void packuswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x67); } @@ -185,122 +185,182 @@ void movlpd(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x12, 0 void cmovo(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 0); } void jo(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x70, 0x80, 0x0F); } void jo(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x70, 0x80, 0x0F); } +void jo(const char *label, LabelType type = T_AUTO) { jo(std::string(label), type); } +void jo(const void *addr) { opJmpAbs(addr, T_NEAR, 0x70, 0x80, 0x0F); } void seto(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 0); } void cmovno(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 1); } void jno(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x71, 0x81, 0x0F); } void jno(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x71, 0x81, 0x0F); } +void jno(const char *label, LabelType type = T_AUTO) { jno(std::string(label), type); } +void jno(const void *addr) { opJmpAbs(addr, T_NEAR, 0x71, 0x81, 0x0F); } void setno(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 1); } void cmovb(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 2); } void jb(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); } void jb(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); } +void jb(const char *label, LabelType type = T_AUTO) { jb(std::string(label), type); } +void jb(const void *addr) { opJmpAbs(addr, T_NEAR, 0x72, 0x82, 0x0F); } void setb(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 2); } void cmovc(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 2); } void jc(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); } void jc(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); } +void jc(const char *label, LabelType type = T_AUTO) { jc(std::string(label), type); } +void jc(const void *addr) { opJmpAbs(addr, T_NEAR, 0x72, 0x82, 0x0F); } void setc(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 2); } void cmovnae(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 2); } void jnae(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); } void jnae(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); } +void jnae(const char *label, LabelType type = T_AUTO) { jnae(std::string(label), type); } +void jnae(const void *addr) { opJmpAbs(addr, T_NEAR, 0x72, 0x82, 0x0F); } void setnae(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 2); } void cmovnb(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 3); } void jnb(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); } void jnb(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); } +void jnb(const char *label, LabelType type = T_AUTO) { jnb(std::string(label), type); } +void jnb(const void *addr) { opJmpAbs(addr, T_NEAR, 0x73, 0x83, 0x0F); } void setnb(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 3); } void cmovae(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 3); } void jae(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); } void jae(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); } +void jae(const char *label, LabelType type = T_AUTO) { jae(std::string(label), type); } +void jae(const void *addr) { opJmpAbs(addr, T_NEAR, 0x73, 0x83, 0x0F); } void setae(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 3); } void cmovnc(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 3); } void jnc(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); } void jnc(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); } +void jnc(const char *label, LabelType type = T_AUTO) { jnc(std::string(label), type); } +void jnc(const void *addr) { opJmpAbs(addr, T_NEAR, 0x73, 0x83, 0x0F); } void setnc(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 3); } void cmove(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 4); } void je(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); } void je(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); } +void je(const char *label, LabelType type = T_AUTO) { je(std::string(label), type); } +void je(const void *addr) { opJmpAbs(addr, T_NEAR, 0x74, 0x84, 0x0F); } void sete(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 4); } void cmovz(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 4); } void jz(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); } void jz(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); } +void jz(const char *label, LabelType type = T_AUTO) { jz(std::string(label), type); } +void jz(const void *addr) { opJmpAbs(addr, T_NEAR, 0x74, 0x84, 0x0F); } void setz(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 4); } void cmovne(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 5); } void jne(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); } void jne(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); } +void jne(const char *label, LabelType type = T_AUTO) { jne(std::string(label), type); } +void jne(const void *addr) { opJmpAbs(addr, T_NEAR, 0x75, 0x85, 0x0F); } void setne(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 5); } void cmovnz(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 5); } void jnz(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); } void jnz(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); } +void jnz(const char *label, LabelType type = T_AUTO) { jnz(std::string(label), type); } +void jnz(const void *addr) { opJmpAbs(addr, T_NEAR, 0x75, 0x85, 0x0F); } void setnz(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 5); } void cmovbe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 6); } void jbe(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); } void jbe(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); } +void jbe(const char *label, LabelType type = T_AUTO) { jbe(std::string(label), type); } +void jbe(const void *addr) { opJmpAbs(addr, T_NEAR, 0x76, 0x86, 0x0F); } void setbe(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 6); } void cmovna(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 6); } void jna(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); } void jna(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); } +void jna(const char *label, LabelType type = T_AUTO) { jna(std::string(label), type); } +void jna(const void *addr) { opJmpAbs(addr, T_NEAR, 0x76, 0x86, 0x0F); } void setna(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 6); } void cmovnbe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 7); } void jnbe(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); } void jnbe(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); } +void jnbe(const char *label, LabelType type = T_AUTO) { jnbe(std::string(label), type); } +void jnbe(const void *addr) { opJmpAbs(addr, T_NEAR, 0x77, 0x87, 0x0F); } void setnbe(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 7); } void cmova(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 7); } void ja(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); } void ja(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); } +void ja(const char *label, LabelType type = T_AUTO) { ja(std::string(label), type); } +void ja(const void *addr) { opJmpAbs(addr, T_NEAR, 0x77, 0x87, 0x0F); } void seta(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 7); } void cmovs(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 8); } void js(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x78, 0x88, 0x0F); } void js(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x78, 0x88, 0x0F); } +void js(const char *label, LabelType type = T_AUTO) { js(std::string(label), type); } +void js(const void *addr) { opJmpAbs(addr, T_NEAR, 0x78, 0x88, 0x0F); } void sets(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 8); } void cmovns(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 9); } void jns(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x79, 0x89, 0x0F); } void jns(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x79, 0x89, 0x0F); } +void jns(const char *label, LabelType type = T_AUTO) { jns(std::string(label), type); } +void jns(const void *addr) { opJmpAbs(addr, T_NEAR, 0x79, 0x89, 0x0F); } void setns(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 9); } void cmovp(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 10); } void jp(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); } void jp(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); } +void jp(const char *label, LabelType type = T_AUTO) { jp(std::string(label), type); } +void jp(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7A, 0x8A, 0x0F); } void setp(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 10); } void cmovpe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 10); } void jpe(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); } void jpe(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); } +void jpe(const char *label, LabelType type = T_AUTO) { jpe(std::string(label), type); } +void jpe(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7A, 0x8A, 0x0F); } void setpe(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 10); } void cmovnp(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 11); } void jnp(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); } void jnp(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); } +void jnp(const char *label, LabelType type = T_AUTO) { jnp(std::string(label), type); } +void jnp(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7B, 0x8B, 0x0F); } void setnp(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 11); } void cmovpo(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 11); } void jpo(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); } void jpo(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); } +void jpo(const char *label, LabelType type = T_AUTO) { jpo(std::string(label), type); } +void jpo(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7B, 0x8B, 0x0F); } void setpo(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 11); } void cmovl(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 12); } void jl(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); } void jl(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); } +void jl(const char *label, LabelType type = T_AUTO) { jl(std::string(label), type); } +void jl(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7C, 0x8C, 0x0F); } void setl(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 12); } void cmovnge(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 12); } void jnge(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); } void jnge(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); } +void jnge(const char *label, LabelType type = T_AUTO) { jnge(std::string(label), type); } +void jnge(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7C, 0x8C, 0x0F); } void setnge(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 12); } void cmovnl(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 13); } void jnl(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); } void jnl(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); } +void jnl(const char *label, LabelType type = T_AUTO) { jnl(std::string(label), type); } +void jnl(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7D, 0x8D, 0x0F); } void setnl(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 13); } void cmovge(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 13); } void jge(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); } void jge(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); } +void jge(const char *label, LabelType type = T_AUTO) { jge(std::string(label), type); } +void jge(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7D, 0x8D, 0x0F); } void setge(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 13); } void cmovle(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 14); } void jle(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); } void jle(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); } +void jle(const char *label, LabelType type = T_AUTO) { jle(std::string(label), type); } +void jle(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7E, 0x8E, 0x0F); } void setle(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 14); } void cmovng(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 14); } void jng(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); } void jng(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); } +void jng(const char *label, LabelType type = T_AUTO) { jng(std::string(label), type); } +void jng(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7E, 0x8E, 0x0F); } void setng(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 14); } void cmovnle(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 15); } void jnle(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); } void jnle(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); } +void jnle(const char *label, LabelType type = T_AUTO) { jnle(std::string(label), type); } +void jnle(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7F, 0x8F, 0x0F); } void setnle(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 15); } void cmovg(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, B01000000 | 15); } void jg(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); } void jg(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); } +void jg(const char *label, LabelType type = T_AUTO) { jg(std::string(label), type); } +void jg(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7F, 0x8F, 0x0F); } void setg(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, B10010000 | 15); } #ifdef XBYAK32 void jcxz(std::string label) { db(0x67); opJmp(label, T_SHORT, 0xe3, 0, 0); }