Add macros for common builtin types

This commit is contained in:
Brendan Hansknecht 2021-09-21 15:38:46 -07:00
parent 1a6ca4be59
commit d3c344e4da
2 changed files with 42 additions and 67 deletions

View file

@ -1430,3 +1430,31 @@ impl<
} }
} }
} }
#[macro_export]
macro_rules! single_register_integers {
() => {
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize
};
}
#[macro_export]
macro_rules! single_register_floats {
() => {
// Float16 is explicitly ignored because it is not supported by must hardware and may require special exceptions.
// Builtin::Float16 |
Builtin::Float32 | Builtin::Float64
};
}
#[macro_export]
macro_rules! single_register_builtins {
() => {
single_register_integers!() | single_register_floats!()
};
}

View file

@ -1,5 +1,7 @@
use crate::generic64::{Assembler, CallConv, RegTrait, SymbolStorage, PTR_SIZE}; use crate::generic64::{Assembler, CallConv, RegTrait, SymbolStorage, PTR_SIZE};
use crate::Relocation; use crate::{
single_register_builtins, single_register_floats, single_register_integers, Relocation,
};
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
@ -191,14 +193,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64SystemV {
} }
for (layout, sym) in args.iter() { for (layout, sym) in args.iter() {
match layout { match layout {
Layout::Builtin( Layout::Builtin(single_register_integers!()) => {
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize,
) => {
if general_i < Self::GENERAL_PARAM_REGS.len() { if general_i < Self::GENERAL_PARAM_REGS.len() {
symbol_map.insert( symbol_map.insert(
*sym, *sym,
@ -217,7 +212,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64SystemV {
); );
} }
} }
Layout::Builtin(Builtin::Float32 | Builtin::Float64) => { Layout::Builtin(single_register_floats!()) => {
if float_i < Self::FLOAT_PARAM_REGS.len() { if float_i < Self::FLOAT_PARAM_REGS.len() {
symbol_map.insert( symbol_map.insert(
*sym, *sym,
@ -262,16 +257,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64SystemV {
// For most return layouts we will do nothing. // For most return layouts we will do nothing.
// In some cases, we need to put the return address as the first arg. // In some cases, we need to put the return address as the first arg.
match ret_layout { match ret_layout {
Layout::Builtin( Layout::Builtin(single_register_builtins!()) => {}
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize
| Builtin::Float32
| Builtin::Float64,
) => {}
x => { x => {
return Err(format!( return Err(format!(
"receiving return type, {:?}, is not yet implemented", "receiving return type, {:?}, is not yet implemented",
@ -281,14 +267,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64SystemV {
} }
for (i, layout) in arg_layouts.iter().enumerate() { for (i, layout) in arg_layouts.iter().enumerate() {
match layout { match layout {
Layout::Builtin( Layout::Builtin(single_register_integers!()) => {
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize,
) => {
if general_i < Self::GENERAL_PARAM_REGS.len() { if general_i < Self::GENERAL_PARAM_REGS.len() {
// Load the value to the param reg. // Load the value to the param reg.
let dst = Self::GENERAL_PARAM_REGS[general_i]; let dst = Self::GENERAL_PARAM_REGS[general_i];
@ -342,7 +321,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64SystemV {
stack_offset += 8; stack_offset += 8;
} }
} }
Layout::Builtin(Builtin::Float32 | Builtin::Float64) => { Layout::Builtin(single_register_floats!()) => {
if float_i < Self::FLOAT_PARAM_REGS.len() { if float_i < Self::FLOAT_PARAM_REGS.len() {
// Load the value to the param reg. // Load the value to the param reg.
let dst = Self::FLOAT_PARAM_REGS[float_i]; let dst = Self::FLOAT_PARAM_REGS[float_i];
@ -553,18 +532,11 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64WindowsFastcall {
for (layout, sym) in args.iter() { for (layout, sym) in args.iter() {
if i < Self::GENERAL_PARAM_REGS.len() { if i < Self::GENERAL_PARAM_REGS.len() {
match layout { match layout {
Layout::Builtin( Layout::Builtin(single_register_integers!()) => {
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize,
) => {
symbol_map symbol_map
.insert(*sym, SymbolStorage::GeneralReg(Self::GENERAL_PARAM_REGS[i])); .insert(*sym, SymbolStorage::GeneralReg(Self::GENERAL_PARAM_REGS[i]));
} }
Layout::Builtin(Builtin::Float32 | Builtin::Float64) => { Layout::Builtin(single_register_floats!()) => {
symbol_map.insert(*sym, SymbolStorage::FloatReg(Self::FLOAT_PARAM_REGS[i])); symbol_map.insert(*sym, SymbolStorage::FloatReg(Self::FLOAT_PARAM_REGS[i]));
} }
Layout::Struct(&[]) => {} Layout::Struct(&[]) => {}
@ -578,16 +550,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64WindowsFastcall {
i += 1; i += 1;
} else { } else {
base_offset += match layout { base_offset += match layout {
Layout::Builtin( Layout::Builtin(single_register_builtins!()) => 8,
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize
| Builtin::Float32
| Builtin::Float64,
) => 8,
x => { x => {
return Err(format!( return Err(format!(
"Loading args with layout {:?} not yet implemented", "Loading args with layout {:?} not yet implemented",
@ -621,16 +584,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64WindowsFastcall {
// For most return layouts we will do nothing. // For most return layouts we will do nothing.
// In some cases, we need to put the return address as the first arg. // In some cases, we need to put the return address as the first arg.
match ret_layout { match ret_layout {
Layout::Builtin( Layout::Builtin(single_register_builtins!()) => {}
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize
| Builtin::Float32
| Builtin::Float64,
) => {}
x => { x => {
return Err(format!( return Err(format!(
"receiving return type, {:?}, is not yet implemented", "receiving return type, {:?}, is not yet implemented",
@ -640,14 +594,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64WindowsFastcall {
} }
for (i, layout) in arg_layouts.iter().enumerate() { for (i, layout) in arg_layouts.iter().enumerate() {
match layout { match layout {
Layout::Builtin( Layout::Builtin(single_register_integers!()) => {
Builtin::Int1
| Builtin::Int8
| Builtin::Int16
| Builtin::Int32
| Builtin::Int64
| Builtin::Usize,
) => {
if i < Self::GENERAL_PARAM_REGS.len() { if i < Self::GENERAL_PARAM_REGS.len() {
// Load the value to the param reg. // Load the value to the param reg.
let dst = Self::GENERAL_PARAM_REGS[reg_i]; let dst = Self::GENERAL_PARAM_REGS[reg_i];
@ -701,7 +648,7 @@ impl CallConv<X86_64GeneralReg, X86_64FloatReg> for X86_64WindowsFastcall {
stack_offset += 8; stack_offset += 8;
} }
} }
Layout::Builtin(Builtin::Float32 | Builtin::Float64) => { Layout::Builtin(single_register_floats!()) => {
if i < Self::FLOAT_PARAM_REGS.len() { if i < Self::FLOAT_PARAM_REGS.len() {
// Load the value to the param reg. // Load the value to the param reg.
let dst = Self::FLOAT_PARAM_REGS[reg_i]; let dst = Self::FLOAT_PARAM_REGS[reg_i];