-%********************************************************
-%* *
-\subsection[primop-stuff]{Argument and return conventions for Prim Ops}
-%* *
-%********************************************************
-
-\begin{code}
-assignPrimOpResultRegs
- :: PrimOp -- The constructors in canonical order
- -> [MagicId] -- The return regs all concatenated to together,
- -- (*including* one for the tag if necy)
-
-assignPrimOpResultRegs op
- = case (getPrimOpResultInfo op) of
-
- ReturnsPrim kind -> [dataReturnConvPrim kind]
-
- ReturnsAlg tycon
- -> let
- cons = tyConDataCons tycon
- result_regs = concat (map get_return_regs cons)
- in
- -- As R1 is dead, it can hold the tag if necessary
- case cons of
- [_] -> result_regs
- other -> (VanillaReg IntRep ILIT(1)) : result_regs
- where
- get_return_regs con
- = case (dataReturnConvAlg con) of
- ReturnInRegs regs -> regs
- ReturnInHeap -> panic "getPrimOpAlgResultRegs"
-\end{code}
-
-@assignPrimOpArgsRobust@ is used only for primitive ops which may
-trigger GC. [MAYBE (WDP 94/05)] For these, we pass all (nonRobust)
-arguments in registers. This function assigns them and tells us which
-of those registers are now live (because we've shoved a followable
-argument into it).
-
-Bug: it is assumed that robust amodes cannot contain pointers. This
-seems reasonable but isn't true. For example, \tr{Array#}'s
-\tr{MallocPtr#}'s are pointers. (This is only known to bite on
-\tr{_ccall_GC_} with a MallocPtr argument.)
-
-See after for some ADR comments...
-
-\begin{code}
-makePrimOpArgsRobust
- :: PrimOp
- -> [CAddrMode] -- Arguments
- -> ([CAddrMode], -- Arg registers
- Int, -- Liveness mask
- AbstractC) -- Simultaneous assignments to assign args to regs
-
-makePrimOpArgsRobust op arg_amodes
- = ASSERT (primOpCanTriggerGC op)
- let
- non_robust_amodes = filter (not . amodeCanSurviveGC) arg_amodes
- arg_kinds = map getAmodeRep non_robust_amodes
-
- (arg_regs, extra_args)
- = assignRegs [{-nothing live-}] arg_kinds
-
- -- Check that all the args fit before returning arg_regs
- final_arg_regs = case extra_args of
- [] -> arg_regs
- other -> pprError "Cannot allocate enough registers for primop (try rearranging code or reducing number of arguments?)" (ppr PprDebug op)
-
- arg_assts
- = mkAbstractCs (zipWithEqual "assign_to_reg" assign_to_reg final_arg_regs non_robust_amodes)
-
- assign_to_reg reg_id amode = CAssign (CReg reg_id) amode
-
- safe_arg regs arg
- | amodeCanSurviveGC arg = (regs, arg)
- | otherwise = (tail regs, CReg (head regs))
- safe_amodes = snd (mapAccumL safe_arg final_arg_regs arg_amodes)
-
- liveness_mask = mkLiveRegsMask final_arg_regs
- in
- (safe_amodes, liveness_mask, arg_assts)
-\end{code}
-