add adcx, adox with APX
This commit is contained in:
parent
77d6acea6d
commit
6b19515ebd
4 changed files with 53 additions and 5 deletions
|
@ -1054,6 +1054,20 @@ void put()
|
|||
printf("void %s(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0x%02X); }\n", p->name, p->code);
|
||||
}
|
||||
}
|
||||
{
|
||||
const struct Tbl {
|
||||
uint8_t code;
|
||||
const char *name;
|
||||
} tbl[] = {
|
||||
{ 0x66, "adcx" },
|
||||
{ 0xF3, "adox" },
|
||||
};
|
||||
for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
|
||||
const Tbl *p = &tbl[i];
|
||||
printf("void %s(const Reg32e& reg, const Operand& op) { if (opROO(Reg(), op, reg, T_66, 0x%02X)) return; opGen(reg, op, 0xF6, 0x%02X, isREG32_REG32orMEM, NONE, 0x38); }\n", p->name, p->code, p->code);
|
||||
printf("void %s(const Reg32e& d, const Reg32e& reg, const Operand& op) { opROO(d, op, reg, T_66, 0x%02X); }\n", p->name, p->code);
|
||||
}
|
||||
}
|
||||
{ // in/out
|
||||
puts("void in_(const Reg& a, uint8_t v) { opInOut(a, 0xE4, v); }");
|
||||
puts("void in_(const Reg& a, const Reg& d) { opInOut(a, d, 0xEC); }");
|
||||
|
@ -1084,8 +1098,6 @@ void put()
|
|||
puts("void movbe(const Address& addr, const Reg& reg) { opModM(addr, reg, 0x0F, 0x38, 0xF1); }");
|
||||
puts("void movdiri(const Address& addr, const Reg32e& reg) { opModM(addr, reg, 0x0F, 0x38, 0xF9); }");
|
||||
puts("void movdir64b(const Reg& reg, const Address& addr) { db(0x66); opModM(addr, reg.cvt32(), 0x0F, 0x38, 0xF8); }");
|
||||
puts("void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }");
|
||||
puts("void adox(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0xF3, isREG32_REG32orMEM, NONE, 0x38); }");
|
||||
puts("void cmpxchg8b(const Address& addr) { opModM(addr, Reg32(1), 0x0F, 0xC7); }");
|
||||
|
||||
puts("void pextrw(const Operand& op, const Mmx& xmm, uint8_t imm) { opExt(op, xmm, 0x15, imm, true); }");
|
||||
|
|
24
test/apx.cpp
24
test/apx.cpp
|
@ -341,3 +341,27 @@ CYBOZU_TEST_AUTO(rm3_2)
|
|||
CYBOZU_TEST_EQUAL(c.getSize(), n);
|
||||
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
|
||||
}
|
||||
|
||||
CYBOZU_TEST_AUTO(adcx)
|
||||
{
|
||||
struct Code : Xbyak::CodeGenerator {
|
||||
Code()
|
||||
{
|
||||
adcx(rax, r30);
|
||||
adcx(ecx, r20d);
|
||||
adcx(ecx, ptr [r31+r29*4]);
|
||||
adcx(r20d, ptr [rax]);
|
||||
adcx(r16, ptr [r31+r29*4]);
|
||||
adcx(r17, ptr [rax]);
|
||||
adcx(rax, rcx, rdx);
|
||||
}
|
||||
} c;
|
||||
const uint8_t tbl[] = {
|
||||
0x62, 0xdc, 0xfd, 0x08, 0x66, 0xc6, 0x62, 0xfc, 0x7d, 0x08, 0x66, 0xcc, 0x62, 0x9c, 0x79, 0x08,
|
||||
0x66, 0x0c, 0xaf, 0x62, 0xe4, 0x7d, 0x08, 0x66, 0x20, 0x62, 0x8c, 0xf9, 0x08, 0x66, 0x04, 0xaf,
|
||||
0x62, 0xe4, 0xfd, 0x08, 0x66, 0x08, 0x62, 0xf4, 0xfd, 0x18, 0x66, 0xca,
|
||||
};
|
||||
const size_t n = sizeof(tbl);
|
||||
CYBOZU_TEST_EQUAL(c.getSize(), n);
|
||||
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
|
||||
}
|
||||
|
|
|
@ -2853,8 +2853,9 @@ public:
|
|||
}
|
||||
|
||||
// (r, r, m) or (r, m, r)
|
||||
void opROO(const Reg& d, const Operand& op1, const Operand& op2, int type, int code0, int code1 = NONE, int code2 = NONE, int immSize = 0)
|
||||
bool opROO(const Reg& d, const Operand& op1, const Operand& op2, int type, int code0, int code1 = NONE, int code2 = NONE, int immSize = 0)
|
||||
{
|
||||
// if (type == 0 && !(d.hasRex2() || op1.hasRex2() || op2.hasRex2())) return false;
|
||||
const Operand *p1 = &op1, *p2 = &op2;
|
||||
if (p1->isMEM()) { std::swap(p1, p2); } else { if (p2->isMEM()) code0 |= 2; }
|
||||
if (p1->isMEM()) XBYAK_THROW(ERR_BAD_COMBINATION)
|
||||
|
@ -2870,6 +2871,7 @@ public:
|
|||
writeCode(type, d, code0, code1, code2);
|
||||
setModRM(3, op2.getIdx(), op1.getIdx());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3010,6 +3012,14 @@ public:
|
|||
size -= len;
|
||||
}
|
||||
}
|
||||
void adcx2(const Reg32e& r1, const Operand& op)
|
||||
{
|
||||
opROO(Reg(), op, r1, T_66, 0x66);
|
||||
}
|
||||
void adcx2(const Reg32e& d, const Reg32e& r1, const Operand& op)
|
||||
{
|
||||
opROO(d, op, r1, T_66, 0x66);
|
||||
}
|
||||
#ifndef XBYAK_DONT_READ_LIST
|
||||
#include "xbyak_mnemonic.h"
|
||||
/*
|
||||
|
|
|
@ -5,7 +5,8 @@ void adc(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x10, 2); }
|
|||
void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); }
|
||||
void adc(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 2); }
|
||||
void adc(const Reg& d, const Operand& op1, const Operand& op2) { opROO(d, op1, op2, 0, 0x10); }
|
||||
void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }
|
||||
void adcx(const Reg32e& d, const Reg32e& reg, const Operand& op) { opROO(d, op, reg, T_66, 0x66); }
|
||||
void adcx(const Reg32e& reg, const Operand& op) { if (opROO(Reg(), op, reg, T_66, 0x66)) return; opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }
|
||||
void add(const Operand& op, uint32_t imm) { opRM_I(op, imm, 0x00, 0); }
|
||||
void add(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x00); }
|
||||
void add(const Reg& d, const Operand& op, uint32_t imm) { opROI(d, op, imm, 0, 0); }
|
||||
|
@ -16,7 +17,8 @@ void addsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x58, 0xF2, isXMM
|
|||
void addss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x58, 0xF3, isXMM_XMMorMEM); }
|
||||
void addsubpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xD0, 0x66, isXMM_XMMorMEM); }
|
||||
void addsubps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xD0, 0xF2, isXMM_XMMorMEM); }
|
||||
void adox(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0xF3, isREG32_REG32orMEM, NONE, 0x38); }
|
||||
void adox(const Reg32e& d, const Reg32e& reg, const Operand& op) { opROO(d, op, reg, T_66, 0xF3); }
|
||||
void adox(const Reg32e& reg, const Operand& op) { if (opROO(Reg(), op, reg, T_66, 0xF3)) return; opGen(reg, op, 0xF6, 0xF3, isREG32_REG32orMEM, NONE, 0x38); }
|
||||
void aesdec(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDE, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
|
||||
void aesdeclast(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDF, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
|
||||
void aesenc(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDC, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue