bswap supports apx

This commit is contained in:
MITSUNARI Shigeo 2023-12-28 17:59:28 +09:00
parent 2e93baa6a6
commit 2e7b62d784
4 changed files with 28 additions and 5 deletions

View file

@ -1144,7 +1144,6 @@ void put()
// misc
{
puts("void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER) opMR(addr, reg, 0, 0x8D); }");
puts("void bswap(const Reg32e& reg) { opRR(Reg32(1), reg, 0, 0x0F); }");
puts("void ret(int imm = 0) { if (imm) { db(0xC2); dw(imm); } else { db(0xC3); } }");
puts("void retf(int imm = 0) { if (imm) { db(0xCA); dw(imm); } else { db(0xCB); } }");

View file

@ -1074,6 +1074,13 @@ CYBOZU_TEST_AUTO(mov_misc)
setb(r31b|T_zu);
setb(r15b|T_zu);
setb(ptr [r30]);
bswap(eax);
bswap(r8d);
bswap(r16d);
bswap(rcx);
bswap(r9);
bswap(r17);
}
} c;
const uint8_t tbl[] = {
@ -1101,7 +1108,13 @@ CYBOZU_TEST_AUTO(mov_misc)
0x62, 0xdc, 0x7f, 0x18, 0x42, 0xc7,
0x62, 0xd4, 0x7f, 0x18, 0x42, 0xc7,
0x62, 0xdc, 0x7f, 0x08, 0x42, 0x06,
// bswap
0x0f, 0xc8,
0x41, 0x0f, 0xc8,
0xd5, 0x90, 0xc8,
0x48, 0x0f, 0xc9,
0x49, 0x0f, 0xc9,
0xd5, 0x98, 0xc9,
};
const size_t n = sizeof(tbl);
CYBOZU_TEST_EQUAL(c.getSize(), n);

View file

@ -1773,8 +1773,8 @@ private:
// ModRM(reg, base);
rex = rexRXB(3, r1.isREG(64) || r2.isREG(64), r2, r1);
if (r1.hasRex2() || r2.hasRex2()) {
if (type & (T_0F|T_0F38|T_0F3A)) XBYAK_THROW(ERR_CANT_USE_REX2)
rex2(0, rex, r2, r1);
if (type & (T_0F38|T_0F3A)) XBYAK_THROW(ERR_CANT_USE_REX2)
rex2((type & T_0F) ? 1 : 0, rex, r2, r1);
return;
}
if (rex || r1.isExt8bit() || r2.isExt8bit()) rex |= 0x40;
@ -3133,6 +3133,18 @@ public:
{
opROO(Reg(), op, x, T_MUST_EVEX, 0xD9);
}
void bswap(const Reg32e& r)
{
int idx = r.getIdx();
uint8_t rex = (r.isREG(64) ? 8 : 0) | ((idx & 8) ? 1 : 0);
if (idx >= 16) {
db(0xD5); db((1<<7) | (idx & 16) | rex);
} else {
if (rex) db(0x40 | rex);
db(0x0F);
}
db(0xC8 + (idx & 7));
}
/*
use single byte nop if useMultiByteNop = false
*/

View file

@ -55,7 +55,6 @@ void bndmov(const BoundsReg& bnd, const Operand& op) { opRO(bnd, op, T_66 | T_0F
void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, T_0F, 0x1B); }
void bsf(const Reg&reg, const Operand& op) { opRO(reg, op, T_0F, 0xBC, op.isREG(16|i32e)); }
void bsr(const Reg&reg, const Operand& op) { opRO(reg, op, T_0F, 0xBD, op.isREG(16|i32e)); }
void bswap(const Reg32e& reg) { opRR(Reg32(1), reg, 0, 0x0F); }
void bt(const Operand& op, const Reg& reg) { opRO(reg, op, T_0F, 0xA3, op.isREG(16|i32e) && op.getBit() == reg.getBit()); }
void bt(const Operand& op, uint8_t imm) { opRext(op, 16|i32e, 4, T_0F, 0xba, false, 1); db(imm); }
void btc(const Operand& op, const Reg& reg) { opRO(reg, op, T_0F, 0xBB, op.isREG(16|i32e) && op.getBit() == reg.getBit()); }