1 //! A place to park MachInst::Inst fragments which are common across multiple architectures.
2 
3 use super::{LowerCtx, VCodeInst};
4 use crate::ir::{self, Inst as IRInst};
5 use smallvec::SmallVec;
6 
7 //============================================================================
8 // Instruction input "slots".
9 //
10 // We use these types to refer to operand numbers, and result numbers, together
11 // with the associated instruction, in a type-safe way.
12 
13 /// Identifier for a particular input of an instruction.
14 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
15 pub(crate) struct InsnInput {
16     pub(crate) insn: IRInst,
17     pub(crate) input: usize,
18 }
19 
20 /// Identifier for a particular output of an instruction.
21 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
22 pub(crate) struct InsnOutput {
23     pub(crate) insn: IRInst,
24     pub(crate) output: usize,
25 }
26 
insn_inputs<I: VCodeInst, C: LowerCtx<I = I>>( ctx: &C, insn: IRInst, ) -> SmallVec<[InsnInput; 4]>27 pub(crate) fn insn_inputs<I: VCodeInst, C: LowerCtx<I = I>>(
28     ctx: &C,
29     insn: IRInst,
30 ) -> SmallVec<[InsnInput; 4]> {
31     (0..ctx.num_inputs(insn))
32         .map(|i| InsnInput { insn, input: i })
33         .collect()
34 }
35 
insn_outputs<I: VCodeInst, C: LowerCtx<I = I>>( ctx: &C, insn: IRInst, ) -> SmallVec<[InsnOutput; 4]>36 pub(crate) fn insn_outputs<I: VCodeInst, C: LowerCtx<I = I>>(
37     ctx: &C,
38     insn: IRInst,
39 ) -> SmallVec<[InsnOutput; 4]> {
40     (0..ctx.num_outputs(insn))
41         .map(|i| InsnOutput { insn, output: i })
42         .collect()
43 }
44 
45 //============================================================================
46 // Atomic instructions.
47 
48 /// Atomic memory update operations.  As of 21 Aug 2020 these are used for the aarch64 and x64
49 /// targets.
50 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
51 #[repr(u8)]
52 pub enum AtomicRmwOp {
53     /// Add
54     Add,
55     /// Sub
56     Sub,
57     /// And
58     And,
59     /// Nand
60     Nand,
61     /// Or
62     Or,
63     /// Exclusive Or
64     Xor,
65     /// Exchange (swap operands)
66     Xchg,
67     /// Unsigned min
68     Umin,
69     /// Unsigned max
70     Umax,
71     /// Signed min
72     Smin,
73     /// Signed max
74     Smax,
75 }
76 
77 impl AtomicRmwOp {
78     /// Converts an `ir::AtomicRmwOp` to the corresponding `inst_common::AtomicRmwOp`.
from(ir_op: ir::AtomicRmwOp) -> Self79     pub fn from(ir_op: ir::AtomicRmwOp) -> Self {
80         match ir_op {
81             ir::AtomicRmwOp::Add => AtomicRmwOp::Add,
82             ir::AtomicRmwOp::Sub => AtomicRmwOp::Sub,
83             ir::AtomicRmwOp::And => AtomicRmwOp::And,
84             ir::AtomicRmwOp::Nand => AtomicRmwOp::Nand,
85             ir::AtomicRmwOp::Or => AtomicRmwOp::Or,
86             ir::AtomicRmwOp::Xor => AtomicRmwOp::Xor,
87             ir::AtomicRmwOp::Xchg => AtomicRmwOp::Xchg,
88             ir::AtomicRmwOp::Umin => AtomicRmwOp::Umin,
89             ir::AtomicRmwOp::Umax => AtomicRmwOp::Umax,
90             ir::AtomicRmwOp::Smin => AtomicRmwOp::Smin,
91             ir::AtomicRmwOp::Smax => AtomicRmwOp::Smax,
92         }
93     }
94 }
95