From be319626ba9cf12060a9733a93c6337593b22bb6 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 23 Nov 2023 11:49:09 +0900 Subject: [PATCH] add ccmpscc with imm --- gen/gen_code.cpp | 1 + test/apx.cpp | 15 +++++++++++++++ xbyak/xbyak.h | 9 +++++++++ xbyak/xbyak_mnemonic.h | 28 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+) diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp index 69058889..4ea4790c 100644 --- a/gen/gen_code.cpp +++ b/gen/gen_code.cpp @@ -636,6 +636,7 @@ void put() // true if SCC = 0b1010, false if SCC = 0b1011 (see APX Architecture Specification p.266) const char *s = p->ext == 10 ? "t" : p->ext == 11 ? "f" : p->name; printf("void ccmp%s(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, %d); }\n", s, p->ext); + printf("void ccmp%s(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, %d); }\n", s, p->ext); } } { diff --git a/test/apx.cpp b/test/apx.cpp index ea5afffe..23054e8d 100644 --- a/test/apx.cpp +++ b/test/apx.cpp @@ -1481,6 +1481,15 @@ CYBOZU_TEST_AUTO(ccmp) ccmpb(r31d, ptr [r30], 11); ccmpb(r31, ptr [r30], 12); + ccmpb(r20b, 0x12, 9); + ccmpb(r20w, 0x1234, 9); + ccmpb(r20d, 0x12345678, 9); + ccmpb(r20, 0x12345678, 9); + ccmpb(byte [r20], 0x12, 9); + ccmpb(word [r20], 0x1234, 9); + ccmpb(dword [r20], 0x12345678, 9); + ccmpb(qword [r20], 0x12345678, 9); + ccmpo(rax, rcx, 0); ccmpno(rax, rcx, 1); ccmpb(rax, rcx, 2); @@ -1506,6 +1515,12 @@ CYBOZU_TEST_AUTO(ccmp) 0x2c, 0x02, 0x38, 0x3e, 0x62, 0x4c, 0x35, 0x02, 0x39, 0x3e, 0x62, 0x4c, 0x3c, 0x02, 0x39, 0x3e, 0x62, 0x4c, 0xc4, 0x02, 0x39, 0x3e, 0x62, 0x4c, 0x4c, 0x02, 0x3a, 0x3e, 0x62, 0x4c, 0x55, 0x02, 0x3b, 0x3e, 0x62, 0x4c, 0x5c, 0x02, 0x3b, 0x3e, 0x62, 0x4c, 0xe4, 0x02, 0x3b, 0x3e, + // ccmpb imm + 0x62, 0x7c, 0x4c, 0x02, 0x80, 0xfc, 0x12, 0x62, 0x7c, 0x4d, 0x02, 0x81, 0xfc, 0x34, 0x12, 0x62, + 0x7c, 0x4c, 0x02, 0x81, 0xfc, 0x78, 0x56, 0x34, 0x12, 0x62, 0x7c, 0xcc, 0x02, 0x81, 0xfc, 0x78, + 0x56, 0x34, 0x12, 0x62, 0x7c, 0x4c, 0x02, 0x80, 0x3c, 0x24, 0x12, 0x62, 0x7c, 0x4d, 0x02, 0x81, + 0x3c, 0x24, 0x34, 0x12, 0x62, 0x7c, 0x4c, 0x02, 0x81, 0x3c, 0x24, 0x78, 0x56, 0x34, 0x12, 0x62, + 0x7c, 0xcc, 0x02, 0x81, 0x3c, 0x24, 0x78, 0x56, 0x34, 0x12, // all 0x62, 0xf4, 0x84, 0x00, 0x39, 0xc8, 0x62, 0xf4, 0x8c, 0x01, 0x39, 0xc8, 0x62, 0xf4, 0x94, 0x02, 0x39, 0xc8, 0x62, 0xf4, 0x9c, 0x03, 0x39, 0xc8, 0x62, 0xf4, 0xa4, 0x04, 0x39, 0xc8, 0x62, 0xf4, diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index 1a715d4d..6ea5935e 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -2657,6 +2657,15 @@ class CodeGenerator : public CodeArray { if (dfv < 0 || 15 < dfv) XBYAK_THROW(ERR_INVALID_DFV) opROO(Reg(15 - dfv, Operand::REG, (op1.getBit() | op2.getBit())), op1, op2, T_VEX|T_CODE1_IF1, 0x38, 0, sc); } + void opCcmpi(const Operand& op, int imm, int dfv, int sc) + { + if (dfv < 0 || 15 < dfv) XBYAK_THROW(ERR_INVALID_DFV) + uint32_t immBit = getImmBit(op, imm); + uint32_t opBit = op.getBit(); + int tmp = immBit < (std::min)(opBit, 32U) ? 2 : 0; + opROO(Reg(15 - dfv, Operand::REG, opBit), op, r15.changeBit(opBit), T_VEX|T_CODE1_IF1, 0x80 | tmp, immBit / 8, sc); + db(imm, immBit / 8); + } #ifdef XBYAK64 void opAMX(const Tmm& t1, const Address& addr, uint64_t type, int code) { diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 5dd17e60..d3f8553f 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -66,33 +66,61 @@ void bts(const Operand& op, const Reg& reg) { opRO(reg, op, T_0F, 0xAB, op.isREG void bts(const Operand& op, uint8_t imm) { opRext(op, 16|i32e, 5, T_0F, 0xba, false, 1); db(imm); } void bzhi(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opRRO(r1, r2, op, T_VEX|T_0F38|T_NF, 0xf5); } void cbw() { db(0x66); db(0x98); } +void ccmpa(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 7); } void ccmpa(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 7); } +void ccmpae(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 3); } void ccmpae(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 3); } +void ccmpb(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 2); } void ccmpb(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 2); } +void ccmpbe(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 6); } void ccmpbe(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 6); } +void ccmpc(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 2); } void ccmpc(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 2); } +void ccmpe(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 4); } void ccmpe(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 4); } +void ccmpf(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 11); } void ccmpf(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 11); } +void ccmpg(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 15); } void ccmpg(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 15); } +void ccmpge(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 13); } void ccmpge(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 13); } +void ccmpl(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 12); } void ccmpl(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 12); } +void ccmple(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 14); } void ccmple(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 14); } +void ccmpna(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 6); } void ccmpna(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 6); } +void ccmpnae(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 2); } void ccmpnae(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 2); } +void ccmpnb(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 3); } void ccmpnb(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 3); } +void ccmpnbe(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 7); } void ccmpnbe(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 7); } +void ccmpnc(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 3); } void ccmpnc(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 3); } +void ccmpne(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 5); } void ccmpne(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 5); } +void ccmpng(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 14); } void ccmpng(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 14); } +void ccmpnge(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 12); } void ccmpnge(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 12); } +void ccmpnl(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 13); } void ccmpnl(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 13); } +void ccmpnle(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 15); } void ccmpnle(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 15); } +void ccmpno(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 1); } void ccmpno(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 1); } +void ccmpns(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 9); } void ccmpns(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 9); } +void ccmpnz(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 5); } void ccmpnz(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 5); } +void ccmpo(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 0); } void ccmpo(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 0); } +void ccmps(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 8); } void ccmps(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 8); } +void ccmpt(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 10); } void ccmpt(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 10); } +void ccmpz(const Operand& op, int imm, int dfv) { opCcmpi(op, imm, dfv, 4); } void ccmpz(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 4); } void cdq() { db(0x99); } void clc() { db(0xF8); }