arm32 codegen
This commit adds arm32 code generation for some IR insts. Floating-point instructions are not supported, because regalloc does not allow to represent overlapping register classes, which are needed by VFP/Neon. There is also no support for big-endianness, I64 and I128 types.
This commit is contained in:
@@ -274,29 +274,18 @@ impl fmt::Display for Pressure {
|
||||
#[cfg(feature = "arm32")]
|
||||
mod tests {
|
||||
use super::Pressure;
|
||||
use crate::isa::{RegClass, TargetIsa};
|
||||
use crate::isa::registers::{RegBank, RegClassData};
|
||||
use crate::isa::{RegClass, RegInfo, RegUnit};
|
||||
use crate::regalloc::RegisterSet;
|
||||
use alloc::boxed::Box;
|
||||
use core::borrow::Borrow;
|
||||
use core::str::FromStr;
|
||||
use target_lexicon::triple;
|
||||
|
||||
// Make an arm32 `TargetIsa`, if possible.
|
||||
fn arm32() -> Option<Box<dyn TargetIsa>> {
|
||||
use crate::isa;
|
||||
use crate::settings;
|
||||
|
||||
let shared_builder = settings::builder();
|
||||
let shared_flags = settings::Flags::new(shared_builder);
|
||||
|
||||
isa::lookup(triple!("arm"))
|
||||
.ok()
|
||||
.map(|b| b.finish(shared_flags))
|
||||
}
|
||||
// Arm32 `TargetIsa` is now `TargetIsaAdapter`, which does not hold any info
|
||||
// about registers, so we directly access `INFO` from registers-arm32.rs.
|
||||
include!(concat!(env!("OUT_DIR"), "/registers-arm32.rs"));
|
||||
|
||||
// Get a register class by name.
|
||||
fn rc_by_name(isa: &dyn TargetIsa, name: &str) -> RegClass {
|
||||
isa.register_info()
|
||||
fn rc_by_name(reginfo: &RegInfo, name: &str) -> RegClass {
|
||||
reginfo
|
||||
.classes
|
||||
.iter()
|
||||
.find(|rc| rc.name == name)
|
||||
@@ -305,11 +294,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn basic_counting() {
|
||||
let isa = arm32().expect("This test requires arm32 support");
|
||||
let isa = isa.borrow();
|
||||
let gpr = rc_by_name(isa, "GPR");
|
||||
let s = rc_by_name(isa, "S");
|
||||
let reginfo = isa.register_info();
|
||||
let reginfo = INFO.borrow();
|
||||
let gpr = rc_by_name(®info, "GPR");
|
||||
let s = rc_by_name(®info, "S");
|
||||
|
||||
let regs = RegisterSet::new();
|
||||
|
||||
let mut pressure = Pressure::new(®info, ®s);
|
||||
@@ -333,12 +321,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn arm_float_bank() {
|
||||
let isa = arm32().expect("This test requires arm32 support");
|
||||
let isa = isa.borrow();
|
||||
let s = rc_by_name(isa, "S");
|
||||
let d = rc_by_name(isa, "D");
|
||||
let q = rc_by_name(isa, "Q");
|
||||
let reginfo = isa.register_info();
|
||||
let reginfo = INFO.borrow();
|
||||
let s = rc_by_name(®info, "S");
|
||||
let d = rc_by_name(®info, "D");
|
||||
let q = rc_by_name(®info, "Q");
|
||||
let regs = RegisterSet::new();
|
||||
|
||||
let mut pressure = Pressure::new(®info, ®s);
|
||||
|
||||
@@ -1149,24 +1149,14 @@ mod tests {
|
||||
use super::{Move, Solver};
|
||||
use crate::entity::EntityRef;
|
||||
use crate::ir::Value;
|
||||
use crate::isa::{RegClass, RegInfo, RegUnit, TargetIsa};
|
||||
use crate::isa::registers::{RegBank, RegClassData};
|
||||
use crate::isa::{RegClass, RegInfo, RegUnit};
|
||||
use crate::regalloc::RegisterSet;
|
||||
use alloc::boxed::Box;
|
||||
use core::str::FromStr;
|
||||
use target_lexicon::triple;
|
||||
use core::borrow::Borrow;
|
||||
|
||||
// Make an arm32 `TargetIsa`, if possible.
|
||||
fn arm32() -> Option<Box<dyn TargetIsa>> {
|
||||
use crate::isa;
|
||||
use crate::settings;
|
||||
|
||||
let shared_builder = settings::builder();
|
||||
let shared_flags = settings::Flags::new(shared_builder);
|
||||
|
||||
isa::lookup(triple!("arm"))
|
||||
.ok()
|
||||
.map(|b| b.finish(shared_flags))
|
||||
}
|
||||
// Arm32 `TargetIsa` is now `TargetIsaAdapter`, which does not hold any info
|
||||
// about registers, so we directly access `INFO` from registers-arm32.rs.
|
||||
include!(concat!(env!("OUT_DIR"), "/registers-arm32.rs"));
|
||||
|
||||
// Get a register class by name.
|
||||
fn rc_by_name(reginfo: &RegInfo, name: &str) -> RegClass {
|
||||
@@ -1207,8 +1197,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn simple_moves() {
|
||||
let isa = arm32().expect("This test requires arm32 support");
|
||||
let reginfo = isa.register_info();
|
||||
let reginfo = INFO.borrow();
|
||||
let gpr = rc_by_name(®info, "GPR");
|
||||
let r0 = gpr.unit(0);
|
||||
let r1 = gpr.unit(1);
|
||||
@@ -1260,8 +1249,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn harder_move_cycles() {
|
||||
let isa = arm32().expect("This test requires arm32 support");
|
||||
let reginfo = isa.register_info();
|
||||
let reginfo = INFO.borrow();
|
||||
let s = rc_by_name(®info, "S");
|
||||
let d = rc_by_name(®info, "D");
|
||||
let d0 = d.unit(0);
|
||||
@@ -1322,8 +1310,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn emergency_spill() {
|
||||
let isa = arm32().expect("This test requires arm32 support");
|
||||
let reginfo = isa.register_info();
|
||||
let reginfo = INFO.borrow();
|
||||
let gpr = rc_by_name(®info, "GPR");
|
||||
let r0 = gpr.unit(0);
|
||||
let r1 = gpr.unit(1);
|
||||
|
||||
Reference in New Issue
Block a user