pipeline_script/llvm/
global.rs1use crate::context::Context;
2use crate::llvm::builder::ir::IRBuilder;
3use crate::llvm::types::LLVMType;
4use crate::llvm::value::array::ArrayValue;
5use crate::llvm::value::bool::BoolValue;
6use crate::llvm::value::double::DoubleValue;
7use crate::llvm::value::float::FloatValue;
8use crate::llvm::value::int::{Int16Value, Int32Value, Int64Value, Int8Value};
9use crate::llvm::value::LLVMValue;
10use llvm_sys::core::{
11 LLVMArrayType2, LLVMConstArray2, LLVMConstInt, LLVMConstReal, LLVMConstString,
12 LLVMCreateBuilder, LLVMDoubleType, LLVMFloatType, LLVMFunctionType, LLVMInt16Type,
13 LLVMInt1Type, LLVMInt32Type, LLVMInt64Type, LLVMInt8Type, LLVMPointerType, LLVMSizeOf,
14 LLVMStructType, LLVMVoidType,
15};
16use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef};
17use std::ffi::{c_uint, CString};
18
19pub struct Global;
20
21impl Global {
22 #[allow(unused)]
23 pub fn const_array(ctx: &Context, array: &[LLVMValue]) -> LLVMValue {
24 let ty = array[0].get_llvm_type(ctx);
26 let mut llvm_values: Vec<LLVMValueRef> =
28 array.iter().map(|v| v.as_llvm_value_ref()).collect();
29 let a = unsafe {
30 LLVMConstArray2(
31 ty.as_llvm_type_ref(),
32 llvm_values.as_mut_ptr(),
33 llvm_values.len() as u64,
34 )
35 };
36 LLVMValue::Array(ArrayValue::new(a, ty, array.len()))
37 }
38 #[allow(unused)]
39 pub fn const_unit() -> LLVMValue {
40 LLVMValue::Unit
41 }
42 #[allow(unused)]
43 pub fn const_double(value: f64) -> DoubleValue {
44 let v = unsafe { LLVMConstReal(LLVMDoubleType(), value) };
45 DoubleValue::new(v)
46 }
47 pub fn const_float(value: f32) -> FloatValue {
48 let v = unsafe { LLVMConstReal(LLVMFloatType(), value as f64) };
49 FloatValue::new(v)
50 }
51 pub fn const_i8(value: i8) -> Int8Value {
52 let v = unsafe { LLVMConstInt(LLVMInt8Type(), value as u64, 0) };
53 Int8Value::new(v)
54 }
55 #[allow(unused)]
56 pub fn const_bool(value: bool) -> BoolValue {
57 let v = unsafe { LLVMConstInt(LLVMInt1Type(), value as u64, 0) };
58 BoolValue::new(v)
59 }
60 pub fn sizeof(ty: LLVMType) -> LLVMValue {
61 unsafe { LLVMSizeOf(ty.as_llvm_type_ref()) }.into()
62 }
63 pub fn const_i16(value: i16) -> Int16Value {
64 let v = unsafe { LLVMConstInt(LLVMInt16Type(), value as u64, 0) };
65 Int16Value::new(v)
66 }
67 pub fn const_i32(value: i32) -> Int32Value {
68 let v = unsafe { LLVMConstInt(LLVMInt32Type(), value as u64, 0) };
69 Int32Value::new(v)
70 }
71 pub fn const_i64(value: i64) -> Int64Value {
72 let v = unsafe { LLVMConstInt(LLVMInt64Type(), value as u64, 0) };
73 Int64Value::new(v)
74 }
75 pub fn i8_type() -> LLVMType {
76 let t = unsafe { LLVMInt8Type() };
77 LLVMType::Int8(t)
78 }
79 pub fn i1_type() -> LLVMType {
80 let t = unsafe { LLVMInt1Type() };
81 LLVMType::Int1(t)
82 }
83 pub fn i16_type() -> LLVMType {
84 let t = unsafe { LLVMInt16Type() };
85 LLVMType::Int16(t)
86 }
87 pub fn i32_type() -> LLVMType {
88 let t = unsafe { LLVMInt32Type() };
89 LLVMType::Int32(t)
90 }
91 pub fn i64_type() -> LLVMType {
92 let t = unsafe { LLVMInt64Type() };
93 LLVMType::Int64(t)
94 }
95 pub fn struct_type(name: String, element_type: Vec<(String, LLVMType)>) -> LLVMType {
96 let mut t = element_type
97 .iter()
98 .map(|t| t.1.as_llvm_type_ref())
99 .collect::<Vec<LLVMTypeRef>>();
100 let t = unsafe { LLVMStructType(t.as_mut_ptr(), element_type.len() as c_uint, 0) };
101 LLVMType::Struct(name, element_type, t)
102 }
103 #[allow(unused)]
117 pub fn array_type(element_type: LLVMType) -> LLVMType {
118 let t = unsafe { LLVMArrayType2(element_type.as_llvm_type_ref(), 2) };
119 LLVMType::Array(Box::new(element_type), t)
120 }
121 pub fn unit_type() -> LLVMType {
122 let t = unsafe { LLVMVoidType() };
123 LLVMType::Unit(t)
124 }
125 #[allow(unused)]
126 pub fn float_type() -> LLVMType {
127 let t = unsafe { LLVMFloatType() };
128 LLVMType::Float(t)
129 }
130 #[allow(unused)]
131 pub fn double_type() -> LLVMType {
132 let t = unsafe { LLVMDoubleType() };
133 LLVMType::Double(t)
134 }
135 pub fn function_type(return_type: LLVMType, param_types: Vec<(String, LLVMType)>) -> LLVMType {
136 let mut t = param_types
137 .iter()
138 .map(|t| t.1.as_llvm_type_ref())
139 .collect::<Vec<LLVMTypeRef>>();
140 let t = unsafe {
141 LLVMFunctionType(
142 return_type.as_llvm_type_ref(),
143 t.as_mut_ptr(),
144 t.len() as c_uint,
145 0,
146 )
147 };
148 LLVMType::Function(Box::new(return_type), param_types, t)
149 }
150 pub fn function_type_with_var_arg(
151 return_type: LLVMType,
152 param_types: Vec<(String, LLVMType)>,
153 ) -> LLVMType {
154 let mut t = param_types
155 .iter()
156 .map(|t| t.1.as_llvm_type_ref())
157 .collect::<Vec<LLVMTypeRef>>();
158 let t = unsafe {
159 LLVMFunctionType(
160 return_type.as_llvm_type_ref(),
161 t.as_mut_ptr(),
162 t.len() as c_uint,
163 1,
164 )
165 };
166 LLVMType::Function(Box::new(return_type), param_types, t)
167 }
168 pub fn pointer_type(element_type: LLVMType) -> LLVMType {
169 let t = unsafe { LLVMPointerType(element_type.as_llvm_type_ref(), 0) };
170 LLVMType::Pointer(Box::new(element_type), t)
171 }
172 pub fn ref_type(element_type: LLVMType) -> LLVMType {
173 let t = unsafe { LLVMPointerType(element_type.as_llvm_type_ref(), 0) };
174 LLVMType::Ref(Box::new(element_type), t)
175 }
176 pub fn string_type() -> LLVMType {
177 let t = unsafe { LLVMPointerType(Global::i8_type().as_llvm_type_ref(), 0) };
178 LLVMType::String(t)
179 }
180 #[allow(unused)]
181 pub fn const_string(str: impl AsRef<str>) -> LLVMValue {
182 let str0 = str.as_ref();
183 let str = CString::new(str0).unwrap();
184 let c = unsafe { LLVMConstString(str.as_ptr(), str0.len() as c_uint, 0) };
185 c.into()
186 }
187 pub fn create_builder() -> IRBuilder {
188 let builder = unsafe { LLVMCreateBuilder() };
189 IRBuilder::new(builder)
190 }
191 #[allow(unused)]
192 pub fn type_of_string(s: &str) -> LLVMType {
193 match s {
194 "Int32" => Global::i32_type(),
195 "Float" => Global::float_type(),
196 "Double" => Global::double_type(),
197 _ => panic!("unknown type"),
199 }
200 }
201}