asmjit::Operand_ Struct Reference
Inheritance diagram for asmjit::Operand_:
asmjit::Operand asmjit::BaseMem asmjit::BaseReg asmjit::BaseRegList asmjit::Imm asmjit::Label asmjit::arm::Mem asmjit::x86::Mem asmjit::arm::Reg asmjit::x86::Reg asmjit::RegListT< RegT > asmjit::a64::Gp asmjit::arm::BaseVec asmjit::x86::Bnd asmjit::x86::CReg asmjit::x86::DReg asmjit::x86::Gp asmjit::x86::KReg asmjit::x86::Mm asmjit::x86::Rip asmjit::x86::SReg asmjit::x86::St asmjit::x86::Tmm asmjit::x86::Vec

Base class representing an operand in AsmJit (non-default constructed version).

Contains no initialization code and can be used safely to define an array of operands that won't be initialized. This is a Operand base structure designed to be statically initialized, static const, or to be used by user code to define an array of operands without having them default initialized at construction time.

The key difference between Operand and Operand_ is:

Operand_ xArray[10]; // Not initialized, contains garbage.
Operand_ yArray[10] {}; // All operands initialized to none explicitly (zero initialized).
Operand yArray[10]; // All operands initialized to none implicitly (zero initialized).

Public Members

Members

Public Types

Constants
Types

Member Functions

Construction & Destruction
Overloaded Operators
Cast
Accessors
Accessors (X86 Specific)

Static Functions

Member Enumeration Documentation

Operand_::VirtIdConstants : uint32_tenum◆ 

Constants useful for VirtId <-> Index translation.

ConstantDescription
kVirtIdMin 

Minimum valid packed-id.

kVirtIdMax 

Maximum valid packed-id, excludes Globals::kInvalidId.

kVirtIdCount 

Count of valid packed-ids.

Member Function Documentation

bool Operand_::isVirtId(uint32_t id)staticnoexcept◆ 

Tests whether the given id is a valid virtual register id.

Since AsmJit supports both physical and virtual registers it must be able to distinguish between these two. The idea is that physical registers are always limited in size, so virtual identifiers start from kVirtIdMin and end at kVirtIdMax.

uint32_t Operand_::indexToVirtId(uint32_t id)staticnoexcept◆ 

Converts a real-id into a packed-id that can be stored in Operand.

uint32_t Operand_::virtIdToIndex(uint32_t id)staticnoexcept◆ 

Converts a packed-id back to real-id.

void Operand_::copyFrom(const Operand_& other)noexcept◆ 

Initializes the operand from other operand (used by operator overloads).

void Operand_::reset()noexcept◆ 

Resets the Operand to none.

None operand is defined the following way:

  • Its signature is zero (OperandType::kNone, and the rest zero as well).
  • Its id is 0.
  • The reserved8_4 field is set to 0.
  • The reserved12_4 field is set to zero.

In other words, reset operands have all members set to zero. Reset operand must match the Operand state right after its construction. Alternatively, if you have an array of operands, you can simply use memset().

using namespace asmjit;
assert(a == b);
b = x86::eax;
assert(a != b);
b.reset();
assert(a == b);
memset(&b, 0, sizeof(Operand));
assert(a == b);

bool Operand_::operator==(const Operand_& other) constconstexprconstexprnoexcept◆ 

Tests whether this operand is the same as other.

bool Operand_::operator!=(const Operand_& other) constconstexprconstexprnoexcept◆ 

Tests whether this operand is not the same as other.

template<typename T>
T& Operand_::as()noexcept[1/2]◆ 

Casts this operand to T type.

template<typename T>
const T& Operand_::as() constnoexcept[2/2]◆ 

Casts this operand to T type (const).

bool Operand_::hasSignature(const Operand_& other) constconstexprconstexprnoexcept[1/2]◆ 

Tests whether the operand's signature matches the signature of the other operand.

bool Operand_::hasSignature(const Signature& other) constconstexprconstexprnoexcept[2/2]◆ 

Tests whether the operand's signature matches the given signature sign.

Signature Operand_::signature() constconstexprconstexprnoexcept◆ 

Returns operand signature as unsigned 32-bit integer.

Signature is first 4 bytes of the operand data. It's used mostly for operand checking as it's much faster to check packed 4 bytes at once than having to check these bytes individually.

void Operand_::setSignature(const Signature& signature)noexcept◆ 

Sets the operand signature, see signature().

Note
Improper use of setSignature() can lead to hard-to-debug errors.

OperandType Operand_::opType() constconstexprconstexprnoexcept◆ 

Returns the type of the operand, see OpType.

bool Operand_::isNone() constconstexprconstexprnoexcept◆ 

Tests whether the operand is none (OperandType::kNone).

bool Operand_::isReg() constconstexprconstexprnoexcept[1/3]◆ 

Tests whether the operand is a register (OperandType::kReg).

bool Operand_::isRegList() constconstexprconstexprnoexcept[1/2]◆ 

Tests whether the operand is a register-list.

Note
Register-list is currently only used by 32-bit ARM architecture.

bool Operand_::isMem() constconstexprconstexprnoexcept◆ 

Tests whether the operand is a memory location (OperandType::kMem).

bool Operand_::isImm() constconstexprconstexprnoexcept◆ 

Tests whether the operand is an immediate (OperandType::kImm).

bool Operand_::isLabel() constconstexprconstexprnoexcept◆ 

Tests whether the operand is a label (OperandType::kLabel).

bool Operand_::isPhysReg() constconstexprconstexprnoexcept◆ 

Tests whether the operand is a physical register.

bool Operand_::isVirtReg() constconstexprconstexprnoexcept◆ 

Tests whether the operand is a virtual register.

uint32_t Operand_::id() constconstexprconstexprnoexcept◆ 

Returns the operand id.

The value returned should be interpreted accordingly to the operand type:

  • None - Should be 0.
  • Reg - Physical or virtual register id.
  • Mem - Multiple meanings - BASE address (register or label id), or high value of a 64-bit absolute address.
  • Imm - Should be 0.
  • Label - Label id if it was created by using newLabel() or Globals::kInvalidId if the label is invalid or not initialized.

bool Operand_::equals(const Operand_& other) constconstexprconstexprnoexcept◆ 

Tests whether the operand is 100% equal to other operand.

Note
This basically performs a binary comparison, if aby bit is different the operands are not equal.

bool Operand_::isReg(RegType type) constconstexprconstexprnoexcept[2/3]◆ 

Tests whether the operand is a register matching the given register type.

bool Operand_::isRegList(RegType type) constconstexprconstexprnoexcept[2/2]◆ 

Tests whether the operand is a register matching the given register type.

bool Operand_::isReg(RegType type, uint32_t regId) constconstexprconstexprnoexcept[3/3]◆ 

Tests whether the operand is register and of register type and id.

bool Operand_::isRegOrMem() constconstexprconstexprnoexcept◆ 

Tests whether the operand is a register or memory.

Note
This is useful on X86 and X86_64 architectures as many instructions support Reg/Mem operand combination. So if the user code works with just Operand, it's possible to check whether the operand is either a register or memory location with a single check.

bool Operand_::isRegOrRegListOrMem() constconstexprconstexprnoexcept◆ 

Tests whether the operand is a register, register-list, or memory.

Note
This is useful on 32-bit ARM architecture to check whether an operand references a register. It can be used in other architectures too, but it would work identically to isRegOrMem() as other architectures don't provide register lists.

uint32_t Operand_::x86RmSize() constconstexprconstexprnoexcept◆ 

Returns a size of a register or an X86 memory operand.

At the moment only X86 and X86_64 memory operands have a size - other memory operands can use bits that represent size as an additional payload. This means that memory size is architecture specific and should be accessed via x86::Mem::size(). Sometimes when the user knows that the operand is either a register or memory operand this function can be helpful as it avoids casting.

Member Data Documentation

Signature Operand_::_signature◆ 

Provides operand type and additional payload.

uint32_t Operand_::_baseId◆ 

Either base id as used by memory operand or any id as used by others.

uint32_t Operand_::_data[2]◆ 

Data specific to the operand type.

The reason we don't use union is that we have constexpr constructors that construct operands and other constexpr functions that return whether another Operand or something else. These cannot generally work with unions so we also cannot use union if we want to be standard compliant.