Fix and add memcpy-intrinsic

This commit is contained in:
Sofia 2025-08-04 17:49:04 +03:00
parent 627d1bcfa5
commit 3b4835cff8
5 changed files with 81 additions and 15 deletions

View File

@ -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];
} }

View File

@ -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

View File

@ -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"),

View File

@ -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);
} }

View File

@ -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 {