summaryrefslogtreecommitdiff
path: root/includes/Cmm.h
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2013-09-17 21:48:39 +0100
committerSimon Marlow <marlowsd@gmail.com>2013-10-01 11:10:08 +0100
commit11b5ce550d1a9bc84dd97629e1cca0b356054898 (patch)
tree5446e455f6165f50291c8877fdead17b74cae13f /includes/Cmm.h
parent56084d76eb1b57ad96a9e1c55f3d3e2d134f98d5 (diff)
downloadhaskell-11b5ce550d1a9bc84dd97629e1cca0b356054898.tar.gz
Remove use of R9, and fix associated bugs
We were passing the function address to stg_gc_prim_p in R9, which was wrong because the call was a high-level call and didn't declare R9 as a parameter. Passing R9 as an argument is the right way, but unfortunately that exposed another bug: we were using the same macro in some low-level Cmm, where it is illegal to call functions with arguments (see Note [syntax of cmm files]). So we now have low-level variants of STK_CHK() and STK_CHK_P() for use in low-level Cmm code.
Diffstat (limited to 'includes/Cmm.h')
-rw-r--r--includes/Cmm.h41
1 files changed, 28 insertions, 13 deletions
diff --git a/includes/Cmm.h b/includes/Cmm.h
index e4898b48d7..0e30c1657d 100644
--- a/includes/Cmm.h
+++ b/includes/Cmm.h
@@ -439,20 +439,32 @@
if (0) { goto __L__; }
#define GC_PRIM(fun) \
- R9 = fun; \
- jump stg_gc_prim();
-
+ jump stg_gc_prim(fun);
+
+// Version of GC_PRIM for use in low-level Cmm. We can call
+// stg_gc_prim, because it takes one argument and therefore has a
+// platform-independent calling convention (Note [Syntax of .cmm
+// files] in CmmParse.y).
+#define GC_PRIM_LL(fun) \
+ R1 = fun; \
+ jump stg_gc_prim [R1];
+
+// We pass the fun as the second argument, because the arg is
+// usually already in the first argument position (R1), so this
+// avoids moving it to a different register / stack slot.
#define GC_PRIM_N(fun,arg) \
- R9 = fun; \
- jump stg_gc_prim_n(arg);
+ jump stg_gc_prim_n(arg,fun);
#define GC_PRIM_P(fun,arg) \
- R9 = fun; \
- jump stg_gc_prim_p(arg);
+ jump stg_gc_prim_p(arg,fun);
+
+#define GC_PRIM_P_LL(fun,arg) \
+ R1 = arg; \
+ R2 = fun; \
+ jump stg_gc_prim_p_ll [R1,R2];
#define GC_PRIM_PP(fun,arg1,arg2) \
- R9 = fun; \
- jump stg_gc_prim_pp(arg1,arg2);
+ jump stg_gc_prim_pp(arg1,arg2,fun);
#define MAYBE_GC_(fun) \
if (CHECK_GC()) { \
@@ -478,23 +490,26 @@
GC_PRIM_PP(fun,arg1,arg2) \
}
-#define STK_CHK(n, fun) \
+#define STK_CHK_LL(n, fun) \
TICK_BUMP(STK_CHK_ctr); \
if (Sp - (n) < SpLim) { \
- GC_PRIM(fun) \
+ GC_PRIM_LL(fun) \
}
-#define STK_CHK_P(n, fun, arg) \
+#define STK_CHK_P_LL(n, fun, arg) \
+ TICK_BUMP(STK_CHK_ctr); \
if (Sp - (n) < SpLim) { \
- GC_PRIM_P(fun,arg) \
+ GC_PRIM_P_LL(fun,arg) \
}
#define STK_CHK_PP(n, fun, arg1, arg2) \
+ TICK_BUMP(STK_CHK_ctr); \
if (Sp - (n) < SpLim) { \
GC_PRIM_PP(fun,arg1,arg2) \
}
#define STK_CHK_ENTER(n, closure) \
+ TICK_BUMP(STK_CHK_ctr); \
if (Sp - (n) < SpLim) { \
jump __stg_gc_enter_1(closure); \
}