aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gen/gen_code.cpp3
-rw-r--r--test/apx.cpp35
-rw-r--r--xbyak/xbyak.h12
-rw-r--r--xbyak/xbyak_mnemonic.h2
4 files changed, 51 insertions, 1 deletions
diff --git a/gen/gen_code.cpp b/gen/gen_code.cpp
index 336330b..892fdbc 100644
--- a/gen/gen_code.cpp
+++ b/gen/gen_code.cpp
@@ -2042,6 +2042,9 @@ void put64()
}
}
}
+ // encodekey
+ puts("void encodekey128(const Reg32& r1, const Reg32& r2) { opEncodeKey(r1, r2, 0xFA, 0xDA); }");
+ puts("void encodekey256(const Reg32& r1, const Reg32& r2) { opEncodeKey(r1, r2, 0xFB, 0xDB); }");
}
void putAMX_TILE()
diff --git a/test/apx.cpp b/test/apx.cpp
index 0b99e20..b2675b8 100644
--- a/test/apx.cpp
+++ b/test/apx.cpp
@@ -1753,6 +1753,7 @@ CYBOZU_TEST_AUTO(kmov)
CYBOZU_TEST_EQUAL(c.getSize(), n);
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}
+
CYBOZU_TEST_AUTO(amx)
{
struct Code : Xbyak::CodeGenerator {
@@ -1835,3 +1836,37 @@ CYBOZU_TEST_AUTO(aeskl)
CYBOZU_TEST_EQUAL(c.getSize(), n);
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}
+
+CYBOZU_TEST_AUTO(encodekey)
+{
+ struct Code : Xbyak::CodeGenerator {
+ Code()
+ {
+ encodekey128(eax, ebx);
+ encodekey128(eax, r8d);
+ encodekey128(r8d, ebx);
+ encodekey128(r30d, r29d);
+
+ encodekey256(eax, ebx);
+ encodekey256(eax, r8d);
+ encodekey256(r8d, ebx);
+ encodekey256(r30d, r29d);
+ }
+ } c;
+ const uint8_t tbl[] = {
+ // encodekey128
+ 0xf3, 0x0f, 0x38, 0xfa, 0xc3,
+ 0x62, 0xd4, 0x7e, 0x08, 0xda, 0xc0,
+ 0x62, 0x74, 0x7e, 0x08, 0xda, 0xc3,
+ 0x62, 0x4c, 0x7e, 0x08, 0xda, 0xf5,
+ // encodekey256
+ 0xf3, 0x0f, 0x38, 0xfb, 0xc3,
+ 0x62, 0xd4, 0x7e, 0x08, 0xdb, 0xc0,
+ 0x62, 0x74, 0x7e, 0x08, 0xdb, 0xc3,
+ 0x62, 0x4c, 0x7e, 0x08, 0xdb, 0xf5,
+ };
+ const size_t n = sizeof(tbl);
+ CYBOZU_TEST_EQUAL(c.getSize(), n);
+ CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
+}
+
diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h
index ef40b99..df00389 100644
--- a/xbyak/xbyak.h
+++ b/xbyak/xbyak.h
@@ -231,6 +231,7 @@ enum {
ERR_INVALID_ZU,
ERR_CANT_USE_REX2,
ERR_INVALID_DFV,
+ ERR_INVALID_REG_IDX,
ERR_INTERNAL // Put it at last.
};
@@ -288,6 +289,7 @@ inline const char *ConvertErrorToString(int err)
"invalid ZU",
"can't use rex2",
"invalid dfv",
+ "invalid reg index",
"internal error"
};
assert(ERR_INTERNAL + 1 == sizeof(errTbl) / sizeof(*errTbl));
@@ -2738,13 +2740,21 @@ private:
}
void opAESKL(const Xmm *x, const Address& addr, uint64_t type1, uint64_t type2, uint8_t code)
{
- if (x && x->getIdx() >= 16) XBYAK_THROW(ERR_BAD_COMBINATION)
+ if (x && x->getIdx() >= 16) XBYAK_THROW(ERR_INVALID_REG_IDX)
if (addr.hasRex2()) {
opROO(Reg(), addr, *x, type2, code);
return;
}
opRO(*x, addr, type1, code);
}
+ void opEncodeKey(const Reg32& r1, const Reg32& r2, uint8_t code1, uint8_t code2)
+ {
+ if (r1.getIdx() < 8 && r2.getIdx() < 8) {
+ db(0xF3); db(0x0F); db(0x38); db(code1); setModRM(3, r1.getIdx(), r2.getIdx());
+ return;
+ }
+ opROO(Reg(), r2, r1, T_MUST_EVEX|T_F3, code2);
+ }
public:
unsigned int getVersion() const { return VERSION; }
using CodeArray::db;
diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h
index a904180..b08ce7d 100644
--- a/xbyak/xbyak_mnemonic.h
+++ b/xbyak/xbyak_mnemonic.h
@@ -1934,6 +1934,8 @@ void aesenc128kl(const Xmm& x, const Address& addr) { opAESKL(&x, addr, T_F3|T_0
void aesenc256kl(const Xmm& x, const Address& addr) { opAESKL(&x, addr, T_F3|T_0F38, T_F3|T_MUST_EVEX, 0xDE); }
void aesencwide128kl(const Address& addr) { opAESKL(&xmm0, addr, T_F3|T_0F38, T_F3|T_MUST_EVEX, 0xD8); }
void aesencwide256kl(const Address& addr) { opAESKL(&xmm2, addr, T_F3|T_0F38, T_F3|T_MUST_EVEX, 0xD8); }
+void encodekey128(const Reg32& r1, const Reg32& r2) { opEncodeKey(r1, r2, 0xFA, 0xDA); }
+void encodekey256(const Reg32& r1, const Reg32& r2) { opEncodeKey(r1, r2, 0xFB, 0xDB); }
void ldtilecfg(const Address& addr) { if (opROO(Reg(), addr, tmm0, T_APX|T_0F38|T_W0, 0x49)) return; opVex(tmm0, &tmm0, addr, T_0F38|T_W0, 0x49); }
void sttilecfg(const Address& addr) { if (opROO(Reg(), addr, tmm0, T_APX|T_66|T_0F38|T_W0, 0x49)) return; opVex(tmm0, &tmm0, addr, T_66|T_0F38 | T_W0, 0x49); }
void tileloadd(const Tmm& tm, const Address& addr) { opAMX(tm, addr, T_F2|T_0F38|T_W0, 0x4B); }