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