This commit is contained in:
Sofia 2025-07-21 20:34:27 +03:00
parent fe145ad2ef
commit 066f441a77
4 changed files with 71 additions and 4 deletions

View File

@ -5,7 +5,7 @@ use std::{cell::RefCell, rc::Rc};
use crate::{
BlockData, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, NamedStruct,
TerminatorKind, Type, TypeData,
TerminatorKind, Type, TypeCategory, TypeData,
debug_information::{
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
InstructionDebugRecordData,
@ -369,7 +369,15 @@ impl Builder {
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
Instr::ICmp(_, lhs, rhs) => {
let t = match_types(&lhs, &rhs, self)?;
if t.comparable() {
if t.comparable() || t.category() != TypeCategory::Integer {
Ok(())
} else {
Err(()) // TODO error: Types not comparable
}
}
Instr::FCmp(_, lhs, rhs) => {
let t = match_types(&lhs, &rhs, self)?;
if t.comparable() || t.category() != TypeCategory::Real {
Ok(())
} else {
Err(()) // TODO error: Types not comparable

View File

@ -8,7 +8,7 @@ use std::{
};
use llvm_sys::{
LLVMIntPredicate, LLVMLinkage, LLVMValueKind,
LLVMIntPredicate, LLVMLinkage, LLVMRealPredicate, LLVMValueKind,
analysis::LLVMVerifyModule,
core::*,
debuginfo::*,
@ -774,7 +774,6 @@ impl InstructionHolder {
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
}
FMul(lhs, rhs) => {
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
@ -827,6 +826,17 @@ impl InstructionHolder {
name.as_ptr(),
)
}
FCmp(pred, lhs, rhs) => {
let lhs = module.values.get(&lhs).unwrap();
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
LLVMBuildFCmp(
module.builder_ref,
pred.as_llvm_unsorted_float(),
lhs.value_ref,
rhs_val,
name.as_ptr(),
)
}
FunctionCall(function_value, instruction_values) => {
let fun = module.functions.get(&function_value).unwrap();
let mut param_list: Vec<LLVMValueRef> = instruction_values
@ -1057,6 +1067,19 @@ impl CmpPredicate {
(NE, _) => LLVMIntNE,
}
}
fn as_llvm_unsorted_float(&self) -> LLVMRealPredicate {
use CmpPredicate::*;
use LLVMRealPredicate::*;
match self {
LT => LLVMRealULT,
LE => LLVMRealULE,
GT => LLVMRealUGT,
GE => LLVMRealUGE,
EQ => LLVMRealUEQ,
NE => LLVMRealUNE,
}
}
}
impl ConstValue {

View File

@ -317,6 +317,7 @@ impl Debug for Instr {
Instr::And(lhs, rhs) => fmt_binop(f, lhs, &"&&", rhs),
Instr::Phi(val) => fmt_call(f, &"Phi", &val),
Instr::ICmp(cmp, lhs, rhs) => fmt_binop(f, lhs, cmp, rhs),
Instr::FCmp(cmp, lhs, rhs) => fmt_binop(f, lhs, cmp, rhs),
Instr::FunctionCall(fun, params) => fmt_call(f, fun, params),
Instr::Alloca(ty) => write!(f, "alloca<{:?}>", ty),
Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),

View File

@ -232,6 +232,7 @@ impl Instr {
Instr::ExtractValue(..) => "extractvalue",
Instr::ICmp(..) => "icmp",
Instr::FunctionCall(..) => "call",
Instr::FCmp(_, _, _) => "fcmp",
}
}
}
@ -396,6 +397,7 @@ pub enum Instr {
/// Integer Comparison
ICmp(CmpPredicate, InstructionValue, InstructionValue),
FCmp(CmpPredicate, InstructionValue, InstructionValue),
FunctionCall(FunctionValue, Vec<InstructionValue>),
}
@ -497,6 +499,7 @@ impl InstructionValue {
FRem(lhs, rhs) => match_types(lhs, rhs, &builder),
And(lhs, rhs) => match_types(lhs, rhs, &builder),
ICmp(_, _, _) => Ok(Type::Bool),
FCmp(_, _, _) => Ok(Type::Bool),
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)),
Alloca(ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
@ -629,6 +632,38 @@ impl Type {
Type::F128PPC => true,
}
}
pub fn category(&self) -> TypeCategory {
match self {
Type::I8
| Type::I16
| Type::I32
| Type::I64
| Type::I128
| Type::U8
| Type::U16
| Type::U32
| Type::U64
| Type::U128 => TypeCategory::Integer,
Type::F16
| Type::F32B
| Type::F32
| Type::F64
| Type::F80
| Type::F128
| Type::F128PPC => TypeCategory::Real,
Type::Bool | Type::Void | Type::CustomType(_) | Type::Array(_, _) | Type::Ptr(_) => {
TypeCategory::Other
}
}
}
}
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub enum TypeCategory {
Integer,
Real,
Other,
}
impl TerminatorKind {