/* -----------------------------------------------------------------------------
- * $Id: StgMacros.h,v 1.51 2003/04/22 16:25:08 simonmar Exp $
+ * $Id: StgMacros.h,v 1.57 2003/11/12 17:27:04 sof Exp $
*
* (c) The GHC Team, 1998-1999
*
we assume that the size of a double is always 2 pointers (wasting a
word when it is only one pointer, but avoiding lots of #ifdefs).
+ NOTE: if you change the layout of RET_DYN stack frames, then you
+ might also need to adjust the value of RESERVED_STACK_WORDS in
+ Constants.h.
-------------------------------------------------------------------------- */
// VERY MAGIC CONSTANTS!
-// must agree with code in HeapStackCheck.c, stg_gen_chk
+// must agree with code in HeapStackCheck.c, stg_gen_chk, and
+// RESERVED_STACK_WORDS in Constants.h.
//
#define RET_DYN_BITMAP_SIZE 8
#define RET_DYN_NONPTR_REGS_SIZE 10
#define ALL_NON_PTRS 0xff
+// Sanity check that RESERVED_STACK_WORDS is reasonable. We can't
+// just derive RESERVED_STACK_WORDS because it's used in Haskell code
+// too.
+#if RESERVED_STACK_WORDS != (3 + RET_DYN_BITMAP_SIZE + RET_DYN_NONPTR_REGS_SIZE)
+#error RESERVED_STACK_WORDS may be wrong!
+#endif
+
#define LIVENESS_MASK(ptr_regs) (ALL_NON_PTRS ^ (ptr_regs))
// We can have up to 255 pointers and 255 nonpointers in the stack
# else
// An object is replaced by a blackhole, so we fill the slop with zeros.
//
+// This looks like it can't work - we're overwriting the contents of
+// the THUNK with slop! Perhaps this never worked??? --SDM
+// The problem is that with eager-black-holing we currently perform
+// the black-holing operation at the *beginning* of the basic block,
+// when we still need the contents of the thunk.
+// Perhaps the thing to do is to overwrite it at the *end* of the
+// basic block, when we've already sucked out the thunk's contents? -- SLPJ
+//
// Todo: maybe use SET_HDR() and remove LDV_recordCreate()?
//
# define UPD_BH_UPDATABLE(info) \
# define UPD_BH_SINGLE_ENTRY(thunk) /* nothing */
#endif /* EAGER_BLACKHOLING */
-#define UPD_FRAME_UPDATEE(p) ((P_)(((StgUpdateFrame *)(p))->updatee))
-
/* -----------------------------------------------------------------------------
Moving Floats and Doubles
guaranteed to be StgWord aligned.
-------------------------------------------------------------------------- */
-static inline void ASSIGN_FLT (W_ [], StgFloat);
-static inline StgFloat PK_FLT (W_ []);
+INLINE_HEADER void ASSIGN_FLT (W_ [], StgFloat);
+INLINE_HEADER StgFloat PK_FLT (W_ []);
#if ALIGNMENT_FLOAT <= ALIGNMENT_LONG
-static inline void ASSIGN_FLT(W_ p_dest[], StgFloat src) { *(StgFloat *)p_dest = src; }
-static inline StgFloat PK_FLT (W_ p_src[]) { return *(StgFloat *)p_src; }
+INLINE_HEADER void ASSIGN_FLT(W_ p_dest[], StgFloat src) { *(StgFloat *)p_dest = src; }
+INLINE_HEADER StgFloat PK_FLT (W_ p_src[]) { return *(StgFloat *)p_src; }
#else /* ALIGNMENT_FLOAT > ALIGNMENT_UNSIGNED_INT */
-static inline void ASSIGN_FLT(W_ p_dest[], StgFloat src)
+INLINE_HEADER void ASSIGN_FLT(W_ p_dest[], StgFloat src)
{
float_thing y;
y.f = src;
*p_dest = y.fu;
}
-static inline StgFloat PK_FLT(W_ p_src[])
+INLINE_HEADER StgFloat PK_FLT(W_ p_src[])
{
float_thing y;
y.fu = *p_src;
#if ALIGNMENT_DOUBLE <= ALIGNMENT_LONG
-static inline void ASSIGN_DBL (W_ [], StgDouble);
-static inline StgDouble PK_DBL (W_ []);
+INLINE_HEADER void ASSIGN_DBL (W_ [], StgDouble);
+INLINE_HEADER StgDouble PK_DBL (W_ []);
-static inline void ASSIGN_DBL(W_ p_dest[], StgDouble src) { *(StgDouble *)p_dest = src; }
-static inline StgDouble PK_DBL (W_ p_src[]) { return *(StgDouble *)p_src; }
+INLINE_HEADER void ASSIGN_DBL(W_ p_dest[], StgDouble src) { *(StgDouble *)p_dest = src; }
+INLINE_HEADER StgDouble PK_DBL (W_ p_src[]) { return *(StgDouble *)p_src; }
#else /* ALIGNMENT_DOUBLE > ALIGNMENT_LONG */
#else /* ! sparc_TARGET_ARCH */
-static inline void ASSIGN_DBL (W_ [], StgDouble);
-static inline StgDouble PK_DBL (W_ []);
+INLINE_HEADER void ASSIGN_DBL (W_ [], StgDouble);
+INLINE_HEADER StgDouble PK_DBL (W_ []);
typedef struct
{ StgWord dhi;
unpacked_double du;
} double_thing;
-static inline void ASSIGN_DBL(W_ p_dest[], StgDouble src)
+INLINE_HEADER void ASSIGN_DBL(W_ p_dest[], StgDouble src)
{
double_thing y;
y.d = src;
*(p_dest+1) = ((double_thing) src).du.dlo \
*/
-static inline StgDouble PK_DBL(W_ p_src[])
+INLINE_HEADER StgDouble PK_DBL(W_ p_src[])
{
double_thing y;
y.du.dhi = p_src[0];
unpacked_double_word wu;
} word64_thing;
-static inline void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
+INLINE_HEADER void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
{
word64_thing y;
y.w = src;
p_dest[1] = y.wu.dlo;
}
-static inline StgWord64 PK_Word64(W_ p_src[])
+INLINE_HEADER StgWord64 PK_Word64(W_ p_src[])
{
word64_thing y;
y.wu.dhi = p_src[0];
return(y.w);
}
-static inline void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
+INLINE_HEADER void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
{
int64_thing y;
y.i = src;
p_dest[1] = y.iu.dlo;
}
-static inline StgInt64 PK_Int64(W_ p_src[])
+INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
{
int64_thing y;
y.iu.dhi = p_src[0];
#elif SIZEOF_VOID_P == 8
-static inline void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
+INLINE_HEADER void ASSIGN_Word64(W_ p_dest[], StgWord64 src)
{
p_dest[0] = src;
}
-static inline StgWord64 PK_Word64(W_ p_src[])
+INLINE_HEADER StgWord64 PK_Word64(W_ p_src[])
{
return p_src[0];
}
-static inline void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
+INLINE_HEADER void ASSIGN_Int64(W_ p_dest[], StgInt64 src)
{
p_dest[0] = src;
}
-static inline StgInt64 PK_Int64(W_ p_src[])
+INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
{
return p_src[0];
}
#if IN_STG_CODE
-static __inline__ void
+INLINE_HEADER void
SaveThreadState(void)
{
StgTSO *tso;
#endif
}
-static __inline__ void
+INLINE_HEADER void
LoadThreadState (void)
{
StgTSO *tso;