1use crate::lcnf::*;
12
13use super::types::LlvmInstr;
14use std::fmt;
15
16impl fmt::Display for LlvmInstr {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 match self {
19 LlvmInstr::Alloca { result, ty, align } => {
20 write!(f, " %{} = alloca {}", result, ty)?;
21 if let Some(a) = align {
22 write!(f, ", align {}", a)?;
23 }
24 Ok(())
25 }
26 LlvmInstr::Load {
27 result,
28 ty,
29 ptr,
30 align,
31 } => {
32 write!(f, " %{} = load {}, ptr {}", result, ty, ptr)?;
33 if let Some(a) = align {
34 write!(f, ", align {}", a)?;
35 }
36 Ok(())
37 }
38 LlvmInstr::Store {
39 val,
40 ty,
41 ptr,
42 align,
43 } => {
44 write!(f, " store {} {}, ptr {}", ty, val, ptr)?;
45 if let Some(a) = align {
46 write!(f, ", align {}", a)?;
47 }
48 Ok(())
49 }
50 LlvmInstr::Add { result, lhs, rhs } => {
51 write!(f, " %{} = add i64 {}, {}", result, lhs, rhs)
52 }
53 LlvmInstr::Sub { result, lhs, rhs } => {
54 write!(f, " %{} = sub i64 {}, {}", result, lhs, rhs)
55 }
56 LlvmInstr::Mul { result, lhs, rhs } => {
57 write!(f, " %{} = mul i64 {}, {}", result, lhs, rhs)
58 }
59 LlvmInstr::SDiv { result, lhs, rhs } => {
60 write!(f, " %{} = sdiv i64 {}, {}", result, lhs, rhs)
61 }
62 LlvmInstr::SRem { result, lhs, rhs } => {
63 write!(f, " %{} = srem i64 {}, {}", result, lhs, rhs)
64 }
65 LlvmInstr::FAdd { result, lhs, rhs } => {
66 write!(f, " %{} = fadd double {}, {}", result, lhs, rhs)
67 }
68 LlvmInstr::FSub { result, lhs, rhs } => {
69 write!(f, " %{} = fsub double {}, {}", result, lhs, rhs)
70 }
71 LlvmInstr::FMul { result, lhs, rhs } => {
72 write!(f, " %{} = fmul double {}, {}", result, lhs, rhs)
73 }
74 LlvmInstr::FDiv { result, lhs, rhs } => {
75 write!(f, " %{} = fdiv double {}, {}", result, lhs, rhs)
76 }
77 LlvmInstr::And { result, lhs, rhs } => {
78 write!(f, " %{} = and i64 {}, {}", result, lhs, rhs)
79 }
80 LlvmInstr::Or { result, lhs, rhs } => {
81 write!(f, " %{} = or i64 {}, {}", result, lhs, rhs)
82 }
83 LlvmInstr::Xor { result, lhs, rhs } => {
84 write!(f, " %{} = xor i64 {}, {}", result, lhs, rhs)
85 }
86 LlvmInstr::Shl { result, lhs, rhs } => {
87 write!(f, " %{} = shl i64 {}, {}", result, lhs, rhs)
88 }
89 LlvmInstr::LShr { result, lhs, rhs } => {
90 write!(f, " %{} = lshr i64 {}, {}", result, lhs, rhs)
91 }
92 LlvmInstr::AShr { result, lhs, rhs } => {
93 write!(f, " %{} = ashr i64 {}, {}", result, lhs, rhs)
94 }
95 LlvmInstr::ICmp {
96 result,
97 pred,
98 lhs,
99 rhs,
100 } => {
101 write!(f, " %{} = icmp {} i64 {}, {}", result, pred, lhs, rhs)
102 }
103 LlvmInstr::FCmp {
104 result,
105 pred,
106 lhs,
107 rhs,
108 } => {
109 write!(f, " %{} = fcmp {} double {}, {}", result, pred, lhs, rhs)
110 }
111 LlvmInstr::Br(label) => write!(f, " br label %{}", label),
112 LlvmInstr::CondBr {
113 cond,
114 true_,
115 false_,
116 } => {
117 write!(f, " br i1 {}, label %{}, label %{}", cond, true_, false_)
118 }
119 LlvmInstr::Ret(None) => write!(f, " ret void"),
120 LlvmInstr::Ret(Some((ty, val))) => write!(f, " ret {} {}", ty, val),
121 LlvmInstr::Unreachable => write!(f, " unreachable"),
122 LlvmInstr::Label(name) => write!(f, "{}:", name),
123 LlvmInstr::Call {
124 result,
125 ret_ty,
126 func,
127 args,
128 } => {
129 if let Some(r) = result {
130 write!(f, " %{} = call {} @{}(", r, ret_ty, func)?;
131 } else {
132 write!(f, " call {} @{}(", ret_ty, func)?;
133 }
134 for (i, (ty, val)) in args.iter().enumerate() {
135 if i > 0 {
136 write!(f, ", ")?;
137 }
138 write!(f, "{} {}", ty, val)?;
139 }
140 write!(f, ")")
141 }
142 LlvmInstr::GetElementPtr {
143 result,
144 base_ty,
145 ptr,
146 indices,
147 } => {
148 write!(
149 f,
150 " %{} = getelementptr inbounds {}, ptr {}",
151 result, base_ty, ptr
152 )?;
153 for (ty, val) in indices {
154 write!(f, ", {} {}", ty, val)?;
155 }
156 Ok(())
157 }
158 LlvmInstr::BitCast {
159 result,
160 val,
161 from_ty,
162 to_ty,
163 } => {
164 write!(
165 f,
166 " %{} = bitcast {} {} to {}",
167 result, from_ty, val, to_ty
168 )
169 }
170 LlvmInstr::Phi {
171 result,
172 ty,
173 incoming,
174 } => {
175 write!(f, " %{} = phi {}", result, ty)?;
176 for (i, (val, label)) in incoming.iter().enumerate() {
177 if i > 0 {
178 write!(f, ",")?;
179 }
180 write!(f, " [ {}, %{} ]", val, label)?;
181 }
182 Ok(())
183 }
184 LlvmInstr::Select {
185 result,
186 cond,
187 true_val,
188 false_val,
189 ty,
190 } => {
191 write!(
192 f,
193 " %{} = select i1 {}, {} {}, {} {}",
194 result, cond, ty, true_val, ty, false_val
195 )
196 }
197 LlvmInstr::ExtractValue {
198 result,
199 agg,
200 agg_ty,
201 indices,
202 } => {
203 write!(f, " %{} = extractvalue {} {}", result, agg_ty, agg)?;
204 for idx in indices {
205 write!(f, ", {}", idx)?;
206 }
207 Ok(())
208 }
209 LlvmInstr::InsertValue {
210 result,
211 agg,
212 agg_ty,
213 val,
214 val_ty,
215 indices,
216 } => {
217 write!(
218 f,
219 " %{} = insertvalue {} {}, {} {}",
220 result, agg_ty, agg, val_ty, val
221 )?;
222 for idx in indices {
223 write!(f, ", {}", idx)?;
224 }
225 Ok(())
226 }
227 LlvmInstr::ZExt {
228 result,
229 val,
230 from_ty,
231 to_ty,
232 } => {
233 write!(f, " %{} = zext {} {} to {}", result, from_ty, val, to_ty)
234 }
235 LlvmInstr::SExt {
236 result,
237 val,
238 from_ty,
239 to_ty,
240 } => {
241 write!(f, " %{} = sext {} {} to {}", result, from_ty, val, to_ty)
242 }
243 LlvmInstr::Trunc {
244 result,
245 val,
246 from_ty,
247 to_ty,
248 } => {
249 write!(f, " %{} = trunc {} {} to {}", result, from_ty, val, to_ty)
250 }
251 LlvmInstr::FpToSI {
252 result,
253 val,
254 from_ty,
255 to_ty,
256 } => {
257 write!(f, " %{} = fptosi {} {} to {}", result, from_ty, val, to_ty)
258 }
259 LlvmInstr::SIToFp {
260 result,
261 val,
262 from_ty,
263 to_ty,
264 } => {
265 write!(f, " %{} = sitofp {} {} to {}", result, from_ty, val, to_ty)
266 }
267 LlvmInstr::FpExt {
268 result,
269 val,
270 from_ty,
271 to_ty,
272 } => {
273 write!(f, " %{} = fpext {} {} to {}", result, from_ty, val, to_ty)
274 }
275 LlvmInstr::FpTrunc {
276 result,
277 val,
278 from_ty,
279 to_ty,
280 } => {
281 write!(
282 f,
283 " %{} = fptrunc {} {} to {}",
284 result, from_ty, val, to_ty
285 )
286 }
287 }
288 }
289}