mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-18 21:14:35 +03:00
Added a possibility to use RIP addressing.
This commit is contained in:
@@ -96,29 +96,33 @@ ASMJIT_ENUM(SizeDefs) {
|
|||||||
|
|
||||||
//! Type of memory operand.
|
//! Type of memory operand.
|
||||||
ASMJIT_ENUM(MemType) {
|
ASMJIT_ENUM(MemType) {
|
||||||
//! Memory operand is a combination of base register and optional index register
|
//! Memory operand is a combination of a base register, an optional index
|
||||||
//! and displacement.
|
//! register, and displacement.
|
||||||
//!
|
//!
|
||||||
//! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
|
//! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
|
||||||
//! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
|
//! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
|
||||||
//! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
|
//! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
|
||||||
kMemTypeBaseIndex = 0,
|
kMemTypeBaseIndex = 0,
|
||||||
|
|
||||||
//! Memory operand is a combination of variable's memory location,
|
//! Memory operand is a combination of variable's memory location, an
|
||||||
//! optional index register and displacement.
|
//! optional index register, and displacement.
|
||||||
//!
|
//!
|
||||||
//! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
|
//! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
|
||||||
//! types in the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
|
//! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
|
||||||
//! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
|
//! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
|
||||||
kMemTypeStackIndex = 1,
|
kMemTypeStackIndex = 1,
|
||||||
|
|
||||||
//! Memory operand refers to the memory location specified by a label.
|
|
||||||
kMemTypeLabel = 2,
|
|
||||||
//! Memory operand is an absolute memory location.
|
//! Memory operand is an absolute memory location.
|
||||||
//!
|
//!
|
||||||
//! Supported mostly by x86, truncated to a 32-bit value when running in
|
//! Supported mostly by x86, truncated to a 32-bit value when running in
|
||||||
//! 64-bit mode (x64).
|
//! 64-bit mode (x64).
|
||||||
kMemTypeAbsolute = 3
|
kMemTypeAbsolute = 2,
|
||||||
|
|
||||||
|
//! Memory operand refers to the memory location specified by a label.
|
||||||
|
kMemTypeLabel = 3,
|
||||||
|
|
||||||
|
//! Memory operand is an address specified by RIP.
|
||||||
|
kMemTypeRip = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -808,6 +808,15 @@ static void X86Assembler_dumpOperand(StringBuilder& sb, uint32_t arch, const Ope
|
|||||||
isAbsolute = true;
|
isAbsolute = true;
|
||||||
sb.appendUInt(static_cast<uint32_t>(m->getDisplacement()), 16);
|
sb.appendUInt(static_cast<uint32_t>(m->getDisplacement()), 16);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kMemTypeRip:
|
||||||
|
// [rip + displacement]
|
||||||
|
sb.appendString("rip", 3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sb.appendFormat("<invalid %d>", m->getMemType());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->hasIndex()) {
|
if (m->hasIndex()) {
|
||||||
@@ -3645,12 +3654,15 @@ _EmitSib:
|
|||||||
EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
|
EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rmMem->getMemType() == kMemTypeLabel) {
|
if (rmMem->getMemType() == kMemTypeAbsolute) {
|
||||||
|
// [Disp32].
|
||||||
|
EMIT_DWORD(static_cast<int32_t>(dispOffset));
|
||||||
|
}
|
||||||
|
else if (rmMem->getMemType() == kMemTypeLabel) {
|
||||||
// Relative->Absolute [x86 mode].
|
// Relative->Absolute [x86 mode].
|
||||||
label = self->getLabelData(rmMem->_vmem.base);
|
label = self->getLabelData(rmMem->_vmem.base);
|
||||||
relocId = self->_relocList.getLength();
|
relocId = self->_relocList.getLength();
|
||||||
|
|
||||||
{
|
|
||||||
RelocData rd;
|
RelocData rd;
|
||||||
rd.type = kRelocRelToAbs;
|
rd.type = kRelocRelToAbs;
|
||||||
rd.size = 4;
|
rd.size = 4;
|
||||||
@@ -3659,7 +3671,6 @@ _EmitSib:
|
|||||||
|
|
||||||
if (self->_relocList.append(rd) != kErrorOk)
|
if (self->_relocList.append(rd) != kErrorOk)
|
||||||
return self->setError(kErrorNoHeapMemory);
|
return self->setError(kErrorNoHeapMemory);
|
||||||
}
|
|
||||||
|
|
||||||
if (label->offset != -1) {
|
if (label->offset != -1) {
|
||||||
// Bound label.
|
// Bound label.
|
||||||
@@ -3674,12 +3685,39 @@ _EmitSib:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// [Disp32].
|
// RIP->Absolute [x86 mode].
|
||||||
EMIT_DWORD(static_cast<int32_t>(dispOffset));
|
relocId = self->_relocList.getLength();
|
||||||
|
|
||||||
|
RelocData rd;
|
||||||
|
rd.type = kRelocRelToAbs;
|
||||||
|
rd.size = 4;
|
||||||
|
rd.from = static_cast<Ptr>((uintptr_t)(cursor - self->_buffer));
|
||||||
|
rd.data = rd.from + static_cast<SignedPtr>(dispOffset);
|
||||||
|
|
||||||
|
if (self->_relocList.append(rd) != kErrorOk)
|
||||||
|
return self->setError(kErrorNoHeapMemory);
|
||||||
|
|
||||||
|
EMIT_DWORD(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (Arch === kArchX64) */ {
|
else /* if (Arch === kArchX64) */ {
|
||||||
if (rmMem->getMemType() == kMemTypeLabel) {
|
if (rmMem->getMemType() == kMemTypeAbsolute) {
|
||||||
|
EMIT_BYTE(x86EncodeMod(0, opReg, 4));
|
||||||
|
if (mIndex >= kInvalidReg) {
|
||||||
|
// [Disp32].
|
||||||
|
EMIT_BYTE(x86EncodeSib(0, 4, 5));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// [Disp32 + Index * Scale].
|
||||||
|
mIndex &= 0x7;
|
||||||
|
ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
|
||||||
|
|
||||||
|
uint32_t shift = rmMem->getShift();
|
||||||
|
EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
|
||||||
|
}
|
||||||
|
EMIT_DWORD(static_cast<int32_t>(dispOffset));
|
||||||
|
}
|
||||||
|
else if (rmMem->getMemType() == kMemTypeLabel) {
|
||||||
// [RIP + Disp32].
|
// [RIP + Disp32].
|
||||||
label = self->getLabelData(rmMem->_vmem.base);
|
label = self->getLabelData(rmMem->_vmem.base);
|
||||||
|
|
||||||
@@ -3703,20 +3741,13 @@ _EmitSib:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
EMIT_BYTE(x86EncodeMod(0, opReg, 4));
|
// [RIP + Disp32].
|
||||||
if (mIndex >= kInvalidReg) {
|
|
||||||
// [Disp32].
|
|
||||||
EMIT_BYTE(x86EncodeSib(0, 4, 5));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// [Disp32 + Index * Scale].
|
|
||||||
mIndex &= 0x7;
|
|
||||||
ASMJIT_ASSERT(mIndex != kX86RegIndexSp);
|
|
||||||
|
|
||||||
uint32_t shift = rmMem->getShift();
|
// Indexing is invalid.
|
||||||
EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
|
if (mIndex < kInvalidReg)
|
||||||
}
|
goto _IllegalDisp;
|
||||||
|
|
||||||
|
EMIT_BYTE(x86EncodeMod(0, opReg, 5));
|
||||||
EMIT_DWORD(static_cast<int32_t>(dispOffset));
|
EMIT_DWORD(static_cast<int32_t>(dispOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -422,6 +422,10 @@ struct ASMJIT_VCLASS X86Assembler : public Assembler {
|
|||||||
return x86::ptr(label, index, shift, disp, _regSize);
|
return x86::ptr(label, index, shift, disp, _regSize);
|
||||||
}
|
}
|
||||||
//! \overload
|
//! \overload
|
||||||
|
ASMJIT_INLINE X86Mem intptr_ptr(const X86RipReg& rip, int32_t disp = 0) const {
|
||||||
|
return x86::ptr(rip, disp, _regSize);
|
||||||
|
}
|
||||||
|
//! \overload
|
||||||
ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const {
|
ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const {
|
||||||
return x86::ptr_abs(pAbs, disp, _regSize);
|
return x86::ptr_abs(pAbs, disp, _regSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2083,6 +2083,10 @@ struct ASMJIT_VCLASS X86Compiler : public Compiler {
|
|||||||
return x86::ptr(label, index, shift, disp, _regSize);
|
return x86::ptr(label, index, shift, disp, _regSize);
|
||||||
}
|
}
|
||||||
//! \overload
|
//! \overload
|
||||||
|
ASMJIT_INLINE X86Mem intptr_ptr(const X86RipReg& rip, int32_t disp = 0) const {
|
||||||
|
return x86::ptr(rip, disp, _regSize);
|
||||||
|
}
|
||||||
|
//! \overload
|
||||||
ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const {
|
ASMJIT_INLINE X86Mem intptr_ptr_abs(Ptr pAbs, int32_t disp = 0) const {
|
||||||
return x86::ptr_abs(pAbs, disp, _regSize);
|
return x86::ptr_abs(pAbs, disp, _regSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1145,6 +1145,11 @@ struct X86Mem : public BaseMem {
|
|||||||
_vmem.displacement = disp;
|
_vmem.displacement = disp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASMJIT_INLINE X86Mem(const X86RipReg& rip, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
|
||||||
|
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeRip, 0, kInvalidValue);
|
||||||
|
_init_packed_d2_d3(kInvalidValue, disp);
|
||||||
|
}
|
||||||
|
|
||||||
ASMJIT_INLINE X86Mem(const X86GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
|
ASMJIT_INLINE X86Mem(const X86GpReg& base, int32_t disp, uint32_t size = 0) : BaseMem(NoInit) {
|
||||||
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
|
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
|
||||||
_getGpdFlags(base)
|
_getGpdFlags(base)
|
||||||
@@ -1870,6 +1875,7 @@ static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86XmmReg& index, ui
|
|||||||
static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
|
static ASMJIT_INLINE X86Mem ptr(const X86GpReg& base, const X86YmmReg& index, uint32_t shift = 0, int32_t disp = 0, uint32_t size = 0) {
|
||||||
return X86Mem(base, index, shift, disp, size);
|
return X86Mem(base, index, shift, disp, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Create `[label + disp]` memory operand with no/custom size information.
|
//! Create `[label + disp]` memory operand with no/custom size information.
|
||||||
static ASMJIT_INLINE X86Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) {
|
static ASMJIT_INLINE X86Mem ptr(const Label& label, int32_t disp = 0, uint32_t size = 0) {
|
||||||
return X86Mem(label, disp, size);
|
return X86Mem(label, disp, size);
|
||||||
@@ -1879,6 +1885,11 @@ static ASMJIT_INLINE X86Mem ptr(const Label& label, const X86GpReg& index, uint3
|
|||||||
return X86Mem(label, index, shift, disp, size); \
|
return X86Mem(label, index, shift, disp, size); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Create `[RIP + disp]` memory operand with no/custom size information.
|
||||||
|
static ASMJIT_INLINE X86Mem ptr(const X86RipReg& rip, int32_t disp = 0, uint32_t size = 0) {
|
||||||
|
return X86Mem(rip, disp, size);
|
||||||
|
}
|
||||||
|
|
||||||
//! Create `[pAbs + disp]` absolute memory operand with no/custom size information.
|
//! Create `[pAbs + disp]` absolute memory operand with no/custom size information.
|
||||||
ASMJIT_API X86Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0);
|
ASMJIT_API X86Mem ptr_abs(Ptr pAbs, int32_t disp = 0, uint32_t size = 0);
|
||||||
//! Create `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information.
|
//! Create `[pAbs + (index.reg << shift) + disp]` absolute memory operand with no/custom size information.
|
||||||
@@ -1910,6 +1921,10 @@ ASMJIT_API X86Mem ptr_abs(Ptr pAbs, const X86Reg& index, uint32_t shift = 0, int
|
|||||||
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) { \
|
static ASMJIT_INLINE X86Mem _Prefix_##_ptr(const Label& label, const X86GpReg& index, uint32_t shift, int32_t disp = 0) { \
|
||||||
return ptr(label, index, shift, disp, _Size_); \
|
return ptr(label, index, shift, disp, _Size_); \
|
||||||
} \
|
} \
|
||||||
|
/*! Create `[RIP + disp]` memory operand. */ \
|
||||||
|
static ASMJIT_INLINE X86Mem _Prefix_##ptr(const X86RipReg& rip, int32_t disp = 0) { \
|
||||||
|
return ptr(rip, disp, _Size_); \
|
||||||
|
} \
|
||||||
/*! Create `[pAbs + disp]` memory operand. */ \
|
/*! Create `[pAbs + disp]` memory operand. */ \
|
||||||
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \
|
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \
|
||||||
return ptr_abs(pAbs, disp, _Size_); \
|
return ptr_abs(pAbs, disp, _Size_); \
|
||||||
|
|||||||
Reference in New Issue
Block a user