-cmmResConv = ConventionStandard CmmCallConv Results
-
-copyIn :: Convention -> Area -> CmmFormals -> [Middle]
-copyIn _ area formals = reverse $ snd $ foldl ci (1, []) formals
- where ci (n, ms) v = (n+1, MidAssign (CmmLocal $ kindlessCmm v)
- (CmmLoad (CmmStackSlot area n) wordRep) : ms)
-
-copyOut :: Convention -> Area -> CmmActuals -> [Middle]
-copyOut conv area actuals = moveSP conv $ snd $ foldl co (1, []) actuals
- where moveSP (ConventionStandard _ Arguments) args =
- MidAssign spReg (outgoingSlot area) : reverse args
- moveSP _ args = reverse $ MidAssign spReg (outgoingSlot area) : args
- co (n, ms) v = (n+1, MidStore (CmmStackSlot area n) (kindlessCmm v) : ms)
-mkEntry :: Area -> Convention -> CmmFormalsWithoutKinds -> [Middle]
-mkEntry area conv formals = copyIn conv area fs
- where fs = map (\f -> CmmKinded f NoHint) formals
+cmmResConv = Native
+
+-- Return the number of bytes used for copying arguments, as well as the
+-- instructions to copy the arguments.
+copyIn :: Convention -> Bool -> Area -> CmmFormals -> (Int, [Middle])
+copyIn _ isCall area formals =
+ foldr ci (init_offset, []) $ assignArgumentsPos isCall localRegType formals
+ where ci (reg, RegisterParam r) (n, ms) =
+ (n, MidAssign (CmmLocal reg) (CmmReg $ CmmGlobal r) : ms)
+ ci (reg, StackParam off) (n, ms) =
+ let ty = localRegType reg
+ off' = off + init_offset
+ in (max n off',
+ MidAssign (CmmLocal reg) (CmmLoad (CmmStackSlot area off') ty) : ms)
+ init_offset = widthInBytes wordWidth
+
+-- The argument layout function ignores the pointer to the info table, so we slot that
+-- in here. When copying-out to a young area, we set the info table for return
+-- and adjust the offsets of the other parameters.
+-- If this is a call instruction, we adjust the offsets of the other parameters.
+copyOut :: Convention -> Transfer -> Area -> CmmActuals -> (Int, [Middle])
+copyOut _ transfer area@(CallArea a) actuals =
+ foldr co (init_offset, []) args'
+ where args = assignArgumentsPos skip_node cmmExprType actuals
+ skip_node = transfer /= Ret
+ (setRA, init_offset) =
+ case a of Young id -> -- set RA if making a call
+ if transfer == Call then
+ ([(CmmLit (CmmLabel (infoTblLbl id)),
+ StackParam init_offset)], ra_width)
+ else ([], 0)
+ Old -> ([], ra_width)
+ ra_width = widthInBytes wordWidth
+ args' = foldl adjust setRA args
+ where adjust rst (v, StackParam off) = (v, StackParam (off + init_offset)) : rst
+ adjust rst x@(_, RegisterParam _) = x : rst
+ co (v, RegisterParam r) (n, ms) = (n, MidAssign (CmmGlobal r) v : ms)
+ co (v, StackParam off) (n, ms) =
+ (max n off, MidStore (CmmStackSlot area off) v : ms)
+copyOut _ _ (RegSlot _) _ = panic "cannot copy arguments into a register slot"
+
+mkEntry :: BlockId -> Convention -> CmmFormals -> (Int, CmmAGraph)
+mkEntry _ conv formals =
+ let (off, copies) = copyIn conv False (CallArea Old) formals in
+ (off, mkMiddles copies)