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