mirror of
https://github.com/herumi/xbyak
synced 2024-11-20 16:06:14 -07:00
under refactoring AddressFrame
This commit is contained in:
parent
4131875510
commit
0b788ecf58
8 changed files with 104 additions and 91 deletions
16
test/Makefile.win
Normal file
16
test/Makefile.win
Normal file
|
@ -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)
|
|
@ -8,9 +8,8 @@ if /i "%1"=="64" (
|
||||||
set OPT3=win32
|
set OPT3=win32
|
||||||
)
|
)
|
||||||
|
|
||||||
pushd ..\gen
|
call set_opt
|
||||||
call update
|
bmake -f Makefile.win all
|
||||||
popd
|
|
||||||
|
|
||||||
if /i "%1"=="64" (
|
if /i "%1"=="64" (
|
||||||
call :sub 1
|
call :sub 1
|
||||||
|
|
|
@ -22,9 +22,8 @@ if /i "%1"=="Y" (
|
||||||
set OPT2=-DXBYAK32
|
set OPT2=-DXBYAK32
|
||||||
set OPT3=win32
|
set OPT3=win32
|
||||||
)
|
)
|
||||||
pushd ..\gen
|
call set_opt
|
||||||
call update
|
bmake -f Makefile.win all
|
||||||
popd
|
|
||||||
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX
|
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX
|
||||||
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX
|
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX
|
||||||
make_nm > a.asm
|
make_nm > a.asm
|
||||||
|
|
|
@ -11,9 +11,8 @@ if /i "%1"=="64" (
|
||||||
set OPT2=-DXBYAK32
|
set OPT2=-DXBYAK32
|
||||||
set OPT3=win32
|
set OPT3=win32
|
||||||
)
|
)
|
||||||
pushd ..\gen
|
call set_opt
|
||||||
call update
|
bmake -f Makefile.win all
|
||||||
popd
|
|
||||||
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
|
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
|
||||||
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
|
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs /DUSE_AVX512
|
||||||
make_nm > a.asm
|
make_nm > a.asm
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
pushd ..\gen
|
call set_opt
|
||||||
call update
|
bmake -f Makefile.win all
|
||||||
popd
|
|
||||||
cl -I../ -I./ -DXBYAK_TEST jmp.cpp %OPT% /Od /Zi
|
cl -I../ -I./ -DXBYAK_TEST jmp.cpp %OPT% /Od /Zi
|
||||||
jmp
|
jmp
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
pushd ..\gen
|
call set_opt
|
||||||
call update
|
bmake -f Makefile.win all
|
||||||
popd
|
|
||||||
cl -I../ -I./ -DXBYAK_TEST misc.cpp %OPT% /Od /Zi
|
cl -I../ -I./ -DXBYAK_TEST misc.cpp %OPT% /Od /Zi
|
||||||
misc
|
misc
|
||||||
|
|
|
@ -22,9 +22,8 @@ if /i "%1"=="Y" (
|
||||||
set OPT2=-DXBYAK32
|
set OPT2=-DXBYAK32
|
||||||
set OPT3=win32
|
set OPT3=win32
|
||||||
)
|
)
|
||||||
pushd ..\gen
|
call set_opt
|
||||||
call update
|
bmake -f Makefile.win all
|
||||||
popd
|
|
||||||
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs
|
echo cl -I../ make_nm.cpp %OPT% %OPT2% /EHs
|
||||||
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs
|
cl -I../ make_nm.cpp %OPT% %OPT2% /EHs
|
||||||
make_nm > a.asm
|
make_nm > a.asm
|
||||||
|
|
149
xbyak/xbyak.h
149
xbyak/xbyak.h
|
@ -324,23 +324,21 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Operand {
|
class Operand {
|
||||||
private:
|
static const uint8 EXT8BIT = 0x80;
|
||||||
static const int EXT8BIT = 0x80;
|
uint8 idx_; // 0..31, EXT8BIT = 1 if spl/bpl/sil/dil
|
||||||
unsigned int idx_:8; // 0..31, MSB = 1 if spl/bpl/sil/dil
|
uint8 kind_;
|
||||||
unsigned int kind_:10;
|
uint16 bit_;
|
||||||
unsigned int bit_:14;
|
|
||||||
public:
|
public:
|
||||||
enum Kind {
|
enum Kind {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
MEM = 1 << 1,
|
MEM = 1 << 0,
|
||||||
IMM = 1 << 2,
|
REG = 1 << 1,
|
||||||
REG = 1 << 3,
|
MMX = 1 << 2,
|
||||||
MMX = 1 << 4,
|
FPU = 1 << 3,
|
||||||
XMM = 1 << 5,
|
XMM = 1 << 4,
|
||||||
FPU = 1 << 6,
|
YMM = 1 << 5,
|
||||||
YMM = 1 << 7,
|
ZMM = 1 << 6,
|
||||||
ZMM = 1 << 8,
|
OPMASK = 1 << 7
|
||||||
OPMASK = 1 << 9
|
|
||||||
};
|
};
|
||||||
enum Code {
|
enum Code {
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
|
@ -357,13 +355,13 @@ public:
|
||||||
Operand() : idx_(0), kind_(0), bit_(0) { }
|
Operand() : idx_(0), kind_(0), bit_(0) { }
|
||||||
Operand(int idx, Kind kind, int bit, bool ext8bit = 0)
|
Operand(int idx, Kind kind, int bit, bool ext8bit = 0)
|
||||||
: idx_(static_cast<uint8>(idx | (ext8bit ? EXT8BIT : 0)))
|
: idx_(static_cast<uint8>(idx | (ext8bit ? EXT8BIT : 0)))
|
||||||
, kind_(kind)
|
, kind_(static_cast<uint8>(kind))
|
||||||
, bit_(bit)
|
, bit_(static_cast<uint16>(bit))
|
||||||
{
|
{
|
||||||
assert((bit_ & (bit_ - 1)) == 0); // bit must be power of two
|
assert((bit_ & (bit_ - 1)) == 0); // bit must be power of two
|
||||||
}
|
}
|
||||||
Kind getKind() const { return static_cast<Kind>(kind_); }
|
Kind getKind() const { return static_cast<Kind>(kind_); }
|
||||||
int getIdx() const { return idx_ & 31; }
|
int getIdx() const { return idx_ & (EXT8BIT - 1); }
|
||||||
bool isNone() const { return kind_ == 0; }
|
bool isNone() const { return kind_ == 0; }
|
||||||
bool isMMX() const { return is(MMX); }
|
bool isMMX() const { return is(MMX); }
|
||||||
bool isXMM() const { return is(XMM); }
|
bool isXMM() const { return is(XMM); }
|
||||||
|
@ -428,7 +426,7 @@ public:
|
||||||
}
|
}
|
||||||
throw Error(ERR_INTERNAL);
|
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;
|
||||||
bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
|
bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
|
||||||
};
|
};
|
||||||
|
@ -574,32 +572,30 @@ public:
|
||||||
|
|
||||||
class RegExp {
|
class RegExp {
|
||||||
public:
|
public:
|
||||||
struct SReg {
|
#ifdef XBYAK64
|
||||||
uint16 bit:10; // 32/64/128/256/512 none if 0
|
enum { i32e = 32 | 64 };
|
||||||
uint16 idx:6;
|
#else
|
||||||
SReg() : bit(0), idx(0) { }
|
enum { i32e = 32 };
|
||||||
void set(const Reg& r) { this->bit = uint16(r.getBit()); this->idx = uint16(r.getIdx()); }
|
#endif
|
||||||
bool operator==(const SReg& rhs) const { return bit == rhs.bit && idx == rhs.idx; }
|
|
||||||
};
|
|
||||||
RegExp(size_t disp = 0) : disp_(disp), scale_(0) { }
|
RegExp(size_t disp = 0) : disp_(disp), scale_(0) { }
|
||||||
RegExp(const Reg& r, int scale = 1)
|
RegExp(const Reg& r, int scale = 1)
|
||||||
: disp_(0)
|
: disp_(0)
|
||||||
, scale_(scale)
|
, 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 (scale != 1 && scale != 2 && scale != 4 && scale != 8) throw Error(ERR_BAD_SCALE);
|
||||||
if (r.getBit() >= 128 || scale != 1) { // xmm/ymm is always index
|
if (r.getBit() >= 128 || scale != 1) { // xmm/ymm is always index
|
||||||
index_.set(r);
|
index_ = r;
|
||||||
} else {
|
} else {
|
||||||
base_.set(r);
|
base_ = r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool isVsib() const { return 128 <= index_.bit && index_.bit <= 256; }
|
bool isVsib() const { return index_.isBit(128|256); }
|
||||||
bool isYMM() const { return index_.bit == 256; }
|
bool isYMM() const { return index_.isBit(256); }
|
||||||
RegExp optimize() const // select smaller size
|
RegExp optimize() const // select smaller size
|
||||||
{
|
{
|
||||||
// [reg * 2] => [reg + reg]
|
// [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;
|
RegExp ret = *this;
|
||||||
ret.base_ = index_;
|
ret.base_ = index_;
|
||||||
ret.scale_ = 1;
|
ret.scale_ = 1;
|
||||||
|
@ -611,43 +607,43 @@ public:
|
||||||
{
|
{
|
||||||
return base_ == rhs.base_ && index_ == rhs.index_ && disp_ == rhs.disp_;
|
return base_ == rhs.base_ && index_ == rhs.index_ && disp_ == rhs.disp_;
|
||||||
}
|
}
|
||||||
const SReg& getBase() const { return base_; }
|
const Operand& getBase() const { return base_; }
|
||||||
const SReg& getIndex() const { return index_; }
|
const Operand& getIndex() const { return index_; }
|
||||||
int getScale() const { return scale_; }
|
int getScale() const { return scale_; }
|
||||||
uint32 getDisp() const { return uint32(disp_); }
|
uint32 getDisp() const { return uint32(disp_); }
|
||||||
void verify() const
|
void verify() const
|
||||||
{
|
{
|
||||||
if (base_.bit >= 128) throw Error(ERR_BAD_SIZE_OF_REGISTER);
|
if (base_.getBit() >= 128) throw Error(ERR_BAD_SIZE_OF_REGISTER);
|
||||||
if (index_.bit && index_.bit <= 64) {
|
if (index_.getBit() && index_.getBit() <= 64) {
|
||||||
if (index_.idx == Operand::ESP) throw Error(ERR_ESP_CANT_BE_INDEX);
|
if (index_.getIdx() == 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() && 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& a, const RegExp& b);
|
||||||
friend RegExp operator-(const RegExp& e, size_t disp);
|
friend RegExp operator-(const RegExp& e, size_t disp);
|
||||||
|
private:
|
||||||
/*
|
/*
|
||||||
[base_ + index_ * scale_ + disp_]
|
[base_ + index_ * scale_ + disp_]
|
||||||
base : Reg32e, index : Reg32e(w/o esp), Xmm, Ymm
|
base : Reg32e, index : Reg32e(w/o esp), Xmm, Ymm
|
||||||
*/
|
*/
|
||||||
size_t disp_;
|
size_t disp_;
|
||||||
int scale_;
|
int scale_;
|
||||||
SReg base_;
|
Operand base_;
|
||||||
SReg index_;
|
Operand index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RegExp operator+(const RegExp& a, const RegExp& b)
|
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;
|
RegExp ret = a;
|
||||||
if (!ret.index_.bit) { ret.index_ = b.index_; ret.scale_ = b.scale_; }
|
if (!ret.index_.getBit()) { ret.index_ = b.index_; ret.scale_ = b.scale_; }
|
||||||
if (b.base_.bit) {
|
if (b.base_.getBit()) {
|
||||||
if (ret.base_.bit) {
|
if (ret.base_.getBit()) {
|
||||||
if (ret.index_.bit) throw Error(ERR_BAD_ADDRESSING);
|
if (ret.index_.getBit()) throw Error(ERR_BAD_ADDRESSING);
|
||||||
// base + base => base + index * 1
|
// base + base => base + index * 1
|
||||||
ret.index_ = b.base_;
|
ret.index_ = b.base_;
|
||||||
// [reg + esp] => [esp + reg]
|
// [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;
|
ret.scale_ = 1;
|
||||||
} else {
|
} else {
|
||||||
ret.base_ = b.base_;
|
ret.base_ = b.base_;
|
||||||
|
@ -877,10 +873,10 @@ class Address : public Operand {
|
||||||
bool is64bitDisp_;
|
bool is64bitDisp_;
|
||||||
bool is32bit_;
|
bool is32bit_;
|
||||||
mutable bool isVsib_;
|
mutable bool isVsib_;
|
||||||
bool isYMM_;
|
RegExp e_;
|
||||||
void verify() const { if (isVsib_) throw Error(ERR_BAD_VSIB_ADDRESSING); }
|
void verify() const { if (isVsib_) throw Error(ERR_BAD_VSIB_ADDRESSING); }
|
||||||
public:
|
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)
|
: Operand(0, MEM, sizeBit)
|
||||||
, size_(0)
|
, size_(0)
|
||||||
, rex_(0)
|
, rex_(0)
|
||||||
|
@ -889,8 +885,8 @@ public:
|
||||||
, isOnlyDisp_(isOnlyDisp)
|
, isOnlyDisp_(isOnlyDisp)
|
||||||
, is64bitDisp_(is64bitDisp)
|
, is64bitDisp_(is64bitDisp)
|
||||||
, is32bit_(is32bit)
|
, is32bit_(is32bit)
|
||||||
, isVsib_(isVsib)
|
, isVsib_(e.isVsib())
|
||||||
, isYMM_(isYMM)
|
, e_(e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void db(int code)
|
void db(int code)
|
||||||
|
@ -907,7 +903,7 @@ public:
|
||||||
}
|
}
|
||||||
void setVsib(bool isVsib) const { isVsib_ = isVsib; }
|
void setVsib(bool isVsib) const { isVsib_ = isVsib; }
|
||||||
bool isVsib() const { return isVsib_; }
|
bool isVsib() const { return isVsib_; }
|
||||||
bool isYMM() const { return isYMM_; }
|
bool isYMM() const { return e_.isYMM(); }
|
||||||
bool is32bit() const { verify(); return is32bit_; }
|
bool is32bit() const { verify(); return is32bit_; }
|
||||||
bool isOnlyDisp() const { verify(); return isOnlyDisp_; } // for mov eax
|
bool isOnlyDisp() const { verify(); return isOnlyDisp_; } // for mov eax
|
||||||
size_t getDisp() const { verify(); return disp_; }
|
size_t getDisp() const { verify(); return disp_; }
|
||||||
|
@ -919,7 +915,7 @@ public:
|
||||||
bool operator==(const Address& rhs) const
|
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_
|
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); }
|
bool operator!=(const Address& rhs) const { return !operator==(rhs); }
|
||||||
};
|
};
|
||||||
|
@ -927,56 +923,63 @@ public:
|
||||||
inline bool Operand::operator==(const Operand& rhs) const
|
inline bool Operand::operator==(const Operand& rhs) const
|
||||||
{
|
{
|
||||||
if (isMEM() && rhs.isMEM()) return static_cast<const Address&>(*this) == static_cast<const Address&>(rhs);
|
if (isMEM() && rhs.isMEM()) return static_cast<const Address&>(*this) == static_cast<const Address&>(rhs);
|
||||||
return isSameNotInherited(rhs);
|
return isEqualIfNotInherited(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddressFrame {
|
class AddressFrame {
|
||||||
private:
|
private:
|
||||||
void operator=(const AddressFrame&);
|
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 int baseIdx = base.getIdx();
|
||||||
const bool isVsib = e.isVsib();
|
const int baseBit = base.getBit();
|
||||||
const bool isYMM = e.isYMM();
|
const int indexBit = index.getBit();
|
||||||
const RegExp::SReg& base = e.getBase();
|
const int indexIdx = index.getIdx();
|
||||||
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);
|
|
||||||
enum {
|
enum {
|
||||||
mod00 = 0, mod01 = 1, mod10 = 2
|
mod00 = 0, mod01 = 1, mod10 = 2
|
||||||
};
|
};
|
||||||
int mod;
|
int mod;
|
||||||
if (!base.bit || ((base.idx & 7) != Operand::EBP && disp == 0)) {
|
if (!baseBit || ((baseIdx & 7) != Operand::EBP && disp == 0)) {
|
||||||
mod = mod00;
|
mod = mod00;
|
||||||
} else if (inner::IsInDisp8(disp)) {
|
} else if (inner::IsInDisp8(disp)) {
|
||||||
mod = mod01;
|
mod = mod01;
|
||||||
} else {
|
} else {
|
||||||
mod = mod10;
|
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] */
|
/* 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
|
#ifdef XBYAK64
|
||||||
if (!base.bit && !index.bit) hasSIB = true;
|
if (!baseBit && !indexBit) hasSIB = true;
|
||||||
#endif
|
#endif
|
||||||
if (hasSIB) {
|
if (hasSIB) {
|
||||||
frame.db((mod << 6) | Operand::ESP);
|
frame.db((mod << 6) | Operand::ESP);
|
||||||
/* SIB = [2:3:3] = [SS:index:base(=rm)] */
|
/* SIB = [2:3:3] = [SS:index:base(=rm)] */
|
||||||
const int indexIdx = index.bit ? (index.idx & 7) : Operand::ESP;
|
const int newIndexIdx = indexBit ? (indexIdx & 7) : Operand::ESP;
|
||||||
const int scale = e.getScale();
|
|
||||||
const int ss = (scale == 8) ? 3 : (scale == 4) ? 2 : (scale == 2) ? 1 : 0;
|
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 {
|
} else {
|
||||||
frame.db((mod << 6) | baseIdx);
|
frame.db((mod << 6) | newBaseIdx);
|
||||||
}
|
}
|
||||||
if (mod == mod01) {
|
if (mod == mod01) {
|
||||||
frame.db(disp);
|
frame.db(disp);
|
||||||
} else if (mod == mod10 || (mod == mod00 && !base.bit)) {
|
} else if (mod == mod10 || (mod == mod00 && !baseBit)) {
|
||||||
frame.dd(disp);
|
frame.dd(disp);
|
||||||
}
|
}
|
||||||
int rex = ((index.idx >> 3) << 1) | (base.idx >> 3);
|
int rex = ((indexIdx >> 3) << 1) | (baseIdx >> 3);
|
||||||
if (rex) rex |= 0x40;
|
if (rex) rex |= 0x40;
|
||||||
frame.setRex(uint8(rex));
|
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;
|
return frame;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
@ -994,11 +997,11 @@ public:
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
Address operator[](uint64 disp) const
|
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 operator[](const RegRip& addr) const
|
||||||
{
|
{
|
||||||
Address frame(bit_, true, addr.disp_, false);
|
Address frame(RegExp(), bit_, true, addr.disp_, false);
|
||||||
frame.db(0x05);
|
frame.db(0x05);
|
||||||
if (addr.label_) {
|
if (addr.label_) {
|
||||||
frame.setLabel(addr.label_);
|
frame.setLabel(addr.label_);
|
||||||
|
|
Loading…
Reference in a new issue