[AArch64] Port AtomicCAS to isle (#4140)
Copyright (c) 2022, Arm Limited.
This commit is contained in:
@@ -239,50 +239,7 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
||||
|
||||
Opcode::AtomicRmw => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::AtomicCas => {
|
||||
let r_dst = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
let mut r_addr = put_input_in_reg(ctx, inputs[0], NarrowValueMode::None);
|
||||
let mut r_expected = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let mut r_replacement = put_input_in_reg(ctx, inputs[2], NarrowValueMode::None);
|
||||
let ty_access = ty.unwrap();
|
||||
assert!(is_valid_atomic_transaction_ty(ty_access));
|
||||
|
||||
if isa_flags.use_lse() {
|
||||
ctx.emit(Inst::gen_move(r_dst, r_expected, ty_access));
|
||||
ctx.emit(Inst::AtomicCAS {
|
||||
rs: r_dst,
|
||||
rt: r_replacement,
|
||||
rn: r_addr,
|
||||
ty: ty_access,
|
||||
});
|
||||
} else {
|
||||
// This is very similar to, but not identical to, the AtomicRmw case. Note
|
||||
// that the AtomicCASLoop sequence does its own masking, so we don't need to worry
|
||||
// about zero-extending narrow (I8/I16/I32) values here.
|
||||
// Make sure that all three args are in virtual regs. See corresponding comment
|
||||
// for `Opcode::AtomicRmw` above.
|
||||
r_addr = ctx.ensure_in_vreg(r_addr, I64);
|
||||
r_expected = ctx.ensure_in_vreg(r_expected, I64);
|
||||
r_replacement = ctx.ensure_in_vreg(r_replacement, I64);
|
||||
// Move the args to the preordained AtomicCASLoop input regs
|
||||
ctx.emit(Inst::gen_move(Writable::from_reg(xreg(25)), r_addr, I64));
|
||||
ctx.emit(Inst::gen_move(
|
||||
Writable::from_reg(xreg(26)),
|
||||
r_expected,
|
||||
I64,
|
||||
));
|
||||
ctx.emit(Inst::gen_move(
|
||||
Writable::from_reg(xreg(28)),
|
||||
r_replacement,
|
||||
I64,
|
||||
));
|
||||
// Now the AtomicCASLoop itself, implemented in the normal way, with an LL-SC loop
|
||||
ctx.emit(Inst::AtomicCASLoop { ty: ty_access });
|
||||
// And finally, copy the preordained AtomicCASLoop output reg to its destination.
|
||||
ctx.emit(Inst::gen_move(r_dst, xreg(27), I64));
|
||||
// Also, x24 and x28 are trashed. `fn aarch64_get_regs` must mention that.
|
||||
}
|
||||
}
|
||||
Opcode::AtomicCas => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::AtomicLoad => {
|
||||
let rt = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user