never executed always true always false
    1 -- | Evaluation of 64 bit values on 32 bit platforms.
    2 module GHC.CmmToAsm.SPARC.CodeGen.Gen64 (
    3         assignMem_I64Code,
    4         assignReg_I64Code,
    5         iselExpr64
    6 )
    7 
    8 where
    9 
   10 import GHC.Prelude
   11 
   12 import {-# SOURCE #-} GHC.CmmToAsm.SPARC.CodeGen.Gen32
   13 import GHC.CmmToAsm.SPARC.CodeGen.Base
   14 import GHC.CmmToAsm.SPARC.CodeGen.Amode
   15 import GHC.CmmToAsm.SPARC.Regs
   16 import GHC.CmmToAsm.SPARC.AddrMode
   17 import GHC.CmmToAsm.SPARC.Imm
   18 import GHC.CmmToAsm.SPARC.Instr
   19 import GHC.CmmToAsm.Monad
   20 import GHC.CmmToAsm.Format
   21 import GHC.Platform.Reg
   22 
   23 import GHC.Cmm
   24 
   25 import GHC.Data.OrdList
   26 import GHC.Utils.Outputable
   27 import GHC.Utils.Panic
   28 
   29 -- | Code to assign a 64 bit value to memory.
   30 assignMem_I64Code
   31         :: CmmExpr              -- ^ expr producing the destination address
   32         -> CmmExpr              -- ^ expr producing the source value.
   33         -> NatM InstrBlock
   34 
   35 assignMem_I64Code addrTree valueTree
   36  = do
   37      ChildCode64 vcode rlo      <- iselExpr64 valueTree
   38 
   39      (src, acode) <- getSomeReg addrTree
   40      let
   41          rhi = getHiVRegFromLo rlo
   42 
   43          -- Big-endian store
   44          mov_hi = ST II32 rhi (AddrRegImm src (ImmInt 0))
   45          mov_lo = ST II32 rlo (AddrRegImm src (ImmInt 4))
   46 
   47          code   = vcode `appOL` acode `snocOL` mov_hi `snocOL` mov_lo
   48 
   49 {-     pprTrace "assignMem_I64Code"
   50         (vcat   [ text "addrTree:  " <+> ppr addrTree
   51                 , text "valueTree: " <+> ppr valueTree
   52                 , text "vcode:"
   53                 , vcat $ map ppr $ fromOL vcode
   54                 , text ""
   55                 , text "acode:"
   56                 , vcat $ map ppr $ fromOL acode ])
   57        $ -}
   58      return code
   59 
   60 
   61 -- | Code to assign a 64 bit value to a register.
   62 assignReg_I64Code
   63         :: CmmReg               -- ^ the destination register
   64         -> CmmExpr              -- ^ expr producing the source value
   65         -> NatM InstrBlock
   66 
   67 assignReg_I64Code (CmmLocal (LocalReg u_dst pk)) valueTree
   68  = do
   69      ChildCode64 vcode r_src_lo <- iselExpr64 valueTree
   70      let
   71          r_dst_lo = RegVirtual $ mkVirtualReg u_dst (cmmTypeFormat pk)
   72          r_dst_hi = getHiVRegFromLo r_dst_lo
   73          r_src_hi = getHiVRegFromLo r_src_lo
   74          mov_lo = mkMOV r_src_lo r_dst_lo
   75          mov_hi = mkMOV r_src_hi r_dst_hi
   76          mkMOV sreg dreg = OR False g0 (RIReg sreg) dreg
   77 
   78      return (vcode `snocOL` mov_hi `snocOL` mov_lo)
   79 
   80 assignReg_I64Code _ _
   81    = panic "assignReg_I64Code(sparc): invalid lvalue"
   82 
   83 
   84 
   85 
   86 -- | Get the value of an expression into a 64 bit register.
   87 
   88 iselExpr64 :: CmmExpr -> NatM ChildCode64
   89 
   90 -- Load a 64 bit word
   91 iselExpr64 (CmmLoad addrTree ty)
   92  | isWord64 ty
   93  = do   Amode amode addr_code   <- getAmode addrTree
   94         let result
   95 
   96                 | AddrRegReg r1 r2      <- amode
   97                 = do    rlo     <- getNewRegNat II32
   98                         tmp     <- getNewRegNat II32
   99                         let rhi = getHiVRegFromLo rlo
  100 
  101                         return  $ ChildCode64
  102                                 (        addr_code
  103                                 `appOL`  toOL
  104                                          [ ADD False False r1 (RIReg r2) tmp
  105                                          , LD II32 (AddrRegImm tmp (ImmInt 0)) rhi
  106                                          , LD II32 (AddrRegImm tmp (ImmInt 4)) rlo ])
  107                                 rlo
  108 
  109                 | AddrRegImm r1 (ImmInt i) <- amode
  110                 = do    rlo     <- getNewRegNat II32
  111                         let rhi = getHiVRegFromLo rlo
  112 
  113                         return  $ ChildCode64
  114                                 (        addr_code
  115                                 `appOL`  toOL
  116                                          [ LD II32 (AddrRegImm r1 (ImmInt $ 0 + i)) rhi
  117                                          , LD II32 (AddrRegImm r1 (ImmInt $ 4 + i)) rlo ])
  118                                 rlo
  119 
  120                 | otherwise
  121                 = panic "SPARC.CodeGen.Gen64: no match"
  122 
  123         result
  124 
  125 
  126 -- Add a literal to a 64 bit integer
  127 iselExpr64 (CmmMachOp (MO_Add _) [e1, CmmLit (CmmInt i _)])
  128  = do   ChildCode64 code1 r1_lo <- iselExpr64 e1
  129         let r1_hi       = getHiVRegFromLo r1_lo
  130 
  131         r_dst_lo        <- getNewRegNat II32
  132         let r_dst_hi    =  getHiVRegFromLo r_dst_lo
  133 
  134         let code =      code1
  135                 `appOL` toOL
  136                         [ ADD False True  r1_lo (RIImm (ImmInteger i)) r_dst_lo
  137                         , ADD True  False r1_hi (RIReg g0)         r_dst_hi ]
  138 
  139         return  $ ChildCode64 code r_dst_lo
  140 
  141 
  142 -- Addition of II64
  143 iselExpr64 (CmmMachOp (MO_Add _) [e1, e2])
  144  = do   ChildCode64 code1 r1_lo <- iselExpr64 e1
  145         let r1_hi       = getHiVRegFromLo r1_lo
  146 
  147         ChildCode64 code2 r2_lo <- iselExpr64 e2
  148         let r2_hi       = getHiVRegFromLo r2_lo
  149 
  150         r_dst_lo        <- getNewRegNat II32
  151         let r_dst_hi    = getHiVRegFromLo r_dst_lo
  152 
  153         let code =      code1
  154                 `appOL` code2
  155                 `appOL` toOL
  156                         [ ADD False True  r1_lo (RIReg r2_lo) r_dst_lo
  157                         , ADD True  False r1_hi (RIReg r2_hi) r_dst_hi ]
  158 
  159         return  $ ChildCode64 code r_dst_lo
  160 
  161 
  162 iselExpr64 (CmmReg (CmmLocal (LocalReg uq ty)))
  163  | isWord64 ty
  164  = do
  165      r_dst_lo <-  getNewRegNat II32
  166      let r_dst_hi = getHiVRegFromLo r_dst_lo
  167          r_src_lo = RegVirtual $ mkVirtualReg uq II32
  168          r_src_hi = getHiVRegFromLo r_src_lo
  169          mov_lo = mkMOV r_src_lo r_dst_lo
  170          mov_hi = mkMOV r_src_hi r_dst_hi
  171          mkMOV sreg dreg = OR False g0 (RIReg sreg) dreg
  172      return (
  173             ChildCode64 (toOL [mov_hi, mov_lo]) r_dst_lo
  174          )
  175 
  176 -- Convert something into II64
  177 iselExpr64 (CmmMachOp (MO_UU_Conv _ W64) [expr])
  178  = do
  179         r_dst_lo        <- getNewRegNat II32
  180         let r_dst_hi    = getHiVRegFromLo r_dst_lo
  181 
  182         -- compute expr and load it into r_dst_lo
  183         (a_reg, a_code) <- getSomeReg expr
  184 
  185         platform        <- getPlatform
  186         let code        = a_code
  187                 `appOL` toOL
  188                         [ mkRegRegMoveInstr platform g0    r_dst_hi     -- clear high 32 bits
  189                         , mkRegRegMoveInstr platform a_reg r_dst_lo ]
  190 
  191         return  $ ChildCode64 code r_dst_lo
  192 
  193 -- only W32 supported for now
  194 iselExpr64 (CmmMachOp (MO_SS_Conv W32 W64) [expr])
  195  = do
  196         r_dst_lo        <- getNewRegNat II32
  197         let r_dst_hi    = getHiVRegFromLo r_dst_lo
  198 
  199         -- compute expr and load it into r_dst_lo
  200         (a_reg, a_code) <- getSomeReg expr
  201 
  202         platform        <- getPlatform
  203         let code        = a_code
  204                 `appOL` toOL
  205                         [ SRA a_reg (RIImm (ImmInt 31)) r_dst_hi
  206                         , mkRegRegMoveInstr platform a_reg r_dst_lo ]
  207 
  208         return  $ ChildCode64 code r_dst_lo
  209 
  210 
  211 iselExpr64 expr
  212    = do
  213       platform <- getPlatform
  214       pprPanic "iselExpr64(sparc)" (pdoc platform expr)