summaryrefslogtreecommitdiff
path: root/utils/genapply
diff options
context:
space:
mode:
Diffstat (limited to 'utils/genapply')
-rw-r--r--utils/genapply/GenApply.hs650
1 files changed, 325 insertions, 325 deletions
diff --git a/utils/genapply/GenApply.hs b/utils/genapply/GenApply.hs
index b255b92d28..d00324f173 100644
--- a/utils/genapply/GenApply.hs
+++ b/utils/genapply/GenApply.hs
@@ -17,7 +17,7 @@ module Main(main) where
import Text.PrettyPrint
import Data.Word
import Data.Bits
-import Data.List ( intersperse )
+import Data.List ( intersperse )
import System.Exit
import System.Environment
import System.IO
@@ -26,12 +26,12 @@ import System.IO
-- Argument kinds (rougly equivalent to PrimRep)
data ArgRep
- = N -- non-ptr
- | P -- ptr
- | V -- void
- | F -- float
- | D -- double
- | L -- long (64-bit)
+ = N -- non-ptr
+ | P -- ptr
+ | V -- void
+ | F -- float
+ | D -- double
+ | L -- long (64-bit)
-- size of a value in *words*
argSize :: ArgRep -> Int
@@ -93,12 +93,12 @@ saveRegOffs = vcat . map (uncurry assign_reg_to_stk)
-- a bit like assignRegs in CgRetConv.lhs
assignRegs
- :: RegStatus -- are we registerised?
- -> Int -- Sp of first arg
- -> [ArgRep] -- args
- -> ([(Reg,Int)], -- regs and offsets to load
- [ArgRep], -- left-over args
- Int) -- Sp of left-over args
+ :: RegStatus -- are we registerised?
+ -> Int -- Sp of first arg
+ -> [ArgRep] -- args
+ -> ([(Reg,Int)], -- regs and offsets to load
+ [ArgRep], -- left-over args
+ Int) -- Sp of left-over args
assignRegs regstatus sp args = assign sp args (availableRegs regstatus) []
assign sp [] regs doc = (doc, [], sp)
@@ -106,7 +106,7 @@ assign sp (V : args) regs doc = assign sp args regs doc
assign sp (arg : args) regs doc
= case findAvailableReg arg regs of
Just (reg, regs') -> assign (sp + argSize arg) args regs'
- ((reg, sp) : doc)
+ ((reg, sp) : doc)
Nothing -> (doc, (arg:args), sp)
findAvailableReg N (vreg:vregs, fregs, dregs, lregs) =
@@ -139,8 +139,8 @@ loadSpWordOff rep off = text rep <> text "[Sp+WDS(" <> int off <> text ")]"
mkBitmap :: [ArgRep] -> Word32
mkBitmap args = foldr f 0 args
where f arg bm | isPtr arg = bm `shiftL` 1
- | otherwise = (bm `shiftL` size) .|. ((1 `shiftL` size) - 1)
- where size = argSize arg
+ | otherwise = (bm `shiftL` size) .|. ((1 `shiftL` size) - 1)
+ where size = argSize arg
-- -----------------------------------------------------------------------------
-- Generating the application functions
@@ -174,113 +174,113 @@ mkApplyInfoName args
= mkApplyName args <> text "_info"
mb_tag_node arity | Just tag <- tagForArity arity = mkTagStmt tag <> semi
- | otherwise = empty
+ | otherwise = empty
mkTagStmt tag = text ("R1 = R1 + "++ show tag)
genMkPAP regstatus macro jump ticker disamb
- no_load_regs -- don't load argumnet regs before jumping
- args_in_regs -- arguments are already in regs
- is_pap args all_args_size fun_info_label
+ no_load_regs -- don't load argumnet regs before jumping
+ args_in_regs -- arguments are already in regs
+ is_pap args all_args_size fun_info_label
is_fun_case
= smaller_arity_cases
$$ exact_arity_case
$$ larger_arity_case
-
+
where
n_args = length args
- -- offset of arguments on the stack at slow apply calls.
+ -- offset of arguments on the stack at slow apply calls.
stk_args_slow_offset = 1
stk_args_offset
- | args_in_regs = 0
- | otherwise = stk_args_slow_offset
+ | args_in_regs = 0
+ | otherwise = stk_args_slow_offset
-- The SMALLER ARITY cases:
--- if (arity == 1) {
--- Sp[0] = Sp[1];
--- Sp[1] = (W_)&stg_ap_1_info;
--- JMP_(GET_ENTRY(R1.cl));
+-- if (arity == 1) {
+-- Sp[0] = Sp[1];
+-- Sp[1] = (W_)&stg_ap_1_info;
+-- JMP_(GET_ENTRY(R1.cl));
smaller_arity_cases = vcat [ smaller_arity i | i <- [1..n_args-1] ]
smaller_arity arity
= text "if (arity == " <> int arity <> text ") {" $$
nest 4 (vcat [
- -- text "TICK_SLOW_CALL_" <> text ticker <> text "_TOO_MANY();",
-
- -- load up regs for the call, if necessary
- load_regs,
-
- -- If we have more args in registers than are required
- -- for the call, then we must save some on the stack,
- -- and set up the stack for the follow-up call.
- -- If the extra arguments are on the stack, then we must
- -- instead shuffle them down to make room for the info
- -- table for the follow-on call.
- if overflow_regs
- then save_extra_regs
- else shuffle_extra_args,
-
- -- for a PAP, we have to arrange that the stack contains a
- -- return address in the even that stg_PAP_entry fails its
- -- heap check. See stg_PAP_entry in Apply.hc for details.
- if is_pap
- then text "R2 = " <> mkApplyInfoName this_call_args <> semi
-
- else empty,
+ -- text "TICK_SLOW_CALL_" <> text ticker <> text "_TOO_MANY();",
+
+ -- load up regs for the call, if necessary
+ load_regs,
+
+ -- If we have more args in registers than are required
+ -- for the call, then we must save some on the stack,
+ -- and set up the stack for the follow-up call.
+ -- If the extra arguments are on the stack, then we must
+ -- instead shuffle them down to make room for the info
+ -- table for the follow-on call.
+ if overflow_regs
+ then save_extra_regs
+ else shuffle_extra_args,
+
+ -- for a PAP, we have to arrange that the stack contains a
+ -- return address in the even that stg_PAP_entry fails its
+ -- heap check. See stg_PAP_entry in Apply.hc for details.
+ if is_pap
+ then text "R2 = " <> mkApplyInfoName this_call_args <> semi
+
+ else empty,
if is_fun_case then mb_tag_node arity else empty,
if overflow_regs
then text "jump_SAVE_CCCS" <> parens (text jump) <> semi
else text "jump " <> text jump <> semi
]) $$
- text "}"
-
- where
- -- offsets in case we need to save regs:
- (reg_locs, _, _)
- = assignRegs regstatus stk_args_offset args
-
- -- register assignment for *this function call*
- (reg_locs', reg_call_leftovers, reg_call_sp_stk_args)
- = assignRegs regstatus stk_args_offset (take arity args)
-
- load_regs
- | no_load_regs || args_in_regs = empty
- | otherwise = loadRegOffs reg_locs'
-
- (this_call_args, rest_args) = splitAt arity args
-
- -- the offset of the stack args from initial Sp
- sp_stk_args
- | args_in_regs = stk_args_offset
- | no_load_regs = stk_args_offset
- | otherwise = reg_call_sp_stk_args
-
- -- the stack args themselves
- this_call_stack_args
- | args_in_regs = reg_call_leftovers -- sp offsets are wrong
- | no_load_regs = this_call_args
- | otherwise = reg_call_leftovers
-
- stack_args_size = sum (map argSize this_call_stack_args)
-
- overflow_regs = args_in_regs && length reg_locs > length reg_locs'
-
- save_extra_regs
- = -- we have extra arguments in registers to save
- let
- extra_reg_locs = drop (length reg_locs') (reverse reg_locs)
- adj_reg_locs = [ (reg, off - adj + 1) |
- (reg,off) <- extra_reg_locs ]
- adj = case extra_reg_locs of
- (reg, fst_off):_ -> fst_off
- size = snd (last adj_reg_locs)
- in
- text "Sp_adj(" <> int (-size - 1) <> text ");" $$
- saveRegOffs adj_reg_locs $$
- loadSpWordOff "W_" 0 <> text " = " <>
- mkApplyInfoName rest_args <> semi
+ text "}"
+
+ where
+ -- offsets in case we need to save regs:
+ (reg_locs, _, _)
+ = assignRegs regstatus stk_args_offset args
+
+ -- register assignment for *this function call*
+ (reg_locs', reg_call_leftovers, reg_call_sp_stk_args)
+ = assignRegs regstatus stk_args_offset (take arity args)
+
+ load_regs
+ | no_load_regs || args_in_regs = empty
+ | otherwise = loadRegOffs reg_locs'
+
+ (this_call_args, rest_args) = splitAt arity args
+
+ -- the offset of the stack args from initial Sp
+ sp_stk_args
+ | args_in_regs = stk_args_offset
+ | no_load_regs = stk_args_offset
+ | otherwise = reg_call_sp_stk_args
+
+ -- the stack args themselves
+ this_call_stack_args
+ | args_in_regs = reg_call_leftovers -- sp offsets are wrong
+ | no_load_regs = this_call_args
+ | otherwise = reg_call_leftovers
+
+ stack_args_size = sum (map argSize this_call_stack_args)
+
+ overflow_regs = args_in_regs && length reg_locs > length reg_locs'
+
+ save_extra_regs
+ = -- we have extra arguments in registers to save
+ let
+ extra_reg_locs = drop (length reg_locs') (reverse reg_locs)
+ adj_reg_locs = [ (reg, off - adj + 1) |
+ (reg,off) <- extra_reg_locs ]
+ adj = case extra_reg_locs of
+ (reg, fst_off):_ -> fst_off
+ size = snd (last adj_reg_locs)
+ in
+ text "Sp_adj(" <> int (-size - 1) <> text ");" $$
+ saveRegOffs adj_reg_locs $$
+ loadSpWordOff "W_" 0 <> text " = " <>
+ mkApplyInfoName rest_args <> semi
shuffle_extra_args
= vcat [text "#ifdef PROFILING",
@@ -310,52 +310,52 @@ genMkPAP regstatus macro jump ticker disamb
shuffle_down j i =
loadSpWordOff "W_" (i-j) <> text " = " <>
- loadSpWordOff "W_" i <> semi
+ loadSpWordOff "W_" i <> semi
-- The EXACT ARITY case
--
--- if (arity == 1) {
--- Sp++;
--- JMP_(GET_ENTRY(R1.cl));
+-- if (arity == 1) {
+-- Sp++;
+-- JMP_(GET_ENTRY(R1.cl));
exact_arity_case
- = text "if (arity == " <> int n_args <> text ") {" $$
- let
- (reg_doc, sp')
- | no_load_regs || args_in_regs = (empty, stk_args_offset)
- | otherwise = loadRegArgs regstatus stk_args_offset args
- in
- nest 4 (vcat [
--- text "TICK_SLOW_CALL_" <> text ticker <> text "_CORRECT();",
- reg_doc,
- text "Sp_adj(" <> int sp' <> text ");",
+ = text "if (arity == " <> int n_args <> text ") {" $$
+ let
+ (reg_doc, sp')
+ | no_load_regs || args_in_regs = (empty, stk_args_offset)
+ | otherwise = loadRegArgs regstatus stk_args_offset args
+ in
+ nest 4 (vcat [
+-- text "TICK_SLOW_CALL_" <> text ticker <> text "_CORRECT();",
+ reg_doc,
+ text "Sp_adj(" <> int sp' <> text ");",
if is_pap
then text "R2 = " <> fun_info_label <> semi
else empty,
if is_fun_case then mb_tag_node n_args else empty,
- text "jump " <> text jump <> semi
- ])
+ text "jump " <> text jump <> semi
+ ])
-- The LARGER ARITY cases:
--
--- } else /* arity > 1 */ {
--- BUILD_PAP(1,0,(W_)&stg_ap_v_info);
--- }
+-- } else /* arity > 1 */ {
+-- BUILD_PAP(1,0,(W_)&stg_ap_v_info);
+-- }
larger_arity_case =
- text "} else {" $$
- let
- save_regs
- | args_in_regs =
- text "Sp_adj(" <> int (-sp_offset) <> text ");" $$
- saveRegOffs reg_locs
- | otherwise =
- empty
- in
- nest 4 (vcat [
--- text "TICK_SLOW_CALL_" <> text ticker <> text "_TOO_FEW();",
- save_regs,
+ text "} else {" $$
+ let
+ save_regs
+ | args_in_regs =
+ text "Sp_adj(" <> int (-sp_offset) <> text ");" $$
+ saveRegOffs reg_locs
+ | otherwise =
+ empty
+ in
+ nest 4 (vcat [
+-- text "TICK_SLOW_CALL_" <> text ticker <> text "_TOO_FEW();",
+ save_regs,
-- Before building the PAP, tag the function closure pointer
if is_fun_case then
vcat [
@@ -365,18 +365,18 @@ genMkPAP regstatus macro jump ticker disamb
]
else empty
,
- text macro <> char '(' <> int n_args <> comma <>
- int all_args_size <>
- text "," <> fun_info_label <>
- text "," <> text disamb <>
- text ");"
- ]) $$
- char '}'
- where
- -- offsets in case we need to save regs:
- (reg_locs, leftovers, sp_offset)
- = assignRegs regstatus stk_args_slow_offset args
- -- BUILD_PAP assumes args start at offset 1
+ text macro <> char '(' <> int n_args <> comma <>
+ int all_args_size <>
+ text "," <> fun_info_label <>
+ text "," <> text disamb <>
+ text ");"
+ ]) $$
+ char '}'
+ where
+ -- offsets in case we need to save regs:
+ (reg_locs, leftovers, sp_offset)
+ = assignRegs regstatus stk_args_slow_offset args
+ -- BUILD_PAP assumes args start at offset 1
-- Note [jump_SAVE_CCCS]
@@ -413,44 +413,44 @@ tagForArity i | i < tAG_BITS_MAX = Just i
enterFastPathHelper tag regstatus no_load_regs args_in_regs args =
vcat [text "if (GETTAG(R1)==" <> int tag <> text ") {",
- reg_doc,
+ reg_doc,
text " Sp_adj(" <> int sp' <> text ");",
-- enter, but adjust offset with tag
- text " jump " <> text "%GET_ENTRY(R1-" <> int tag <> text ");",
+ text " jump " <> text "%GET_ENTRY(R1-" <> int tag <> text ");",
text "}"
]
-- I don't totally understand this code, I copied it from
-- exact_arity_case
-- TODO: refactor
where
- -- offset of arguments on the stack at slow apply calls.
+ -- offset of arguments on the stack at slow apply calls.
stk_args_slow_offset = 1
stk_args_offset
- | args_in_regs = 0
- | otherwise = stk_args_slow_offset
+ | args_in_regs = 0
+ | otherwise = stk_args_slow_offset
(reg_doc, sp')
- | no_load_regs || args_in_regs = (empty, stk_args_offset)
- | otherwise = loadRegArgs regstatus stk_args_offset args
+ | no_load_regs || args_in_regs = (empty, stk_args_offset)
+ | otherwise = loadRegArgs regstatus stk_args_offset args
tickForArity arity
| True
= empty
| Just tag <- tagForArity arity
= vcat [
- text "W_[TOTAL_CALLS] = W_[TOTAL_CALLS] + 1;",
- text "W_[SLOW_CALLS_" <> int arity <> text "] = W_[SLOW_CALLS_" <> int arity <> text "] + 1;",
- text "if (TO_W_(StgFunInfoExtra_arity(%FUN_INFO(%INFO_PTR(UNTAG(R1))))) == " <> int arity <> text " ) {",
- text " W_[RIGHT_ARITY_" <> int arity <> text "] = W_[RIGHT_ARITY_" <> int arity <> text "] + 1;",
- text " if (GETTAG(R1)==" <> int tag <> text ") {",
- text " W_[TAGGED_PTR_" <> int arity <> text "] = W_[TAGGED_PTR_" <> int arity <> text "] + 1;",
- text " } else {",
- -- force a halt when not tagged!
--- text " W_[0]=0;",
- text " }",
- text "}"
- ]
+ text "W_[TOTAL_CALLS] = W_[TOTAL_CALLS] + 1;",
+ text "W_[SLOW_CALLS_" <> int arity <> text "] = W_[SLOW_CALLS_" <> int arity <> text "] + 1;",
+ text "if (TO_W_(StgFunInfoExtra_arity(%FUN_INFO(%INFO_PTR(UNTAG(R1))))) == " <> int arity <> text " ) {",
+ text " W_[RIGHT_ARITY_" <> int arity <> text "] = W_[RIGHT_ARITY_" <> int arity <> text "] + 1;",
+ text " if (GETTAG(R1)==" <> int tag <> text ") {",
+ text " W_[TAGGED_PTR_" <> int arity <> text "] = W_[TAGGED_PTR_" <> int arity <> text "] + 1;",
+ text " } else {",
+ -- force a halt when not tagged!
+-- text " W_[0]=0;",
+ text " }",
+ text "}"
+ ]
tickForArity _ = text "W_[TOTAL_CALLS] = W_[TOTAL_CALLS] + 1;"
-- -----------------------------------------------------------------------------
@@ -488,45 +488,45 @@ genApply regstatus args =
-- print "static void *lbls[] ="
-- print " { [FUN] &&fun_lbl,"
-- print " [FUN_1_0] &&fun_lbl,"
--- print " [FUN_0_1] &&fun_lbl,"
--- print " [FUN_2_0] &&fun_lbl,"
--- print " [FUN_1_1] &&fun_lbl,"
--- print " [FUN_0_2] &&fun_lbl,"
+-- print " [FUN_0_1] &&fun_lbl,"
+-- print " [FUN_2_0] &&fun_lbl,"
+-- print " [FUN_1_1] &&fun_lbl,"
+-- print " [FUN_0_2] &&fun_lbl,"
-- print " [FUN_STATIC] &&fun_lbl,"
-- print " [PAP] &&pap_lbl,"
-- print " [THUNK] &&thunk_lbl,"
--- print " [THUNK_1_0] &&thunk_lbl,"
--- print " [THUNK_0_1] &&thunk_lbl,"
--- print " [THUNK_2_0] &&thunk_lbl,"
--- print " [THUNK_1_1] &&thunk_lbl,"
--- print " [THUNK_0_2] &&thunk_lbl,"
+-- print " [THUNK_1_0] &&thunk_lbl,"
+-- print " [THUNK_0_1] &&thunk_lbl,"
+-- print " [THUNK_2_0] &&thunk_lbl,"
+-- print " [THUNK_1_1] &&thunk_lbl,"
+-- print " [THUNK_0_2] &&thunk_lbl,"
-- print " [THUNK_STATIC] &&thunk_lbl,"
-- print " [THUNK_SELECTOR] &&thunk_lbl,"
--- print " [IND] &&ind_lbl,"
+-- print " [IND] &&ind_lbl,"
-- print " [IND_STATIC] &&ind_lbl,"
--- print " [IND_PERM] &&ind_lbl,"
+-- print " [IND_PERM] &&ind_lbl,"
-- print " };"
tickForArity (length args),
text "",
text "IF_DEBUG(apply,foreign \"C\" debugBelch(\"" <> fun_ret_label <>
- text "... \"); foreign \"C\" printClosure(R1 \"ptr\"));",
+ text "... \"); foreign \"C\" printClosure(R1 \"ptr\"));",
text "IF_DEBUG(sanity,foreign \"C\" checkStackFrame(Sp+WDS(" <> int (1 + all_args_size)
- <> text ")\"ptr\"));",
+ <> text ")\"ptr\"));",
-- text "IF_DEBUG(sanity,checkStackChunk(Sp+" <> int (1 + all_args_size) <>
--- text ", CurrentTSO->stack + CurrentTSO->stack_size));",
+-- text ", CurrentTSO->stack + CurrentTSO->stack_size));",
-- text "TICK_SLOW_CALL(" <> int (length args) <> text ");",
let do_assert [] _ = []
- do_assert (arg:args) offset
- | isPtr arg = this : rest
- | otherwise = rest
- where this = text "ASSERT(LOOKS_LIKE_CLOSURE_PTR(Sp("
- <> int offset <> text ")));"
- rest = do_assert args (offset + argSize arg)
+ do_assert (arg:args) offset
+ | isPtr arg = this : rest
+ | otherwise = rest
+ where this = text "ASSERT(LOOKS_LIKE_CLOSURE_PTR(Sp("
+ <> int offset <> text ")));"
+ rest = do_assert args (offset + argSize arg)
in
vcat (do_assert args 1),
@@ -543,20 +543,20 @@ genApply regstatus args =
-- print " goto *lbls[info->type];";
-- else:
text "switch [INVALID_OBJECT .. N_CLOSURE_TYPES] (TO_W_(%INFO_TYPE(%STD_INFO(info)))) {",
- nest 4 (vcat [
+ nest 4 (vcat [
-- if fast == 1:
-- print " bco_lbl:"
-- else:
- text "case BCO: {",
- nest 4 (vcat [
- text "arity = TO_W_(StgBCO_arity(R1));",
- text "ASSERT(arity > 0);",
- genMkPAP regstatus "BUILD_PAP" "ENTRY_LBL(stg_BCO)" "FUN" "BCO"
- True{-stack apply-} False{-args on stack-} False{-not a PAP-}
- args all_args_size fun_info_label {- tag stmt -}False
- ]),
- text "}",
+ text "case BCO: {",
+ nest 4 (vcat [
+ text "arity = TO_W_(StgBCO_arity(R1));",
+ text "ASSERT(arity > 0);",
+ genMkPAP regstatus "BUILD_PAP" "ENTRY_LBL(stg_BCO)" "FUN" "BCO"
+ True{-stack apply-} False{-args on stack-} False{-not a PAP-}
+ args all_args_size fun_info_label {- tag stmt -}False
+ ]),
+ text "}",
-- if fast == 1:
-- print " fun_lbl:"
@@ -568,38 +568,38 @@ genApply regstatus args =
text " FUN_1_1,",
text " FUN_0_2,",
text " FUN_STATIC: {",
- nest 4 (vcat [
- text "arity = TO_W_(StgFunInfoExtra_arity(%FUN_INFO(info)));",
- text "ASSERT(arity > 0);",
+ nest 4 (vcat [
+ text "arity = TO_W_(StgFunInfoExtra_arity(%FUN_INFO(info)));",
+ text "ASSERT(arity > 0);",
genMkPAP regstatus "BUILD_PAP" "%GET_ENTRY(UNTAG(R1))" "FUN" "FUN"
- False{-reg apply-} False{-args on stack-} False{-not a PAP-}
- args all_args_size fun_info_label {- tag stmt -}True
- ]),
- text "}",
+ False{-reg apply-} False{-args on stack-} False{-not a PAP-}
+ args all_args_size fun_info_label {- tag stmt -}True
+ ]),
+ text "}",
-- if fast == 1:
-- print " pap_lbl:"
-- else:
- text "case PAP: {",
- nest 4 (vcat [
- text "arity = TO_W_(StgPAP_arity(R1));",
- text "ASSERT(arity > 0);",
- genMkPAP regstatus "NEW_PAP" "stg_PAP_apply" "PAP" "PAP"
- True{-stack apply-} False{-args on stack-} True{-is a PAP-}
- args all_args_size fun_info_label {- tag stmt -}False
- ]),
- text "}",
+ text "case PAP: {",
+ nest 4 (vcat [
+ text "arity = TO_W_(StgPAP_arity(R1));",
+ text "ASSERT(arity > 0);",
+ genMkPAP regstatus "NEW_PAP" "stg_PAP_apply" "PAP" "PAP"
+ True{-stack apply-} False{-args on stack-} True{-is a PAP-}
+ args all_args_size fun_info_label {- tag stmt -}False
+ ]),
+ text "}",
- text "",
+ text "",
-- if fast == 1:
-- print " thunk_lbl:"
-- else:
- text "case AP,",
- text " AP_STACK,",
- text " BLACKHOLE,",
- text " WHITEHOLE,",
+ text "case AP,",
+ text " AP_STACK,",
+ text " BLACKHOLE,",
+ text " WHITEHOLE,",
text " THUNK,",
text " THUNK_1_0,",
text " THUNK_0_1,",
@@ -608,18 +608,18 @@ genApply regstatus args =
text " THUNK_0_2,",
text " THUNK_STATIC,",
text " THUNK_SELECTOR: {",
- nest 4 (vcat [
+ nest 4 (vcat [
-- text "TICK_SLOW_CALL_UNEVALD(" <> int (length args) <> text ");",
- text "Sp(0) = " <> fun_info_label <> text ";",
- -- CAREFUL! in SMP mode, the info table may already have been
- -- overwritten by an indirection, so we must enter the original
- -- info pointer we read, don't read it again, because it might
- -- not be enterable any more.
+ text "Sp(0) = " <> fun_info_label <> text ";",
+ -- CAREFUL! in SMP mode, the info table may already have been
+ -- overwritten by an indirection, so we must enter the original
+ -- info pointer we read, don't read it again, because it might
+ -- not be enterable any more.
text "jump_SAVE_CCCS(%ENTRY_CODE(info));",
-- see Note [jump_SAVE_CCCS]
text ""
- ]),
- text "}",
+ ]),
+ text "}",
-- if fast == 1:
-- print " ind_lbl:"
@@ -627,13 +627,13 @@ genApply regstatus args =
text "case IND,",
text " IND_STATIC,",
text " IND_PERM: {",
- nest 4 (vcat [
- text "R1 = StgInd_indirectee(R1);",
+ nest 4 (vcat [
+ text "R1 = StgInd_indirectee(R1);",
-- An indirection node might contain a tagged pointer
- text "goto again;"
- ]),
- text "}",
- text "",
+ text "goto again;"
+ ]),
+ text "}",
+ text "",
-- if fast == 0:
@@ -642,8 +642,8 @@ genApply regstatus args =
text "foreign \"C\" barf(\"" <> fun_ret_label <> text "\") never returns;"
),
text "}"
-
- ]),
+
+ ]),
text "}"
]),
text "}"
@@ -675,7 +675,7 @@ genApplyFast regstatus args =
text "R1 = UNTAG(R1);",
text "info = %GET_STD_INFO(R1);",
text "switch [INVALID_OBJECT .. N_CLOSURE_TYPES] (TO_W_(%INFO_TYPE(info))) {",
- nest 4 (vcat [
+ nest 4 (vcat [
text "case FUN,",
text " FUN_1_0,",
text " FUN_0_1,",
@@ -683,29 +683,29 @@ genApplyFast regstatus args =
text " FUN_1_1,",
text " FUN_0_2,",
text " FUN_STATIC: {",
- nest 4 (vcat [
- text "arity = TO_W_(StgFunInfoExtra_arity(%GET_FUN_INFO(R1)));",
- text "ASSERT(arity > 0);",
+ nest 4 (vcat [
+ text "arity = TO_W_(StgFunInfoExtra_arity(%GET_FUN_INFO(R1)));",
+ text "ASSERT(arity > 0);",
genMkPAP regstatus "BUILD_PAP" "%GET_ENTRY(UNTAG(R1))" "FUN" "FUN"
- False{-reg apply-} True{-args in regs-} False{-not a PAP-}
- args all_args_size fun_info_label {- tag stmt -}True
- ]),
- char '}',
-
- text "default: {",
- let
- (reg_locs, leftovers, sp_offset) = assignRegs regstatus 1 args
- -- leave a one-word space on the top of the stack when
- -- calling the slow version
- in
- nest 4 (vcat [
- text "Sp_adj" <> parens (int (-sp_offset)) <> semi,
- saveRegOffs reg_locs,
- text "jump" <+> fun_ret_label <> semi
- ]),
- char '}'
- ]),
- char '}'
+ False{-reg apply-} True{-args in regs-} False{-not a PAP-}
+ args all_args_size fun_info_label {- tag stmt -}True
+ ]),
+ char '}',
+
+ text "default: {",
+ let
+ (reg_locs, leftovers, sp_offset) = assignRegs regstatus 1 args
+ -- leave a one-word space on the top of the stack when
+ -- calling the slow version
+ in
+ nest 4 (vcat [
+ text "Sp_adj" <> parens (int (-sp_offset)) <> semi,
+ saveRegOffs reg_locs,
+ text "jump" <+> fun_ret_label <> semi
+ ]),
+ char '}'
+ ]),
+ char '}'
]),
char '}'
]
@@ -719,7 +719,7 @@ genApplyFast regstatus args =
-- available) and jump to the function's entry code.
--
-- On entry: R1 points to the function closure
--- arguments are on the stack starting at Sp
+-- arguments are on the stack starting at Sp
--
-- Invariant: the list of arguments never contains void. Since we're only
-- interested in loading arguments off the stack here, we can ignore
@@ -738,9 +738,9 @@ genStackApply regstatus args =
where
(assign_regs, sp') = loadRegArgs regstatus 0 args
body = vcat [assign_regs,
- text "Sp_adj" <> parens (int sp') <> semi,
- text "jump %GET_ENTRY(UNTAG(R1));"
- ]
+ text "Sp_adj" <> parens (int sp') <> semi,
+ text "jump %GET_ENTRY(UNTAG(R1));"
+ ]
-- -----------------------------------------------------------------------------
-- Stack save entry points.
@@ -762,15 +762,15 @@ genStackSave regstatus args =
]
where
body = vcat [text "Sp_adj" <> parens (int (-sp_offset)) <> semi,
- saveRegOffs reg_locs,
- text "Sp(2) = R1;",
- text "Sp(1) =" <+> int stk_args <> semi,
- text "Sp(0) = stg_gc_fun_info;",
- text "jump stg_gc_noregs;"
- ]
+ saveRegOffs reg_locs,
+ text "Sp(2) = R1;",
+ text "Sp(1) =" <+> int stk_args <> semi,
+ text "Sp(0) = stg_gc_fun_info;",
+ text "jump stg_gc_noregs;"
+ ]
std_frame_size = 3 -- the std bits of the frame. See StgRetFun in Closures.h,
- -- and the comment on stg_fun_gc_gen in HeapStackCheck.hc.
+ -- and the comment on stg_fun_gc_gen in HeapStackCheck.hc.
(reg_locs, leftovers, sp_offset) = assignRegs regstatus std_frame_size args
-- number of words of arguments on the stack.
@@ -782,51 +782,51 @@ genStackSave regstatus args =
main = do
args <- getArgs
regstatus <- case args of
- [] -> return Registerised
- ["-u"] -> return Unregisterised
- _other -> do hPutStrLn stderr "syntax: genapply [-u]"
- exitWith (ExitFailure 1)
+ [] -> return Registerised
+ ["-u"] -> return Unregisterised
+ _other -> do hPutStrLn stderr "syntax: genapply [-u]"
+ exitWith (ExitFailure 1)
let the_code = vcat [
- text "// DO NOT EDIT!",
- text "// Automatically generated by GenApply.hs",
- text "",
- text "#include \"Cmm.h\"",
- text "#include \"AutoApply.h\"",
- text "",
-
- vcat (intersperse (text "") $
- map (genApply regstatus) applyTypes),
- vcat (intersperse (text "") $
- map (genStackFns regstatus) stackApplyTypes),
-
- vcat (intersperse (text "") $
- map (genApplyFast regstatus) applyTypes),
-
- genStackApplyArray stackApplyTypes,
- genStackSaveArray stackApplyTypes,
- genBitmapArray stackApplyTypes,
-
- text "" -- add a newline at the end of the file
- ]
+ text "// DO NOT EDIT!",
+ text "// Automatically generated by GenApply.hs",
+ text "",
+ text "#include \"Cmm.h\"",
+ text "#include \"AutoApply.h\"",
+ text "",
+
+ vcat (intersperse (text "") $
+ map (genApply regstatus) applyTypes),
+ vcat (intersperse (text "") $
+ map (genStackFns regstatus) stackApplyTypes),
+
+ vcat (intersperse (text "") $
+ map (genApplyFast regstatus) applyTypes),
+
+ genStackApplyArray stackApplyTypes,
+ genStackSaveArray stackApplyTypes,
+ genBitmapArray stackApplyTypes,
+
+ text "" -- add a newline at the end of the file
+ ]
-- in
putStr (render the_code)
-- These have been shown to cover about 99% of cases in practice...
applyTypes = [
- [V],
- [F],
- [D],
- [L],
- [N],
- [P],
- [P,V],
- [P,P],
- [P,P,V],
- [P,P,P],
- [P,P,P,V],
- [P,P,P,P],
- [P,P,P,P,P],
- [P,P,P,P,P,P]
+ [V],
+ [F],
+ [D],
+ [L],
+ [N],
+ [P],
+ [P,V],
+ [P,P],
+ [P,P,V],
+ [P,P,P],
+ [P,P,P,V],
+ [P,P,P,P],
+ [P,P,P,P,P],
+ [P,P,P,P,P,P]
]
-- No need for V args in the stack apply cases.
@@ -834,29 +834,29 @@ applyTypes = [
-- between N and P (they both live in the same register), only the bitmap
-- changes, so we could share the apply/save code between lots of cases.
stackApplyTypes = [
- [],
- [N],
- [P],
- [F],
- [D],
- [L],
- [N,N],
- [N,P],
- [P,N],
- [P,P],
- [N,N,N],
- [N,N,P],
- [N,P,N],
- [N,P,P],
- [P,N,N],
- [P,N,P],
- [P,P,N],
- [P,P,P],
- [P,P,P,P],
- [P,P,P,P,P],
- [P,P,P,P,P,P],
- [P,P,P,P,P,P,P],
- [P,P,P,P,P,P,P,P]
+ [],
+ [N],
+ [P],
+ [F],
+ [D],
+ [L],
+ [N,N],
+ [N,P],
+ [P,N],
+ [P,P],
+ [N,N,N],
+ [N,N,P],
+ [N,P,N],
+ [N,P,P],
+ [P,N,N],
+ [P,N,P],
+ [P,P,N],
+ [P,P,P],
+ [P,P,P,P],
+ [P,P,P,P,P],
+ [P,P,P,P,P,P],
+ [P,P,P,P,P,P,P],
+ [P,P,P,P,P,P,P,P]
]
genStackFns regstatus args
@@ -897,7 +897,7 @@ genBitmapArray types =
]
where
gen_bitmap ty = text "W_" <+> int bitmap_val <> semi
- where bitmap_val =
- (fromIntegral (mkBitmap ty) `shiftL` BITMAP_BITS_SHIFT)
- .|. sum (map argSize ty)
+ where bitmap_val =
+ (fromIntegral (mkBitmap ty) `shiftL` BITMAP_BITS_SHIFT)
+ .|. sum (map argSize ty)