x64: port atomic_rmw to ISLE (#4389)

* 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
This commit is contained in:
Andrew Brown
2022-07-06 16:58:59 -07:00
committed by GitHub
parent f98076ae88
commit 8629cbc6a4
10 changed files with 196 additions and 172 deletions

View File

@@ -415,10 +415,10 @@
;; The sequence consists of an initial "normal" load from `dst`, followed
;; by a loop which computes the new value and tries to compare-and-swap
;; ("CAS") it into `dst`, using the native instruction `lock
;; cmpxchg{b,w,l,q}` . The loop iterates until the CAS is successful.
;; If there is no contention, there will be only one pass through the
;; loop body. The sequence does *not* perform any explicit memory fence
;; instructions (mfence/sfence/lfence).
;; cmpxchg{b,w,l,q}`. The loop iterates until the CAS is successful. If
;; there is no contention, there will be only one pass through the loop
;; body. The sequence does *not* perform any explicit memory fence
;; instructions (`mfence`/`sfence`/`lfence`).
;;
;; Note that the transaction is atomic in the sense that, as observed by
;; some other thread, `dst` either has the initial or final value, but no
@@ -430,15 +430,12 @@
;; problem.
;;
;; This instruction sequence has fixed register uses as follows:
;;
;; %r9 (read) address
;; %r10 (read) second operand for `op`
;; %r11 (written) scratch reg; value afterwards has no meaning
;; %rax (written) the old value at %r9
;; %rflags is written. Do not assume anything about it after the instruction.
;; - %rax (written) the old value at `mem`
;; - %rflags is written. Do not assume anything about it after the
;; instruction.
(AtomicRmwSeq (ty Type) ;; I8, I16, I32, or I64
(op AtomicRmwOp)
(address Reg)
(op MachAtomicRmwOp)
(mem SyntheticAmode)
(operand Reg)
(temp WritableReg)
(dst_old WritableReg))
@@ -2921,6 +2918,19 @@
(_ Unit (emit (MInst.LockCmpxchg ty replacement expected addr dst))))
dst))
(decl x64_atomic_rmw_seq (Type MachAtomicRmwOp SyntheticAmode Gpr) Gpr)
(rule (x64_atomic_rmw_seq ty op mem input)
(let ((dst WritableGpr (temp_writable_gpr))
(tmp WritableGpr (temp_writable_gpr))
(_ Unit (emit (MInst.AtomicRmwSeq ty op mem input tmp dst))))
dst))
;; CLIF IR has one enumeration for atomic operations (`AtomicRmwOp`) while the
;; mach backend has another (`MachAtomicRmwOp`)--this converts one to the other.
(type MachAtomicRmwOp extern (enum))
(decl atomic_rmw_op_to_mach_atomic_rmw_op (AtomicRmwOp) MachAtomicRmwOp)
(extern constructor atomic_rmw_op_to_mach_atomic_rmw_op atomic_rmw_op_to_mach_atomic_rmw_op)
;;;; Automatic conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(convert Gpr InstOutput output_gpr)
@@ -2973,6 +2983,7 @@
(convert SyntheticAmode XmmMem synthetic_amode_to_xmm_mem)
(convert IntCC CC intcc_to_cc)
(convert AtomicRmwOp MachAtomicRmwOp atomic_rmw_op_to_mach_atomic_rmw_op)
(decl reg_to_xmm_mem (Reg) XmmMem)
(rule (reg_to_xmm_mem r)