diff options
author | MITSUNARI Shigeo <[email protected]> | 2019-09-05 21:52:55 +0900 |
---|---|---|
committer | MITSUNARI Shigeo <[email protected]> | 2019-09-05 21:52:55 +0900 |
commit | 06235fa6510ca7b0be92ca8c02a1383f6b8afe4d (patch) | |
tree | 347782a2ddca34b6480e48a3ec6b90b0e75e7cad | |
parent | 7fc0c2bb74e80f0aa1b5b25040131bf991a346c7 (diff) | |
download | xbyak-06235fa6510ca7b0be92ca8c02a1383f6b8afe4d.tar.gz xbyak-06235fa6510ca7b0be92ca8c02a1383f6b8afe4d.zip |
add loop/loope/loopne
-rw-r--r-- | gen/gen_code.cpp | 16 | ||||
-rw-r--r-- | test/jmp.cpp | 35 | ||||
-rw-r--r-- | xbyak/xbyak_mnemonic.h | 9 |
3 files changed, 60 insertions, 0 deletions
diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index 5ca982e..dae0c5e 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -616,6 +616,22 @@ void put() printf("void set%s(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | %d); }%s\n", p->name, p->ext, msg); } } + { + const struct Tbl { + const char *name; + uint8 code; + } tbl[] = { + { "loop", 0xE2 }, + { "loope", 0xE1 }, + { "loopne", 0xE0 }, + }; + for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) { + const Tbl *p = &tbl[i]; + printf("void %s(std::string label) { opJmp(label, T_SHORT, 0x%02X, 0, 0); }\n", p->name, p->code); + printf("void %s(const Label& label) { opJmp(label, T_SHORT, 0x%02X, 0, 0); }\n", p->name, p->code); + printf("void %s(const char *label) { %s(std::string(label)); }\n", p->name, p->name); + } + } //////////////////////////////////////////////////////////////// { const GenericTbl tbl[] = { diff --git a/test/jmp.cpp b/test/jmp.cpp index 9fe8ff6..4921a5a 100644 --- a/test/jmp.cpp +++ b/test/jmp.cpp @@ -205,6 +205,41 @@ CYBOZU_TEST_AUTO(testJmpCx) } } +CYBOZU_TEST_AUTO(loop) +{ + const uint8 ok[] = { + // lp: + 0x31, 0xC0, // xor eax, eax + 0xE2, 0xFC, // loop lp + 0xE0, 0xFA, // loopne lp + 0xE1, 0xF8, // loope lp + }; + struct Code : CodeGenerator { + Code(bool useLabel) + { + if (useLabel) { + Xbyak::Label lp = L(); + xor_(eax, eax); + loop(lp); + loopne(lp); + loope(lp); + } else { + L("@@"); + xor_(eax, eax); + loop("@b"); + loopne("@b"); + loope("@b"); + } + } + }; + Code code1(false); + CYBOZU_TEST_EQUAL(code1.getSize(), sizeof(ok)); + CYBOZU_TEST_EQUAL_ARRAY(code1.getCode(), ok, sizeof(ok)); + Code code2(true); + CYBOZU_TEST_EQUAL(code2.getSize(), sizeof(ok)); + CYBOZU_TEST_EQUAL_ARRAY(code2.getCode(), ok, sizeof(ok)); +} + #ifdef _MSC_VER #pragma warning(disable : 4310) #endif diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 2f2d768..b2fb1d8 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -446,6 +446,15 @@ void lock() { db(0xF0); } void lodsb() { db(0xAC); } void lodsd() { db(0xAD); } void lodsw() { db(0x66); db(0xAD); } +void loop(const Label& label) { opJmp(label, T_SHORT, 0xE2, 0, 0); } +void loop(const char *label) { loop(std::string(label)); } +void loop(std::string label) { opJmp(label, T_SHORT, 0xE2, 0, 0); } +void loope(const Label& label) { opJmp(label, T_SHORT, 0xE1, 0, 0); } +void loope(const char *label) { loope(std::string(label)); } +void loope(std::string label) { opJmp(label, T_SHORT, 0xE1, 0, 0); } +void loopne(const Label& label) { opJmp(label, T_SHORT, 0xE0, 0, 0); } +void loopne(const char *label) { loopne(std::string(label)); } +void loopne(std::string label) { opJmp(label, T_SHORT, 0xE0, 0, 0); } void lzcnt(const Reg®, const Operand& op) { opSp1(reg, op, 0xF3, 0x0F, 0xBD); } void maskmovdqu(const Xmm& reg1, const Xmm& reg2) { db(0x66); opModR(reg1, reg2, 0x0F, 0xF7); } void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) throw Error(ERR_BAD_COMBINATION); opModR(reg1, reg2, 0x0F, 0xF7); } |