doCopyMutableArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff
                     -> FCode ()
doCopyMutableArrayOp = emitCopyArray copy
  where
    -- The only time the memory might overlap is when the two arrays
    -- we were provided are the same array!
    -- TODO: Optimize branch for common case of no aliasing.
    copy src dst dst_p src_p bytes = do
        dflags <- getDynFlags
        [moveCall, cpyCall] <- forkAlts [
            getCode $ emitMemmoveCall dst_p src_p (mkIntExpr dflags bytes)
            (wORD_SIZE dflags),
            getCode $ emitMemcpyCall  dst_p src_p (mkIntExpr dflags bytes)
            (wORD_SIZE dflags)
            ]
        emit =<< mkCmmIfThenElse (cmmEqWord dflags src dst) moveCall cpyCall
doCopyMutableArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff
                     -> FCode ()
doCopyMutableArrayOp = emitCopyArray copy
  where
    -- The only time the memory might overlap is when the two arrays
    -- we were provided are the same array!
    -- TODO: Optimize branch for common case of no aliasing.
    copy src dst dst_p src_p bytes = do
        dflags <- getDynFlags
        [moveCall, cpyCall] <- forkAlts [
            getCode $ emitMemmoveCall dst_p src_p (mkIntExpr dflags bytes)
            (wORD_SIZE dflags),
            getCode $ emitMemcpyCall  dst_p src_p (mkIntExpr dflags bytes)
            (wORD_SIZE dflags)
            ]
        emit =<< mkCmmIfThenElse (cmmEqWord dflags src dst) moveCall cpyCall
doCopyMutableArrayOp = emitCopyArray copy
  where
    -- The only time the memory might overlap is when the two arrays
    -- we were provided are the same array!
    -- TODO: Optimize branch for common case of no aliasing.
    copy src dst dst_p src_p bytes = do
        dflags <- getDynFlags
        [moveCall, cpyCall] <- forkAlts [
            getCode $ emitMemmoveCall dst_p src_p (mkIntExpr dflags bytes)
            (wORD_SIZE dflags),
            getCode $ emitMemcpyCall  dst_p src_p (mkIntExpr dflags bytes)
            (wORD_SIZE dflags)
            ]
        emit =<< mkCmmIfThenElse (cmmEqWord dflags src dst) moveCall cpyCall