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:
Jakub Krauz
2020-09-16 12:11:29 +02:00
parent c29f4599ac
commit f6a140a662
26 changed files with 7103 additions and 381 deletions

View File

@@ -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(&reginfo, "GPR");
let s = rc_by_name(&reginfo, "S");
let regs = RegisterSet::new();
let mut pressure = Pressure::new(&reginfo, &regs);
@@ -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(&reginfo, "S");
let d = rc_by_name(&reginfo, "D");
let q = rc_by_name(&reginfo, "Q");
let regs = RegisterSet::new();
let mut pressure = Pressure::new(&reginfo, &regs);

View File

@@ -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(&reginfo, "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(&reginfo, "S");
let d = rc_by_name(&reginfo, "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(&reginfo, "GPR");
let r0 = gpr.unit(0);
let r1 = gpr.unit(1);