diff options
-rw-r--r-- | .github/workflows/main.yml | 1 | ||||
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | gen/Makefile | 2 | ||||
-rw-r--r-- | meson.build | 2 | ||||
-rw-r--r-- | readme.md | 5 | ||||
-rw-r--r-- | readme.txt | 4 | ||||
-rw-r--r-- | sample/Makefile | 6 | ||||
-rw-r--r-- | sample/memfd.cpp | 39 | ||||
-rw-r--r-- | test/Makefile | 4 | ||||
-rw-r--r-- | test/misc.cpp | 14 | ||||
-rw-r--r-- | xbyak/xbyak.h | 20 | ||||
-rw-r--r-- | xbyak/xbyak_mnemonic.h | 2 |
12 files changed, 89 insertions, 12 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3fad142..39dcc86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,5 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + - run: sudo apt update - run: sudo apt install nasm yasm g++-multilib tcsh - run: make test diff --git a/CMakeLists.txt b/CMakeLists.txt index e92a621..bf72cf0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 2.6...3.0.2) -project(xbyak LANGUAGES CXX VERSION 6.02) +project(xbyak LANGUAGES CXX VERSION 6.03) file(GLOB headers xbyak/*.h) diff --git a/gen/Makefile b/gen/Makefile index c3cd0ea..9442f0d 100644 --- a/gen/Makefile +++ b/gen/Makefile @@ -1,6 +1,6 @@ TARGET=../xbyak/xbyak_mnemonic.h BIN=sortline gen_code gen_avx512 -CFLAGS=-I../ -O2 -DXBYAK_NO_OP_NAMES -Wall -Wextra -Wno-missing-field-initializers +CFLAGS=-I../ -O2 -DXBYAK_NO_OP_NAMES -Wall -Wextra -Wno-missing-field-initializers $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) all: $(TARGET) ../CMakeLists.txt ../meson.build sortline: sortline.cpp $(CXX) $(CFLAGS) $< -o $@ diff --git a/meson.build b/meson.build index a29dff6..94ed527 100644 --- a/meson.build +++ b/meson.build @@ -5,7 +5,7 @@ project( 'xbyak', 'cpp', - version: '6.02', + version: '6.03', license: 'BSD-3-Clause', default_options: 'b_ndebug=if-release' ) @@ -1,6 +1,6 @@ [![Build Status](https://github.com/herumi/xbyak/actions/workflows/main.yml/badge.svg)](https://github.com/herumi/xbyak/actions/workflows/main.yml) -#lXbyak 6.02 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ +#lXbyak 6.03 ; JIT assembler for x86(IA32), x64(AMD64, x86-64) by C++ ## Abstract @@ -19,6 +19,7 @@ Use `and_()`, `or_()`, ... instead of `and()`, `or()`. If you want to use them, then specify `-fno-operator-names` option to gcc/clang. ### News +- MmapAllocator supports memfd with user-defined strings. see sample/memfd.cpp - strictly check address offset disp32 in a signed 32-bit integer. e.g., `ptr[(void*)0xffffffff]` causes an error. - define `XBYAK_OLD_DISP_CHECK` if you need an old check, but the option will be remoevd. - add `jmp(mem, T_FAR)`, `call(mem, T_FAR)` `retf()` for far absolute indirect jump. @@ -469,6 +470,8 @@ modified new BSD License http://opensource.org/licenses/BSD-3-Clause ## History +* 2022/Jan/28 ver 6.02 strict check the range of 32-bit dispacement +* 2021/Dec/14 ver 6.01 support T_FAR jump/call and retf * 2021/Sep/14 ver 6.00 fully support AVX512-FP16 * 2021/Sep/09 ver 5.997 fix vrndscale* to support {sae} * 2021/Sep/03 ver 5.996 fix v{add,sub,mul,div,max,min}{sd,ss} to support T_rd_sae. @@ -1,5 +1,5 @@ - C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 6.02
+ C++用x86(IA-32), x64(AMD64, x86-64) JITアセンブラ Xbyak 6.03
-----------------------------------------------------------------------------
◎概要
@@ -400,6 +400,8 @@ sample/{echo,hello}.bfは http://www.kmonos.net/alang/etc/brainfuck.php から -----------------------------------------------------------------------------
◎履歴
+2022/01/28 ver 6.02 dispacementの32bit範囲チェックの厳密化
+2021/12/14 ver 6.01 T_FAR jump/callとretfをサポート
2021/09/14 ver 6.00 AVX512-FP16を完全サポート
2021/09/09 ver 5.997 vrndscale*を{sae}をサポートするよう修正
2021/09/03 ver 5.996 v{add,sub,mul,div,max,min}{sd,ss}をT_rd_saeなどをサポートするよう修正
diff --git a/sample/Makefile b/sample/Makefile index 0c100a3..7c910bb 100644 --- a/sample/Makefile +++ b/sample/Makefile @@ -37,6 +37,7 @@ endif ifneq ($(OS),mac) TARGET += static_buf64 +TARGET += memfd endif @@ -51,7 +52,7 @@ all: $(TARGET) CFLAGS_WARN=-Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wfloat-equal -Wpointer-arith #-pedantic -CFLAGS=-g -O2 -fomit-frame-pointer -Wall -I../ $(CFLAGS_WARN) +CFLAGS=-g -O2 -fomit-frame-pointer -Wall -I../ $(CFLAGS_WARN) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) test: $(CXX) $(CFLAGS) test0.cpp -o $@ -m32 @@ -95,6 +96,8 @@ jmp_table: $(CXX) $(CFLAGS) jmp_table.cpp -o $@ -m32 jmp_table64: $(CXX) $(CFLAGS) jmp_table.cpp -o $@ -m64 +memfd: + $(CXX) $(CFLAGS) memfd.cpp -o $@ -m64 profiler: profiler.cpp ../xbyak/xbyak_util.h $(CXX) $(CFLAGS) profiler.cpp -o $@ profiler-vtune: profiler.cpp ../xbyak/xbyak_util.h @@ -121,3 +124,4 @@ test_util : test_util.cpp $(XBYAK_INC) ../xbyak/xbyak_util.h test_util2 : test_util.cpp $(XBYAK_INC) ../xbyak/xbyak_util.h jmp_table: jmp_table.cpp $(XBYAK_INC) jmp_table64: jmp_table.cpp $(XBYAK_INC) +memfd: memfd.cpp $(XBYAK_INC) diff --git a/sample/memfd.cpp b/sample/memfd.cpp new file mode 100644 index 0000000..1066c55 --- /dev/null +++ b/sample/memfd.cpp @@ -0,0 +1,39 @@ +/* + a sample to use MmapAllocator with an user-defined name + cat /proc/`psidof ./memfd`/maps + +7fca70b44000-7fca70b4a000 rw-p 00000000 00:00 0 +7fca70b67000-7fca70b68000 rwxs 00000000 00:05 19960170 /memfd:xyz (deleted) +7fca70b68000-7fca70b69000 rwxs 00000000 00:05 19960169 /memfd:abc (deleted) +7fca70b69000-7fca70b6a000 r--p 00029000 103:03 19136541 /lib/x86_64-linux-gnu/ld-2.27.so +7fca70b6a000-7fca70b6b000 rw-p 0002a000 103:03 19136541 /lib/x86_64-linux-gnu/ld-2.27.so +*/ +#define XBYAK_USE_MEMFD +#include <xbyak/xbyak.h> +#include <fstream> + +class Code : Xbyak::MmapAllocator, public Xbyak::CodeGenerator { +public: + Code(const char *name, int v) + : Xbyak::MmapAllocator(name) + , Xbyak::CodeGenerator(4096, nullptr, this /* specify external MmapAllocator */) + { + mov(eax, v); + ret(); + } +}; + +int main() +{ + Code c1("Xbyak::abc", 123); + Code c2("Xbyak::xyz", 456); + printf("c1 %d\n", c1.getCode<int (*)()>()()); + printf("c2 %d\n", c2.getCode<int (*)()>()()); + std::ifstream ifs("/proc/self/maps", std::ios::binary); + if (ifs) { + std::string line; + while (std::getline(ifs, line)) { + printf("%s\n", line.c_str()); + } + } +} diff --git a/test/Makefile b/test/Makefile index ac69b3e..b9dd413 100644 --- a/test/Makefile +++ b/test/Makefile @@ -22,7 +22,7 @@ all: $(TARGET) CFLAGS_WARN=-Wall -Wextra -Wformat=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wfloat-equal -Wpointer-arith -CFLAGS=-O2 -fomit-frame-pointer -Wall -fno-operator-names -I../ -I./ $(CFLAGS_WARN) #-std=c++0x +CFLAGS=-O2 -fomit-frame-pointer -Wall -fno-operator-names -I../ -I./ $(CFLAGS_WARN) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) #-std=c++0x make_nm: $(CXX) $(CFLAGS) make_nm.cpp -o $@ normalize_prefix: normalize_prefix.cpp ../xbyak/xbyak.h @@ -95,7 +95,7 @@ test: $(MAKE) test_avx512 clean: - rm -rf *.o $(TARGET) lib_run nm.cpp nm_frame make_512 + $(RM) a.asm *.lst *.obj *.o $(TARGET) lib_run nm.cpp nm_frame make_512 lib_run: lib_test.cpp lib_run.cpp lib.h $(CXX) $(CFLAGS) lib_run.cpp lib_test.cpp -o lib_run diff --git a/test/misc.cpp b/test/misc.cpp index 0e1c3f4..140072e 100644 --- a/test/misc.cpp +++ b/test/misc.cpp @@ -23,6 +23,20 @@ CYBOZU_TEST_AUTO(setSize) } code; } +CYBOZU_TEST_AUTO(badSSE) +{ + struct Code : Xbyak::CodeGenerator { + Code() + { + CYBOZU_TEST_EXCEPTION(paddd(xm16, xm1), Xbyak::Error); + CYBOZU_TEST_EXCEPTION(pslld(xm16, 1), Xbyak::Error); + CYBOZU_TEST_EXCEPTION(movapd(xm16, xm1), Xbyak::Error); + CYBOZU_TEST_EXCEPTION(movhpd(xm16, ptr[eax]), Xbyak::Error); + CYBOZU_TEST_EXCEPTION(pextrb(eax, xm16, 1), Xbyak::Error); + } + } code; +} + CYBOZU_TEST_AUTO(compOperand) { using namespace Xbyak::util; diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index b99ebfa..c5c38dd 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -142,7 +142,7 @@ namespace Xbyak { enum { DEFAULT_MAX_CODE_SIZE = 4096, - VERSION = 0x6020 /* 0xABCD = A.BC(D) */ + VERSION = 0x6030 /* 0xABCD = A.BC(D) */ }; #ifndef MIE_INTEGER_TYPE_DEFINED @@ -383,6 +383,7 @@ enum LabelMode { custom allocator */ struct Allocator { + explicit Allocator(const std::string& = "") {} // same interface with MmapAllocator virtual uint8_t *alloc(size_t size) { return reinterpret_cast<uint8_t*>(AlignedMalloc(size, inner::ALIGN_PAGE_SIZE)); } virtual void free(uint8_t *p) { AlignedFree(p); } virtual ~Allocator() {} @@ -414,10 +415,12 @@ inline int getMacOsVersion() } // util #endif -class MmapAllocator : Allocator { +class MmapAllocator : public Allocator { + const std::string name_; // only used with XBYAK_USE_MEMFD typedef XBYAK_STD_UNORDERED_MAP<uintptr_t, size_t> SizeList; SizeList sizeList_; public: + explicit MmapAllocator(const std::string& name = "xbyak") : name_(name) {} uint8_t *alloc(size_t size) { const size_t alignedSizeM1 = inner::ALIGN_PAGE_SIZE - 1; @@ -435,7 +438,7 @@ public: #endif int fd = -1; #if defined(XBYAK_USE_MEMFD) - fd = memfd_create("xbyak", MFD_CLOEXEC); + fd = memfd_create(name_.c_str(), MFD_CLOEXEC); if (fd != -1) { mode = MAP_SHARED; if (ftruncate(fd, size) != 0) XBYAK_THROW_RET(ERR_CANT_ALLOC, 0) @@ -459,6 +462,8 @@ public: sizeList_.erase(i); } }; +#else +typedef Allocator MmapAllocator; #endif class Address; @@ -1623,6 +1628,11 @@ private: { return op1.isREG(i32e) && ((op2.isREG(i32e) && op1.getBit() == op2.getBit()) || op2.isMEM()); } + static inline bool isValidSSE(const Operand& op1) + { + // SSE instructions do not support XMM16 - XMM31 + return !(op1.isXMM() && op1.getIdx() >= 16); + } void rex(const Operand& op1, const Operand& op2 = Operand()) { uint8_t rex = 0; @@ -1965,6 +1975,7 @@ private: void opGen(const Operand& reg, const Operand& op, int code, int pref, bool isValid(const Operand&, const Operand&), int imm8 = NONE, int preCode = NONE) { if (isValid && !isValid(reg, op)) XBYAK_THROW(ERR_BAD_COMBINATION) + if (!isValidSSE(reg) || !isValidSSE(op)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (pref != NONE) db(pref); if (op.isMEM()) { opModM(op.getAddress(), reg.getReg(), 0x0F, preCode, code, (imm8 != NONE) ? 1 : 0); @@ -1975,6 +1986,7 @@ private: } void opMMX_IMM(const Mmx& mmx, int imm8, int code, int ext) { + if (!isValidSSE(mmx)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (mmx.isXMM()) db(0x66); opModR(Reg32(ext), mmx, 0x0F, code); db(imm8); @@ -1985,6 +1997,7 @@ private: } void opMovXMM(const Operand& op1, const Operand& op2, int code, int pref) { + if (!isValidSSE(op1) || !isValidSSE(op2)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (pref != NONE) db(pref); if (op1.isXMM() && op2.isMEM()) { opModM(op2.getAddress(), op1.getReg(), 0x0F, code); @@ -1996,6 +2009,7 @@ private: } void opExt(const Operand& op, const Mmx& mmx, int code, int imm, bool hasMMX2 = false) { + if (!isValidSSE(op) || !isValidSSE(mmx)) XBYAK_THROW(ERR_NOT_SUPPORTED) if (hasMMX2 && op.isREG(i32e)) { /* pextrw is special */ if (mmx.isXMM()) db(0x66); opModR(op.getReg(), mmx, 0x0F, 0xC5); db(imm); diff --git a/xbyak/xbyak_mnemonic.h b/xbyak/xbyak_mnemonic.h index 4676b56..9f309b6 100644 --- a/xbyak/xbyak_mnemonic.h +++ b/xbyak/xbyak_mnemonic.h @@ -1,4 +1,4 @@ -const char *getVersionString() const { return "6.02"; } +const char *getVersionString() const { return "6.03"; } 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 adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); } |