Re-implement atomic load and stores
The AArch64 support was a bit broken and was using Armv7 style barriers, which aren't required with Armv8 acquire-release load/stores. The fallback CAS loops and RMW, for AArch64, have also been updated to use acquire-release, exclusive, instructions which, again, remove the need for barriers. The CAS loop has also been further optimised by using the extending form of the cmp instruction. Copyright (c) 2021, Arm Limited.
This commit is contained in:
@@ -1522,28 +1522,40 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
}
|
||||
}
|
||||
|
||||
Opcode::AtomicLoad => {
|
||||
let r_data = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
let r_addr = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let ty_access = ty.unwrap();
|
||||
assert!(is_valid_atomic_transaction_ty(ty_access));
|
||||
ctx.emit(Inst::AtomicLoad {
|
||||
ty: ty_access,
|
||||
r_data,
|
||||
r_addr,
|
||||
});
|
||||
Opcode::AtomicLoad
|
||||
| Opcode::AtomicUload8
|
||||
| Opcode::AtomicUload16
|
||||
| Opcode::AtomicUload32 => {
|
||||
let rt = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
let rn = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let ty = ty.unwrap();
|
||||
let access_ty = match op {
|
||||
Opcode::AtomicLoad => ty,
|
||||
Opcode::AtomicUload8 => I8,
|
||||
Opcode::AtomicUload16 => I16,
|
||||
Opcode::AtomicUload32 => I32,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert!(is_valid_atomic_transaction_ty(access_ty));
|
||||
ctx.emit(Inst::LoadAcquire { access_ty, rt, rn });
|
||||
}
|
||||
|
||||
Opcode::AtomicStore => {
|
||||
let r_data = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let r_addr = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let ty_access = ctx.input_ty(insn, 0);
|
||||
assert!(is_valid_atomic_transaction_ty(ty_access));
|
||||
ctx.emit(Inst::AtomicStore {
|
||||
ty: ty_access,
|
||||
r_data,
|
||||
r_addr,
|
||||
});
|
||||
Opcode::AtomicStore
|
||||
| Opcode::AtomicStore32
|
||||
| Opcode::AtomicStore16
|
||||
| Opcode::AtomicStore8 => {
|
||||
let rt = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let rn = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let ty = ctx.input_ty(insn, 0);
|
||||
let access_ty = match op {
|
||||
Opcode::AtomicStore => ty,
|
||||
Opcode::AtomicStore32 => I32,
|
||||
Opcode::AtomicStore16 => I16,
|
||||
Opcode::AtomicStore8 => I8,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert!(is_valid_atomic_transaction_ty(access_ty));
|
||||
ctx.emit(Inst::StoreRelease { access_ty, rt, rn });
|
||||
}
|
||||
|
||||
Opcode::Fence => {
|
||||
|
||||
Reference in New Issue
Block a user