1 //! A place to park MachInst::Inst fragments which are common across multiple architectures.
2 
3 use super::{Lower, 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 
27 pub(crate) fn insn_inputs<I: VCodeInst>(ctx: &Lower<I>, insn: IRInst) -> SmallVec<[InsnInput; 4]> {
28     (0..ctx.num_inputs(insn))
29         .map(|i| InsnInput { insn, input: i })
30         .collect()
31 }
32 
33 pub(crate) fn insn_outputs<I: VCodeInst>(
34     ctx: &Lower<I>,
35     insn: IRInst,
36 ) -> SmallVec<[InsnOutput; 4]> {
37     (0..ctx.num_outputs(insn))
38         .map(|i| InsnOutput { insn, output: i })
39         .collect()
40 }
41 
42 //============================================================================
43 // Atomic instructions.
44 
45 /// Atomic memory update operations.
46 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
47 #[repr(u8)]
48 pub enum MachAtomicRmwOp {
49     /// Add
50     Add,
51     /// Sub
52     Sub,
53     /// And
54     And,
55     /// Nand
56     Nand,
57     /// Or
58     Or,
59     /// Exclusive Or
60     Xor,
61     /// Exchange (swap operands)
62     Xchg,
63     /// Unsigned min
64     Umin,
65     /// Unsigned max
66     Umax,
67     /// Signed min
68     Smin,
69     /// Signed max
70     Smax,
71 }
72 
73 impl MachAtomicRmwOp {
74     /// Converts an `ir::AtomicRmwOp` to the corresponding
75     /// `inst_common::AtomicRmwOp`.
76     pub fn from(ir_op: ir::AtomicRmwOp) -> Self {
77         match ir_op {
78             ir::AtomicRmwOp::Add => MachAtomicRmwOp::Add,
79             ir::AtomicRmwOp::Sub => MachAtomicRmwOp::Sub,
80             ir::AtomicRmwOp::And => MachAtomicRmwOp::And,
81             ir::AtomicRmwOp::Nand => MachAtomicRmwOp::Nand,
82             ir::AtomicRmwOp::Or => MachAtomicRmwOp::Or,
83             ir::AtomicRmwOp::Xor => MachAtomicRmwOp::Xor,
84             ir::AtomicRmwOp::Xchg => MachAtomicRmwOp::Xchg,
85             ir::AtomicRmwOp::Umin => MachAtomicRmwOp::Umin,
86             ir::AtomicRmwOp::Umax => MachAtomicRmwOp::Umax,
87             ir::AtomicRmwOp::Smin => MachAtomicRmwOp::Smin,
88             ir::AtomicRmwOp::Smax => MachAtomicRmwOp::Smax,
89         }
90     }
91 }
92