import CLabel
import Cmm
-import DynFlags
import FastString
import qualified Outputable
-- complete this completely though as we need to pass all CmmStatic
-- sections before all references can be resolved. This last step is
-- done by 'resolveLlvmData'.
-genLlvmData :: DynFlags -> (Section, [CmmStatic]) -> LlvmUnresData
-genLlvmData _ ( _ , (CmmDataLabel lbl):xs) =
+genLlvmData :: (Section, [CmmStatic]) -> LlvmUnresData
+genLlvmData (sec, CmmDataLabel lbl:xs) =
let static = map genData xs
label = strCLabel_llvm lbl
getStatTypes (Right x) = getStatType x
strucTy = LMStruct types
- alias = LMAlias (label `appendFS` structStr) strucTy
- in (lbl, alias, static)
+ alias = LMAlias ((label `appendFS` structStr), strucTy)
+ in (lbl, sec, alias, static)
-genLlvmData _ _ = panic "genLlvmData: CmmData section doesn't start with label!"
+genLlvmData _ = panic "genLlvmData: CmmData section doesn't start with label!"
-resolveLlvmDatas :: DynFlags -> LlvmEnv -> [LlvmUnresData] -> [LlvmData]
+
+resolveLlvmDatas :: LlvmEnv -> [LlvmUnresData] -> [LlvmData]
-> (LlvmEnv, [LlvmData])
-resolveLlvmDatas _ env [] ldata
+resolveLlvmDatas env [] ldata
= (env, ldata)
-resolveLlvmDatas dflags env (udata : rest) ldata
- = let (env', ndata) = resolveLlvmData dflags env udata
- in resolveLlvmDatas dflags env' rest (ldata ++ [ndata])
+resolveLlvmDatas env (udata : rest) ldata
+ = let (env', ndata) = resolveLlvmData env udata
+ in resolveLlvmDatas env' rest (ldata ++ [ndata])
-- | Fix up CLabel references now that we should have passed all CmmData.
-resolveLlvmData :: DynFlags -> LlvmEnv -> LlvmUnresData -> (LlvmEnv, LlvmData)
-resolveLlvmData _ env (lbl, alias, unres) =
+resolveLlvmData :: LlvmEnv -> LlvmUnresData -> (LlvmEnv, LlvmData)
+resolveLlvmData env (lbl, sec, alias, unres) =
let (env', static, refs) = resDatas env unres ([], [])
refs' = catMaybes refs
struct = Just $ LMStaticStruc static alias
label = strCLabel_llvm lbl
link = if (externallyVisibleCLabel lbl)
then ExternallyVisible else Internal
- glob = LMGlobalVar label alias link Nothing Nothing
+ const = isSecConstant sec
+ glob = LMGlobalVar label alias link Nothing Nothing const
in (env', (refs' ++ [(glob, struct)], [alias]))
+-- | Should a data in this section be considered constant
+isSecConstant :: Section -> Bool
+isSecConstant Text = True
+isSecConstant Data = False
+isSecConstant ReadOnlyData = True
+isSecConstant RelocatableReadOnlyData = True
+isSecConstant UninitialisedData = False
+isSecConstant ReadOnlyData16 = True
+isSecConstant (OtherSection _) = False
+
+
-- ----------------------------------------------------------------------------
-- ** Resolve Data/CLabel references
--
--
-- We check the 'LlvmEnv' to see if the reference has been defined in this
-- module. If it has we can retrieve its type and make a pointer, otherwise
--- we introduce a generic external defenition for the referenced label and
+-- we introduce a generic external definition for the referenced label and
-- then make a pointer.
resData :: LlvmEnv -> UnresStatic -> (LlvmEnv, LlvmStatic, [Maybe LMGlobal])
-- pointer to it.
Just ty' ->
let var = LMGlobalVar label (LMPointer ty')
- ExternallyVisible Nothing Nothing
+ ExternallyVisible Nothing Nothing False
ptr = LMStaticPointer var
in (env, LMPtoI ptr lmty, [Nothing])
= Right $ LMStaticLit (LMIntLit i (LMInt $ widthInBits w))
genStaticLit (CmmFloat r w)
- = Right $ LMStaticLit (LMFloatLit r (widthToLlvmFloat w))
+ = Right $ LMStaticLit (LMFloatLit (fromRational r) (widthToLlvmFloat w))
-- Leave unresolved, will fix later
genStaticLit c@(CmmLabel _ ) = Left $ c