Skip to main content

MachineInsts

Struct MachineInsts 

Source
pub struct MachineInsts {
    pub prefix: &'static str,
    pub operands: fn(&str) -> Option<&'static [OperandDesc]>,
    pub takes_imm: fn(&str) -> bool,
    pub takes_mem: fn(&str) -> bool,
    pub touches_mem: fn(&str) -> bool,
    pub calls: fn(&str) -> bool,
    pub scales: &'static [u8],
}
Expand description

What a pass has to know about a machine to tell an instruction it has from one it does not.

Every question is of a name, for the reason crate::BitInsts takes names: the pass is in a pipeline crate, spec/10-backend.md section 10.8 says a pipeline crate holds no target specific code, so an opcode is a name to it and what any name means is the target’s answer.

Fields§

§prefix: &'static str

What a rule file and the machine IR put in front of this target’s opcodes, such as x64..

§operands: fn(&str) -> Option<&'static [OperandDesc]>

The operands an instruction of that name has, the ones it writes before the ones it reads.

None for a name this target does not have, which is the answer that makes a proposal naming an opcode nobody described a proposal the target refuses rather than one it lets through with no opinion.

The registers an addressing mode names are not in here, for the reason they are not in rucc_target::x86_64::Form::operands: they are operands and the allocator rewrites them like any other, but which operand each of them is belongs to the addressing mode.

§takes_imm: fn(&str) -> bool

Whether an instruction of that name carries an immediate.

§takes_mem: fn(&str) -> bool

Whether an instruction of that name carries an addressing mode.

§touches_mem: fn(&str) -> bool

Whether an instruction of that name reads or writes memory.

Asked by a pass moving a memory access from where it is to somewhere later, which is safe while nothing it passes touches memory at all. Reading and writing are one question rather than two, because moving a read past a read is still a reordering of two accesses, and machine IR does not say which accesses the program insisted on: a volatile read and an ordinary one are the same instruction with the same operands by the time a pass here sees them.

It is a coarser answer than an alias analysis would give and a target does not have to know anything it does not already know to give it. Whether two addresses are the same place is a question nothing below selection has an analysis for, so the answer to arriving at one is to stop rather than to guess.

A call answers true here and that is still not the whole answer about a call. What a call does to memory is not in the instruction at all, which is why Self::calls is a separate question and why a pass that has to know what survived one has to ask that as well.

§calls: fn(&str) -> bool

Whether an instruction of that name is a call.

Asked by a pass that has to know which registers an instruction leaves alone, because a call is the one instruction whose operands do not answer that. The registers a convention does not preserve are gone across one, and the ones an argument travelled in are written down as reads rather than as writes, so a pass reading the operand vector would be told a value in an argument register survives a call it does not survive.

§scales: &'static [u8]

What an addressing mode on this target may multiply its index by.

A list rather than a range because the machines that have an index have a handful of scales and not an interval, and a pass folding an address into a memory operand has to ask whether the number it worked out is one of them.

Implementations§

Source§

impl MachineInsts

Source

pub fn bare<'a>(&self, name: &'a str) -> &'a str

The name with this target’s prefix taken off, which is how its own description spells it.

The machine IR holds the prefixed spelling and every table behind these functions is written without it, so this is the one place the two spellings meet.

Source

pub fn has(&self, name: &str) -> bool

Whether this target has an instruction of that name at all.

Source

pub fn calls(&self, name: &str) -> bool

Whether an instruction of that name is a call on this target.

Source

pub fn touches_mem(&self, name: &str) -> bool

Whether an instruction of that name reads or writes memory on this target.

Source

pub fn scales(&self, scale: u8) -> bool

Whether this target multiplies an index by that.

Trait Implementations§

Source§

impl Clone for MachineInsts

Source§

fn clone(&self) -> MachineInsts

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for MachineInsts

Source§

impl Debug for MachineInsts

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.