cranelift::prelude::isa::x64::encoding::evex

Struct EvexInstruction

pub struct EvexInstruction { /* private fields */ }
Expand description

Constructs an EVEX-encoded instruction using a builder pattern. This approach makes it visually easier to transform something the manual’s syntax, EVEX.256.66.0F38.W1 1F /r to code: EvexInstruction::new().length(...).prefix(...).map(...).w(true).opcode(0x1F).reg(...).rm(...).

Implementations§

§

impl EvexInstruction

pub fn new() -> EvexInstruction

Construct a default EVEX instruction.

pub fn length(self, length: EvexVectorLength) -> EvexInstruction

Set the length of the instruction . Note that there are sets of instructions (i.e. rounding, memory broadcast) that modify the same underlying bits–at some point (TODO) we can add a way to set those context bits and verify that both are not used (e.g. rounding AND length). For now, this method is very convenient.

pub fn prefix(self, prefix: LegacyPrefixes) -> EvexInstruction

Set the legacy prefix byte of the instruction: None | 66 | F0 | F2 | F3. EVEX instructions pack these into the prefix, not as separate bytes.

pub fn map(self, map: OpcodeMap) -> EvexInstruction

Set the opcode map byte of the instruction: None | 0F | 0F38 | 0F3A. EVEX instructions pack these into the prefix, not as separate bytes.

pub fn w(self, w: bool) -> EvexInstruction

Set the W bit, typically used to indicate an instruction using 64 bits of an operand (e.g. 64 bit lanes). EVEX packs this bit in the EVEX prefix; previous encodings used the REX prefix.

pub fn opcode(self, opcode: u8) -> EvexInstruction

Set the instruction opcode byte.

pub fn tuple_type(self, tt: Avx512TupleType) -> EvexInstruction

Set the “tuple type” which is used for 8-bit scaling when a memory operand is used.

pub fn reg(self, reg: impl Into<Register>) -> EvexInstruction

Set the register to use for the reg bits; many instructions use this as the write operand. Setting this affects both the ModRM byte (reg section) and the EVEX prefix (the extension bits for register encodings > 8).

pub fn mask(self, mask: EvexMasking) -> EvexInstruction

Set the mask to use. See section 2.6 in the Intel Software Developer’s Manual, volume 2A for more details.

pub fn vvvvv(self, reg: impl Into<Register>) -> EvexInstruction

Set the vvvvv register; some instructions allow using this as a second, non-destructive source register in 3-operand instructions (e.g. 2 read, 1 write).

pub fn rm(self, reg: impl Into<RegisterOrAmode>) -> EvexInstruction

Set the register to use for the rm bits; many instructions use this as the “read from register/memory” operand. Setting this affects both the ModRM byte (rm section) and the EVEX prefix (the extension bits for register encodings > 8).

pub fn imm(self, imm: u8) -> EvexInstruction

Set the imm byte.

pub fn encode(&self, sink: &mut MachBuffer<MInst>)

Emit the EVEX-encoded instruction to the code sink:

  • the 4-byte EVEX prefix;
  • the opcode byte;
  • the ModR/M byte
  • SIB bytes, if necessary
  • an optional immediate, if necessary (not currently implemented)

Trait Implementations§

§

impl Default for EvexInstruction

Because some of the bit flags in the EVEX prefix are reversed and users of EvexInstruction may choose to skip setting fields, here we set some sane defaults. Note that:

  • the first byte is always 0x62 but you will notice it at the end of the default bits value implemented–remember the little-endian order
  • some bits are always set to certain values: bits 10-11 to 0, bit 18 to 1
  • the other bits set correspond to reversed bits: R, X, B, R’ (byte 1), vvvv (byte 2), V’ (byte 3).

See the default_emission test for what these defaults are equivalent to (e.g. using RAX, unsetting the W bit, etc.)

§

fn default() -> EvexInstruction

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.