asmjit::Operand_ Struct Reference
Inheritance diagram for asmjit::Operand_:
asmjit::Operand asmjit::BaseMem asmjit::BaseReg asmjit::Imm asmjit::Label asmjit::arm::Mem asmjit::x86::Mem asmjit::arm::Reg asmjit::x86::Reg asmjit::arm::Gp asmjit::arm::Vec 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

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_::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.

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

Tests whether the operand specifies a size (i.e. the size is not zero).

bool Operand_::hasSize(uint32_t s) constconstexprconstexprnoexcept[2/2]◆ 

Tests whether the size of the operand matches size.

uint32_t Operand_::size() constconstexprconstexprnoexcept◆ 

Returns the size of the operand in bytes.

The value returned depends on the operand type:

  • None - Should always return zero size.
  • Reg - Should always return the size of the register. If the register size depends on architecture (like x86::CReg and x86::DReg) the size returned should be the greatest possible (so it should return 64-bit size in such case).
  • Mem - Size is optional and will be in most cases zero.
  • Imm - Should always return zero size.
  • Label - Should always return zero size.

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_::isReg(RegType type, uint32_t id) 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.

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.