pipeline_script/llvm/value/
double.rs1use crate::context::Context;
2use crate::llvm::value::bool::BoolValue;
3use crate::llvm::value::LLVMValue;
4use llvm_sys::core::LLVMIsUndef;
5use llvm_sys::prelude::LLVMValueRef;
6
7#[derive(Clone, Debug)]
8pub struct DoubleValue {
9 reference: LLVMValueRef,
10}
11
12impl DoubleValue {
13 pub fn new(reference: LLVMValueRef) -> Self {
14 Self { reference }
15 }
16 pub fn get_reference(&self) -> LLVMValueRef {
17 self.reference
18 }
19 pub fn is_undef(&self) -> bool {
20 unsafe { LLVMIsUndef(self.reference) == 1 }
21 }
22
23 pub fn eq(&self, ctx: &Context, other: &DoubleValue) -> BoolValue {
24 let builder = ctx.get_builder();
25 builder.build_eq(self.reference, other.reference)
26 }
27
28 pub fn add(&self, ctx: &Context, other: &DoubleValue) -> DoubleValue {
29 let builder = ctx.get_builder();
30 let result = builder.build_fadd(self.clone().into(), other.clone().into());
31 if let LLVMValue::Double(double_val) = result {
32 double_val
33 } else {
34 panic!("Expected DoubleValue from fadd operation")
35 }
36 }
37
38 pub fn mul(&self, ctx: &Context, other: &DoubleValue) -> DoubleValue {
39 let builder = ctx.get_builder();
40 let result = builder.build_fmul(self.clone().into(), other.clone().into());
41 if let LLVMValue::Double(double_val) = result {
42 double_val
43 } else {
44 panic!("Expected DoubleValue from fmul operation")
45 }
46 }
47
48 pub fn neg(&self, ctx: &Context) -> DoubleValue {
49 let builder = ctx.get_builder();
50 let result = builder.build_fneg(self.clone().into());
51 if let LLVMValue::Double(double_val) = result {
52 double_val
53 } else {
54 panic!("Expected DoubleValue from fneg operation")
55 }
56 }
57
58 pub fn less_than(&self, ctx: &Context, other: &DoubleValue) -> BoolValue {
59 let builder = ctx.get_builder();
60 let result = unsafe {
61 llvm_sys::core::LLVMBuildFCmp(
62 builder.get_llvm_builder(),
63 llvm_sys::LLVMRealPredicate::LLVMRealOLT,
64 self.reference,
65 other.reference,
66 std::ffi::CString::new("").unwrap().as_ptr(),
67 )
68 };
69 BoolValue::new(result)
70 }
71
72 pub fn greater_than(&self, ctx: &Context, other: &DoubleValue) -> BoolValue {
73 let builder = ctx.get_builder();
74 let result = unsafe {
75 llvm_sys::core::LLVMBuildFCmp(
76 builder.get_llvm_builder(),
77 llvm_sys::LLVMRealPredicate::LLVMRealOGT,
78 self.reference,
79 other.reference,
80 std::ffi::CString::new("").unwrap().as_ptr(),
81 )
82 };
83 BoolValue::new(result)
84 }
85
86 pub fn to_int32(&self, ctx: &Context) -> crate::llvm::value::int::Int32Value {
87 let builder = ctx.get_builder();
88 let result = unsafe {
89 llvm_sys::core::LLVMBuildFPToSI(
90 builder.get_llvm_builder(),
91 self.reference,
92 llvm_sys::core::LLVMInt32Type(),
93 std::ffi::CString::new("").unwrap().as_ptr(),
94 )
95 };
96 crate::llvm::value::int::Int32Value::new(result)
97 }
98
99 pub fn to_float(&self, ctx: &Context) -> crate::llvm::value::float::FloatValue {
100 let builder = ctx.get_builder();
101 let name = std::ffi::CString::new("").unwrap();
102 let result = unsafe {
103 llvm_sys::core::LLVMBuildFPTrunc(
104 builder.get_llvm_builder(),
105 self.reference,
106 llvm_sys::core::LLVMFloatType(),
107 name.as_ptr(),
108 )
109 };
110 crate::llvm::value::float::FloatValue::new(result)
111 }
112}
113
114impl From<DoubleValue> for LLVMValue {
115 fn from(value: DoubleValue) -> Self {
116 LLVMValue::Double(value)
117 }
118}