pub struct Target { /* private fields */ }Expand description
A target: register file, classes, instructions, and the registers with fixed jobs.
Targets are static data; x86_64::TARGET is the
one this release ships.
§Examples
use backend_lang::x86_64::{self, RSP, RBP, FLAGS};
let t = &x86_64::TARGET;
assert_eq!(t.name(), "x86-64");
assert_eq!(t.stack_pointer(), RSP);
assert_eq!(t.frame_pointer(), RBP);
assert_eq!(t.flags(), Some(FLAGS));Implementations§
Source§impl Target
impl Target
Sourcepub const fn new(
name: &'static str,
isa: Isa,
regs: &'static [RegInfo],
classes: &'static [ClassInfo],
insts: &'static [InstDesc],
config: TargetConfig,
) -> Target
pub const fn new( name: &'static str, isa: Isa, regs: &'static [RegInfo], classes: &'static [ClassInfo], insts: &'static [InstDesc], config: TargetConfig, ) -> Target
Describes a target.
insts must begin with the Opcode::COPY and Opcode::PCOPY
descriptions (see Target::generic_insts); registers’ classes must
index classes; at most MAX_PREGS registers.
The crate’s own targets are checked by its tests; a hand-made one
that breaks these rules is caught by Function::verify as operands
that fit no class.
§Examples
A variant of x86-64 without xchg, to make the parallel-move
resolver break cycles through a scratch register instead:
use backend_lang::target::{MoveCaps, ImmRange, Target, TargetConfig};
use backend_lang::x86_64;
let base = &x86_64::TARGET;
let mut cfg = TargetConfig::of(base);
cfg.move_caps = MoveCaps::new(false, false, ImmRange::I32);
let no_swap = Target::new("x86-64-noswap", base.isa(), base.regs(), base.classes(), base.insts(), cfg);
assert!(!no_swap.move_caps().swap());Sourcepub const fn generic_insts() -> [InstDesc; 2]
pub const fn generic_insts() -> [InstDesc; 2]
The two generic descriptions every instruction table starts with,
Opcode::COPY then Opcode::PCOPY.
§Examples
use backend_lang::target::{InstKind, Target};
let [copy, pcopy] = Target::generic_insts();
assert_eq!(copy.kind(), InstKind::Copy);
assert_eq!(pcopy.name(), "pcopy");Sourcepub const fn isa(&self) -> Isa
pub const fn isa(&self) -> Isa
The ISA, which selects the encoder.
§Examples
use backend_lang::target::Isa;
use backend_lang::x86_64;
assert_eq!(x86_64::TARGET.isa(), Isa::X86_64);Sourcepub const fn regs(&self) -> &'static [RegInfo]
pub const fn regs(&self) -> &'static [RegInfo]
The register file, indexed by PReg::index.
§Examples
use backend_lang::x86_64;
assert_eq!(x86_64::TARGET.regs().len(), 33);Sourcepub fn reg(&self, reg: PReg) -> &RegInfo
pub fn reg(&self, reg: PReg) -> &RegInfo
One register’s description. An index the target does not have gets a
placeholder named <invalid>, in no class.
§Examples
use backend_lang::PReg;
use backend_lang::x86_64::{self, RDI};
assert_eq!(x86_64::TARGET.reg(RDI).name(), "rdi");
assert_eq!(x86_64::TARGET.reg(PReg::new(100).unwrap()).name(), "<invalid>");Sourcepub fn has_reg(&self, reg: PReg) -> bool
pub fn has_reg(&self, reg: PReg) -> bool
Whether the target has a register with this index.
§Examples
use backend_lang::PReg;
use backend_lang::x86_64::{self, RAX};
assert!(x86_64::TARGET.has_reg(RAX));
assert!(!x86_64::TARGET.has_reg(PReg::new(100).unwrap()));Sourcepub const fn classes(&self) -> &'static [ClassInfo]
pub const fn classes(&self) -> &'static [ClassInfo]
The class table, indexed by RegClass::index.
§Examples
use backend_lang::x86_64;
assert_eq!(x86_64::TARGET.classes().len(), 3);Sourcepub fn class(&self, class: RegClass) -> &ClassInfo
pub fn class(&self, class: RegClass) -> &ClassInfo
One class’s description. A class the target does not have gets an
empty placeholder named <invalid>.
§Examples
use backend_lang::RegClass;
use backend_lang::x86_64::{self, GPR};
assert_eq!(x86_64::TARGET.class(GPR).name(), "gpr");
assert!(x86_64::TARGET.class(RegClass::new(9)).regs().is_empty());Sourcepub fn has_class(&self, class: RegClass) -> bool
pub fn has_class(&self, class: RegClass) -> bool
Whether the target has this class.
§Examples
use backend_lang::RegClass;
use backend_lang::x86_64::{self, VEC};
assert!(x86_64::TARGET.has_class(VEC));
assert!(!x86_64::TARGET.has_class(RegClass::new(9)));Sourcepub const fn insts(&self) -> &'static [InstDesc]
pub const fn insts(&self) -> &'static [InstDesc]
The instruction table, indexed by Opcode::index.
§Examples
use backend_lang::x86_64;
assert!(x86_64::TARGET.insts().len() > 80);Sourcepub fn inst(&self, opcode: Opcode) -> Option<&'static InstDesc>
pub fn inst(&self, opcode: Opcode) -> Option<&'static InstDesc>
One instruction’s description, or None for an opcode the target
does not have.
§Examples
use backend_lang::target::Opcode;
use backend_lang::x86_64::{self, op};
assert!(x86_64::TARGET.inst(op::LEA64).is_some());
assert!(x86_64::TARGET.inst(Opcode::new(60000)).is_none());Sourcepub fn opcode(&self, name: &str) -> Option<Opcode>
pub fn opcode(&self, name: &str) -> Option<Opcode>
The opcode whose MIR name is name, by a scan of the table.
§Examples
use backend_lang::x86_64::{self, op};
assert_eq!(x86_64::TARGET.opcode("sub32"), Some(op::SUB32));
assert_eq!(x86_64::TARGET.opcode("frobnicate"), None);Sourcepub const fn stack_pointer(&self) -> PReg
pub const fn stack_pointer(&self) -> PReg
The stack pointer.
§Examples
use backend_lang::x86_64::{self, RSP};
assert_eq!(x86_64::TARGET.stack_pointer(), RSP);Sourcepub const fn frame_pointer(&self) -> PReg
pub const fn frame_pointer(&self) -> PReg
The frame pointer.
§Examples
use backend_lang::x86_64::{self, RBP};
assert_eq!(x86_64::TARGET.frame_pointer(), RBP);Sourcepub const fn flags(&self) -> Option<PReg>
pub const fn flags(&self) -> Option<PReg>
The condition-flags register, modelled as a physical register so that flag producers and consumers are ordinary implicit definitions and uses.
§Examples
use backend_lang::x86_64::{self, FLAGS};
assert_eq!(x86_64::TARGET.flags(), Some(FLAGS));Sourcepub const fn addr_class(&self) -> RegClass
pub const fn addr_class(&self) -> RegClass
The class of memory operands’ base and index registers.
§Examples
use backend_lang::x86_64::{self, GPR};
assert_eq!(x86_64::TARGET.addr_class(), GPR);Sourcepub const fn move_caps(&self) -> MoveCaps
pub const fn move_caps(&self) -> MoveCaps
How values move on this target.
§Examples
use backend_lang::x86_64;
assert!(x86_64::TARGET.move_caps().swap());Sourcepub const fn max_mem_operands(&self) -> u8
pub const fn max_mem_operands(&self) -> u8
The most memory operands one instruction may have (one on x86-64).
§Examples
use backend_lang::x86_64;
assert_eq!(x86_64::TARGET.max_mem_operands(), 1);Sourcepub const fn conds(&self) -> u8
pub const fn conds(&self) -> u8
The number of condition codes; a Cond operand is below it.
§Examples
use backend_lang::x86_64;
assert_eq!(x86_64::TARGET.conds(), 16);Sourcepub fn cond_name(&self, cond: CondCode) -> &'static str
pub fn cond_name(&self, cond: CondCode) -> &'static str
A condition code’s name (<invalid> for one the target does not
have).
§Examples
use backend_lang::mir::CondCode;
use backend_lang::x86_64;
assert_eq!(x86_64::TARGET.cond_name(CondCode::new(4)), "e");
assert_eq!(x86_64::TARGET.cond_name(CondCode::new(99)), "<invalid>");