Skip to main content

CallRegs

Struct CallRegs 

Source
pub struct CallRegs {
Show 20 fields pub int_class: RegClass, pub sse_class: RegClass, pub int_args: &'static [PhysReg], pub sse_args: &'static [PhysReg], pub shared_positions: bool, pub int_returns: &'static [PhysReg], pub sse_returns: &'static [PhysReg], pub x87_returns: &'static [PhysReg], pub int_saved: &'static [PhysReg], pub sse_saved: &'static [PhysReg], pub int_order: &'static [PhysReg], pub sse_order: &'static [PhysReg], pub stack_pointer: PhysReg, pub frame_pointer: PhysReg, pub vector_count: Option<PhysReg>, pub red_zone: u32, pub shadow: u32, pub stack_align: u32, pub return_address: u32, pub word: u32,
}
Expand description

Which registers a calling convention gives which job.

This is the second half of a target description and it is separate from RegFile because the two do not vary together. x86-64 has one register file and two conventions over it, and they disagree about nearly everything below: rdi is where the first argument arrives on SysV and a register a callee has to preserve on Windows, and a Windows caller reserves thirty two bytes below the call that a SysV caller does not.

The allocation order is here rather than on a class because it is a consequence of what a call clobbers. A value that does not live across a call belongs in a register the callee is free to destroy, because putting it in a preserved one costs a push and a pop in the prologue of whichever function ends up owning it.

Every register named here is a register of the file the same target describes, and each list is in the order the convention uses them, so the fourth integer argument is int_args[3] and nothing has to count.

Fields§

§int_class: RegClass

The class the general purpose registers named here are in.

A register is a number inside its class, so a list of them says nothing about which registers they are without this. Everything else could get the class from the operand it came off, and a frame cannot, because a saved register is not an operand of anything.

§sse_class: RegClass

The class the vector registers named here are in.

§int_args: &'static [PhysReg]

The general purpose registers integer arguments arrive in, in order.

§sse_args: &'static [PhysReg]

The vector registers floating point arguments arrive in, in order.

Whether an argument’s position counts against both lists or only against its own is CallRegs::shared_positions.

§shared_positions: bool

Whether an argument’s position counts against both argument lists or only against its own.

False on SysV, which counts each separately, so a double after six integers is still in xmm0. True on Windows, which counts one position for both, so a double in the third position is in xmm2 and r8 is skipped.

§int_returns: &'static [PhysReg]

The general purpose registers an integer return value comes back in.

§sse_returns: &'static [PhysReg]

The vector registers a floating point return value comes back in.

§x87_returns: &'static [PhysReg]

The x87 registers a long double comes back in, which is empty on a target whose long double is a double.

§int_saved: &'static [PhysReg]

The general purpose registers a call leaves alone, so a value in one survives it.

§sse_saved: &'static [PhysReg]

The vector registers a call leaves alone, which is none of them on SysV.

§int_order: &'static [PhysReg]

The general purpose registers the allocator may hand out, in the order it prefers them.

The stack pointer is never in this list, and neither is the frame pointer, which a target could allocate when nothing needs a frame and which nothing here does yet.

§sse_order: &'static [PhysReg]

The vector registers the allocator may hand out, in the order it prefers them.

§stack_pointer: PhysReg

The stack pointer.

§frame_pointer: PhysReg

The frame pointer, which is the register a prologue puts the old stack pointer in.

§vector_count: Option<PhysReg>

Where a variadic call says how many vector registers it passed arguments in, when the convention makes it say.

SysV puts the count in al and a variadic callee reads it to decide whether to save the vector argument registers at all, which is what makes a call to printf with no floating point argument cheap.

§red_zone: u32

How many bytes below the stack pointer a leaf function may use without moving it.

A hundred and twenty eight on SysV and nothing on Windows. It is nothing in kernel code on either, because an interrupt handler runs on the interrupted stack and writes over exactly this, which is what -mno-red-zone is for.

§shadow: u32

How many bytes a caller reserves below the call for the callee to spill its register arguments into, which is thirty two on Windows and nothing on SysV.

§stack_align: u32

What the stack pointer has to be a multiple of at the instruction that makes a call.

Sixteen on every convention here, and it is a real obligation rather than a preference, because a callee is entitled to use an aligned vector store on its own frame and gets a fault rather than a wrong answer when a caller got this wrong.

§return_address: u32

How many bytes the call instruction itself pushes before the callee starts running.

Eight on x86-64, where the return address is on the stack, and nothing on a machine that leaves it in a register. It is what makes the stack pointer misaligned on entry by exactly one word, which every frame layout has to undo.

§word: u32

How many bytes one general purpose register takes when it is saved on the stack.

Implementations§

Source§

impl CallRegs

Source

pub fn preserves_int(&self, reg: PhysReg) -> bool

Whether a call preserves that general purpose register.

Source

pub fn preserves_sse(&self, reg: PhysReg) -> bool

Whether a call preserves that vector register.

Trait Implementations§

Source§

impl Clone for CallRegs

Source§

fn clone(&self) -> CallRegs

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 CallRegs

Source§

impl Debug for CallRegs

Source§

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

Formats the value using the given formatter. Read more
Source§

impl Eq for CallRegs

Source§

impl PartialEq for CallRegs

Source§

fn eq(&self, other: &CallRegs) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for CallRegs

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.