Fix binary operators for floats, make library functions extern
This commit is contained in:
		
							parent
							
								
									feac7163f2
								
							
						
					
					
						commit
						3d3a9a34f9
					
				| @ -668,7 +668,7 @@ impl FunctionHolder { | |||||||
|                 LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMPrivateLinkage); |                 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); |                 LLVMSetLinkage(own_function.value_ref, LLVMLinkage::LLVMExternalLinkage); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -148,7 +148,7 @@ impl Default for FunctionFlags { | |||||||
|         FunctionFlags { |         FunctionFlags { | ||||||
|             is_extern: false, |             is_extern: false, | ||||||
|             is_main: false, |             is_main: false, | ||||||
|             is_pub: false, |             is_pub: true, | ||||||
|             is_imported: false, |             is_imported: false, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -204,6 +204,38 @@ pub struct Block<'builder> { | |||||||
|     value: BlockValue, |     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> { | impl<'builder> Block<'builder> { | ||||||
|     pub fn build<T: Into<String>>( |     pub fn build<T: Into<String>>( | ||||||
|         &mut self, |         &mut self, | ||||||
| @ -223,6 +255,21 @@ impl<'builder> Block<'builder> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn build_anon(&mut self, instruction: Instr) -> Result<InstructionValue, ()> { | ||||||
|  |         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) { |     pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.builder |             self.builder | ||||||
|  | |||||||
| @ -632,25 +632,22 @@ impl mir::Expression { | |||||||
|                     .codegen(scope, state) |                     .codegen(scope, state) | ||||||
|                     .expect("rhs has no return value") |                     .expect("rhs has no return value") | ||||||
|                     .instr(); |                     .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( |                 Some(StackValue( | ||||||
|                     StackValueKind::Immutable(match binop { |                     StackValueKind::Immutable(scope.block.build_anon(instr).unwrap()), | ||||||
|                         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(), |  | ||||||
|                     }), |  | ||||||
|                     TypeKind::U32, |                     TypeKind::U32, | ||||||
|                 )) |                 )) | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -123,7 +123,7 @@ pub fn perform_all_passes<'map>( | |||||||
| 
 | 
 | ||||||
|     let state = context.pass(&mut LinkerPass { |     let state = context.pass(&mut LinkerPass { | ||||||
|         module_map, |         module_map, | ||||||
|         ignore_no_main: true, |         is_lib: true, | ||||||
|     })?; |     })?; | ||||||
| 
 | 
 | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|  | |||||||
| @ -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 { |     pub fn size_of(&self) -> u64 { | ||||||
|         match self { |         match self { | ||||||
|             TypeKind::Bool => 1, |             TypeKind::Bool => 1, | ||||||
|  | |||||||
| @ -63,7 +63,7 @@ pub fn compile_std( | |||||||
| /// MIR.
 | /// MIR.
 | ||||||
| pub struct LinkerPass<'map> { | pub struct LinkerPass<'map> { | ||||||
|     pub module_map: &'map mut ModuleMap, |     pub module_map: &'map mut ModuleMap, | ||||||
|     pub ignore_no_main: bool, |     pub is_lib: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type LinkerPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>; | type LinkerPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>; | ||||||
| @ -72,9 +72,9 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|     type Data = (); |     type Data = (); | ||||||
|     type TError = ErrorKind; |     type TError = ErrorKind; | ||||||
|     fn context(&mut self, context: &mut Context, mut state: LinkerPassState) -> PassResult { |     fn context(&mut self, context: &mut Context, mut state: LinkerPassState) -> PassResult { | ||||||
|         let mains = context |         let mut mains = context | ||||||
|             .modules |             .modules | ||||||
|             .iter() |             .iter_mut() | ||||||
|             .filter(|m| m.is_main) |             .filter(|m| m.is_main) | ||||||
|             .collect::<Vec<_>>(); |             .collect::<Vec<_>>(); | ||||||
|         if mains.len() > 1 { |         if mains.len() > 1 { | ||||||
| @ -83,13 +83,13 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|         } |         } | ||||||
|         if let Some(main) = mains.first() { |         if let Some(main) = mains.first() { | ||||||
|             if let None = main.functions.iter().find(|f| f.name == "main") { |             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()); |                     state.note_errors(&vec![ErrorKind::NoMainFunction], Metadata::default()); | ||||||
|                     return Ok(()); |                     return Ok(()); | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
|         } else { |         } else { | ||||||
|             if !self.ignore_no_main { |             if !self.is_lib { | ||||||
|                 state.note_errors(&vec![ErrorKind::NoMainDefined], Metadata::default()); |                 state.note_errors(&vec![ErrorKind::NoMainDefined], Metadata::default()); | ||||||
|                 return Ok(()); |                 return Ok(()); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| // Arithmetic, function calls and imports! | // Arithmetic, function calls and imports! | ||||||
| 
 | 
 | ||||||
| fn OneHalf(var1: f32) -> f32 { | pub fn OneHalf(var1: f32) -> f32 { | ||||||
|   return var1 * 1.5; |   return var1 * 1.5; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user