diff --git a/examples/math_intrinsics.reid b/examples/math_intrinsics.reid index a084be6..b6b7661 100644 --- a/examples/math_intrinsics.reid +++ b/examples/math_intrinsics.reid @@ -1,5 +1,14 @@ +extern fn printf(message: *char, num: f64); + fn main() -> i32 { let b = 5; - return i32::abs(-7); + let mut otus = i32::malloc(1); + otus[0] = 10500300; + let potus = i32::malloc(1); + i32::memcpy(potus, otus, 1); + + printf("log10 %f\n", f64::round(123.3) as f64); + printf("log10 %f\n", potus[0] as f64); + return potus[0]; } \ No newline at end of file diff --git a/libtest.sh b/libtest.sh index 19385a0..654be8a 100755 --- a/libtest.sh +++ b/libtest.sh @@ -16,7 +16,7 @@ BINARY="$(echo $1 | cut -d'.' -f1)"".out" echo $1 -cargo run --example cli $@ && \ +cargo run --example cli $@ && \ ./$BINARY ; echo "Return value: ""$?" ## Command from: clang -v hello.o -o test diff --git a/reid-llvm-lib/src/intrinsics.rs b/reid-llvm-lib/src/intrinsics.rs index 35494a6..b76b443 100644 --- a/reid-llvm-lib/src/intrinsics.rs +++ b/reid-llvm-lib/src/intrinsics.rs @@ -37,7 +37,7 @@ impl LLVMIntrinsic { let name = match ty.category() { 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)), + TypeCategory::Real => format!("llvm.maximum.{}", ty.llvm_ty_str(builder)), _ => return Err(crate::ErrorKind::Null), }; Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) @@ -46,7 +46,7 @@ impl LLVMIntrinsic { let name = match ty.category() { 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)), + TypeCategory::Real => format!("llvm.minimum.{}", ty.llvm_ty_str(builder)), _ => return Err(crate::ErrorKind::Null), }; Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) @@ -65,7 +65,7 @@ impl LLVMIntrinsic { TypeCategory::Ptr => String::from("llvm.memcpy"), _ => return Err(crate::ErrorKind::Null), }; - Ok((name, vec![ty.clone(), ty.clone()], Type::Void)) + Ok((name, vec![ty.clone(), ty.clone(), Type::U64, Type::Bool], Type::Void)) } LLVMIntrinsic::Sqrt(ty) => { let name = match ty.category() { @@ -221,7 +221,7 @@ impl LLVMIntrinsic { } LLVMIntrinsic::Round(ty) => { let name = match ty.category() { - TypeCategory::Real => format!("llvm.round.{}", ty.llvm_ty_str(builder)), + TypeCategory::Real => format!("llvm.rint.{}", ty.llvm_ty_str(builder)), _ => return Err(crate::ErrorKind::Null), }; Ok((name, vec![ty.clone()], ty.clone())) @@ -243,10 +243,10 @@ impl Type { Type::U32 => String::from("i32"), Type::U64 => String::from("i64"), Type::U128 => String::from("i128"), - Type::F16 => String::from("half"), - Type::F32B => String::from("bfloat"), - Type::F32 => String::from("float"), - Type::F64 => String::from("double"), + Type::F16 => String::from("f16"), + Type::F32B => String::from("f32b"), + Type::F32 => String::from("f32"), + Type::F64 => String::from("f64"), Type::F80 => String::from("x86_fp80"), Type::F128 => String::from("fp128"), Type::F128PPC => String::from("ppc_fp128"), diff --git a/reid/examples/cli.rs b/reid/examples/cli.rs index 24981f3..4d6612c 100644 --- a/reid/examples/cli.rs +++ b/reid/examples/cli.rs @@ -66,7 +66,7 @@ fn main() -> Result<(), std::io::Error> { } let linker = std::env::var("LD").unwrap_or("ld".to_owned()); - let mut linker = LDRunner::from_command(&linker).with_library("c"); + let mut linker = LDRunner::from_command(&linker).with_library("c").with_library("m"); for library in libraries { linker = linker.with_library(&library); } diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index 9e63d07..0435b4b 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -118,7 +118,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { linkage_name: None, is_pub: true, is_imported: false, - return_type: TypeKind::U64, + return_type: TypeKind::Void, parameters: vec![FunctionParam { name: String::from("self"), ty: TypeKind::Borrow(Box::new(ty.clone()), false), @@ -249,7 +249,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { linkage_name: None, is_pub: true, is_imported: false, - return_type: TypeKind::U64, + return_type: ty.clone(), parameters: vec![ FunctionParam { name: String::from("self"), @@ -258,12 +258,12 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { }, FunctionParam { name: String::from("exponent"), - ty: TypeKind::U64, + ty: TypeKind::U32, meta: Default::default(), }, ], kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM( - LLVMIntrinsicKind::PowI(ty.clone(), TypeKind::U64), + LLVMIntrinsicKind::PowI(ty.clone(), TypeKind::U32), ty.clone(), ))), source: None, @@ -342,6 +342,34 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { signature_meta: Default::default(), }); + intrinsics.push(FunctionDefinition { + name: "memcpy".to_owned(), + linkage_name: None, + is_pub: true, + is_imported: false, + return_type: TypeKind::Void, + parameters: vec![ + FunctionParam { + name: String::from("destination"), + ty: TypeKind::UserPtr(Box::new(ty.clone())), + meta: Default::default(), + }, + FunctionParam { + name: String::from("source"), + ty: TypeKind::UserPtr(Box::new(ty.clone())), + meta: Default::default(), + }, + FunctionParam { + name: String::from("length"), + ty: TypeKind::U64, + meta: Default::default(), + }, + ], + kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicMemcpy(ty.clone()))), + source: None, + signature_meta: Default::default(), + }); + intrinsics.push(FunctionDefinition { name: "null".to_owned(), linkage_name: None, @@ -652,6 +680,35 @@ impl IntrinsicFunction for IntrinsicSizeOf { } } +#[derive(Clone, Debug)] +pub struct IntrinsicMemcpy(TypeKind); +impl IntrinsicFunction for IntrinsicMemcpy { + fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result { + let dest = params.get(0).unwrap(); + let src = params.get(1).unwrap(); + let length = params.get(2).unwrap(); + let intrinsic = scope.get_intrinsic(LLVMIntrinsicKind::Memcpy(TypeKind::UserPtr(Box::new(self.0.clone())))); + + let sizeof = scope + .block + .build(Instr::Constant(ConstValueKind::U64( + self.0.size_of(&scope.type_map) / 8, + ))) + .unwrap(); + let bytes = scope.block.build(Instr::Mul(sizeof, length.instr())).unwrap(); + + dbg!(self.0.size_of(&scope.type_map) / 8); + let params = vec![ + dest.instr(), + src.instr(), + bytes, + scope.block.build(Instr::Constant(ConstValueKind::Bool(false))).unwrap(), + ]; + let value = scope.block.build(Instr::FunctionCall(intrinsic, params)).unwrap(); + Ok(StackValue(StackValueKind::Literal(value), TypeKind::Void)) + } +} + #[derive(Clone, Debug)] pub struct IntrinsicMalloc(TypeKind); impl IntrinsicFunction for IntrinsicMalloc {