diff --git a/src/cpu/mips3/x64/xbyak/xbyak.h b/src/cpu/mips3/x64/xbyak/xbyak.h index 19a89568f..f81138c74 100644 --- a/src/cpu/mips3/x64/xbyak/xbyak.h +++ b/src/cpu/mips3/x64/xbyak/xbyak.h @@ -25,7 +25,7 @@ #endif //#define XBYAK_USE_MMAP_ALLOCATOR -#ifndef __GNUC__ +#if !defined(__GNUC__) || defined(__MINGW32__) #undef XBYAK_USE_MMAP_ALLOCATOR #endif @@ -96,7 +96,7 @@ namespace Xbyak { enum { DEFAULT_MAX_CODE_SIZE = 4096, - VERSION = 0x4710 /* 0xABCD = A.BC(D) */ + VERSION = 0x4810 /* 0xABCD = A.BC(D) */ }; #ifndef MIE_INTEGER_TYPE_DEFINED @@ -283,7 +283,7 @@ struct Allocator { virtual bool useProtect() const { return true; } }; -#ifdef __GNUC__ +#ifdef XBYAK_USE_MMAP_ALLOCATOR class MmapAllocator : Allocator { typedef XBYAK_STD_UNORDERED_MAP SizeList; SizeList sizeList_; @@ -411,6 +411,8 @@ public: bool operator!=(const Operand& rhs) const { return !operator==(rhs); } }; +class Label; + struct Reg8; struct Reg16; struct Reg32; @@ -471,13 +473,18 @@ struct Reg64 : public Reg32e { explicit Reg64(int idx = 0) : Reg32e(idx, 64) {} }; struct RegRip { - uint32 disp_; - explicit RegRip(unsigned int disp = 0) : disp_(disp) {} - friend const RegRip operator+(const RegRip& r, unsigned int disp) { - return RegRip(r.disp_ + disp); + sint64 disp_; + Label* label_; + explicit RegRip(sint64 disp = 0, Label* label = 0) : disp_(disp), label_(label) {} + friend const RegRip operator+(const RegRip& r, sint64 disp) { + return RegRip(r.disp_ + disp, r.label_); } - friend const RegRip operator-(const RegRip& r, unsigned int disp) { - return RegRip(r.disp_ - disp); + friend const RegRip operator-(const RegRip& r, sint64 disp) { + return RegRip(r.disp_ - disp, r.label_); + } + friend const RegRip operator+(const RegRip& r, Label& label) { + if (r.label_) throw Error(ERR_BAD_ADDRESSING); + return RegRip(r.disp_, &label); } }; #endif @@ -722,6 +729,7 @@ public: } void dw(uint32 code) { db(code, 2); } void dd(uint32 code) { db(code, 4); } + void dq(uint64 code) { db(code, 8); } const uint8 *getCode() const { return top_; } template const F getCode() const { return CastTo(top_); } @@ -731,7 +739,7 @@ public: size_t getSize() const { return size_; } void setSize(size_t size) { - if (size >= maxSize_) throw Error(ERR_OFFSET_IS_TOO_BIG); + if (size > maxSize_) throw Error(ERR_OFFSET_IS_TOO_BIG); size_ = size; } void dump() const @@ -814,6 +822,7 @@ class Address : public Operand { uint8 size_; uint8 rex_; uint64 disp_; + const Label* label_; bool isOnlyDisp_; bool is64bitDisp_; bool is32bit_; @@ -826,6 +835,7 @@ public: , size_(0) , rex_(0) , disp_(disp) + , label_(0) , isOnlyDisp_(isOnlyDisp) , is64bitDisp_(is64bitDisp) , is32bit_(is32bit) @@ -854,6 +864,8 @@ public: uint8 getRex() const { verify(); return rex_; } bool is64bitDisp() const { verify(); return is64bitDisp_; } // for moffset void setRex(uint8 rex) { rex_ = rex; } + void setLabel(const Label* label) { label_ = label; } + const Label* getLabel() const { return label_; } }; class AddressFrame { @@ -925,8 +937,12 @@ public: Address operator[](const RegRip& addr) const { Address frame(bit_, true, addr.disp_, false); - frame.db(B00000101); - frame.dd(addr.disp_); + frame.db(0x05); + if (addr.label_) { + frame.setLabel(addr.label_); + } else { + frame.dd(inner::VerifyInInt32(addr.disp_)); + } return frame; } #endif @@ -940,6 +956,11 @@ struct JmpLabel { size_t endOfJmp; /* offset from top to the end address of jmp */ int jmpSize; inner::LabelMode mode; + uint64 disp; // disp for [rip + disp] + explicit JmpLabel(size_t endOfJmp = 0, int jmpSize = 0, inner::LabelMode mode = inner::LasIs, uint64 disp = 0) + : endOfJmp(endOfJmp), jmpSize(jmpSize), mode(mode), disp(disp) + { + } }; class LabelManager; @@ -1022,7 +1043,7 @@ class LabelManager { } else if (jmp->mode == inner::Labs) { disp = size_t(base_->getCurr()); } else { - disp = addrOffset - jmp->endOfJmp; + disp = addrOffset - jmp->endOfJmp + jmp->disp; #ifdef XBYAK64 if (jmp->jmpSize <= 4 && !inner::IsInInt32(disp)) throw Error(ERR_OFFSET_IS_TOO_BIG); #endif @@ -1288,7 +1309,7 @@ private: rex(addr, reg); db(code0 | (reg.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2); addr.updateRegField(static_cast(reg.getIdx())); - db(addr.getCode(), static_cast(addr.getSize())); + opAddr(addr); } void makeJmp(uint32 disp, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref) { @@ -1311,17 +1332,16 @@ private: if (labelMgr_.getOffset(&offset, label)) { /* label exists */ makeJmp(inner::VerifyInInt32(offset - size_), type, shortCode, longCode, longPref); } else { - JmpLabel jmp; + int jmpSize = 0; if (type == T_NEAR) { - jmp.jmpSize = 4; + jmpSize = 4; if (longPref) db(longPref); db(longCode); dd(0); } else { - jmp.jmpSize = 1; + jmpSize = 1; db(shortCode); db(0); } - jmp.mode = inner::LasIs; - jmp.endOfJmp = size_; + JmpLabel jmp(size_, jmpSize, inner::LasIs); labelMgr_.addUndefinedLabel(label, jmp); } } @@ -1338,6 +1358,13 @@ private: } } + void opAddr(const Address &addr) + { + db(addr.getCode(), static_cast(addr.getSize())); + if (addr.getLabel()) { // [rip + Label] + putL_inner(*addr.getLabel(), true, addr.getDisp()); + } + } /* preCode is for SSSE3/SSE4 */ void opGen(const Operand& reg, const Operand& op, int code, int pref, bool isValid(const Operand&, const Operand&), int imm8 = NONE, int preCode = NONE) { @@ -1497,7 +1524,7 @@ private: rex(addr, st0); db(code); addr.updateRegField(ext); - db(addr.getCode(), static_cast(addr.getSize())); + opAddr(addr); } // use code1 if reg1 == st0 // use code2 if reg1 != st0 && reg2 == st0 @@ -1532,7 +1559,7 @@ private: if (p2->isMEM()) { const Address& addr = static_cast(*p2); addr.updateRegField(static_cast(r.getIdx())); - db(addr.getCode(), static_cast(addr.getSize())); + opAddr(addr); } else { db(getModRM(3, r.getIdx(), p2->getIdx())); } @@ -1792,13 +1819,15 @@ private: return bit / 8; } template - void putL_inner(T& label) + void putL_inner(T& label, bool relative = false, uint64 disp = 0) { - const int jmpSize = (int)sizeof(size_t); + const int jmpSize = relative ? 4 : (int)sizeof(size_t); if (isAutoGrow() && size_ + 16 >= maxSize_) growMemory(); size_t offset = 0; if (labelMgr_.getOffset(&offset, label)) { - if (isAutoGrow()) { + if (relative) { + db(inner::VerifyInInt32(offset + disp - size_ - jmpSize), jmpSize); + } else if (isAutoGrow()) { db(uint64(0), jmpSize); save(size_ - jmpSize, offset, jmpSize, inner::LaddTop); } else { @@ -1807,10 +1836,7 @@ private: return; } db(uint64(0), jmpSize); - JmpLabel jmp; - jmp.endOfJmp = size_; - jmp.jmpSize = jmpSize; - jmp.mode = isAutoGrow() ? inner::LaddTop : inner::Labs; + JmpLabel jmp(size_, jmpSize, (relative ? inner::LasIs : isAutoGrow() ? inner::LaddTop : inner::Labs), disp); labelMgr_.addUndefinedLabel(label, jmp); } public: diff --git a/src/cpu/mips3/x64/xbyak/xbyak_mnemonic.h b/src/cpu/mips3/x64/xbyak/xbyak_mnemonic.h index d460e4cef..2005ad070 100644 --- a/src/cpu/mips3/x64/xbyak/xbyak_mnemonic.h +++ b/src/cpu/mips3/x64/xbyak/xbyak_mnemonic.h @@ -1,4 +1,4 @@ -const char *getVersionString() const { return "4.71"; } +const char *getVersionString() const { return "4.81"; } void packssdw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x6B); } void packsswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x63); } void packuswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x67); } diff --git a/src/cpu/mips3/x64/xbyak/xbyak_util.h b/src/cpu/mips3/x64/xbyak/xbyak_util.h index 7f3e336ac..166f3e346 100644 --- a/src/cpu/mips3/x64/xbyak/xbyak_util.h +++ b/src/cpu/mips3/x64/xbyak/xbyak_util.h @@ -7,7 +7,7 @@ Xbyak::util::Cpu ; detect CPU @note this header is UNDER CONSTRUCTION! */ -#include "xbyak/xbyak.h" +#include "xbyak.h" #ifdef _MSC_VER #if (_MSC_VER < 1400) && defined(XBYAK32)