Skip to content

Commit

Permalink
add ccmpscc
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Nov 23, 2023
1 parent 17f7d27 commit c4d0503
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 6 deletions.
5 changes: 5 additions & 0 deletions gen/gen_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,11 @@ void put()
printf("void j%s(const char *label, LabelType type = T_AUTO) { j%s(std::string(label), type); }%s\n", p->name, p->name, msg);
printf("void j%s(const void *addr) { opJmpAbs(addr, T_NEAR, 0x%02X, 0x%02X, 0x%02X); }%s\n", p->name, p->ext | 0x70, p->ext | 0x80, 0x0F, msg);
printf("void set%s(const Operand& op) { if (opROO(Reg(), op, Reg(), T_VEX|T_ZU|T_F2, 0x40 | %d)) return; opRext(op, 8, 0, T_0F, 0x90 | %d); }%s\n", p->name, p->ext, p->ext, msg);

// ccmpscc
// 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);
}
}
{
Expand Down
57 changes: 57 additions & 0 deletions test/apx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,3 +1461,60 @@ CYBOZU_TEST_AUTO(push2_pop2)
CYBOZU_TEST_EQUAL(c.getSize(), n);
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}

CYBOZU_TEST_AUTO(ccmp)
{
struct Code : Xbyak::CodeGenerator {
Code()
{
ccmpb(rax, rbx, 0);
ccmpb(r30b, r31b, 1);
ccmpb(r30w, r31w, 2);
ccmpb(r30d, r31d, 3);
ccmpb(r30, r31, 4);
ccmpb(ptr [r30], r31b, 5);
ccmpb(ptr [r30], r31w, 6);
ccmpb(ptr [r30], r31d, 7);
ccmpb(ptr [r30], r31, 8);
ccmpb(r31b, ptr [r30], 9);
ccmpb(r31w, ptr [r30], 10);
ccmpb(r31d, ptr [r30], 11);
ccmpb(r31, ptr [r30], 12);

ccmpo(rax, rcx, 0);
ccmpno(rax, rcx, 1);
ccmpb(rax, rcx, 2);
ccmpnb(rax, rcx, 3);
ccmpz(rax, rcx, 4);
ccmpnz(rax, rcx, 5);
ccmpbe(rax, rcx, 6);
ccmpnbe(rax, rcx, 7);
ccmps(rax, rcx, 8);
ccmpns(rax, rcx, 9);
ccmpt(rax, rcx, 10);
ccmpf(rax, rcx, 11);
ccmpl(rax, rcx, 12);
ccmpnl(rax, rcx, 13);
ccmple(rax, rcx, 14);
ccmpnle(rax, rcx, 15);
}
} c;
const uint8_t tbl[] = {
// ccmpb
0x62, 0xf4, 0x84, 0x02, 0x39, 0xd8, 0x62, 0x4c, 0x0c, 0x02, 0x38, 0xfe, 0x62, 0x4c, 0x15, 0x02,
0x39, 0xfe, 0x62, 0x4c, 0x1c, 0x02, 0x39, 0xfe, 0x62, 0x4c, 0xa4, 0x02, 0x39, 0xfe, 0x62, 0x4c,
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,
// 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,
0xac, 0x05, 0x39, 0xc8, 0x62, 0xf4, 0xb4, 0x06, 0x39, 0xc8, 0x62, 0xf4, 0xbc, 0x07, 0x39, 0xc8,
0x62, 0xf4, 0xc4, 0x08, 0x39, 0xc8, 0x62, 0xf4, 0xcc, 0x09, 0x39, 0xc8, 0x62, 0xf4, 0xd4, 0x0a,
0x39, 0xc8, 0x62, 0xf4, 0xdc, 0x0b, 0x39, 0xc8, 0x62, 0xf4, 0xe4, 0x0c, 0x39, 0xc8, 0x62, 0xf4,
0xec, 0x0d, 0x39, 0xc8, 0x62, 0xf4, 0xf4, 0x0e, 0x39, 0xc8, 0x62, 0xf4, 0xfc, 0x0f, 0x39, 0xc8,
};
const size_t n = sizeof(tbl);
CYBOZU_TEST_EQUAL(c.getSize(), n);
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}
8 changes: 2 additions & 6 deletions xbyak/xbyak.h
Original file line number Diff line number Diff line change
Expand Up @@ -1943,7 +1943,7 @@ class CodeGenerator : public CodeArray {
db((R3<<7) | (X3<<6) | B3 | R4 | B4 | M);
db((w<<7) | V | X4 | pp);
if (sc != NONE) {
db((L<<5) | (ND<<4) | (16 - sc));
db((L<<5) | (ND<<4) | sc);
} else {
db((L<<5) | (ND<<4) | (V4<<3) | (NF<<2));
}
Expand Down Expand Up @@ -2655,7 +2655,7 @@ class CodeGenerator : public CodeArray {
void opCcmp(const Operand& op1, const Operand& op2, int dfv, int sc)
{
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, sc);
opROO(Reg(15 - dfv, Operand::REG, (op1.getBit() | op2.getBit())), op1, op2, T_VEX|T_CODE1_IF1, 0x38, 0, sc);
}
#ifdef XBYAK64
void opAMX(const Tmm& t1, const Address& addr, uint64_t type, int code)
Expand Down Expand Up @@ -3051,10 +3051,6 @@ class CodeGenerator : public CodeArray {
// set default encoding to select Vex or Evex
void setDefaultEncoding(PreferredEncoding encoding) { defaultEncoding_ = encoding; }

void ccmpb(const Operand& op1, const Operand& op2, int dfv)
{
opCcmp(op1, op2, dfv, 0);
}
/*
use single byte nop if useMultiByteNop = false
*/
Expand Down
28 changes: 28 additions & 0 deletions xbyak/xbyak_mnemonic.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,34 @@ 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& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 7); }
void ccmpae(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 3); }
void ccmpb(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 2); }
void ccmpbe(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 6); }
void ccmpc(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 2); }
void ccmpe(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 4); }
void ccmpf(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 11); }
void ccmpg(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 15); }
void ccmpge(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 13); }
void ccmpl(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 12); }
void ccmple(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 14); }
void ccmpna(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 6); }
void ccmpnae(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 2); }
void ccmpnb(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 3); }
void ccmpnbe(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 7); }
void ccmpnc(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 3); }
void ccmpne(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 5); }
void ccmpng(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 14); }
void ccmpnge(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 12); }
void ccmpnl(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 13); }
void ccmpnle(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 15); }
void ccmpno(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 1); }
void ccmpns(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 9); }
void ccmpnz(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 5); }
void ccmpo(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 0); }
void ccmps(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 8); }
void ccmpt(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 10); }
void ccmpz(const Operand& op1, const Operand& op2, int dfv) { opCcmp(op1, op2, dfv, 4); }
void cdq() { db(0x99); }
void clc() { db(0xF8); }
void cld() { db(0xFC); }
Expand Down

0 comments on commit c4d0503

Please sign in to comment.