add loop/loope/loopne

This commit is contained in:
MITSUNARI Shigeo 2019-09-05 21:52:55 +09:00
parent 7fc0c2bb74
commit 06235fa651
3 changed files with 60 additions and 0 deletions

View file

@ -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[] = {

View file

@ -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

View file

@ -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&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); }