doAtomicRMW :: LocalReg      -- ^ Result reg
            -> AtomicMachOp  -- ^ Atomic op (e.g. add)
            -> CmmExpr       -- ^ MutableByteArray#
            -> CmmExpr       -- ^ Index
            -> CmmType       -- ^ Type of element by which we are indexing
            -> CmmExpr       -- ^ Op argument (e.g. amount to add)
            -> FCode ()
doAtomicRMW res amop mba idx idx_ty n = do
    dflags <- getDynFlags
    let width = typeWidth idx_ty
        addr  = cmmIndexOffExpr dflags (arrWordsHdrSize dflags)
                width mba idx
    emitPrimCall
        [ res ]
        (MO_AtomicRMW width amop)
        [ addr, n ]

-- | Emit an atomic read to a byte array that acts as a memory barrier.
doAtomicRMW :: LocalReg      -- ^ Result reg
            -> AtomicMachOp  -- ^ Atomic op (e.g. add)
            -> CmmExpr       -- ^ MutableByteArray#
            -> CmmExpr       -- ^ Index
            -> CmmType       -- ^ Type of element by which we are indexing
            -> CmmExpr       -- ^ Op argument (e.g. amount to add)
            -> FCode ()
doAtomicRMW res amop mba idx idx_ty n = do
    dflags <- getDynFlags
    let width = typeWidth idx_ty
        addr  = cmmIndexOffExpr dflags (arrWordsHdrSize dflags)
                width mba idx
    emitPrimCall
        [ res ]
        (MO_AtomicRMW width amop)
        [ addr, n ]

-- | Emit an atomic read to a byte array that acts as a memory barrier.
doAtomicRMW res amop mba idx idx_ty n = do
    dflags <- getDynFlags
    let width = typeWidth idx_ty
        addr  = cmmIndexOffExpr dflags (arrWordsHdrSize dflags)
                width mba idx
    emitPrimCall
        [ res ]
        (MO_AtomicRMW width amop)
        [ addr, n ]

-- | Emit an atomic read to a byte array that acts as a memory barrier.