llvm_ir/instruction/
groups.rs

1use super::{HasResult, Instruction, Name, Operand, TypeRef, Typed};
2use crate::types::Types;
3use std::convert::TryFrom;
4
5/// Just the BinaryOps.  This ends up being better than a `&dyn `[`BinaryOp`](../trait.BinaryOp.html) for various reasons.
6#[derive(PartialEq, Clone, Debug, Hash)]
7pub enum BinaryOp {
8    // Integer binary ops
9    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    // Bitwise binary ops
18    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    // Floating-point binary ops
26    FAdd(super::FAdd),
27    FSub(super::FSub),
28    FMul(super::FMul),
29    FDiv(super::FDiv),
30    FRem(super::FRem),
31}
32
33/// Just the UnaryOps.  This ends up being better than a `&dyn `[`UnaryOp`](../trait.UnaryOp.html) for various reasons.
34#[derive(PartialEq, Clone, Debug, Hash)]
35pub enum UnaryOp {
36    // listed alphabetically
37    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
203/* --TODO not yet implemented: metadata
204impl HasMetadata for BinaryOp {
205    fn get_metadata(&self) -> &InstructionMetadata {
206        match self {
207            BinaryOp::Add(i) => i.get_metadata(),
208            BinaryOp::Sub(i) => i.get_metadata(),
209            BinaryOp::Mul(i) => i.get_metadata(),
210            BinaryOp::UDiv(i) => i.get_metadata(),
211            BinaryOp::SDiv(i) => i.get_metadata(),
212            BinaryOp::URem(i) => i.get_metadata(),
213            BinaryOp::SRem(i) => i.get_metadata(),
214            BinaryOp::And(i) => i.get_metadata(),
215            BinaryOp::Or(i) => i.get_metadata(),
216            BinaryOp::Xor(i) => i.get_metadata(),
217            BinaryOp::Shl(i) => i.get_metadata(),
218            BinaryOp::LShr(i) => i.get_metadata(),
219            BinaryOp::AShr(i) => i.get_metadata(),
220            BinaryOp::FAdd(i) => i.get_metadata(),
221            BinaryOp::FSub(i) => i.get_metadata(),
222            BinaryOp::FMul(i) => i.get_metadata(),
223            BinaryOp::FDiv(i) => i.get_metadata(),
224            BinaryOp::FRem(i) => i.get_metadata(),
225        }
226    }
227}
228
229impl HasMetadata for UnaryOp {
230    fn get_metadata(&self) -> &InstructionMetadata {
231        match self {
232            UnaryOp::AddrSpaceCast(i) => i.get_metadata(),
233            UnaryOp::BitCast(i) => i.get_metadata(),
234            UnaryOp::FNeg(i) => i.get_metadata(),
235            UnaryOp::FPExt(i) => i.get_metadata(),
236            UnaryOp::FPToSI(i) => i.get_metadata(),
237            UnaryOp::FPToUI(i) => i.get_metadata(),
238            UnaryOp::FPTrunc(i) => i.get_metadata(),
239            #[cfg(feature="llvm-10-or-greater")]
240            UnaryOp::Freeze(i) => i.get_metadata(),
241            UnaryOp::IntToPtr(i) => i.get_metadata(),
242            UnaryOp::PtrToInt(i) => i.get_metadata(),
243            UnaryOp::SExt(i) => i.get_metadata(),
244            UnaryOp::SIToFP(i) => i.get_metadata(),
245            UnaryOp::Trunc(i) => i.get_metadata(),
246            UnaryOp::UIToFP(i) => i.get_metadata(),
247            UnaryOp::ZExt(i) => i.get_metadata(),
248        }
249    }
250}
251*/
252
253impl 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}