asmjit::BaseEmitter Class Referenceabstract

Provides a base foundation to emit code - specialized by Assembler and BaseBuilder.

Public Members

Public Types

Member Functions

Construction & Destruction
Cast
Emitter Type & Flags
Target Information
Initialization & Finalization
Logging
Error Handling
Encoding Options
Validation Options
Instruction Options
Sections
Labels
Emit
Emit Utilities
Align
Embed
Comment
Events

Member Enumeration Documentation

BaseEmitter::EmitterType : uint32_tenum

Emitter type.

ConstantDescription
kTypeNone 

Unknown or uninitialized.

kTypeAssembler 

Emitter inherits from BaseAssembler.

kTypeBuilder 

Emitter inherits from BaseBuilder.

kTypeCompiler 

Emitter inherits from BaseCompiler.

kTypeCount 

Count of emitter types.

BaseEmitter::EmitterFlags : uint32_tenum

Emitter flags.

ConstantDescription
kFlagOwnLogger 

The emitter has its own Logger (not propagated from CodeHolder).

kFlagOwnErrorHandler 

The emitter has its own ErrorHandler (not propagated from CodeHolder).

kFlagFinalized 

The emitter was finalized.

kFlagDestroyed 

The emitter was destroyed.

BaseEmitter::EncodingOptions : uint32_tenum

Encoding options.

ConstantDescription
kEncodingOptionOptimizeForSize 

Emit instructions that are optimized for size, if possible.

Default: false.

X86 Specific
------------

When this option is set it the assembler will try to fix instructions
if possible into operation equivalent instructions that take less bytes
by taking advantage of implicit zero extension. For example instruction
like `mov r64, imm` and `and r64, imm` can be translated to `mov r32, imm`
and `and r32, imm` when the immediate constant is lesser than `2^31`. 
kEncodingOptionOptimizedAlign 

Emit optimized code-alignment sequences.

Default: false.

X86 Specific
------------

Default align sequence used by X86 architecture is one-byte (0x90)
opcode that is often shown by disassemblers as NOP. However there are
more optimized align sequences for 2-11 bytes that may execute faster
on certain CPUs. If this feature is enabled AsmJit will generate
specialized sequences for alignment between 2 to 11 bytes. 
kEncodingOptionPredictedJumps 

Emit jump-prediction hints.

Default: false.

X86 Specific
------------

Jump prediction is usually based on the direction of the jump. If the
jump is backward it is usually predicted as taken; and if the jump is
forward it is usually predicted as not-taken. The reason is that loops
generally use backward jumps and conditions usually use forward jumps.
However this behavior can be overridden by using instruction prefixes.
If this option is enabled these hints will be emitted.

This feature is disabled by default, because the only processor that
used to take into consideration prediction hints was P4. Newer processors
implement heuristics for branch prediction and ignore static hints. This
means that this feature can be only used for annotation purposes. 

BaseEmitter::ValidationOptions : uint32_tenum

Validation options are used to tell emitters to perform strict validation of instructions passed to emit().

BaseAssembler implementation perform by default only basic checks that are necessary to identify all variations of an instruction so the correct encoding can be selected. This is fine for production-ready code as the assembler doesn't have to perform checks that would slow it down. However, sometimes these checks are beneficial especially when the project that uses AsmJit is in a development phase, in which mistakes happen often. To make the experience of using AsmJit seamless it offers validation features that can be controlled by ValidationOptions.

ConstantDescription
kValidationOptionAssembler 

Perform strict validation in BaseAssembler::emit() implementations.

This flag ensures that each instruction is checked before it's encoded
into a binary representation. This flag is only relevant for \ref
BaseAssembler implementations, but can be set in any other emitter type,
in that case if that emitter needs to create an assembler on its own,
for the purpose of \ref finalize()  it would propagate this flag to such
assembler so all instructions passed to it are explicitly validated.

Default: false. 
kValidationOptionIntermediate 

Perform strict validation in BaseBuilder::emit() and BaseCompiler::emit() implementations.

This flag ensures that each instruction is checked before an InstNode representing the instruction is created by Builder or Compiler.

Default: false.

Member Function Documentation

uint32_t BaseEmitter::emitterType() constnoexcept

Returns the type of this emitter, see EmitterType.

uint32_t BaseEmitter::emitterFlags() constnoexcept

Returns emitter flags , see Flags.

bool BaseEmitter::isAssembler() constnoexcept

Tests whether the emitter inherits from BaseAssembler.

bool BaseEmitter::isBuilder() constnoexcept

Tests whether the emitter inherits from BaseBuilder.

Note
Both Builder and Compiler emitters would return true.

bool BaseEmitter::isCompiler() constnoexcept

Tests whether the emitter inherits from BaseCompiler.

bool BaseEmitter::hasEmitterFlag(uint32_t flag) constnoexcept

Tests whether the emitter has the given flag enabled.

bool BaseEmitter::isFinalized() constnoexcept

Tests whether the emitter is finalized.

bool BaseEmitter::isDestroyed() constnoexcept

Tests whether the emitter is destroyed (only used during destruction).

CodeHolder* BaseEmitter::code() constnoexcept

Returns the CodeHolder this emitter is attached to.

const Environment& BaseEmitter::environment() constnoexcept

Returns the target environment, see Environment.

The returned Environment reference matches CodeHolder::environment().

bool BaseEmitter::is32Bit() constnoexcept

Tests whether the target architecture is 32-bit.

bool BaseEmitter::is64Bit() constnoexcept

Tests whether the target architecture is 64-bit.

uint32_t BaseEmitter::arch() constnoexcept

Returns the target architecture type.

uint32_t BaseEmitter::subArch() constnoexcept

Returns the target architecture sub-type.

uint32_t BaseEmitter::registerSize() constnoexcept

Returns the target architecture's GP register size (4 or 8 bytes).

bool BaseEmitter::isInitialized() constnoexcept

Tests whether the emitter is initialized (i.e. attached to CodeHolder).

Error BaseEmitter::finalize()virtual

Finalizes this emitter.

Materializes the content of the emitter by serializing it to the attached CodeHolder through an architecture specific BaseAssembler. This function won't do anything if the emitter inherits from BaseAssembler as assemblers emit directly to a CodeBuffer held by CodeHolder. However, if this is an emitter that inherits from BaseBuilder or BaseCompiler then these emitters need the materialization phase as they store their content in a representation not visible to CodeHolder.

Reimplemented in asmjit::x86::Compiler, and asmjit::x86::Builder.

bool BaseEmitter::hasLogger() constnoexcept

Tests whether the emitter has a logger.

bool BaseEmitter::hasOwnLogger() constnoexcept

Tests whether the emitter has its own logger.

Own logger means that it overrides the possible logger that may be used by CodeHolder this emitter is attached to.

Logger* BaseEmitter::logger() constnoexcept

Returns the logger this emitter uses.

The returned logger is either the emitter's own logger or it's logger used by CodeHolder this emitter is attached to.

void BaseEmitter::setLogger(Logger* logger)noexcept

Sets or resets the logger of the emitter.

If the logger argument is non-null then the logger will be considered emitter's own logger, see hasOwnLogger() for more details. If the given logger is null then the emitter will automatically use logger that is attached to the CodeHolder this emitter is attached to.

void BaseEmitter::resetLogger()noexcept

Resets the logger of this emitter.

The emitter will bail to using a logger attached to CodeHolder this emitter is attached to, or no logger at all if CodeHolder doesn't have one.

bool BaseEmitter::hasErrorHandler() constnoexcept

Tests whether the emitter has an error handler attached.

bool BaseEmitter::hasOwnErrorHandler() constnoexcept

Tests whether the emitter has its own error handler.

Own error handler means that it overrides the possible error handler that may be used by CodeHolder this emitter is attached to.

ErrorHandler* BaseEmitter::errorHandler() constnoexcept

Returns the error handler this emitter uses.

The returned error handler is either the emitter's own error handler or it's error handler used by CodeHolder this emitter is attached to.

void BaseEmitter::setErrorHandler(ErrorHandler* errorHandler)noexcept

Sets or resets the error handler of the emitter.

void BaseEmitter::resetErrorHandler()noexcept

Resets the error handler.

Error BaseEmitter::reportError(Error err, const char* message = nullptr)

Handles the given error in the following way:

  1. If the emitter has ErrorHandler attached, it calls its ErrorHandler::handleError() member function first, and then returns the error. The handleError() function may throw.
  2. if the emitter doesn't have ErrorHandler, the error is simply returned.

uint32_t BaseEmitter::encodingOptions() constnoexcept

Returns encoding options, see EncodingOptions.

bool BaseEmitter::hasEncodingOption(uint32_t option) constnoexcept

Tests whether the encoding option is set.

void BaseEmitter::addEncodingOptions(uint32_t options)noexcept

Enables the given encoding options, see EncodingOptions.

void BaseEmitter::clearEncodingOptions(uint32_t options)noexcept

Disables the given encoding options, see EncodingOptions.

uint32_t BaseEmitter::validationOptions() constnoexcept

Returns the emitter's validation options, see ValidationOptions.

bool BaseEmitter::hasValidationOption(uint32_t option) constnoexcept

Tests whether the given option is present in validation options.

void BaseEmitter::addValidationOptions(uint32_t options)noexcept

Activates the given validation options, see ValidationOptions.

This function is used to activate explicit validation options that will be then used by all emitter implementations. There are in general two possibilities:

  • Architecture specific assembler is used. In this case a kValidationOptionAssembler can be used to turn on explicit validation that will be used before an instruction is emitted. This means that internally an extra step will be performed to make sure that the instruction is correct. This is needed, because by default assemblers prefer speed over strictness.

    This option should be used in debug builds as it's pretty expensive.

  • Architecture specific builder or compiler is used. In this case the user can turn on kValidationOptionIntermediate option that adds explicit validation step before the Builder or Compiler creates an InstNode to represent an emitted instruction. Error will be returned if the instruction is ill-formed. In addition, also kValidationOptionAssembler can be used, which would not be consumed by Builder / Compiler directly, but it would be propagated to an architecture specific BaseAssembler implementation it creates during BaseEmitter::finalize().

void BaseEmitter::clearValidationOptions(uint32_t options)noexcept

Deactivates the given validation options.

See addValidationOptions() and ValidationOptions for more details.

uint32_t BaseEmitter::forcedInstOptions() constnoexcept

Returns forced instruction options.

Forced instruction options are merged with next instruction options before the instruction is encoded. These options have some bits reserved that are used by error handling, logging, and instruction validation purposes. Other options are globals that affect each instruction.

uint32_t BaseEmitter::instOptions() constnoexcept

Returns options of the next instruction.

void BaseEmitter::setInstOptions(uint32_t options)noexcept

Returns options of the next instruction.

void BaseEmitter::addInstOptions(uint32_t options)noexcept

Adds options of the next instruction.

void BaseEmitter::resetInstOptions()noexcept

Resets options of the next instruction.

bool BaseEmitter::hasExtraReg() constnoexcept

Tests whether the extra register operand is valid.

const RegOnly& BaseEmitter::extraReg() constnoexcept

Returns an extra operand that will be used by the next instruction (architecture specific).

void BaseEmitter::setExtraReg(const BaseReg& reg)noexcept[1/2]

Sets an extra operand that will be used by the next instruction (architecture specific).

void BaseEmitter::setExtraReg(const RegOnly& reg)noexcept[2/2]

Sets an extra operand that will be used by the next instruction (architecture specific).

void BaseEmitter::resetExtraReg()noexcept

Resets an extra operand that will be used by the next instruction (architecture specific).

const char* BaseEmitter::inlineComment() constnoexcept

Returns comment/annotation of the next instruction.

void BaseEmitter::setInlineComment(const char* s)noexcept

Sets comment/annotation of the next instruction.

Note
This string is set back to null by _emit(), but until that it has to remain valid as the Emitter is not required to make a copy of it (and it would be slow to do that for each instruction).

void BaseEmitter::resetInlineComment()noexcept

Resets the comment/annotation to nullptr.

Label BaseEmitter::newLabel()pure virtual

Creates a new label.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Label BaseEmitter::newNamedLabel(const char* name, size_t nameSize = SIZE_MAX, uint32_t type = Label::kTypeGlobal, uint32_t parentId = Globals::kInvalidId)pure virtual

Creates a new named label.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Label BaseEmitter::newExternalLabel(const char* name, size_t nameSize = SIZE_MAX)

Creates a new external label.

Label BaseEmitter::labelByName(const char* name, size_t nameSize = SIZE_MAX, uint32_t parentId = Globals::kInvalidId)noexcept

Returns Label by name.

Returns invalid Label in case that the name is invalid or label was not found.

Note
This function doesn't trigger ErrorHandler in case the name is invalid or no such label exist. You must always check the validity of the Label returned.

Error BaseEmitter::bind(const Label& label)pure virtual

Binds the label to the current position of the current section.

Note
Attempt to bind the same label multiple times will return an error.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

bool BaseEmitter::isLabelValid(uint32_t labelId) constnoexcept[1/2]

Tests whether the label id is valid (i.e. registered).

bool BaseEmitter::isLabelValid(const Label& label) constnoexcept[2/2]

Tests whether the label is valid (i.e. registered).

Error BaseEmitter::_emitI(uint32_t instId)[1/7]

Emits an instruction (internal).

Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0)[2/7]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1)[3/7]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2)[4/7]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3)[5/7]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4)[6/7]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

Error BaseEmitter::_emitI(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5)[7/7]

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

template<typename... Args>
Error BaseEmitter::emit(uint32_t instId, Args&&... operands)

Emits an instruction instId with the given operands.

Error BaseEmitter::align(uint32_t alignMode, uint32_t alignment)pure virtual

Aligns the current CodeBuffer position to the alignment specified.

The sequence that is used to fill the gap between the aligned location and the current location depends on the align mode, see AlignMode.

Implemented in asmjit::x86::Assembler, and asmjit::BaseBuilder.

Error BaseEmitter::embed(const void* data, size_t dataSize)pure virtual

Embeds raw data into the CodeBuffer.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedDataArray(uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1)pure virtual

Embeds a typed data array.

This is the most flexible function for embedding data as it allows to:

  • Assign a typeId to the data, so the emitter knows the type of items stored in data. Binary data should use Type::kIdU8.
  • Repeat the given data repeatCount times, so the data can be used as a fill pattern for example, or as a pattern used by SIMD instructions.

Implemented in asmjit::BaseAssembler, and asmjit::BaseBuilder.

Error BaseEmitter::embedInt8(int8_t value, size_t repeatCount = 1)

Embeds int8_t value repeated by repeatCount.

Error BaseEmitter::embedUInt8(uint8_t value, size_t repeatCount = 1)

Embeds uint8_t value repeated by repeatCount.

Error BaseEmitter::embedInt16(int16_t value, size_t repeatCount = 1)

Embeds int16_t value repeated by repeatCount.

Error BaseEmitter::embedUInt16(uint16_t value, size_t repeatCount = 1)

Embeds uint16_t value repeated by repeatCount.

Error BaseEmitter::embedInt32(int32_t value, size_t repeatCount = 1)

Embeds int32_t value repeated by repeatCount.

Error BaseEmitter::embedUInt32(uint32_t value, size_t repeatCount = 1)

Embeds uint32_t value repeated by repeatCount.

Error BaseEmitter::embedInt64(int64_t value, size_t repeatCount = 1)

Embeds int64_t value repeated by repeatCount.

Error BaseEmitter::embedUInt64(uint64_t value, size_t repeatCount = 1)

Embeds uint64_t value repeated by repeatCount.

Error BaseEmitter::embedFloat(float value, size_t repeatCount = 1)

Embeds a floating point value repeated by repeatCount.

Error BaseEmitter::embedDouble(double value, size_t repeatCount = 1)

Embeds a floating point value repeated by repeatCount.

Error BaseEmitter::embedConstPool(const Label& label, const ConstPool& pool)pure virtual

Embeds a constant pool at the current offset by performing the following:

  1. Aligns by using kAlignData to the minimum pool alignment.
  2. Binds the ConstPool label so it's bound to an aligned location.
  3. Emits ConstPool content.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedLabel(const Label& label, size_t dataSize = 0)pure virtual

Embeds an absolute label address as data.

The dataSize is an optional argument that can be used to specify the size of the address data. If it's zero (default) the address size is deduced from the target architecture (either 4 or 8 bytes).

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::embedLabelDelta(const Label& label, const Label& base, size_t dataSize = 0)pure virtual

Embeds a delta (distance) between the label and base calculating it as label - base.

This function was designed to make it easier to embed lookup tables where each index is a relative distance of two labels.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::comment(const char* data, size_t size = SIZE_MAX)pure virtual

Emits a comment stored in data with an optional size parameter.

Implemented in asmjit::BaseBuilder, and asmjit::BaseAssembler.

Error BaseEmitter::commentf(const char* fmt, ...)

Emits a formatted comment specified by fmt and variable number of arguments.

Error BaseEmitter::commentv(const char* fmt, va_list ap)

Emits a formatted comment specified by fmt and ap.

Error BaseEmitter::onAttach(CodeHolder* code)pure virtualnoexcept

Called after the emitter was attached to CodeHolder.

Implemented in asmjit::x86::Assembler, asmjit::x86::Compiler, asmjit::x86::Builder, asmjit::BaseBuilder, asmjit::BaseCompiler, and asmjit::BaseAssembler.

Error BaseEmitter::onDetach(CodeHolder* code)pure virtualnoexcept

Called after the emitter was detached from CodeHolder.

Implemented in asmjit::x86::Assembler, asmjit::BaseBuilder, asmjit::BaseCompiler, and asmjit::BaseAssembler.

void BaseEmitter::onSettingsUpdated()virtualnoexcept

Called when CodeHolder has updated an important setting, which involves the following:

This function ensures that the settings are properly propagated from CodeHolder to the emitter.

Note
This function is virtual and can be overridden, however, if you do so, always call BaseEmitter::onSettingsUpdated() within your own implementation to ensure that the emitter is in a consisten state.

Member Data Documentation

uint8_t BaseEmitter::_emitterType = 0

uint8_t BaseEmitter::_emitterFlags = 0

uint8_t BaseEmitter::_validationFlags = 0

Validation flags in case validation is used, see InstAPI::ValidationFlags.

Note
Validation flags are specific to the emitter and they are setup at construction time and then never changed.

uint8_t BaseEmitter::_validationOptions = 0

Validation options, see ValidationOptions.

uint32_t BaseEmitter::_encodingOptions = 0

Encoding options, see EncodingOptions.

uint32_t BaseEmitter::_forcedInstOptions = BaseInst::kOptionReserved

Forced instruction options, combined with _instOptions by emit().

uint32_t BaseEmitter::_privateData = 0

Internal private data used freely by any emitter.

CodeHolder* BaseEmitter::_code = nullptr

CodeHolder the emitter is attached to.

Logger* BaseEmitter::_logger = nullptr

Attached Logger.

ErrorHandler* BaseEmitter::_errorHandler = nullptr

Attached ErrorHandler.

Environment BaseEmitter::_environment {}

Describes the target environment, matches CodeHolder::environment().

RegInfo BaseEmitter::_gpRegInfo {}

Native GP register signature and signature related information.

uint32_t BaseEmitter::_instOptions = 0

Next instruction options (affects the next instruction).

RegOnly BaseEmitter::_extraReg {}

Extra register (op-mask {k} on AVX-512) (affects the next instruction).

const char* BaseEmitter::_inlineComment = nullptr

Inline comment of the next instruction (affects the next instruction).