[AArch64] Port atomic rmw to ISLE (#4021)
Also fix and extend the current implementation: - AtomicRMWOp::Clr != AtomicRmwOp::And, as the input needs to be inverted first. - Inputs to the cmp for the RMWLoop case are sign-extended when needed. - Lower Xchg to Swp. - Lower Sub to Add with a negated input. - Added more runtests. Copyright (c) 2022, Arm Limited.
This commit is contained in:
@@ -5,8 +5,8 @@ pub mod generated_code;
|
||||
|
||||
// Types that the generated ISLE code uses via `use super::*`.
|
||||
use super::{
|
||||
writable_zero_reg, zero_reg, AMode, ASIMDFPModImm, ASIMDMovModImm, AtomicRmwOp, BranchTarget,
|
||||
CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp, FPUOpRI, FloatCC, Imm12, ImmLogic, ImmShift,
|
||||
writable_zero_reg, zero_reg, AMode, ASIMDFPModImm, ASIMDMovModImm, BranchTarget, CallIndInfo,
|
||||
CallInfo, Cond, CondBrKind, ExtendOp, FPUOpRI, FloatCC, Imm12, ImmLogic, ImmShift,
|
||||
Inst as MInst, IntCC, JTSequenceInfo, MachLabel, MoveWideConst, MoveWideOp, NarrowValueMode,
|
||||
Opcode, OperandSize, PairAMode, Reg, ScalarSize, ShiftOpAndAmt, UImm5, VecMisc2, VectorSize,
|
||||
NZCV,
|
||||
@@ -17,10 +17,11 @@ use crate::settings::Flags;
|
||||
use crate::{
|
||||
binemit::CodeOffset,
|
||||
ir::{
|
||||
immediates::*, types::*, ExternalName, Inst, InstructionData, MemFlags, TrapCode, Value,
|
||||
ValueList,
|
||||
immediates::*, types::*, AtomicRmwOp, ExternalName, Inst, InstructionData, MemFlags,
|
||||
TrapCode, Value, ValueList,
|
||||
},
|
||||
isa::aarch64::inst::args::{ShiftOp, ShiftOpShiftImm},
|
||||
isa::aarch64::lower::{is_valid_atomic_transaction_ty, writable_xreg, xreg},
|
||||
isa::unwind::UnwindInst,
|
||||
machinst::{ty_bits, InsnOutput, LowerCtx},
|
||||
};
|
||||
@@ -66,6 +67,14 @@ where
|
||||
{
|
||||
isle_prelude_methods!();
|
||||
|
||||
fn use_lse(&mut self, _: Inst) -> Option<()> {
|
||||
if self.isa_flags.use_lse() {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn move_wide_const_from_u64(&mut self, n: u64) -> Option<MoveWideConst> {
|
||||
MoveWideConst::maybe_from_u64(n)
|
||||
}
|
||||
@@ -114,6 +123,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn valid_atomic_transaction(&mut self, ty: Type) -> Option<Type> {
|
||||
if is_valid_atomic_transaction_ty(ty) {
|
||||
Some(ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the fallback case for loading a 64-bit integral constant into a
|
||||
/// register.
|
||||
///
|
||||
@@ -194,6 +211,14 @@ where
|
||||
zero_reg()
|
||||
}
|
||||
|
||||
fn xreg(&mut self, index: u8) -> Reg {
|
||||
xreg(index)
|
||||
}
|
||||
|
||||
fn writable_xreg(&mut self, index: u8) -> WritableReg {
|
||||
writable_xreg(index)
|
||||
}
|
||||
|
||||
fn extended_value_from_value(&mut self, val: Value) -> Option<ExtendedValue> {
|
||||
let (val, extend) =
|
||||
super::get_as_extended_value(self.lower_ctx, val, NarrowValueMode::None)?;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
src/clif.isle 443b34b797fc8ace
|
||||
src/prelude.isle d8a93eb727abd7f4
|
||||
src/isa/aarch64/inst.isle 77984cc33a05be7
|
||||
src/isa/aarch64/lower.isle 71c7e603b0e4bdef
|
||||
src/prelude.isle a7915a6b88310eb5
|
||||
src/isa/aarch64/inst.isle a2c0ae729bfa24a8
|
||||
src/isa/aarch64/lower.isle 15641ca7f0ac061a
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user