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