From 627d1bcfa53c58be933e4688f35e0674b0b7fa58 Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 4 Aug 2025 16:55:47 +0300 Subject: [PATCH] Add a large amount of new intrinsics --- examples/math_intrinsics.reid | 2 +- reid-llvm-lib/src/intrinsics.rs | 220 +++++++++++++++++++++-- reid/src/codegen/intrinsics.rs | 306 +++++++++++++++++++++++++++----- reid/src/codegen/scope.rs | 41 +++-- 4 files changed, 504 insertions(+), 65 deletions(-) diff --git a/examples/math_intrinsics.reid b/examples/math_intrinsics.reid index 2d8fd2e..a084be6 100644 --- a/examples/math_intrinsics.reid +++ b/examples/math_intrinsics.reid @@ -1,5 +1,5 @@ fn main() -> i32 { let b = 5; - return b.min(7); + return i32::abs(-7); } \ No newline at end of file diff --git a/reid-llvm-lib/src/intrinsics.rs b/reid-llvm-lib/src/intrinsics.rs index 520ed5b..35494a6 100644 --- a/reid-llvm-lib/src/intrinsics.rs +++ b/reid-llvm-lib/src/intrinsics.rs @@ -1,37 +1,231 @@ -use crate::{CompileResult, Type, builder::Builder}; +use crate::{CompileResult, Type, TypeCategory, builder::Builder}; #[derive(Clone, Debug)] pub enum LLVMIntrinsic { + Abs(Type), Max(Type), Min(Type), + Memcpy(Type), + Sqrt(Type), + PowI(Type, Type), + Pow(Type), + Sin(Type), + Cos(Type), + Tan(Type), + ASin(Type), + ACos(Type), + ATan(Type), + ATan2(Type), + SinH(Type), + CosH(Type), + TanH(Type), + Log(Type), + Log2(Type), + Log10(Type), + Copysign(Type), + Floor(Type), + Ceil(Type), + Trunc(Type), + RoundEven(Type), + Round(Type), } impl LLVMIntrinsic { - pub fn check(&self, builder: &Builder) -> CompileResult<()> { - self.signature(builder)?; - Ok(()) - } - - pub fn signature(&self, builder: &Builder) -> CompileResult<(String, Vec, Type)> { + pub(crate) fn signature(&self, builder: &Builder) -> CompileResult<(String, Vec, Type)> { match self { LLVMIntrinsic::Max(ty) => { let name = match ty.category() { - crate::TypeCategory::SignedInteger => format!("llvm.smax.{}", ty.llvm_ty_str(builder)), - crate::TypeCategory::UnsignedInteger => format!("llvm.umax.{}", ty.llvm_ty_str(builder)), - crate::TypeCategory::Real => format!("llvm.max.{}", ty.llvm_ty_str(builder)), + TypeCategory::SignedInteger => format!("llvm.smax.{}", ty.llvm_ty_str(builder)), + TypeCategory::UnsignedInteger => format!("llvm.umax.{}", ty.llvm_ty_str(builder)), + TypeCategory::Real => format!("llvm.max.{}", ty.llvm_ty_str(builder)), _ => return Err(crate::ErrorKind::Null), }; Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) } LLVMIntrinsic::Min(ty) => { let name = match ty.category() { - crate::TypeCategory::SignedInteger => format!("llvm.smin.{}", ty.llvm_ty_str(builder)), - crate::TypeCategory::UnsignedInteger => format!("llvm.umin.{}", ty.llvm_ty_str(builder)), - crate::TypeCategory::Real => format!("llvm.min.{}", ty.llvm_ty_str(builder)), + TypeCategory::SignedInteger => format!("llvm.smin.{}", ty.llvm_ty_str(builder)), + TypeCategory::UnsignedInteger => format!("llvm.umin.{}", ty.llvm_ty_str(builder)), + TypeCategory::Real => format!("llvm.min.{}", ty.llvm_ty_str(builder)), _ => return Err(crate::ErrorKind::Null), }; Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) } + LLVMIntrinsic::Abs(ty) => { + let name = match ty.category() { + TypeCategory::SignedInteger => format!("llvm.abs.{}", ty.llvm_ty_str(builder)), + TypeCategory::UnsignedInteger => format!("llvm.abs.{}", ty.llvm_ty_str(builder)), + TypeCategory::Real => format!("llvm.fabs.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone(), Type::Bool], ty.clone())) + } + LLVMIntrinsic::Memcpy(ty) => { + let name = match ty.category() { + TypeCategory::Ptr => String::from("llvm.memcpy"), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone(), ty.clone()], Type::Void)) + } + LLVMIntrinsic::Sqrt(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.sqrt.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::PowI(ty1, ty2) => { + let name = match (ty1.category(), ty2.category()) { + (TypeCategory::Real, TypeCategory::SignedInteger) => { + format!("llvm.powi.{}.{}", ty1.llvm_ty_str(builder), ty2.llvm_ty_str(builder)) + } + (TypeCategory::Real, TypeCategory::UnsignedInteger) => { + format!("llvm.powi.{}.{}", ty1.llvm_ty_str(builder), ty2.llvm_ty_str(builder)) + } + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty1.clone(), ty2.clone()], ty1.clone())) + } + LLVMIntrinsic::Pow(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.pow.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) + } + LLVMIntrinsic::Sin(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.sin.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Cos(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.cos.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Tan(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.tan.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::ASin(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.asin.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::ACos(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.acos.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::ATan(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.atan.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::ATan2(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.atan2.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) + } + LLVMIntrinsic::SinH(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.sinh.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::CosH(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.cosh.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::TanH(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.tanh.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Log(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.log.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Log2(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.log2.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Log10(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.log10.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Copysign(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.copysign.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Floor(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.floor.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Ceil(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.ceil.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Trunc(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.trunc.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::RoundEven(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.roundeven.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } + LLVMIntrinsic::Round(ty) => { + let name = match ty.category() { + TypeCategory::Real => format!("llvm.round.{}", ty.llvm_ty_str(builder)), + _ => return Err(crate::ErrorKind::Null), + }; + Ok((name, vec![ty.clone()], ty.clone())) + } } } } diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index af08835..9e63d07 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -1,7 +1,7 @@ use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; use crate::{ - codegen::{scope::IntrinsicKind, ErrorKind, StackValueKind}, + codegen::{ErrorKind, StackValueKind}, mir::{ implement::TypeCategory, BinaryOperator, BinopDefinition, CmpOperator, FunctionDefinition, FunctionDefinitionKind, FunctionParam, TypeKind, @@ -33,6 +33,36 @@ const FLOATS: [TypeKind; 7] = [ TypeKind::F128PPC, ]; +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub enum LLVMIntrinsicKind { + Max(TypeKind), + Min(TypeKind), + Abs(TypeKind), + Memcpy(TypeKind), + Sqrt(TypeKind), + PowI(TypeKind, TypeKind), + Pow(TypeKind), + Sin(TypeKind), + Cos(TypeKind), + Tan(TypeKind), + ASin(TypeKind), + ACos(TypeKind), + ATan(TypeKind), + ATan2(TypeKind), + SinH(TypeKind), + CosH(TypeKind), + TanH(TypeKind), + Log(TypeKind), + Log2(TypeKind), + Log10(TypeKind), + Copysign(TypeKind), + Floor(TypeKind), + Ceil(TypeKind), + Trunc(TypeKind), + RoundEven(TypeKind), + Round(TypeKind), +} + const INTRINSIC_IDENT: &str = "reid.intrinsic"; const MALLOC_IDENT: &str = "malloc"; @@ -58,6 +88,28 @@ pub fn form_intrinsics() -> Vec { intrinsics } +pub fn simple_intrinsic + Clone>( + name: T, + params: Vec, + ret: TypeKind, + intrisic: LLVMIntrinsicKind, +) -> FunctionDefinition { + FunctionDefinition { + name: name.into(), + linkage_name: None, + is_pub: true, + is_imported: false, + return_type: ret.clone(), + parameters: params + .iter() + .map(|p| FunctionParam::from(p.clone(), ret.clone())) + .collect(), + kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM(intrisic, ret.clone()))), + source: None, + signature_meta: Default::default(), + } +} + pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { let mut intrinsics = Vec::new(); if let TypeKind::Array(_, len) = ty { @@ -77,42 +129,189 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { signature_meta: Default::default(), }); } + if ty.category() == TypeCategory::Real { + intrinsics.push(simple_intrinsic( + "sin", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Sin(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "cos", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Cos(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "tan", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Tan(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "sinh", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::SinH(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "cosh", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::CosH(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "tanh", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::TanH(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "asin", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::ASin(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "acos", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::ACos(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "atan", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::ATan(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "atan2", + vec!["self", "other"], + ty.clone(), + LLVMIntrinsicKind::ATan2(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "log", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Log(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "log2", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Log2(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "log10", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Log10(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "floor", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Floor(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "ceil", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Ceil(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "trunc", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Trunc(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "round", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::Round(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "even", + vec!["self"], + ty.clone(), + LLVMIntrinsicKind::RoundEven(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "pow", + vec!["self", "exponent"], + ty.clone(), + LLVMIntrinsicKind::Pow(ty.clone()), + )); + intrinsics.push(FunctionDefinition { + name: "powi".to_owned(), + linkage_name: None, + is_pub: true, + is_imported: false, + return_type: TypeKind::U64, + parameters: vec![ + FunctionParam { + name: String::from("self"), + ty: ty.clone(), + meta: Default::default(), + }, + FunctionParam { + name: String::from("exponent"), + ty: TypeKind::U64, + meta: Default::default(), + }, + ], + kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM( + LLVMIntrinsicKind::PowI(ty.clone(), TypeKind::U64), + ty.clone(), + ))), + source: None, + signature_meta: Default::default(), + }); + } match ty.category() { TypeCategory::Integer | TypeCategory::Real | TypeCategory::Bool => { - intrinsics.push(FunctionDefinition { - name: "max".to_owned(), - linkage_name: None, - is_pub: true, - is_imported: false, - return_type: ty.clone(), - parameters: vec![ - FunctionParam::from("self", ty.clone()), - FunctionParam::from("other", ty.clone()), - ], - kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM( - IntrinsicKind::Max(ty.clone()), - ty.clone(), - ))), - source: None, - signature_meta: Default::default(), - }); - intrinsics.push(FunctionDefinition { - name: "min".to_owned(), - linkage_name: None, - is_pub: true, - is_imported: false, - return_type: ty.clone(), - parameters: vec![ - FunctionParam::from("self", ty.clone()), - FunctionParam::from("other", ty.clone()), - ], - kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM( - IntrinsicKind::Min(ty.clone()), - ty.clone(), - ))), - source: None, - signature_meta: Default::default(), - }); + intrinsics.push(simple_intrinsic( + "max", + vec!["self", "other"], + ty.clone(), + LLVMIntrinsicKind::Max(ty.clone()), + )); + intrinsics.push(simple_intrinsic( + "min", + vec!["self", "other"], + ty.clone(), + LLVMIntrinsicKind::Min(ty.clone()), + )); + if ty.signed() { + intrinsics.push(FunctionDefinition { + name: "abs".to_owned(), + linkage_name: None, + is_pub: true, + is_imported: false, + return_type: ty.clone(), + parameters: vec![FunctionParam { + name: String::from("self"), + ty: ty.clone(), + meta: Default::default(), + }], + kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleUnaryInstr({ + let ty = ty.clone(); + |scope, param| { + let intrinsic = scope.get_intrinsic(LLVMIntrinsicKind::Abs(ty)); + let constant = scope.block.build(Instr::Constant(ConstValueKind::Bool(false))).unwrap(); + let value = scope + .block + .build(Instr::FunctionCall(intrinsic, vec![param, constant])) + .unwrap(); + value + } + }))), + source: None, + signature_meta: Default::default(), + }); + } } _ => {} } @@ -179,7 +378,7 @@ where meta: Default::default(), }, return_type: ty.clone(), - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), + fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleBinaryInstr(fun))), meta: Default::default(), exported: false, } @@ -202,7 +401,7 @@ where meta: Default::default(), }, return_type: lhs.clone(), - fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), + fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleBinaryInstr(fun))), meta: Default::default(), exported: false, } @@ -379,12 +578,37 @@ macro_rules! intrinsic_debug { } #[derive(Clone)] -pub struct IntrinsicSimpleInstr(T) +pub struct IntrinsicSimpleUnaryInstr(T) +where + T: FnOnce(&mut Scope, InstructionValue) -> InstructionValue; + +impl std::fmt::Debug for IntrinsicSimpleUnaryInstr +where + T: FnOnce(&mut Scope, InstructionValue) -> InstructionValue, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("IntrinsicSimpleUnaryInstr").finish() + } +} + +impl IntrinsicFunction for IntrinsicSimpleUnaryInstr +where + T: FnOnce(&mut Scope, InstructionValue) -> InstructionValue, +{ + fn codegen<'b, 'c>(&self, scope: &mut Scope<'b, 'c>, params: &[StackValue]) -> Result { + let param = params.get(0).unwrap(); + let instr = self.clone().0(scope, param.instr()); + Ok(StackValue(StackValueKind::Literal(instr), param.1.clone())) + } +} + +#[derive(Clone)] +pub struct IntrinsicSimpleBinaryInstr(T) where T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue; -intrinsic_debug!(IntrinsicSimpleInstr, "IntrinsicSimpleInstr"); +intrinsic_debug!(IntrinsicSimpleBinaryInstr, "IntrinsicSimpleBinaryInstr"); -impl IntrinsicFunction for IntrinsicSimpleInstr +impl IntrinsicFunction for IntrinsicSimpleBinaryInstr where T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, { @@ -479,7 +703,7 @@ impl IntrinsicFunction for IntrinsicConst { } #[derive(Clone, Debug)] -pub struct IntrinsicLLVM(IntrinsicKind, TypeKind); +pub struct IntrinsicLLVM(LLVMIntrinsicKind, TypeKind); impl IntrinsicFunction for IntrinsicLLVM { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result { let intrinsic = scope.get_intrinsic(self.0.clone()); diff --git a/reid/src/codegen/scope.rs b/reid/src/codegen/scope.rs index fbfefd1..4e8fcd5 100644 --- a/reid/src/codegen/scope.rs +++ b/reid/src/codegen/scope.rs @@ -8,6 +8,7 @@ use reid_lib::{ }; use crate::{ + codegen::intrinsics::LLVMIntrinsicKind, lexer::FullToken, mir::{ pass::{AssociatedFunctionKey, BinopKey}, @@ -17,12 +18,6 @@ use crate::{ use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen}; -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -pub enum IntrinsicKind { - Max(TypeKind), - Min(TypeKind), -} - pub struct Scope<'ctx, 'scope> { pub(super) context: &'ctx Context, pub(super) modules: &'scope HashMap>, @@ -41,7 +36,7 @@ pub struct Scope<'ctx, 'scope> { pub(super) globals: &'scope HashMap, pub(super) debug: Option>, pub(super) allocator: Rc>, - pub(super) llvm_intrinsics: Rc>>, + pub(super) llvm_intrinsics: Rc>>, } impl<'ctx, 'a> Scope<'ctx, 'a> { @@ -84,7 +79,7 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { self.allocator.borrow_mut().allocate(meta, ty) } - pub fn get_intrinsic(&self, kind: IntrinsicKind) -> FunctionValue { + pub fn get_intrinsic(&self, kind: LLVMIntrinsicKind) -> FunctionValue { let mut intrinsics = self.llvm_intrinsics.borrow_mut(); if let Some(fun) = intrinsics.get(&kind) { *fun @@ -92,8 +87,34 @@ impl<'ctx, 'a> Scope<'ctx, 'a> { let intrinsic = self .module .intrinsic(match &kind { - IntrinsicKind::Max(ty) => LLVMIntrinsic::Max(ty.get_type(self.type_values)), - IntrinsicKind::Min(ty) => LLVMIntrinsic::Min(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Max(ty) => LLVMIntrinsic::Max(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Min(ty) => LLVMIntrinsic::Min(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Abs(ty) => LLVMIntrinsic::Abs(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Memcpy(ty) => LLVMIntrinsic::Memcpy(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Sqrt(ty) => LLVMIntrinsic::Sqrt(ty.get_type(self.type_values)), + LLVMIntrinsicKind::PowI(lhs, rhs) => { + LLVMIntrinsic::PowI(lhs.get_type(self.type_values), rhs.get_type(self.type_values)) + } + LLVMIntrinsicKind::Pow(ty) => LLVMIntrinsic::Pow(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Sin(ty) => LLVMIntrinsic::Sin(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Cos(ty) => LLVMIntrinsic::Cos(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Tan(ty) => LLVMIntrinsic::Tan(ty.get_type(self.type_values)), + LLVMIntrinsicKind::ASin(ty) => LLVMIntrinsic::ASin(ty.get_type(self.type_values)), + LLVMIntrinsicKind::ACos(ty) => LLVMIntrinsic::ACos(ty.get_type(self.type_values)), + LLVMIntrinsicKind::ATan(ty) => LLVMIntrinsic::ATan(ty.get_type(self.type_values)), + LLVMIntrinsicKind::ATan2(ty) => LLVMIntrinsic::ATan2(ty.get_type(self.type_values)), + LLVMIntrinsicKind::SinH(ty) => LLVMIntrinsic::SinH(ty.get_type(self.type_values)), + LLVMIntrinsicKind::CosH(ty) => LLVMIntrinsic::CosH(ty.get_type(self.type_values)), + LLVMIntrinsicKind::TanH(ty) => LLVMIntrinsic::TanH(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Log(ty) => LLVMIntrinsic::Log(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Log2(ty) => LLVMIntrinsic::Log2(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Log10(ty) => LLVMIntrinsic::Log10(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Copysign(ty) => LLVMIntrinsic::Copysign(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Floor(ty) => LLVMIntrinsic::Floor(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Ceil(ty) => LLVMIntrinsic::Ceil(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Trunc(ty) => LLVMIntrinsic::Trunc(ty.get_type(self.type_values)), + LLVMIntrinsicKind::RoundEven(ty) => LLVMIntrinsic::RoundEven(ty.get_type(self.type_values)), + LLVMIntrinsicKind::Round(ty) => LLVMIntrinsic::Round(ty.get_type(self.type_values)), }) .unwrap(); intrinsics.insert(kind, intrinsic.clone());