inline Num.IsZero of gen-dev

This commit is contained in:
satotake 2021-11-22 15:08:12 +00:00 committed by GitHub
parent c9ec095741
commit 6f42ea3260
4 changed files with 87 additions and 8 deletions

View file

@ -510,6 +510,15 @@ impl Assembler<AArch64GeneralReg, AArch64FloatReg> for AArch64Assembler {
unimplemented!("registers less than not implemented yet for AArch64"); unimplemented!("registers less than not implemented yet for AArch64");
} }
#[inline(always)]
fn is_zero_reg64_reg64(
_buf: &mut Vec<'_, u8>,
_dst: AArch64GeneralReg,
_src: AArch64GeneralReg,
) {
unimplemented!("registers is zero not implemented yet for AArch64");
}
#[inline(always)] #[inline(always)]
fn ret(buf: &mut Vec<'_, u8>) { fn ret(buf: &mut Vec<'_, u8>) {
ret_reg64(buf, AArch64GeneralReg::LR) ret_reg64(buf, AArch64GeneralReg::LR)

View file

@ -186,6 +186,8 @@ pub trait Assembler<GeneralReg: RegTrait, FloatReg: RegTrait> {
src2: GeneralReg, src2: GeneralReg,
); );
fn is_zero_reg64_reg64(buf: &mut Vec<'_, u8>, dst: GeneralReg, src: GeneralReg);
fn ret(buf: &mut Vec<'_, u8>); fn ret(buf: &mut Vec<'_, u8>);
} }
@ -500,12 +502,7 @@ impl<
// move return value to dst. // move return value to dst.
match ret_layout { match ret_layout {
Layout::Builtin(Builtin::Int1) => { Layout::Builtin(Builtin::Int64 | Builtin::Int1) => {
let dst_reg = self.claim_general_reg(dst)?;
ASM::mov_reg64_reg64(&mut self.buf, dst_reg, CC::GENERAL_RETURN_REGS[0]);
Ok(())
}
Layout::Builtin(Builtin::Int64) => {
let dst_reg = self.claim_general_reg(dst)?; let dst_reg = self.claim_general_reg(dst)?;
ASM::mov_reg64_reg64(&mut self.buf, dst_reg, CC::GENERAL_RETURN_REGS[0]); ASM::mov_reg64_reg64(&mut self.buf, dst_reg, CC::GENERAL_RETURN_REGS[0]);
Ok(()) Ok(())
@ -899,6 +896,23 @@ impl<
} }
} }
fn build_num_is_zero(
&mut self,
dst: &Symbol,
src: &Symbol,
arg_layout: &Layout<'a>,
) -> Result<(), String> {
match arg_layout {
Layout::Builtin(Builtin::Int64) => {
let dst_reg = self.claim_general_reg(dst)?;
let src_reg = self.load_to_general_reg(src)?;
ASM::is_zero_reg64_reg64(&mut self.buf, dst_reg, src_reg);
Ok(())
}
x => Err(format!("NumIsZero: layout, {:?}, not implemented yet", x)),
}
}
fn create_struct( fn create_struct(
&mut self, &mut self,
sym: &Symbol, sym: &Symbol,

View file

@ -1118,6 +1118,12 @@ impl Assembler<X86_64GeneralReg, X86_64FloatReg> for X86_64Assembler {
setl_reg64(buf, dst); setl_reg64(buf, dst);
} }
#[inline(always)]
fn is_zero_reg64_reg64(buf: &mut Vec<'_, u8>, dst: X86_64GeneralReg, src: X86_64GeneralReg) {
test_reg64_reg64(buf, src, src);
sete_reg64(buf, dst);
}
#[inline(always)] #[inline(always)]
fn ret(buf: &mut Vec<'_, u8>) { fn ret(buf: &mut Vec<'_, u8>) {
ret(buf); ret(buf);

View file

@ -5,7 +5,7 @@
use bumpalo::{collections::Vec, Bump}; use bumpalo::{collections::Vec, Bump};
use roc_builtins::bitcode::{self, FloatWidth, IntWidth}; use roc_builtins::bitcode::{self, FloatWidth, IntWidth};
use roc_collections::all::{MutMap, MutSet}; use roc_collections::all::{MutMap, MutSet};
use roc_module::ident::TagName; use roc_module::ident::{ModuleName, TagName};
use roc_module::low_level::LowLevel; use roc_module::low_level::LowLevel;
use roc_module::symbol::{Interns, Symbol}; use roc_module::symbol::{Interns, Symbol};
use roc_mono::ir::{ use roc_mono::ir::{
@ -236,13 +236,24 @@ where
arg_layouts, arg_layouts,
ret_layout, ret_layout,
) )
} else { } else if func_sym
.module_string(&self.env().interns)
.starts_with(ModuleName::APP)
{
let fn_name = LayoutIds::default() let fn_name = LayoutIds::default()
.get(*func_sym, layout) .get(*func_sym, layout)
.to_symbol_string(*func_sym, &self.env().interns); .to_symbol_string(*func_sym, &self.env().interns);
// Now that the arguments are needed, load them if they are literals. // Now that the arguments are needed, load them if they are literals.
self.load_literal_symbols(arguments)?; self.load_literal_symbols(arguments)?;
self.build_fn_call(sym, fn_name, arguments, arg_layouts, ret_layout) self.build_fn_call(sym, fn_name, arguments, arg_layouts, ret_layout)
} else {
self.build_run_low_level_dev(
sym,
*func_sym,
arguments,
arg_layouts,
ret_layout,
)
} }
} }
@ -460,6 +471,37 @@ where
} }
} }
// build dev backend-only low-level
fn build_run_low_level_dev(
&mut self,
sym: &Symbol,
func_sym: Symbol,
args: &'a [Symbol],
arg_layouts: &[Layout<'a>],
ret_layout: &Layout<'a>,
) -> Result<(), String> {
self.load_literal_symbols(args)?;
match func_sym {
Symbol::NUM_IS_ZERO => {
debug_assert_eq!(
1,
args.len(),
"NumIsZero: expected to have exactly one argument"
);
debug_assert_eq!(
Layout::Builtin(Builtin::Int1),
*ret_layout,
"NumIsZero: expected to have return layout of type I1"
);
self.build_num_is_zero(sym, &args[0], &arg_layouts[0])
}
_ => Err(format!(
"the function, {:?}, is not yet implemented",
func_sym
)),
}
}
/// build_fn_call creates a call site for a function. /// build_fn_call creates a call site for a function.
/// This includes dealing with things like saving regs and propagating the returned value. /// This includes dealing with things like saving regs and propagating the returned value.
fn build_fn_call( fn build_fn_call(
@ -541,6 +583,14 @@ where
arg_layout: &Layout<'a>, arg_layout: &Layout<'a>,
) -> Result<(), String>; ) -> Result<(), String>;
/// build_num_is_zero stores the result of `src == 0` into dst.
fn build_num_is_zero(
&mut self,
dst: &Symbol,
src: &Symbol,
arg_layout: &Layout<'a>,
) -> Result<(), String>;
/// literal_map gets the map from symbol to literal, used for lazy loading and literal folding. /// literal_map gets the map from symbol to literal, used for lazy loading and literal folding.
fn literal_map(&mut self) -> &mut MutMap<Symbol, Literal<'a>>; fn literal_map(&mut self) -> &mut MutMap<Symbol, Literal<'a>>;