1use super::{HasResult, Instruction, Name, Operand, TypeRef, Typed};
2use crate::types::Types;
3use std::convert::TryFrom;
4
5#[derive(PartialEq, Clone, Debug, Hash)]
7pub enum BinaryOp {
8 Add(super::Add),
10 Sub(super::Sub),
11 Mul(super::Mul),
12 UDiv(super::UDiv),
13 SDiv(super::SDiv),
14 URem(super::URem),
15 SRem(super::SRem),
16
17 And(super::And),
19 Or(super::Or),
20 Xor(super::Xor),
21 Shl(super::Shl),
22 LShr(super::LShr),
23 AShr(super::AShr),
24
25 FAdd(super::FAdd),
27 FSub(super::FSub),
28 FMul(super::FMul),
29 FDiv(super::FDiv),
30 FRem(super::FRem),
31}
32
33#[derive(PartialEq, Clone, Debug, Hash)]
35pub enum UnaryOp {
36 AddrSpaceCast(super::AddrSpaceCast),
38 BitCast(super::BitCast),
39 FNeg(super::FNeg),
40 FPExt(super::FPExt),
41 FPToSI(super::FPToSI),
42 FPToUI(super::FPToUI),
43 FPTrunc(super::FPTrunc),
44 #[cfg(feature = "llvm-10-or-greater")]
45 Freeze(super::Freeze),
46 IntToPtr(super::IntToPtr),
47 PtrToInt(super::PtrToInt),
48 SExt(super::SExt),
49 SIToFP(super::SIToFP),
50 Trunc(super::Trunc),
51 UIToFP(super::UIToFP),
52 ZExt(super::ZExt),
53}
54
55impl From<BinaryOp> for Instruction {
56 fn from(bo: BinaryOp) -> Instruction {
57 match bo {
58 BinaryOp::Add(i) => i.into(),
59 BinaryOp::Sub(i) => i.into(),
60 BinaryOp::Mul(i) => i.into(),
61 BinaryOp::UDiv(i) => i.into(),
62 BinaryOp::SDiv(i) => i.into(),
63 BinaryOp::URem(i) => i.into(),
64 BinaryOp::SRem(i) => i.into(),
65 BinaryOp::And(i) => i.into(),
66 BinaryOp::Or(i) => i.into(),
67 BinaryOp::Xor(i) => i.into(),
68 BinaryOp::Shl(i) => i.into(),
69 BinaryOp::LShr(i) => i.into(),
70 BinaryOp::AShr(i) => i.into(),
71 BinaryOp::FAdd(i) => i.into(),
72 BinaryOp::FSub(i) => i.into(),
73 BinaryOp::FMul(i) => i.into(),
74 BinaryOp::FDiv(i) => i.into(),
75 BinaryOp::FRem(i) => i.into(),
76 }
77 }
78}
79
80impl From<UnaryOp> for Instruction {
81 fn from(uo: UnaryOp) -> Instruction {
82 match uo {
83 UnaryOp::AddrSpaceCast(i) => i.into(),
84 UnaryOp::BitCast(i) => i.into(),
85 UnaryOp::FNeg(i) => i.into(),
86 UnaryOp::FPExt(i) => i.into(),
87 UnaryOp::FPToSI(i) => i.into(),
88 UnaryOp::FPToUI(i) => i.into(),
89 UnaryOp::FPTrunc(i) => i.into(),
90 #[cfg(feature = "llvm-10-or-greater")]
91 UnaryOp::Freeze(i) => i.into(),
92 UnaryOp::IntToPtr(i) => i.into(),
93 UnaryOp::PtrToInt(i) => i.into(),
94 UnaryOp::SExt(i) => i.into(),
95 UnaryOp::SIToFP(i) => i.into(),
96 UnaryOp::Trunc(i) => i.into(),
97 UnaryOp::UIToFP(i) => i.into(),
98 UnaryOp::ZExt(i) => i.into(),
99 }
100 }
101}
102
103impl TryFrom<Instruction> for BinaryOp {
104 type Error = &'static str;
105 fn try_from(inst: Instruction) -> Result<Self, Self::Error> {
106 match inst {
107 Instruction::Add(i) => Ok(BinaryOp::Add(i)),
108 Instruction::Sub(i) => Ok(BinaryOp::Sub(i)),
109 Instruction::Mul(i) => Ok(BinaryOp::Mul(i)),
110 Instruction::UDiv(i) => Ok(BinaryOp::UDiv(i)),
111 Instruction::SDiv(i) => Ok(BinaryOp::SDiv(i)),
112 Instruction::URem(i) => Ok(BinaryOp::URem(i)),
113 Instruction::SRem(i) => Ok(BinaryOp::SRem(i)),
114 Instruction::And(i) => Ok(BinaryOp::And(i)),
115 Instruction::Or(i) => Ok(BinaryOp::Or(i)),
116 Instruction::Xor(i) => Ok(BinaryOp::Xor(i)),
117 Instruction::Shl(i) => Ok(BinaryOp::Shl(i)),
118 Instruction::LShr(i) => Ok(BinaryOp::LShr(i)),
119 Instruction::AShr(i) => Ok(BinaryOp::AShr(i)),
120 Instruction::FAdd(i) => Ok(BinaryOp::FAdd(i)),
121 Instruction::FSub(i) => Ok(BinaryOp::FSub(i)),
122 Instruction::FMul(i) => Ok(BinaryOp::FMul(i)),
123 Instruction::FDiv(i) => Ok(BinaryOp::FDiv(i)),
124 Instruction::FRem(i) => Ok(BinaryOp::FRem(i)),
125 _ => Err("Not a binary op"),
126 }
127 }
128}
129
130impl TryFrom<Instruction> for UnaryOp {
131 type Error = &'static str;
132 fn try_from(inst: Instruction) -> Result<Self, Self::Error> {
133 match inst {
134 Instruction::AddrSpaceCast(i) => Ok(UnaryOp::AddrSpaceCast(i)),
135 Instruction::BitCast(i) => Ok(UnaryOp::BitCast(i)),
136 Instruction::FNeg(i) => Ok(UnaryOp::FNeg(i)),
137 Instruction::FPExt(i) => Ok(UnaryOp::FPExt(i)),
138 Instruction::FPToSI(i) => Ok(UnaryOp::FPToSI(i)),
139 Instruction::FPToUI(i) => Ok(UnaryOp::FPToUI(i)),
140 Instruction::FPTrunc(i) => Ok(UnaryOp::FPTrunc(i)),
141 #[cfg(feature = "llvm-10-or-greater")]
142 Instruction::Freeze(i) => Ok(UnaryOp::Freeze(i)),
143 Instruction::IntToPtr(i) => Ok(UnaryOp::IntToPtr(i)),
144 Instruction::PtrToInt(i) => Ok(UnaryOp::PtrToInt(i)),
145 Instruction::SExt(i) => Ok(UnaryOp::SExt(i)),
146 Instruction::SIToFP(i) => Ok(UnaryOp::SIToFP(i)),
147 Instruction::Trunc(i) => Ok(UnaryOp::Trunc(i)),
148 Instruction::UIToFP(i) => Ok(UnaryOp::UIToFP(i)),
149 Instruction::ZExt(i) => Ok(UnaryOp::ZExt(i)),
150 _ => Err("Not a unary op"),
151 }
152 }
153}
154
155impl Typed for BinaryOp {
156 fn get_type(&self, types: &Types) -> TypeRef {
157 match self {
158 BinaryOp::Add(i) => types.type_of(i),
159 BinaryOp::Sub(i) => types.type_of(i),
160 BinaryOp::Mul(i) => types.type_of(i),
161 BinaryOp::UDiv(i) => types.type_of(i),
162 BinaryOp::SDiv(i) => types.type_of(i),
163 BinaryOp::URem(i) => types.type_of(i),
164 BinaryOp::SRem(i) => types.type_of(i),
165 BinaryOp::And(i) => types.type_of(i),
166 BinaryOp::Or(i) => types.type_of(i),
167 BinaryOp::Xor(i) => types.type_of(i),
168 BinaryOp::Shl(i) => types.type_of(i),
169 BinaryOp::LShr(i) => types.type_of(i),
170 BinaryOp::AShr(i) => types.type_of(i),
171 BinaryOp::FAdd(i) => types.type_of(i),
172 BinaryOp::FSub(i) => types.type_of(i),
173 BinaryOp::FMul(i) => types.type_of(i),
174 BinaryOp::FDiv(i) => types.type_of(i),
175 BinaryOp::FRem(i) => types.type_of(i),
176 }
177 }
178}
179
180impl Typed for UnaryOp {
181 fn get_type(&self, types: &Types) -> TypeRef {
182 match self {
183 UnaryOp::AddrSpaceCast(i) => types.type_of(i),
184 UnaryOp::BitCast(i) => types.type_of(i),
185 UnaryOp::FNeg(i) => types.type_of(i),
186 UnaryOp::FPExt(i) => types.type_of(i),
187 UnaryOp::FPToSI(i) => types.type_of(i),
188 UnaryOp::FPToUI(i) => types.type_of(i),
189 UnaryOp::FPTrunc(i) => types.type_of(i),
190 #[cfg(feature = "llvm-10-or-greater")]
191 UnaryOp::Freeze(i) => types.type_of(i),
192 UnaryOp::IntToPtr(i) => types.type_of(i),
193 UnaryOp::PtrToInt(i) => types.type_of(i),
194 UnaryOp::SExt(i) => types.type_of(i),
195 UnaryOp::SIToFP(i) => types.type_of(i),
196 UnaryOp::Trunc(i) => types.type_of(i),
197 UnaryOp::UIToFP(i) => types.type_of(i),
198 UnaryOp::ZExt(i) => types.type_of(i),
199 }
200 }
201}
202
203impl HasResult for BinaryOp {
254 fn get_result(&self) -> &Name {
255 match self {
256 BinaryOp::Add(i) => i.get_result(),
257 BinaryOp::Sub(i) => i.get_result(),
258 BinaryOp::Mul(i) => i.get_result(),
259 BinaryOp::UDiv(i) => i.get_result(),
260 BinaryOp::SDiv(i) => i.get_result(),
261 BinaryOp::URem(i) => i.get_result(),
262 BinaryOp::SRem(i) => i.get_result(),
263 BinaryOp::And(i) => i.get_result(),
264 BinaryOp::Or(i) => i.get_result(),
265 BinaryOp::Xor(i) => i.get_result(),
266 BinaryOp::Shl(i) => i.get_result(),
267 BinaryOp::LShr(i) => i.get_result(),
268 BinaryOp::AShr(i) => i.get_result(),
269 BinaryOp::FAdd(i) => i.get_result(),
270 BinaryOp::FSub(i) => i.get_result(),
271 BinaryOp::FMul(i) => i.get_result(),
272 BinaryOp::FDiv(i) => i.get_result(),
273 BinaryOp::FRem(i) => i.get_result(),
274 }
275 }
276}
277
278impl HasResult for UnaryOp {
279 fn get_result(&self) -> &Name {
280 match self {
281 UnaryOp::AddrSpaceCast(i) => i.get_result(),
282 UnaryOp::BitCast(i) => i.get_result(),
283 UnaryOp::FNeg(i) => i.get_result(),
284 UnaryOp::FPExt(i) => i.get_result(),
285 UnaryOp::FPToSI(i) => i.get_result(),
286 UnaryOp::FPToUI(i) => i.get_result(),
287 UnaryOp::FPTrunc(i) => i.get_result(),
288 #[cfg(feature = "llvm-10-or-greater")]
289 UnaryOp::Freeze(i) => i.get_result(),
290 UnaryOp::IntToPtr(i) => i.get_result(),
291 UnaryOp::PtrToInt(i) => i.get_result(),
292 UnaryOp::SExt(i) => i.get_result(),
293 UnaryOp::SIToFP(i) => i.get_result(),
294 UnaryOp::Trunc(i) => i.get_result(),
295 UnaryOp::UIToFP(i) => i.get_result(),
296 UnaryOp::ZExt(i) => i.get_result(),
297 }
298 }
299}
300
301impl super::BinaryOp for BinaryOp {
302 fn get_operand0(&self) -> &Operand {
303 match self {
304 BinaryOp::Add(i) => i.get_operand0(),
305 BinaryOp::Sub(i) => i.get_operand0(),
306 BinaryOp::Mul(i) => i.get_operand0(),
307 BinaryOp::UDiv(i) => i.get_operand0(),
308 BinaryOp::SDiv(i) => i.get_operand0(),
309 BinaryOp::URem(i) => i.get_operand0(),
310 BinaryOp::SRem(i) => i.get_operand0(),
311 BinaryOp::And(i) => i.get_operand0(),
312 BinaryOp::Or(i) => i.get_operand0(),
313 BinaryOp::Xor(i) => i.get_operand0(),
314 BinaryOp::Shl(i) => i.get_operand0(),
315 BinaryOp::LShr(i) => i.get_operand0(),
316 BinaryOp::AShr(i) => i.get_operand0(),
317 BinaryOp::FAdd(i) => i.get_operand0(),
318 BinaryOp::FSub(i) => i.get_operand0(),
319 BinaryOp::FMul(i) => i.get_operand0(),
320 BinaryOp::FDiv(i) => i.get_operand0(),
321 BinaryOp::FRem(i) => i.get_operand0(),
322 }
323 }
324
325 fn get_operand1(&self) -> &Operand {
326 match self {
327 BinaryOp::Add(i) => i.get_operand1(),
328 BinaryOp::Sub(i) => i.get_operand1(),
329 BinaryOp::Mul(i) => i.get_operand1(),
330 BinaryOp::UDiv(i) => i.get_operand1(),
331 BinaryOp::SDiv(i) => i.get_operand1(),
332 BinaryOp::URem(i) => i.get_operand1(),
333 BinaryOp::SRem(i) => i.get_operand1(),
334 BinaryOp::And(i) => i.get_operand1(),
335 BinaryOp::Or(i) => i.get_operand1(),
336 BinaryOp::Xor(i) => i.get_operand1(),
337 BinaryOp::Shl(i) => i.get_operand1(),
338 BinaryOp::LShr(i) => i.get_operand1(),
339 BinaryOp::AShr(i) => i.get_operand1(),
340 BinaryOp::FAdd(i) => i.get_operand1(),
341 BinaryOp::FSub(i) => i.get_operand1(),
342 BinaryOp::FMul(i) => i.get_operand1(),
343 BinaryOp::FDiv(i) => i.get_operand1(),
344 BinaryOp::FRem(i) => i.get_operand1(),
345 }
346 }
347}
348
349impl super::UnaryOp for UnaryOp {
350 fn get_operand(&self) -> &Operand {
351 match self {
352 UnaryOp::AddrSpaceCast(i) => i.get_operand(),
353 UnaryOp::BitCast(i) => i.get_operand(),
354 UnaryOp::FNeg(i) => i.get_operand(),
355 UnaryOp::FPExt(i) => i.get_operand(),
356 UnaryOp::FPToSI(i) => i.get_operand(),
357 UnaryOp::FPToUI(i) => i.get_operand(),
358 UnaryOp::FPTrunc(i) => i.get_operand(),
359 #[cfg(feature = "llvm-10-or-greater")]
360 UnaryOp::Freeze(i) => i.get_operand(),
361 UnaryOp::IntToPtr(i) => i.get_operand(),
362 UnaryOp::PtrToInt(i) => i.get_operand(),
363 UnaryOp::SExt(i) => i.get_operand(),
364 UnaryOp::SIToFP(i) => i.get_operand(),
365 UnaryOp::Trunc(i) => i.get_operand(),
366 UnaryOp::UIToFP(i) => i.get_operand(),
367 UnaryOp::ZExt(i) => i.get_operand(),
368 }
369 }
370}