-- | Evaluation of 64 bit values on 32 bit platforms.moduleSPARC.CodeGen.Gen64(assignMem_I64Code ,assignReg_I64Code ,iselExpr64 )whereimportGhcPrelude import{-# SOURCE#-}SPARC.CodeGen.Gen32 importSPARC.CodeGen.Base importSPARC.CodeGen.Amode importSPARC.Regs importSPARC.AddrMode importSPARC.Imm importSPARC.Instr importSPARC.Ppr ()importNCGMonad importInstruction importFormat importReg importCmm importDynFlags importOrdList importOutputable -- | Code to assign a 64 bit value to memory.assignMem_I64Code::CmmExpr -- ^ expr producing the destination address->CmmExpr -- ^ expr producing the source value.->NatM InstrBlock assignMem_I64Code addrTree valueTree =doChildCode64 vcode rlo <-iselExpr64 valueTree (src ,acode )<-getSomeReg addrTree letrhi =getHiVRegFromLo rlo -- Big-endian storemov_hi =ST II32 rhi (AddrRegImm src (ImmInt 0))mov_lo =ST II32 rlo (AddrRegImm src (ImmInt 4))code =vcode `appOL `acode `snocOL `mov_hi `snocOL `mov_lo {- pprTrace "assignMem_I64Code" (vcat [ text "addrTree: " <+> ppr addrTree , text "valueTree: " <+> ppr valueTree , text "vcode:" , vcat $ map ppr $ fromOL vcode , text "" , text "acode:" , vcat $ map ppr $ fromOL acode ]) $ -}returncode -- | Code to assign a 64 bit value to a register.assignReg_I64Code::CmmReg -- ^ the destination register->CmmExpr -- ^ expr producing the source value->NatM InstrBlock assignReg_I64Code (CmmLocal (LocalReg u_dst pk ))valueTree =doChildCode64 vcode r_src_lo <-iselExpr64 valueTree letr_dst_lo =RegVirtual $mkVirtualReg u_dst (cmmTypeFormat pk )r_dst_hi =getHiVRegFromLo r_dst_lo r_src_hi =getHiVRegFromLo r_src_lo mov_lo =mkMOV r_src_lo r_dst_lo mov_hi =mkMOV r_src_hi r_dst_hi mkMOV sreg dreg =OR Falseg0 (RIReg sreg )dreg return(vcode `snocOL `mov_hi `snocOL `mov_lo )assignReg_I64Code__=panic "assignReg_I64Code(sparc): invalid lvalue"-- | Get the value of an expression into a 64 bit register.iselExpr64::CmmExpr ->NatM ChildCode64 -- Load a 64 bit wordiselExpr64 (CmmLoad addrTree ty )|isWord64 ty =doAmode amode addr_code <-getAmode addrTree letresult |AddrRegReg r1 r2 <-amode =dorlo <-getNewRegNat II32 tmp <-getNewRegNat II32 letrhi =getHiVRegFromLo rlo return$ChildCode64 (addr_code `appOL `toOL [ADD FalseFalser1 (RIReg r2 )tmp ,LD II32 (AddrRegImm tmp (ImmInt 0))rhi ,LD II32 (AddrRegImm tmp (ImmInt 4))rlo ])rlo |AddrRegImm r1 (ImmInt i )<-amode =dorlo <-getNewRegNat II32 letrhi =getHiVRegFromLo rlo return$ChildCode64 (addr_code `appOL `toOL [LD II32 (AddrRegImm r1 (ImmInt $0+i ))rhi ,LD II32 (AddrRegImm r1 (ImmInt $4+i ))rlo ])rlo |otherwise=panic "SPARC.CodeGen.Gen64: no match"result -- Add a literal to a 64 bit integeriselExpr64(CmmMachOp (MO_Add _)[e1 ,CmmLit (CmmInt i _)])=doChildCode64 code1 r1_lo <-iselExpr64 e1 letr1_hi =getHiVRegFromLo r1_lo r_dst_lo <-getNewRegNat II32 letr_dst_hi =getHiVRegFromLo r_dst_lo letcode =code1 `appOL `toOL [ADD FalseTruer1_lo (RIImm (ImmInteger i ))r_dst_lo ,ADD TrueFalser1_hi (RIReg g0 )r_dst_hi ]return$ChildCode64 code r_dst_lo -- Addition of II64iselExpr64(CmmMachOp (MO_Add _)[e1 ,e2 ])=doChildCode64 code1 r1_lo <-iselExpr64 e1 letr1_hi =getHiVRegFromLo r1_lo ChildCode64 code2 r2_lo <-iselExpr64 e2 letr2_hi =getHiVRegFromLo r2_lo r_dst_lo <-getNewRegNat II32 letr_dst_hi =getHiVRegFromLo r_dst_lo letcode =code1 `appOL `code2 `appOL `toOL [ADD FalseTruer1_lo (RIReg r2_lo )r_dst_lo ,ADD TrueFalser1_hi (RIReg r2_hi )r_dst_hi ]return$ChildCode64 code r_dst_lo iselExpr64(CmmReg (CmmLocal (LocalReg uq ty )))|isWord64 ty =dor_dst_lo <-getNewRegNat II32 letr_dst_hi =getHiVRegFromLo r_dst_lo r_src_lo =RegVirtual $mkVirtualReg uq II32 r_src_hi =getHiVRegFromLo r_src_lo mov_lo =mkMOV r_src_lo r_dst_lo mov_hi =mkMOV r_src_hi r_dst_hi mkMOV sreg dreg =OR Falseg0 (RIReg sreg )dreg return(ChildCode64 (toOL [mov_hi ,mov_lo ])r_dst_lo )-- Convert something into II64iselExpr64(CmmMachOp (MO_UU_Conv _W64 )[expr ])=dor_dst_lo <-getNewRegNat II32 letr_dst_hi =getHiVRegFromLo r_dst_lo -- compute expr and load it into r_dst_lo(a_reg ,a_code )<-getSomeReg expr dflags <-getDynFlags letplatform =targetPlatform dflags code =a_code `appOL `toOL [mkRegRegMoveInstr platform g0 r_dst_hi -- clear high 32 bits,mkRegRegMoveInstr platform a_reg r_dst_lo ]return$ChildCode64 code r_dst_lo -- only W32 supported for nowiselExpr64(CmmMachOp (MO_SS_Conv W32 W64 )[expr ])=dor_dst_lo <-getNewRegNat II32 letr_dst_hi =getHiVRegFromLo r_dst_lo -- compute expr and load it into r_dst_lo(a_reg ,a_code )<-getSomeReg expr dflags <-getDynFlags letplatform =targetPlatform dflags code =a_code `appOL `toOL [SRA a_reg (RIImm (ImmInt 31))r_dst_hi ,mkRegRegMoveInstr platform a_reg r_dst_lo ]return$ChildCode64 code r_dst_lo iselExpr64expr =pprPanic "iselExpr64(sparc)"(ppr expr )