pipeline_script/llvm/value/
double.rs

1use 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}