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