Skip to content

Commit

Permalink
add tests of 2-op imul
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Nov 17, 2023
1 parent d20142d commit 5087529
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 30 deletions.
69 changes: 41 additions & 28 deletions test/apx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ CYBOZU_TEST_AUTO(inc_dec)
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}

CYBOZU_TEST_AUTO(div)
CYBOZU_TEST_AUTO(div_op1)
{
struct Code : Xbyak::CodeGenerator {
Code()
Expand Down Expand Up @@ -804,29 +804,6 @@ CYBOZU_TEST_AUTO(div)
not_(word [r20+r30*1]);
not_(dword [r20+r30*1]);
not_(qword [r20+r30*1]);

// 2op
// imul(r30b, al); // QQQ : not supported?
imul(r30w, ax);
imul(r30d, eax);
imul(r30, rax);
imul(r30|T_nf, rax);
imul(rcx|T_nf, rax);
imul(rcx, ptr [r30]);

neg(r30b, al);
neg(r30w, ax);
neg(r30d, eax);
neg(r30, rax);
neg(r30|T_nf, rax);
neg(rcx|T_nf, rax);
neg(rcx, ptr [r30]);

not_(r30b, al);
not_(r30w, ax);
not_(r30d, eax);
not_(r30, rax);
not_(rcx, ptr [r30]);
}
} c;
const uint8_t tbl[] = {
Expand Down Expand Up @@ -862,12 +839,48 @@ CYBOZU_TEST_AUTO(div)
0xf7, 0xd4, 0x62, 0xfc, 0xfc, 0x08, 0xf7, 0xd4, 0x62, 0xbc, 0x78, 0x08, 0xf6, 0x14, 0x34, 0x62,
0xbc, 0x79, 0x08, 0xf7, 0x14, 0x34, 0x62, 0xbc, 0x78, 0x08, 0xf7, 0x14, 0x34, 0x62, 0xbc, 0xf8,
0x08, 0xf7, 0x14, 0x34,
};
const size_t n = sizeof(tbl);
CYBOZU_TEST_EQUAL(c.getSize(), n);
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}

// 2op
CYBOZU_TEST_AUTO(imul_2op)
{
struct Code : Xbyak::CodeGenerator {
Code()
{
// imul(r30b, al); // QQQ : not supported?
imul(r30w, ax);
imul(r30d, eax);
imul(r30, rax);
imul(r30|T_nf, rax);
imul(rcx|T_nf, rax);
imul(rcx, ptr [r30]);

neg(r30b, al);
neg(r30w, ax);
neg(r30d, eax);
neg(r30, rax);
neg(r30|T_nf, rax);
neg(rcx|T_nf, rax);
neg(rcx, ptr [r30]);

not_(r30b, al);
not_(r30w, ax);
not_(r30d, eax);
not_(r30, rax);
not_(rcx, ptr [r30]);
}
} c;
const uint8_t tbl[] = {
// imul
0x62, 0x64, 0x7d, 0x08, 0xaf, 0xf0, 0x62, 0x64, 0x7c, 0x08, 0xaf, 0xf0, 0x62, 0x64, 0xfc, 0x08,
0xaf, 0xf0, 0x62, 0x64, 0xfc, 0x0c, 0xaf, 0xf0, 0x62, 0xf4, 0xfc, 0x0c, 0xaf, 0xc8, 0x62, 0xdc,
0xfc, 0x08, 0xaf, 0x0e,
0x62, 0x64, 0x7d, 0x08, 0xaf, 0xf0,
0x62, 0x64, 0x7c, 0x08, 0xaf, 0xf0,
0x62, 0x64, 0xfc, 0x08, 0xaf, 0xf0,
0x62, 0x64, 0xfc, 0x0c, 0xaf, 0xf0,
0x62, 0xf4, 0xfc, 0x0c, 0xaf, 0xc8,
0x62, 0xdc, 0xfc, 0x08, 0xaf, 0x0e,

// neg
0x62, 0xf4, 0x0c, 0x10, 0xf6, 0xd8, 0x62, 0xf4, 0x0d, 0x10, 0xf7, 0xd8, 0x62, 0xf4, 0x0c, 0x10,
Expand Down
5 changes: 3 additions & 2 deletions xbyak/xbyak.h
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ class Operand {
XBYAK_CONSTEXPR bool hasEvex() const { return isZMM() || isExtIdx2() || getOpmaskIdx() || getRounding(); }
XBYAK_CONSTEXPR bool hasRex() const { return isExt8bit() || isREG(64) || isExtIdx(); }
XBYAK_CONSTEXPR bool hasRex2() const;
XBYAK_CONSTEXPR bool hasRex2NF() const { return hasRex2() || NF_; }
XBYAK_CONSTEXPR bool hasZero() const { return zero_; }
XBYAK_CONSTEXPR int getOpmaskIdx() const { return mask_; }
XBYAK_CONSTEXPR int getRounding() const { return rounding_; }
Expand Down Expand Up @@ -2176,7 +2177,7 @@ class CodeGenerator : public CodeArray {
int opBit = op.getBit();
if (disableRex && opBit == 64) opBit = 32;
const Reg r(ext, Operand::REG, opBit);
if ((type & T_VEX) && (op.hasRex2() || op.getNF()) && opROO(Reg(0, Operand::REG, opBit), op, r, type, code)) return;
if ((type & T_VEX) && op.hasRex2NF() && opROO(Reg(0, Operand::REG, opBit), op, r, type, code)) return;
if (op.isMEM()) {
opMR(op.getAddress(), r, type, code, immSize);
} else if (op.isREG(bit)) {
Expand Down Expand Up @@ -2899,7 +2900,7 @@ class CodeGenerator : public CodeArray {
// (r, r, m) or (r, m, r)
bool opROO(const Reg& d, const Operand& op1, const Operand& op2, uint64_t type, int code, int immSize = 0)
{
if (!(type & T_VEX) && !d.isREG() && !(d.hasRex2() || op1.hasRex2() || op2.hasRex2())) return false;
if (!d.isREG() && !(d.hasRex2NF() || op1.hasRex2NF() || op2.hasRex2NF())) return false;
const Operand *p1 = &op1, *p2 = &op2;
if (p1->isMEM()) { std::swap(p1, p2); } else { if (p2->isMEM()) code |= 2; }
if (p1->isMEM()) XBYAK_THROW_RET(ERR_BAD_COMBINATION, false)
Expand Down

0 comments on commit 5087529

Please sign in to comment.