* x64: port `atomic_rmw` to ISLE This change ports `atomic_rmw` to ISLE for the x64 backend. It does not change the lowering in any way, though it seems possible that the fixed regs need not be as fixed and that there are opportunities for single instruction lowerings. It does rename `inst_common::AtomicRmwOp` to `MachAtomicRmwOp` to disambiguate with the IR enum with the same name. * x64: remove remaining hardcoded register constraints for `atomic_rmw` * x64: use `SyntheticAmode` in `AtomicRmwSeq` * review: add missing reg collector for amode * review: collect memory registers in the 'late' phase
95 lines
2.6 KiB
Rust
95 lines
2.6 KiB
Rust
//! A place to park MachInst::Inst fragments which are common across multiple architectures.
|
|
|
|
use super::{LowerCtx, VCodeInst};
|
|
use crate::ir::{self, Inst as IRInst};
|
|
use smallvec::SmallVec;
|
|
|
|
//============================================================================
|
|
// Instruction input "slots".
|
|
//
|
|
// We use these types to refer to operand numbers, and result numbers, together
|
|
// with the associated instruction, in a type-safe way.
|
|
|
|
/// Identifier for a particular input of an instruction.
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub(crate) struct InsnInput {
|
|
pub(crate) insn: IRInst,
|
|
pub(crate) input: usize,
|
|
}
|
|
|
|
/// Identifier for a particular output of an instruction.
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub(crate) struct InsnOutput {
|
|
pub(crate) insn: IRInst,
|
|
pub(crate) output: usize,
|
|
}
|
|
|
|
pub(crate) fn insn_inputs<I: VCodeInst, C: LowerCtx<I = I>>(
|
|
ctx: &C,
|
|
insn: IRInst,
|
|
) -> SmallVec<[InsnInput; 4]> {
|
|
(0..ctx.num_inputs(insn))
|
|
.map(|i| InsnInput { insn, input: i })
|
|
.collect()
|
|
}
|
|
|
|
pub(crate) fn insn_outputs<I: VCodeInst, C: LowerCtx<I = I>>(
|
|
ctx: &C,
|
|
insn: IRInst,
|
|
) -> SmallVec<[InsnOutput; 4]> {
|
|
(0..ctx.num_outputs(insn))
|
|
.map(|i| InsnOutput { insn, output: i })
|
|
.collect()
|
|
}
|
|
|
|
//============================================================================
|
|
// Atomic instructions.
|
|
|
|
/// Atomic memory update operations.
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
#[repr(u8)]
|
|
pub enum MachAtomicRmwOp {
|
|
/// Add
|
|
Add,
|
|
/// Sub
|
|
Sub,
|
|
/// And
|
|
And,
|
|
/// Nand
|
|
Nand,
|
|
/// Or
|
|
Or,
|
|
/// Exclusive Or
|
|
Xor,
|
|
/// Exchange (swap operands)
|
|
Xchg,
|
|
/// Unsigned min
|
|
Umin,
|
|
/// Unsigned max
|
|
Umax,
|
|
/// Signed min
|
|
Smin,
|
|
/// Signed max
|
|
Smax,
|
|
}
|
|
|
|
impl MachAtomicRmwOp {
|
|
/// Converts an `ir::AtomicRmwOp` to the corresponding
|
|
/// `inst_common::AtomicRmwOp`.
|
|
pub fn from(ir_op: ir::AtomicRmwOp) -> Self {
|
|
match ir_op {
|
|
ir::AtomicRmwOp::Add => MachAtomicRmwOp::Add,
|
|
ir::AtomicRmwOp::Sub => MachAtomicRmwOp::Sub,
|
|
ir::AtomicRmwOp::And => MachAtomicRmwOp::And,
|
|
ir::AtomicRmwOp::Nand => MachAtomicRmwOp::Nand,
|
|
ir::AtomicRmwOp::Or => MachAtomicRmwOp::Or,
|
|
ir::AtomicRmwOp::Xor => MachAtomicRmwOp::Xor,
|
|
ir::AtomicRmwOp::Xchg => MachAtomicRmwOp::Xchg,
|
|
ir::AtomicRmwOp::Umin => MachAtomicRmwOp::Umin,
|
|
ir::AtomicRmwOp::Umax => MachAtomicRmwOp::Umax,
|
|
ir::AtomicRmwOp::Smin => MachAtomicRmwOp::Smin,
|
|
ir::AtomicRmwOp::Smax => MachAtomicRmwOp::Smax,
|
|
}
|
|
}
|
|
}
|