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.
|
||||
ASMJIT_ENUM(MemType) {
|
||||
//! Memory operand is a combination of base register and optional index register
|
||||
//! and displacement.
|
||||
//! Memory operand is a combination of a base register, an optional index
|
||||
//! register, and displacement.
|
||||
//!
|
||||
//! The `Assembler` interprets `kMemTypeBaseIndex` and `kMemTypeStackIndex`
|
||||
//! types the same way, but `Compiler` interprets `kMemTypeBaseIndex` as
|
||||
//! `[base + index]` and `kMemTypeStackIndex` as `[stack(base) + index]`.
|
||||
kMemTypeBaseIndex = 0,
|
||||
|
||||
//! Memory operand is a combination of variable's memory location,
|
||||
//! optional index register and displacement.
|
||||
//! Memory operand is a combination of variable's memory location, an
|
||||
//! optional index register, and displacement.
|
||||
//!
|
||||
//! 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]`.
|
||||
kMemTypeStackIndex = 1,
|
||||
|
||||
//! Memory operand refers to the memory location specified by a label.
|
||||
kMemTypeLabel = 2,
|
||||
//! Memory operand is an absolute memory location.
|
||||
//!
|
||||
//! Supported mostly by x86, truncated to a 32-bit value when running in
|
||||
//! 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;
|
||||
sb.appendUInt(static_cast<uint32_t>(m->getDisplacement()), 16);
|
||||
break;
|
||||
|
||||
case kMemTypeRip:
|
||||
// [rip + displacement]
|
||||
sb.appendString("rip", 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
sb.appendFormat("<invalid %d>", m->getMemType());
|
||||
break;
|
||||
}
|
||||
|
||||
if (m->hasIndex()) {
|
||||
@@ -3645,12 +3654,15 @@ _EmitSib:
|
||||
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].
|
||||
label = self->getLabelData(rmMem->_vmem.base);
|
||||
relocId = self->_relocList.getLength();
|
||||
|
||||
{
|
||||
RelocData rd;
|
||||
rd.type = kRelocRelToAbs;
|
||||
rd.size = 4;
|
||||
@@ -3659,7 +3671,6 @@ _EmitSib:
|
||||
|
||||
if (self->_relocList.append(rd) != kErrorOk)
|
||||
return self->setError(kErrorNoHeapMemory);
|
||||
}
|
||||
|
||||
if (label->offset != -1) {
|
||||
// Bound label.
|
||||
@@ -3674,12 +3685,39 @@ _EmitSib:
|
||||
}
|
||||
}
|
||||
else {
|
||||
// [Disp32].
|
||||
EMIT_DWORD(static_cast<int32_t>(dispOffset));
|
||||
// RIP->Absolute [x86 mode].
|
||||
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) */ {
|
||||
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].
|
||||
label = self->getLabelData(rmMem->_vmem.base);
|
||||
|
||||
@@ -3703,20 +3741,13 @@ _EmitSib:
|
||||
}
|
||||
}
|
||||
else {
|
||||
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);
|
||||
// [RIP + Disp32].
|
||||
|
||||
uint32_t shift = rmMem->getShift();
|
||||
EMIT_BYTE(x86EncodeSib(shift, mIndex, 5));
|
||||
}
|
||||
// Indexing is invalid.
|
||||
if (mIndex < kInvalidReg)
|
||||
goto _IllegalDisp;
|
||||
|
||||
EMIT_BYTE(x86EncodeMod(0, opReg, 5));
|
||||
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);
|
||||
}
|
||||
//! \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 {
|
||||
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);
|
||||
}
|
||||
//! \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 {
|
||||
return x86::ptr_abs(pAbs, disp, _regSize);
|
||||
}
|
||||
|
||||
@@ -1145,6 +1145,11 @@ struct X86Mem : public BaseMem {
|
||||
_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) {
|
||||
_init_packed_op_sz_b0_b1_id(kOperandTypeMem, size, kMemTypeBaseIndex,
|
||||
_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) {
|
||||
return X86Mem(base, index, shift, disp, size);
|
||||
}
|
||||
|
||||
//! 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) {
|
||||
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); \
|
||||
}
|
||||
|
||||
//! 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.
|
||||
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.
|
||||
@@ -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) { \
|
||||
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. */ \
|
||||
static ASMJIT_INLINE X86Mem _Prefix_##_ptr##_abs(Ptr pAbs, int32_t disp = 0) { \
|
||||
return ptr_abs(pAbs, disp, _Size_); \
|
||||
|
||||
Reference in New Issue
Block a user