The new encoding format allows entries that mean "stop with this legalization code" which makes it possible to configure legalization actions per instruction, instead of only per controlling type variable. This patch adds the Rust side of the legalization codes: - Add an `Encodings::legalize()` method on the encoding iterator which can be called after the iterator has returned `None`. The returned code is either the default legalization action for the type, or a specific code encountered in the encoding list. - Change `lookup_enclist` to return a full iterator instead of just an offset. The two-phase lookup can bail at multiple points, each time with a default legalization code from the level 1 table. This default legalization code is stored in the returned iterator. - Change all the implementations of legal_encodings() in the ISA implementations. This change means that we don't need to return a Result any longer. The `Encodings` iterator can be empty with an associated legalization code.
108 lines
3.0 KiB
Rust
108 lines
3.0 KiB
Rust
//! ARM 32-bit Instruction Set Architecture.
|
|
|
|
pub mod settings;
|
|
mod abi;
|
|
mod binemit;
|
|
mod enc_tables;
|
|
mod registers;
|
|
|
|
use binemit::{CodeSink, MemoryCodeSink, emit_function};
|
|
use super::super::settings as shared_settings;
|
|
use isa::enc_tables::{self as shared_enc_tables, lookup_enclist, Encodings};
|
|
use isa::Builder as IsaBuilder;
|
|
use isa::{TargetIsa, RegInfo, RegClass, EncInfo};
|
|
use ir;
|
|
use regalloc;
|
|
|
|
#[allow(dead_code)]
|
|
struct Isa {
|
|
shared_flags: shared_settings::Flags,
|
|
isa_flags: settings::Flags,
|
|
cpumode: &'static [shared_enc_tables::Level1Entry<u16>],
|
|
}
|
|
|
|
/// Get an ISA builder for creating ARM32 targets.
|
|
pub fn isa_builder() -> IsaBuilder {
|
|
IsaBuilder {
|
|
setup: settings::builder(),
|
|
constructor: isa_constructor,
|
|
}
|
|
}
|
|
|
|
fn isa_constructor(shared_flags: shared_settings::Flags,
|
|
builder: &shared_settings::Builder)
|
|
-> Box<TargetIsa> {
|
|
let level1 = if shared_flags.is_compressed() {
|
|
&enc_tables::LEVEL1_T32[..]
|
|
} else {
|
|
&enc_tables::LEVEL1_A32[..]
|
|
};
|
|
Box::new(Isa {
|
|
isa_flags: settings::Flags::new(&shared_flags, builder),
|
|
shared_flags,
|
|
cpumode: level1,
|
|
})
|
|
}
|
|
|
|
impl TargetIsa for Isa {
|
|
fn name(&self) -> &'static str {
|
|
"arm32"
|
|
}
|
|
|
|
fn flags(&self) -> &shared_settings::Flags {
|
|
&self.shared_flags
|
|
}
|
|
|
|
fn register_info(&self) -> RegInfo {
|
|
registers::INFO.clone()
|
|
}
|
|
|
|
fn encoding_info(&self) -> EncInfo {
|
|
enc_tables::INFO.clone()
|
|
}
|
|
|
|
fn legal_encodings<'a>(&'a self,
|
|
dfg: &'a ir::DataFlowGraph,
|
|
inst: &'a ir::InstructionData,
|
|
ctrl_typevar: ir::Type)
|
|
-> Encodings<'a> {
|
|
lookup_enclist(ctrl_typevar,
|
|
inst,
|
|
dfg,
|
|
self.cpumode,
|
|
&enc_tables::LEVEL2[..],
|
|
&enc_tables::ENCLISTS[..],
|
|
&enc_tables::RECIPE_PREDICATES[..],
|
|
&enc_tables::INST_PREDICATES[..],
|
|
self.isa_flags.predicate_view())
|
|
}
|
|
|
|
fn legalize_signature(&self, sig: &mut ir::Signature, current: bool) {
|
|
abi::legalize_signature(sig, &self.shared_flags, current)
|
|
}
|
|
|
|
fn regclass_for_abi_type(&self, ty: ir::Type) -> RegClass {
|
|
abi::regclass_for_abi_type(ty)
|
|
}
|
|
|
|
fn allocatable_registers(&self, func: &ir::Function) -> regalloc::AllocatableSet {
|
|
abi::allocatable_registers(func)
|
|
}
|
|
|
|
fn emit_inst(&self,
|
|
func: &ir::Function,
|
|
inst: ir::Inst,
|
|
divert: &mut regalloc::RegDiversions,
|
|
sink: &mut CodeSink) {
|
|
binemit::emit_inst(func, inst, divert, sink)
|
|
}
|
|
|
|
fn emit_function(&self, func: &ir::Function, sink: &mut MemoryCodeSink) {
|
|
emit_function(func, binemit::emit_inst, sink)
|
|
}
|
|
|
|
fn reloc_names(&self) -> &'static [&'static str] {
|
|
&binemit::RELOC_NAMES
|
|
}
|
|
}
|