genAssign :: CmmReg -> CmmExpr -> LlvmM StmtData
genAssign reg val = do
    vreg <- getCmmReg reg
    (vval, stmts2, top2) <- exprToVar val
    let stmts = stmts2

    let ty = (pLower . getVarType) vreg
    dflags <- getDynFlags
    case ty of
      -- Some registers are pointer types, so need to cast value to pointer
      LMPointer _ | getVarType vval == llvmWord dflags -> do
          (v, s1) <- doExpr ty $ Cast LM_Inttoptr vval ty
          let s2 = Store v vreg
          return (stmts `snocOL` s1 `snocOL` s2, top2)

      LMVector _ _ -> do
          (v, s1) <- doExpr ty $ Cast LM_Bitcast vval ty
          let s2 = Store v vreg
          return (stmts `snocOL` s1 `snocOL` s2, top2)

      _ -> do
          let s1 = Store vval vreg
          return (stmts `snocOL` s1, top2)


-- | CmmStore operation
genAssign :: CmmReg -> CmmExpr -> LlvmM StmtData
genAssign reg val = do
    vreg <- getCmmReg reg
    (vval, stmts2, top2) <- exprToVar val
    let stmts = stmts2

    let ty = (pLower . getVarType) vreg
    dflags <- getDynFlags
    case ty of
      -- Some registers are pointer types, so need to cast value to pointer
      LMPointer _ | getVarType vval == llvmWord dflags -> do
          (v, s1) <- doExpr ty $ Cast LM_Inttoptr vval ty
          let s2 = Store v vreg
          return (stmts `snocOL` s1 `snocOL` s2, top2)

      LMVector _ _ -> do
          (v, s1) <- doExpr ty $ Cast LM_Bitcast vval ty
          let s2 = Store v vreg
          return (stmts `snocOL` s1 `snocOL` s2, top2)

      _ -> do
          let s1 = Store vval vreg
          return (stmts `snocOL` s1, top2)


-- | CmmStore operation
genAssign reg val = do
    vreg <- getCmmReg reg
    (vval, stmts2, top2) <- exprToVar val
    let stmts = stmts2

    let ty = (pLower . getVarType) vreg
    dflags <- getDynFlags
    case ty of
      -- Some registers are pointer types, so need to cast value to pointer
      LMPointer _ | getVarType vval == llvmWord dflags -> do
          (v, s1) <- doExpr ty $ Cast LM_Inttoptr vval ty
          let s2 = Store v vreg
          return (stmts `snocOL` s1 `snocOL` s2, top2)

      LMVector _ _ -> do
          (v, s1) <- doExpr ty $ Cast LM_Bitcast vval ty
          let s2 = Store v vreg
          return (stmts `snocOL` s1 `snocOL` s2, top2)

      _ -> do
          let s1 = Store vval vreg
          return (stmts `snocOL` s1, top2)


-- | CmmStore operation