From 0b788ecf581d03b19d8f2f222ad4778cb6a0a138 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Tue, 14 Jun 2016 17:47:34 +0900 Subject: [PATCH] under refactoring AddressFrame --- test/Makefile.win | 16 +++++ test/test_address.bat | 5 +- test/test_avx.bat | 5 +- test/test_avx512.bat | 5 +- test/test_jmp.bat | 5 +- test/test_misc.bat | 5 +- test/test_nm.bat | 5 +- xbyak/xbyak.h | 149 +++++++++++++++++++++--------------------- 8 files changed, 104 insertions(+), 91 deletions(-) create mode 100644 test/Makefile.win diff --git a/test/Makefile.win b/test/Makefile.win new file mode 100644 index 0000000..9d5f8fe --- /dev/null +++ b/test/Makefile.win @@ -0,0 +1,16 @@ +OPT=/EHsc -I../xbyak /W4 -D_CRT_SECURE_NO_WARNINGS +../xbyak/xbyak_mnemonic.h: ../gen/gen_code.exe + ../gen/gen_code.exe > $@ + +../gen/gen_code.exe: ../gen/gen_code.cpp #../xbyak/xbyak.h + cl ../gen/gen_code.cpp $(OPT) /Fe:../gen/gen_code.exe + +../xbyak/xbyak_avx512.h: ../gen/gen_avx512.exe + ../gen/gen_avx512.exe > $@ + +../gen/gen_avx512.exe: ../gen/gen_avx512.cpp #../xbyak/xbyak.h + cl ../gen/gen_avx512.cpp $(OPT) /Fe:../gen/gen_avx512.exe + +SUB_HEADER=../xbyak/xbyak_mnemonic.h ../xbyak/xbyak_avx512.h + +all: $(SUB_HEADER) diff --git a/test/test_address.bat b/test/test_address.bat index 7faa23a..030c04d 100644 --- a/test/test_address.bat +++ b/test/test_address.bat @@ -8,9 +8,8 @@ if /i "%1"=="64" ( set OPT3=win32 ) -pushd ..\gen -call update -popd +call set_opt +bmake -f Makefile.win all if /i "%1"=="64" ( call :sub 1 diff --git a/test/test_avx.bat b/test/test_avx.bat index b48bab9..5e51aa2 100644 --- a/test/test_avx.bat +++ b/test/test_avx.bat @@ -22,9 +22,8 @@ if /i "%1"=="Y" ( set OPT2=-DXBYAK32 set OPT3=win32 ) -pushd ..\gen -call update -popd +call set_opt +bmake -f Makefile.win all echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX make_nm > a.asm diff --git a/test/test_avx512.bat b/test/test_avx512.bat index adae931..0e1fa9c 100755 --- a/test/test_avx512.bat +++ b/test/test_avx512.bat @@ -11,9 +11,8 @@ if /i "%1"=="64" ( set OPT2=-DXBYAK32 set OPT3=win32 ) -pushd ..\gen -call update -popd +call set_opt +bmake -f Makefile.win all echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512 cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512 make_nm > a.asm diff --git a/test/test_jmp.bat b/test/test_jmp.bat index bfb4064..83cb0c3 100644 --- a/test/test_jmp.bat +++ b/test/test_jmp.bat @@ -1,5 +1,4 @@ -pushd ..\gen -call update -popd +call set_opt +bmake -f Makefile.win all cl -I../ -I./ -DXBYAK_TEST jmp.cpp %OPT% /Od /Zi jmp diff --git a/test/test_misc.bat b/test/test_misc.bat index 9aeb925..cdb81d3 100755 --- a/test/test_misc.bat +++ b/test/test_misc.bat @@ -1,5 +1,4 @@ -pushd ..\gen -call update -popd +call set_opt +bmake -f Makefile.win all cl -I../ -I./ -DXBYAK_TEST misc.cpp %OPT% /Od /Zi misc diff --git a/test/test_nm.bat b/test/test_nm.bat index df0a97c..32abfac 100644 --- a/test/test_nm.bat +++ b/test/test_nm.bat @@ -22,9 +22,8 @@ if /i "%1"=="Y" ( set OPT2=-DXBYAK32 set OPT3=win32 ) -pushd ..\gen -call update -popd +call set_opt +bmake -f Makefile.win all echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs cl -I../ make_nm.cpp %OPT% %OPT2% /EHs make_nm > a.asm diff --git a/xbyak/xbyak.h b/xbyak/xbyak.h index b78dbd3..4b716e0 100644 --- a/xbyak/xbyak.h +++ b/xbyak/xbyak.h @@ -324,23 +324,21 @@ public: #endif class Operand { -private: - static const int EXT8BIT = 0x80; - unsigned int idx_:8; // 0..31, MSB = 1 if spl/bpl/sil/dil - unsigned int kind_:10; - unsigned int bit_:14; + static const uint8 EXT8BIT = 0x80; + uint8 idx_; // 0..31, EXT8BIT = 1 if spl/bpl/sil/dil + uint8 kind_; + uint16 bit_; public: enum Kind { NONE = 0, - MEM = 1 << 1, - IMM = 1 << 2, - REG = 1 << 3, - MMX = 1 << 4, - XMM = 1 << 5, - FPU = 1 << 6, - YMM = 1 << 7, - ZMM = 1 << 8, - OPMASK = 1 << 9 + MEM = 1 << 0, + REG = 1 << 1, + MMX = 1 << 2, + FPU = 1 << 3, + XMM = 1 << 4, + YMM = 1 << 5, + ZMM = 1 << 6, + OPMASK = 1 << 7 }; enum Code { #ifdef XBYAK64 @@ -357,13 +355,13 @@ public: Operand() : idx_(0), kind_(0), bit_(0) { } Operand(int idx, Kind kind, int bit, bool ext8bit = 0) : idx_(static_cast(idx | (ext8bit ? EXT8BIT : 0))) - , kind_(kind) - , bit_(bit) + , kind_(static_cast(kind)) + , bit_(static_cast(bit)) { assert((bit_ & (bit_ - 1)) == 0); // bit must be power of two } Kind getKind() const { return static_cast(kind_); } - int getIdx() const { return idx_ & 31; } + int getIdx() const { return idx_ & (EXT8BIT - 1); } bool isNone() const { return kind_ == 0; } bool isMMX() const { return is(MMX); } bool isXMM() const { return is(XMM); } @@ -428,7 +426,7 @@ public: } throw Error(ERR_INTERNAL); } - bool isSameNotInherited(const Operand& rhs) const { return idx_ == rhs.idx_ && kind_ == rhs.kind_ && bit_ == rhs.bit_; } + bool isEqualIfNotInherited(const Operand& rhs) const { return idx_ == rhs.idx_ && kind_ == rhs.kind_ && bit_ == rhs.bit_; } bool operator==(const Operand& rhs) const; bool operator!=(const Operand& rhs) const { return !operator==(rhs); } }; @@ -574,32 +572,30 @@ public: class RegExp { public: - struct SReg { - uint16 bit:10; // 32/64/128/256/512 none if 0 - uint16 idx:6; - SReg() : bit(0), idx(0) { } - void set(const Reg& r) { this->bit = uint16(r.getBit()); this->idx = uint16(r.getIdx()); } - bool operator==(const SReg& rhs) const { return bit == rhs.bit && idx == rhs.idx; } - }; +#ifdef XBYAK64 + enum { i32e = 32 | 64 }; +#else + enum { i32e = 32 }; +#endif RegExp(size_t disp = 0) : disp_(disp), scale_(0) { } RegExp(const Reg& r, int scale = 1) : disp_(0) , scale_(scale) { - if (!r.is(Reg::REG, 32|64) && !r.is(Reg::XMM|Reg::YMM)) throw Error(ERR_BAD_SIZE_OF_REGISTER); + if (!r.isREG(i32e) && !r.is(Reg::XMM|Reg::YMM)) throw Error(ERR_BAD_SIZE_OF_REGISTER); if (scale != 1 && scale != 2 && scale != 4 && scale != 8) throw Error(ERR_BAD_SCALE); if (r.getBit() >= 128 || scale != 1) { // xmm/ymm is always index - index_.set(r); + index_ = r; } else { - base_.set(r); + base_ = r; } } - bool isVsib() const { return 128 <= index_.bit && index_.bit <= 256; } - bool isYMM() const { return index_.bit == 256; } + bool isVsib() const { return index_.isBit(128|256); } + bool isYMM() const { return index_.isBit(256); } RegExp optimize() const // select smaller size { // [reg * 2] => [reg + reg] - if (index_.bit <= 64 && !base_.bit && index_.bit && scale_ == 2) { + if (index_.isBit(i32e) && !base_.getBit() && index_.getBit() && scale_ == 2) { RegExp ret = *this; ret.base_ = index_; ret.scale_ = 1; @@ -611,43 +607,43 @@ public: { return base_ == rhs.base_ && index_ == rhs.index_ && disp_ == rhs.disp_; } - const SReg& getBase() const { return base_; } - const SReg& getIndex() const { return index_; } + const Operand& getBase() const { return base_; } + const Operand& getIndex() const { return index_; } int getScale() const { return scale_; } uint32 getDisp() const { return uint32(disp_); } void verify() const { - if (base_.bit >= 128) throw Error(ERR_BAD_SIZE_OF_REGISTER); - if (index_.bit && index_.bit <= 64) { - if (index_.idx == Operand::ESP) throw Error(ERR_ESP_CANT_BE_INDEX); - if (base_.bit && base_.bit != index_.bit) throw Error(ERR_BAD_SIZE_OF_REGISTER); + if (base_.getBit() >= 128) throw Error(ERR_BAD_SIZE_OF_REGISTER); + if (index_.getBit() && index_.getBit() <= 64) { + if (index_.getIdx() == Operand::ESP) throw Error(ERR_ESP_CANT_BE_INDEX); + if (base_.getBit() && base_.getBit() != index_.getBit()) throw Error(ERR_BAD_SIZE_OF_REGISTER); } } -private: friend RegExp operator+(const RegExp& a, const RegExp& b); friend RegExp operator-(const RegExp& e, size_t disp); +private: /* [base_ + index_ * scale_ + disp_] base : Reg32e, index : Reg32e(w/o esp), Xmm, Ymm */ size_t disp_; int scale_; - SReg base_; - SReg index_; + Operand base_; + Operand index_; }; inline RegExp operator+(const RegExp& a, const RegExp& b) { - if (a.index_.bit && b.index_.bit) throw Error(ERR_BAD_ADDRESSING); + if (a.index_.getBit() && b.index_.getBit()) throw Error(ERR_BAD_ADDRESSING); RegExp ret = a; - if (!ret.index_.bit) { ret.index_ = b.index_; ret.scale_ = b.scale_; } - if (b.base_.bit) { - if (ret.base_.bit) { - if (ret.index_.bit) throw Error(ERR_BAD_ADDRESSING); + if (!ret.index_.getBit()) { ret.index_ = b.index_; ret.scale_ = b.scale_; } + if (b.base_.getBit()) { + if (ret.base_.getBit()) { + if (ret.index_.getBit()) throw Error(ERR_BAD_ADDRESSING); // base + base => base + index * 1 ret.index_ = b.base_; // [reg + esp] => [esp + reg] - if (ret.index_.idx == Operand::ESP) std::swap(ret.base_, ret.index_); + if (ret.index_.getIdx() == Operand::ESP) std::swap(ret.base_, ret.index_); ret.scale_ = 1; } else { ret.base_ = b.base_; @@ -877,10 +873,10 @@ class Address : public Operand { bool is64bitDisp_; bool is32bit_; mutable bool isVsib_; - bool isYMM_; + RegExp e_; void verify() const { if (isVsib_) throw Error(ERR_BAD_VSIB_ADDRESSING); } public: - Address(uint32 sizeBit, bool isOnlyDisp, size_t disp, bool is32bit, bool is64bitDisp = false, bool isVsib = false, bool isYMM = false) + Address(const RegExp& e, uint32 sizeBit, bool isOnlyDisp, size_t disp, bool is32bit, bool is64bitDisp = false) : Operand(0, MEM, sizeBit) , size_(0) , rex_(0) @@ -889,8 +885,8 @@ public: , isOnlyDisp_(isOnlyDisp) , is64bitDisp_(is64bitDisp) , is32bit_(is32bit) - , isVsib_(isVsib) - , isYMM_(isYMM) + , isVsib_(e.isVsib()) + , e_(e) { } void db(int code) @@ -907,7 +903,7 @@ public: } void setVsib(bool isVsib) const { isVsib_ = isVsib; } bool isVsib() const { return isVsib_; } - bool isYMM() const { return isYMM_; } + bool isYMM() const { return e_.isYMM(); } bool is32bit() const { verify(); return is32bit_; } bool isOnlyDisp() const { verify(); return isOnlyDisp_; } // for mov eax size_t getDisp() const { verify(); return disp_; } @@ -919,7 +915,7 @@ public: bool operator==(const Address& rhs) const { return getBit() == rhs.getBit() && size_ == rhs.size_ && rex_ == rhs.rex_ && disp_ == rhs.disp_ && label_ == rhs.label_ && isOnlyDisp_ == rhs.isOnlyDisp_ - && is64bitDisp_ == rhs.is64bitDisp_ && is32bit_ == rhs.is32bit_ && isVsib_ == rhs.isVsib_ && isYMM_ == rhs.isYMM_; + && is64bitDisp_ == rhs.is64bitDisp_ && is32bit_ == rhs.is32bit_ && isVsib_ == rhs.isVsib_ && isYMM() == rhs.isYMM(); } bool operator!=(const Address& rhs) const { return !operator==(rhs); } }; @@ -927,56 +923,63 @@ public: inline bool Operand::operator==(const Operand& rhs) const { if (isMEM() && rhs.isMEM()) return static_cast(*this) == static_cast(rhs); - return isSameNotInherited(rhs); + return isEqualIfNotInherited(rhs); } class AddressFrame { private: void operator=(const AddressFrame&); - Address makeAddress(const RegExp& e) const + static inline void setModRM(Address& frame, const Operand& base, const Operand& index, int scale, uint32 disp) { - e.verify(); - const bool isVsib = e.isVsib(); - const bool isYMM = e.isYMM(); - const RegExp::SReg& base = e.getBase(); - const RegExp::SReg& index = e.getIndex(); - const uint32 disp = e.getDisp(); - Address frame(bit_, (!base.bit && !index.bit), disp, base.bit == 32 || index.bit == 32, false, isVsib, isYMM); + const int baseIdx = base.getIdx(); + const int baseBit = base.getBit(); + const int indexBit = index.getBit(); + const int indexIdx = index.getIdx(); enum { mod00 = 0, mod01 = 1, mod10 = 2 }; int mod; - if (!base.bit || ((base.idx & 7) != Operand::EBP && disp == 0)) { + if (!baseBit || ((baseIdx & 7) != Operand::EBP && disp == 0)) { mod = mod00; } else if (inner::IsInDisp8(disp)) { mod = mod01; } else { mod = mod10; } - const int baseIdx = base.bit ? (base.idx & 7) : Operand::EBP; + const int newBaseIdx = baseBit ? (baseIdx & 7) : Operand::EBP; /* ModR/M = [2:3:3] = [Mod:reg/code:R/M] */ - bool hasSIB = index.bit || (base.idx & 7) == Operand::ESP; + bool hasSIB = indexBit || (baseIdx & 7) == Operand::ESP; #ifdef XBYAK64 - if (!base.bit && !index.bit) hasSIB = true; + if (!baseBit && !indexBit) hasSIB = true; #endif if (hasSIB) { frame.db((mod << 6) | Operand::ESP); /* SIB = [2:3:3] = [SS:index:base(=rm)] */ - const int indexIdx = index.bit ? (index.idx & 7) : Operand::ESP; - const int scale = e.getScale(); + const int newIndexIdx = indexBit ? (indexIdx & 7) : Operand::ESP; const int ss = (scale == 8) ? 3 : (scale == 4) ? 2 : (scale == 2) ? 1 : 0; - frame.db((ss << 6) | (indexIdx << 3) | baseIdx); + frame.db((ss << 6) | (newIndexIdx << 3) | newBaseIdx); } else { - frame.db((mod << 6) | baseIdx); + frame.db((mod << 6) | newBaseIdx); } if (mod == mod01) { frame.db(disp); - } else if (mod == mod10 || (mod == mod00 && !base.bit)) { + } else if (mod == mod10 || (mod == mod00 && !baseBit)) { frame.dd(disp); } - int rex = ((index.idx >> 3) << 1) | (base.idx >> 3); + int rex = ((indexIdx >> 3) << 1) | (baseIdx >> 3); if (rex) rex |= 0x40; frame.setRex(uint8(rex)); + } + Address makeAddress(const RegExp& e) const + { + e.verify(); + const Operand& base = e.getBase(); + const Operand& index = e.getIndex(); + const int baseBit = base.getBit(); + const int indexBit = index.getBit(); + const uint32 disp = e.getDisp(); + Address frame(e, bit_, (!baseBit && !indexBit), disp, baseBit == 32 || indexBit == 32, false); + setModRM(frame, base, index, e.getScale(), disp); return frame; } public: @@ -994,11 +997,11 @@ public: #ifdef XBYAK64 Address operator[](uint64 disp) const { - return Address(64, true, disp, false, true); + return Address(RegExp(), 64, true, disp, false, true); } Address operator[](const RegRip& addr) const { - Address frame(bit_, true, addr.disp_, false); + Address frame(RegExp(), bit_, true, addr.disp_, false); frame.db(0x05); if (addr.label_) { frame.setLabel(addr.label_);