Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
herumi committed Dec 28, 2023
2 parents 2e93baa + c0888cc commit e1b6896
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 25 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.5)

project(xbyak LANGUAGES CXX VERSION 7.03)
project(xbyak LANGUAGES CXX VERSION 7.04)

file(GLOB headers xbyak/*.h)

Expand Down
1 change: 1 addition & 0 deletions doc/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# History

* 2023/Dec/28 ver 7.04 rex2 supports two-byte opecode
* 2023/Dec/26 ver 7.03 set the default value of dfv to 0
* 2023/Dec/20 ver 7.02 SHA* support APX
* 2023/Dec/19 ver 7.01 support AESKLE, WIDE_KL, KEYLOCKER, KEYLOCKER_WIDE, detection of APX10/APX
Expand Down
1 change: 0 additions & 1 deletion gen/gen_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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); } }");

Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
project(
'xbyak',
'cpp',
version: '7.03',
version: '7.04',
license: 'BSD-3-Clause',
default_options: 'b_ndebug=if-release'
)
Expand Down
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# Xbyak 7.03 [![Badge Build]][Build Status]
# Xbyak 7.04 [![Badge Build]][Build Status]

*A C++ JIT assembler for x86 (IA32), x64 (AMD64, x86-64)*

Expand Down
3 changes: 2 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 7.03
C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 7.04

-----------------------------------------------------------------------------
◎概要
Expand Down Expand Up @@ -404,6 +404,7 @@ sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から
-----------------------------------------------------------------------------
◎履歴

2023/12/28 ver 7.04 2バイトオペコードのrex2対応
2023/12/26 ver 7.03 dfvのデフォルト値を0に設定
2023/12/20 ver 7.02 SHA*のAPX対応
2023/12/19 ver 7.01 AESKLE, WIDE_KL, KEYLOCKER, KEYLOCKER_WIDE対応 APX10/APX判定対応
Expand Down
40 changes: 39 additions & 1 deletion test/apx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1898,3 +1911,28 @@ CYBOZU_TEST_AUTO(sha)
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}

CYBOZU_TEST_AUTO(0x0f_rex2)
{
struct Code : Xbyak::CodeGenerator {
Code()
{
addps(xmm3, ptr [r30+r20*4+0x4]);
movups(xmm5, ptr [r16]);
movq(r31, xmm5);
cvtsd2si(r20, ptr [r30]);
bsr(r20, r30);
}
} c;
const uint8_t tbl[] = {
0xd5, 0xb1, 0x58, 0x5c, 0xa6, 0x04,
0xd5, 0x90, 0x10, 0x28, 0x66,
0xd5, 0x99, 0x7e, 0xef, 0xf2,
0xd5, 0xd9, 0x2d, 0x26,
0xd5, 0xd9, 0xbd, 0xe6,

};
const size_t n = sizeof(tbl);
CYBOZU_TEST_EQUAL(c.getSize(), n);
CYBOZU_TEST_EQUAL_ARRAY(c.getCode(), tbl, n);
}

49 changes: 32 additions & 17 deletions xbyak/xbyak.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ namespace Xbyak {

enum {
DEFAULT_MAX_CODE_SIZE = 4096,
VERSION = 0x7030 /* 0xABCD = A.BC(.D) */
VERSION = 0x7040 /* 0xABCD = A.BC(.D) */
};

#ifndef MIE_INTEGER_TYPE_DEFINED
Expand Down Expand Up @@ -1736,14 +1736,15 @@ class CodeGenerator : public CodeArray {
db(0xD5);
db((rexRXB(4, bit3, r, b, x) << 4) | rex4bit);
}
void rex(const Operand& op1, const Operand& op2 = Operand(), uint64_t type = 0)
// return true if rex2 is selected
bool rex(const Operand& op1, const Operand& op2 = Operand(), uint64_t type = 0)
{
if (op1.getNF() | op2.getNF()) XBYAK_THROW(ERR_INVALID_NF)
if (op1.getZU() | op2.getZU()) XBYAK_THROW(ERR_INVALID_ZU)
if (op1.getNF() | op2.getNF()) XBYAK_THROW_RET(ERR_INVALID_NF, false)
if (op1.getZU() | op2.getZU()) XBYAK_THROW_RET(ERR_INVALID_ZU, false)
uint8_t rex = 0;
const Operand *p1 = &op1, *p2 = &op2;
if (p1->isMEM()) std::swap(p1, p2);
if (p1->isMEM()) XBYAK_THROW(ERR_BAD_COMBINATION)
if (p1->isMEM()) XBYAK_THROW_RET(ERR_BAD_COMBINATION, false)
// except movsx(16bit, 32/64bit)
bool p66 = (op1.isBit(16) && !op2.isBit(i32e)) || (op2.isBit(16) && !op1.isBit(i32e));
if ((type & T_66) || p66) db(0x66);
Expand All @@ -1753,6 +1754,7 @@ class CodeGenerator : public CodeArray {
if (type & T_F3) {
db(0xF3);
}
bool is0F = type & T_0F;
if (p2->isMEM()) {
const Reg& r = *static_cast<const Reg*>(p1);
const Address& addr = p2->getAddress();
Expand All @@ -1762,9 +1764,9 @@ class CodeGenerator : public CodeArray {
if (BIT == 64 && addr.is32bit()) db(0x67);
rex = rexRXB(3, r.isREG(64), r, base, idx);
if (r.hasRex2() || addr.hasRex2()) {
if (type & (T_0F|T_0F38|T_0F3A)) XBYAK_THROW(ERR_CANT_USE_REX2)
rex2(0, rex, r, base, idx);
return;
if (type & (T_0F38|T_0F3A)) XBYAK_THROW_RET(ERR_CANT_USE_REX2, false)
rex2(is0F, rex, r, base, idx);
return true;
}
if (rex || r.isExt8bit()) rex |= 0x40;
} else {
Expand All @@ -1773,13 +1775,14 @@ class CodeGenerator : public CodeArray {
// 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);
return;
if (type & (T_0F38|T_0F3A)) XBYAK_THROW_RET(ERR_CANT_USE_REX2, 0)
rex2(is0F, rex, r2, r1);
return true;
}
if (rex || r1.isExt8bit() || r2.isExt8bit()) rex |= 0x40;
}
if (rex) db(rex);
return false;
}
// @@@begin of avx_type_def.h
static const uint64_t T_NONE = 0ull;
Expand Down Expand Up @@ -2022,9 +2025,9 @@ class CodeGenerator : public CodeArray {
}
LabelManager labelMgr_;
bool isInDisp16(uint32_t x) const { return 0xFFFF8000 <= x || x <= 0x7FFF; }
void writeCode(uint64_t type, const Reg& r, int code)
void writeCode(uint64_t type, const Reg& r, int code, bool rex2 = false)
{
if (!(type & T_APX)) {
if (!(type&T_APX || rex2)) {
if (type & T_0F) {
db(0x0F);
} else if (type & T_0F38) {
Expand All @@ -2037,15 +2040,15 @@ class CodeGenerator : public CodeArray {
}
void opRR(const Reg& reg1, const Reg& reg2, uint64_t type, int code)
{
rex(reg2, reg1, type);
writeCode(type, reg1, code);
bool rex2 = rex(reg2, reg1, type);
writeCode(type, reg1, code, rex2);
setModRM(3, reg1.getIdx(), reg2.getIdx());
}
void opMR(const Address& addr, const Reg& r, uint64_t type, int code, int immSize = 0)
{
if (addr.is64bitDisp()) XBYAK_THROW(ERR_CANT_USE_64BIT_DISP)
rex(addr, r, type);
writeCode(type, r, code);
bool rex2 = rex(addr, r, type);
writeCode(type, r, code, rex2);
opAddr(addr, r.getIdx(), immSize);
}
void opLoadSeg(const Address& addr, const Reg& reg, uint64_t type, int code)
Expand Down Expand Up @@ -3133,6 +3136,18 @@ class CodeGenerator : public CodeArray {
{
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
*/
Expand Down
3 changes: 1 addition & 2 deletions xbyak/xbyak_mnemonic.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const char *getVersionString() const { return "7.03"; }
const char *getVersionString() const { return "7.04"; }
void aadd(const Address& addr, const Reg32e &reg) { opMR(addr, reg, T_0F38, 0x0FC); }
void aand(const Address& addr, const Reg32e &reg) { opMR(addr, reg, T_0F38 | T_66, 0x0FC); }
void adc(const Operand& op, uint32_t imm) { opOI(op, imm, 0x10, 2); }
Expand Down Expand Up @@ -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()); }
Expand Down

0 comments on commit e1b6896

Please sign in to comment.