- | primOpOutOfLine primop
- = tailCallPrimOp primop args
-
- | otherwise
- = ASSERT(primop /= SeqOp) -- can't handle SeqOp
-
- getArgAmodes args `thenFC` \ arg_amodes ->
-
- case (getPrimOpResultInfo primop) of
-
- ReturnsPrim kind ->
- let result_amode = CReg (dataReturnConvPrim kind) in
- performReturn
- (COpStmt [result_amode] op arg_amodes [{-no vol_regs-}])
- (mkPrimReturnCode (text "primapp)" <+> ppr x))
-
- -- otherwise, must be returning an enumerated type (eg. Bool).
- -- we've only got the tag in R2, so we have to load the constructor
- -- itself into R1.
-
- ReturnsAlg tycon
- | isUnboxedTupleTyCon tycon -> primRetUnboxedTuple op args res_ty
-
- | isEnumerationTyCon tycon ->
- performReturn
- (COpStmt [dyn_tag] op arg_amodes [{-no vol_regs-}])
- (\ sequel ->
- absC (CAssign (CReg node) closure_lbl) `thenC`
- mkDynamicAlgReturnCode tycon dyn_tag sequel)
-
- where
- -- Pull a unique out of thin air to put the tag in.
- -- It shouldn't matter if this overlaps with anything - we're
- -- about to return anyway.
- dyn_tag = CTemp (mkBuiltinUnique 0) IntRep
-
- closure_lbl = CVal (CIndex
- (CLbl (mkClosureTblLabel tycon) PtrRep)
- dyn_tag PtrRep) PtrRep
-
+ | primOpOutOfLine primop
+ = tailCallPrimOp primop args
+
+ | ReturnsPrim VoidRep <- result_info
+ = do cgPrimOp [] primop args emptyVarSet
+ performReturn emitDirectReturnInstr
+
+ | ReturnsPrim rep <- result_info
+ = do cgPrimOp [dataReturnConvPrim (primRepToCgRep rep)]
+ primop args emptyVarSet
+ performReturn emitDirectReturnInstr
+
+ | ReturnsAlg tycon <- result_info, isUnboxedTupleTyCon tycon
+ = do (reps, regs, _hints) <- newUnboxedTupleRegs res_ty
+ cgPrimOp regs primop args emptyVarSet{-no live vars-}
+ returnUnboxedTuple (zip reps (map CmmReg regs))
+
+ | ReturnsAlg tycon <- result_info, isEnumerationTyCon tycon
+ -- c.f. cgExpr (...TagToEnumOp...)
+ = do tag_reg <- newTemp wordRep
+ cgPrimOp [tag_reg] primop args emptyVarSet
+ stmtC (CmmAssign nodeReg (tagToClosure tycon (CmmReg tag_reg)))
+ performReturn (emitAlgReturnCode tycon (CmmReg tag_reg))
+ where
+ result_info = getPrimOpResultInfo primop