diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index baf99e2..680d71a 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -668,7 +668,7 @@ impl FunctionHolder { LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMPrivateLinkage); } - if in_main_module && self.data.flags.is_main { + if in_main_module && self.data.flags.is_main || self.data.flags.is_pub { LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage); } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 869310a..5867c1d 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -148,7 +148,7 @@ impl Default for FunctionFlags { FunctionFlags { is_extern: false, is_main: false, - is_pub: false, + is_pub: true, is_imported: false, } } @@ -204,6 +204,38 @@ pub struct Block<'builder> { value: BlockValue, } +impl Instr { + pub fn default_name(&self) -> &str { + match self { + Instr::Param(_) => "param", + Instr::Constant(_) => "const1", + Instr::Add(..) => "add", + Instr::FAdd(..) => "fadd", + Instr::Sub(..) => "sub", + Instr::FSub(..) => "fsub", + Instr::Mul(..) => "mul", + Instr::FMul(..) => "fmul", + Instr::UDiv(..) => "udiv", + Instr::SDiv(..) => "sdiv", + Instr::FDiv(..) => "fdiv", + Instr::URem(..) => "urem", + Instr::SRem(..) => "srem", + Instr::FRem(..) => "frem", + Instr::And(..) => "and", + Instr::Phi(_) => "phi", + Instr::Alloca(_) => "alloca", + Instr::Load(_, _) => "load", + Instr::Store(..) => "store", + Instr::ArrayAlloca(_, _) => "arrayalloca", + Instr::GetElemPtr(..) => "getelemptr", + Instr::GetStructElemPtr(..) => "getstructelemptr", + Instr::ExtractValue(..) => "extractvalue", + Instr::ICmp(..) => "icmp", + Instr::FunctionCall(..) => "call", + } + } +} + impl<'builder> Block<'builder> { pub fn build>( &mut self, @@ -223,6 +255,21 @@ impl<'builder> Block<'builder> { } } + pub fn build_anon(&mut self, instruction: Instr) -> Result { + unsafe { + let name = instruction.default_name().to_owned(); + self.builder.add_instruction( + &self.value, + InstructionData { + kind: instruction, + location: None, + meta: None, + }, + name, + ) + } + } + pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) { unsafe { self.builder diff --git a/reid/src/codegen.rs b/reid/src/codegen.rs index 83ce607..ccd17c5 100644 --- a/reid/src/codegen.rs +++ b/reid/src/codegen.rs @@ -632,25 +632,22 @@ impl mir::Expression { .codegen(scope, state) .expect("rhs has no return value") .instr(); + let lhs_type = lhs_exp.return_type(&Default::default()).unwrap().1; + let instr = match (binop, lhs_type.signed(), lhs_type.is_float()) { + (mir::BinaryOperator::Add, _, false) => Instr::Add(lhs, rhs), + (mir::BinaryOperator::Add, _, true) => Instr::FAdd(lhs, rhs), + (mir::BinaryOperator::Minus, _, false) => Instr::Sub(lhs, rhs), + (mir::BinaryOperator::Minus, _, true) => Instr::FSub(lhs, rhs), + (mir::BinaryOperator::Mult, _, false) => Instr::Mul(lhs, rhs), + (mir::BinaryOperator::Mult, _, true) => Instr::FMul(lhs, rhs), + (mir::BinaryOperator::And, _, _) => Instr::And(lhs, rhs), + (mir::BinaryOperator::Cmp(i), _, true) => { + Instr::ICmp(i.int_predicate(), lhs, rhs) + } + _ => todo!(), + }; Some(StackValue( - StackValueKind::Immutable(match binop { - mir::BinaryOperator::Add => { - scope.block.build("add", Instr::Add(lhs, rhs)).unwrap() - } - mir::BinaryOperator::Minus => { - scope.block.build("sub", Instr::Sub(lhs, rhs)).unwrap() - } - mir::BinaryOperator::Mult => { - scope.block.build("mul", Instr::Mul(lhs, rhs)).unwrap() - } - mir::BinaryOperator::And => { - scope.block.build("and", Instr::And(lhs, rhs)).unwrap() - } - mir::BinaryOperator::Cmp(l) => scope - .block - .build("cmp", Instr::ICmp(l.int_predicate(), lhs, rhs)) - .unwrap(), - }), + StackValueKind::Immutable(scope.block.build_anon(instr).unwrap()), TypeKind::U32, )) } diff --git a/reid/src/lib.rs b/reid/src/lib.rs index eedc9d9..434087d 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -123,7 +123,7 @@ pub fn perform_all_passes<'map>( let state = context.pass(&mut LinkerPass { module_map, - ignore_no_main: true, + is_lib: true, })?; #[cfg(debug_assertions)] diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index 7f79e6e..c13ccc4 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -60,6 +60,37 @@ impl TypeKind { } } + pub fn is_float(&self) -> bool { + match self { + TypeKind::Bool => false, + TypeKind::I8 => false, + TypeKind::I16 => false, + TypeKind::I32 => false, + TypeKind::I64 => false, + TypeKind::I128 => false, + TypeKind::U8 => false, + TypeKind::U16 => false, + TypeKind::U32 => false, + TypeKind::U64 => false, + TypeKind::U128 => false, + TypeKind::Void => false, + TypeKind::StringPtr => false, + TypeKind::Array(_, _) => false, + TypeKind::CustomType(_) => false, + TypeKind::CodegenPtr(_) => false, + TypeKind::Vague(_) => false, + TypeKind::Borrow(_, _) => false, + TypeKind::UserPtr(_) => false, + TypeKind::F16 => true, + TypeKind::F32B => true, + TypeKind::F32 => true, + TypeKind::F64 => true, + TypeKind::F128 => true, + TypeKind::F80 => true, + TypeKind::F128PPC => true, + } + } + pub fn size_of(&self) -> u64 { match self { TypeKind::Bool => 1, diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index 7407238..7704666 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -63,7 +63,7 @@ pub fn compile_std( /// MIR. pub struct LinkerPass<'map> { pub module_map: &'map mut ModuleMap, - pub ignore_no_main: bool, + pub is_lib: bool, } type LinkerPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>; @@ -72,9 +72,9 @@ impl<'map> Pass for LinkerPass<'map> { type Data = (); type TError = ErrorKind; fn context(&mut self, context: &mut Context, mut state: LinkerPassState) -> PassResult { - let mains = context + let mut mains = context .modules - .iter() + .iter_mut() .filter(|m| m.is_main) .collect::>(); if mains.len() > 1 { @@ -83,13 +83,13 @@ impl<'map> Pass for LinkerPass<'map> { } if let Some(main) = mains.first() { if let None = main.functions.iter().find(|f| f.name == "main") { - if !self.ignore_no_main { + if !self.is_lib { state.note_errors(&vec![ErrorKind::NoMainFunction], Metadata::default()); return Ok(()); } }; } else { - if !self.ignore_no_main { + if !self.is_lib { state.note_errors(&vec![ErrorKind::NoMainDefined], Metadata::default()); return Ok(()); } diff --git a/reid_src/float.reid b/reid_src/float.reid index 7cbe158..94953ca 100644 --- a/reid_src/float.reid +++ b/reid_src/float.reid @@ -1,5 +1,5 @@ // Arithmetic, function calls and imports! -fn OneHalf(var1: f32) -> f32 { +pub fn OneHalf(var1: f32) -> f32 { return var1 * 1.5; }