Machine Code Generation for C++
Contains no initialization code and can be used safely to define an array of operands that won't be initialized. This is an
Operand compatible data structure designed to be statically initialized, static const, or to be used by the user to define an array of operands without having them default initialized.
The key difference between
Label tag is used as a sub-type, forming a unique signature across all operand types as 0x1 is never associated with any register type.
This means that a memory operand's BASE register can be constructed from virtually any operand (register vs. label) by just assigning its type (register type or label-tag) and operand id.
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
Converts a real-id into a packed-id that can be stored in Operand.
Converts a packed-id back to real-id.
Initializes the operand from
other operand (used by operator overloads).
Operand to none.
None operand is defined the following way:
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
Tests whether this operand is the same as
Tests whether this operand is not the same as
Casts this operand to
Casts this operand to
T type (const).
Tests whether the operand's signature matches the given signature
Tests whether the operand's signature matches the signature of the
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 4 bytes at once than having to check these bytes individually.
Sets the operand signature, see
setSignature()can lead to hard-to-debug errors.
Returns the type of the operand, see
Tests whether the operand is none (
Tests whether the operand is a register (
Tests whether the operand is a memory location (
Tests whether the operand is an immediate (
Tests whether the operand is a label (
Tests whether the operand is a physical register.
Tests whether the operand is a virtual register.
Tests whether the operand specifies a size (i.e. the size is not zero).
Tests whether the size of the operand matches
Returns the size of the operand in bytes.
The value returned depends on the operand type:
x86::DReg) the size returned should be the greatest possible (so it should return 64-bit size in such case).
Returns the operand id.
The value returned should be interpreted accordingly to the operand type:
Globals::kInvalidIdif the label is invalid or not initialized.
Tests whether the operand is 100% equal to
Tests whether the operand is a register matching
Tests whether the operand is register and of
Tests whether the operand is a register or memory.
Operand's signature that provides operand type and additional information.
Either base id as used by memory operand or any id as used by others.
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 wither another Operand or something else. These cannot generally work with unions so we also cannot use
union if we want to be standard compliant.