Add FCmp
This commit is contained in:
parent
fe145ad2ef
commit
066f441a77
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user