Fix and add memcpy-intrinsic
This commit is contained in:
		
							parent
							
								
									627d1bcfa5
								
							
						
					
					
						commit
						3b4835cff8
					
				| @ -1,5 +1,14 @@ | |||||||
| 
 | 
 | ||||||
|  | extern fn printf(message: *char, num: f64); | ||||||
|  | 
 | ||||||
| fn main() -> i32 { | fn main() -> i32 { | ||||||
|     let b = 5; |     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]; | ||||||
| } | } | ||||||
| @ -16,7 +16,7 @@ BINARY="$(echo $1 | cut -d'.' -f1)"".out" | |||||||
| 
 | 
 | ||||||
| echo $1 | echo $1 | ||||||
| 
 | 
 | ||||||
| cargo run  --example cli $@ && \ | cargo run --example cli $@ && \ | ||||||
| ./$BINARY ; echo "Return value: ""$?" | ./$BINARY ; echo "Return value: ""$?" | ||||||
| 
 | 
 | ||||||
| ## Command from: clang -v hello.o -o test | ## Command from: clang -v hello.o -o test | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ impl LLVMIntrinsic { | |||||||
|                 let name = match ty.category() { |                 let name = match ty.category() { | ||||||
|                     TypeCategory::SignedInteger => format!("llvm.smax.{}", 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::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), |                     _ => return Err(crate::ErrorKind::Null), | ||||||
|                 }; |                 }; | ||||||
|                 Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) |                 Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) | ||||||
| @ -46,7 +46,7 @@ impl LLVMIntrinsic { | |||||||
|                 let name = match ty.category() { |                 let name = match ty.category() { | ||||||
|                     TypeCategory::SignedInteger => format!("llvm.smin.{}", 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::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), |                     _ => return Err(crate::ErrorKind::Null), | ||||||
|                 }; |                 }; | ||||||
|                 Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) |                 Ok((name, vec![ty.clone(), ty.clone()], ty.clone())) | ||||||
| @ -65,7 +65,7 @@ impl LLVMIntrinsic { | |||||||
|                     TypeCategory::Ptr => String::from("llvm.memcpy"), |                     TypeCategory::Ptr => String::from("llvm.memcpy"), | ||||||
|                     _ => return Err(crate::ErrorKind::Null), |                     _ => 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) => { |             LLVMIntrinsic::Sqrt(ty) => { | ||||||
|                 let name = match ty.category() { |                 let name = match ty.category() { | ||||||
| @ -221,7 +221,7 @@ impl LLVMIntrinsic { | |||||||
|             } |             } | ||||||
|             LLVMIntrinsic::Round(ty) => { |             LLVMIntrinsic::Round(ty) => { | ||||||
|                 let name = match ty.category() { |                 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), |                     _ => return Err(crate::ErrorKind::Null), | ||||||
|                 }; |                 }; | ||||||
|                 Ok((name, vec![ty.clone()], ty.clone())) |                 Ok((name, vec![ty.clone()], ty.clone())) | ||||||
| @ -243,10 +243,10 @@ impl Type { | |||||||
|             Type::U32 => String::from("i32"), |             Type::U32 => String::from("i32"), | ||||||
|             Type::U64 => String::from("i64"), |             Type::U64 => String::from("i64"), | ||||||
|             Type::U128 => String::from("i128"), |             Type::U128 => String::from("i128"), | ||||||
|             Type::F16 => String::from("half"), |             Type::F16 => String::from("f16"), | ||||||
|             Type::F32B => String::from("bfloat"), |             Type::F32B => String::from("f32b"), | ||||||
|             Type::F32 => String::from("float"), |             Type::F32 => String::from("f32"), | ||||||
|             Type::F64 => String::from("double"), |             Type::F64 => String::from("f64"), | ||||||
|             Type::F80 => String::from("x86_fp80"), |             Type::F80 => String::from("x86_fp80"), | ||||||
|             Type::F128 => String::from("fp128"), |             Type::F128 => String::from("fp128"), | ||||||
|             Type::F128PPC => String::from("ppc_fp128"), |             Type::F128PPC => String::from("ppc_fp128"), | ||||||
|  | |||||||
| @ -66,7 +66,7 @@ fn main() -> Result<(), std::io::Error> { | |||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 let linker = std::env::var("LD").unwrap_or("ld".to_owned()); |                 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 { |                 for library in libraries { | ||||||
|                     linker = linker.with_library(&library); |                     linker = linker.with_library(&library); | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -118,7 +118,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> { | |||||||
|             linkage_name: None, |             linkage_name: None, | ||||||
|             is_pub: true, |             is_pub: true, | ||||||
|             is_imported: false, |             is_imported: false, | ||||||
|             return_type: TypeKind::U64, |             return_type: TypeKind::Void, | ||||||
|             parameters: vec![FunctionParam { |             parameters: vec![FunctionParam { | ||||||
|                 name: String::from("self"), |                 name: String::from("self"), | ||||||
|                 ty: TypeKind::Borrow(Box::new(ty.clone()), false), |                 ty: TypeKind::Borrow(Box::new(ty.clone()), false), | ||||||
| @ -249,7 +249,7 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> { | |||||||
|             linkage_name: None, |             linkage_name: None, | ||||||
|             is_pub: true, |             is_pub: true, | ||||||
|             is_imported: false, |             is_imported: false, | ||||||
|             return_type: TypeKind::U64, |             return_type: ty.clone(), | ||||||
|             parameters: vec![ |             parameters: vec![ | ||||||
|                 FunctionParam { |                 FunctionParam { | ||||||
|                     name: String::from("self"), |                     name: String::from("self"), | ||||||
| @ -258,12 +258,12 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> { | |||||||
|                 }, |                 }, | ||||||
|                 FunctionParam { |                 FunctionParam { | ||||||
|                     name: String::from("exponent"), |                     name: String::from("exponent"), | ||||||
|                     ty: TypeKind::U64, |                     ty: TypeKind::U32, | ||||||
|                     meta: Default::default(), |                     meta: Default::default(), | ||||||
|                 }, |                 }, | ||||||
|             ], |             ], | ||||||
|             kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM( |             kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicLLVM( | ||||||
|                 LLVMIntrinsicKind::PowI(ty.clone(), TypeKind::U64), |                 LLVMIntrinsicKind::PowI(ty.clone(), TypeKind::U32), | ||||||
|                 ty.clone(), |                 ty.clone(), | ||||||
|             ))), |             ))), | ||||||
|             source: None, |             source: None, | ||||||
| @ -342,6 +342,34 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> { | |||||||
|         signature_meta: Default::default(), |         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 { |     intrinsics.push(FunctionDefinition { | ||||||
|         name: "null".to_owned(), |         name: "null".to_owned(), | ||||||
|         linkage_name: None, |         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<StackValue, ErrorKind> { | ||||||
|  |         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)] | #[derive(Clone, Debug)] | ||||||
| pub struct IntrinsicMalloc(TypeKind); | pub struct IntrinsicMalloc(TypeKind); | ||||||
| impl IntrinsicFunction for IntrinsicMalloc { | impl IntrinsicFunction for IntrinsicMalloc { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user