Add FCmp
This commit is contained in:
parent
fe145ad2ef
commit
066f441a77
@ -5,7 +5,7 @@ use std::{cell::RefCell, rc::Rc};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BlockData, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, NamedStruct,
|
BlockData, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, NamedStruct,
|
||||||
TerminatorKind, Type, TypeData,
|
TerminatorKind, Type, TypeCategory, TypeData,
|
||||||
debug_information::{
|
debug_information::{
|
||||||
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue,
|
||||||
InstructionDebugRecordData,
|
InstructionDebugRecordData,
|
||||||
@ -369,7 +369,15 @@ impl Builder {
|
|||||||
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
Instr::And(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||||
Instr::ICmp(_, lhs, rhs) => {
|
Instr::ICmp(_, lhs, rhs) => {
|
||||||
let t = match_types(&lhs, &rhs, self)?;
|
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(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(()) // TODO error: Types not comparable
|
Err(()) // TODO error: Types not comparable
|
||||||
|
@ -8,7 +8,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use llvm_sys::{
|
use llvm_sys::{
|
||||||
LLVMIntPredicate, LLVMLinkage, LLVMValueKind,
|
LLVMIntPredicate, LLVMLinkage, LLVMRealPredicate, LLVMValueKind,
|
||||||
analysis::LLVMVerifyModule,
|
analysis::LLVMVerifyModule,
|
||||||
core::*,
|
core::*,
|
||||||
debuginfo::*,
|
debuginfo::*,
|
||||||
@ -774,7 +774,6 @@ impl InstructionHolder {
|
|||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
LLVMBuildMul(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
||||||
}
|
}
|
||||||
|
|
||||||
FMul(lhs, rhs) => {
|
FMul(lhs, rhs) => {
|
||||||
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
let lhs_val = module.values.get(&lhs).unwrap().value_ref;
|
||||||
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
let rhs_val = module.values.get(&rhs).unwrap().value_ref;
|
||||||
@ -827,6 +826,17 @@ impl InstructionHolder {
|
|||||||
name.as_ptr(),
|
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) => {
|
FunctionCall(function_value, instruction_values) => {
|
||||||
let fun = module.functions.get(&function_value).unwrap();
|
let fun = module.functions.get(&function_value).unwrap();
|
||||||
let mut param_list: Vec<LLVMValueRef> = instruction_values
|
let mut param_list: Vec<LLVMValueRef> = instruction_values
|
||||||
@ -1057,6 +1067,19 @@ impl CmpPredicate {
|
|||||||
(NE, _) => LLVMIntNE,
|
(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 {
|
impl ConstValue {
|
||||||
|
@ -317,6 +317,7 @@ impl Debug for Instr {
|
|||||||
Instr::And(lhs, rhs) => fmt_binop(f, lhs, &"&&", rhs),
|
Instr::And(lhs, rhs) => fmt_binop(f, lhs, &"&&", rhs),
|
||||||
Instr::Phi(val) => fmt_call(f, &"Phi", &val),
|
Instr::Phi(val) => fmt_call(f, &"Phi", &val),
|
||||||
Instr::ICmp(cmp, lhs, rhs) => fmt_binop(f, lhs, cmp, rhs),
|
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::FunctionCall(fun, params) => fmt_call(f, fun, params),
|
||||||
Instr::Alloca(ty) => write!(f, "alloca<{:?}>", ty),
|
Instr::Alloca(ty) => write!(f, "alloca<{:?}>", ty),
|
||||||
Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
|
Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
|
||||||
|
@ -232,6 +232,7 @@ impl Instr {
|
|||||||
Instr::ExtractValue(..) => "extractvalue",
|
Instr::ExtractValue(..) => "extractvalue",
|
||||||
Instr::ICmp(..) => "icmp",
|
Instr::ICmp(..) => "icmp",
|
||||||
Instr::FunctionCall(..) => "call",
|
Instr::FunctionCall(..) => "call",
|
||||||
|
Instr::FCmp(_, _, _) => "fcmp",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,6 +397,7 @@ pub enum Instr {
|
|||||||
|
|
||||||
/// Integer Comparison
|
/// Integer Comparison
|
||||||
ICmp(CmpPredicate, InstructionValue, InstructionValue),
|
ICmp(CmpPredicate, InstructionValue, InstructionValue),
|
||||||
|
FCmp(CmpPredicate, InstructionValue, InstructionValue),
|
||||||
|
|
||||||
FunctionCall(FunctionValue, Vec<InstructionValue>),
|
FunctionCall(FunctionValue, Vec<InstructionValue>),
|
||||||
}
|
}
|
||||||
@ -497,6 +499,7 @@ impl InstructionValue {
|
|||||||
FRem(lhs, rhs) => match_types(lhs, rhs, &builder),
|
FRem(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
And(lhs, rhs) => match_types(lhs, rhs, &builder),
|
And(lhs, rhs) => match_types(lhs, rhs, &builder),
|
||||||
ICmp(_, _, _) => Ok(Type::Bool),
|
ICmp(_, _, _) => Ok(Type::Bool),
|
||||||
|
FCmp(_, _, _) => Ok(Type::Bool),
|
||||||
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
||||||
Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)),
|
Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)),
|
||||||
Alloca(ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
Alloca(ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
||||||
@ -629,6 +632,38 @@ impl Type {
|
|||||||
Type::F128PPC => true,
|
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 {
|
impl TerminatorKind {
|
||||||
|
Loading…
Reference in New Issue
Block a user