} StgLargeSRT;
/* ----------------------------------------------------------------------------
+ Relative pointers
+
+ Several pointer fields in info tables are expressed as offsets
+ relative to the info pointer, so that we can generate
+ position-independent code.
+
+ There is a complication on the x86_64 platform, where pointeres are
+ 64 bits, but the tools don't support 64-bit relative relocations.
+ However, the default memory model (small) ensures that all symbols
+ have values in the lower 2Gb of the address space, so offsets all
+ fit in 32 bits. Hence we can use 32-bit offset fields.
+ ------------------------------------------------------------------------- */
+
+#if x86_64_TARGET_ARCH
+#define OFFSET_FIELD(n) StgHalfInt n; StgHalfWord __pad_##n;
+#else
+#define OFFSET_FIELD(n) StgInt n;
+#endif
+
+/* ----------------------------------------------------------------------------
Info Tables
------------------------------------------------------------------------- */
#ifndef TABLES_NEXT_TO_CODE
StgLargeBitmap* large_bitmap; /* pointer to large bitmap structure */
#else
- StgWord large_bitmap_offset; /* offset from info table to large bitmap structure */
+ OFFSET_FIELD( large_bitmap_offset ); /* offset from info table to large bitmap structure */
#endif
StgWord selector_offset; /* used in THUNK_SELECTORs */
-------------------------------------------------------------------------- */
typedef struct _StgFunInfoExtraRev {
- StgWord slow_apply_offset; /* apply to args on the stack */
- StgWord bitmap; /* arg ptr/nonptr bitmap */
- StgWord srt_offset; /* pointer to the SRT table */
+ OFFSET_FIELD ( slow_apply_offset ); /* apply to args on the stack */
+ union {
+ StgWord bitmap;
+ OFFSET_FIELD ( bitmap_offset ); /* arg ptr/nonptr bitmap */
+ } b;
+ OFFSET_FIELD ( srt_offset ); /* pointer to the SRT table */
StgHalfWord fun_type; /* function type */
StgHalfWord arity; /* function arity */
} StgFunInfoExtraRev;
typedef struct {
#if defined(TABLES_NEXT_TO_CODE)
- StgWord srt_offset; /* offset to the SRT table */
+ OFFSET_FIELD( srt_offset ); /* offset to the SRT table */
StgInfoTable i;
#else
StgInfoTable i;
StgInfoTable i;
#endif
#if defined(TABLES_NEXT_TO_CODE)
- StgWord srt_offset; /* offset to the SRT table */
+ OFFSET_FIELD( srt_offset ); /* offset to the SRT table */
#else
StgSRT *srt; /* pointer to the SRT table */
#endif
#ifdef TABLES_NEXT_TO_CODE
#define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) (((StgWord) ((info)+1)) \
- + (info)->f.bitmap))
+ + (info)->f.b.bitmap_offset))
#else
-#define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) ((info)->f.bitmap))
+#define GET_FUN_LARGE_BITMAP(info) ((StgLargeBitmap*) ((info)->f.b.bitmap_offset))
#endif
callee-saves
%rax
%rbx YES
- %rcx
- %rdx (seem to be used as arg regs on x86-64)
- %rsi (seem to be used as arg regs on x86-64)
- %rdi (seem to be used as arg regs on x86-64)
- %rbp YES
+ %rcx arg reg, caller-saves
+ %rdx arg reg, caller-saves
+ %rsi arg reg, caller-saves
+ %rdi arg reg, caller-saves
+ %rbp YES (our *prime* register)
%rsp (unavailable - stack pointer)
- %r8
- %r9
- %r10
- %r11
+ %r8 arg reg, caller-saves
+ %r9 arg reg, caller-saves
+ %r10 caller-saves
+ %r11 caller-saves
%r12 YES
%r13 YES
%r14 YES
%r15 YES
+
+ %xmm0-7 arg regs, caller-saves
+ %xmm8-15 caller-saves
+
+ A better reg mapping might be:
+
+ %rbp Sp
+ %rbx R1
+ %r8 R2
+ %r9 R3
+ %r10 R4
+ %r12 Hp
+ %r14 SpLim
+ %r15 HpLim
+ %xmm8-11 F1-F4
+ %xmm12-13 D1-D2
+
+ Use the caller-saves regs for Rn, because we don't always have to
+ save those (as opposed to Sp/Hp/SpLim etc. which always have to be
+ saved).
+
--------------------------------------------------------------------------- */
#if x86_64_REGS
#if SIZEOF_VOID_P == 8
typedef StgInt64 StgInt;
typedef StgWord64 StgWord;
+typedef StgInt32 StgHalfInt;
typedef StgWord32 StgHalfWord;
#else
#if SIZEOF_VOID_P == 4
typedef StgInt32 StgInt;
typedef StgWord32 StgWord;
+typedef StgInt16 StgHalfInt;
typedef StgWord16 StgHalfWord;
#else
#error GHC untested on this architecture: sizeof(void *) != 4 or 8
bitmap_size = stp->n_blocks * BLOCK_SIZE / (sizeof(W_)*BITS_PER_BYTE);
if (bitmap_size > 0) {
- bitmap_bdescr = allocGroup((nat)BLOCK_ROUND_UP(bitmap_size)
+ bitmap_bdescr = allocGroup((lnat)BLOCK_ROUND_UP(bitmap_size)
/ BLOCK_SIZE);
stp->bitmap = bitmap_bdescr;
bitmap = bitmap_bdescr->start;
p = (StgPtr)args;
switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->f.bitmap);
- size = BITMAP_SIZE(fun_info->f.bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
+ size = BITMAP_SIZE(fun_info->f.b.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
size = GET_FUN_LARGE_BITMAP(fun_info)->size;
switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->f.bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
scavenge_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
p = (StgPtr)args;
switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->f.bitmap);
- size = BITMAP_SIZE(fun_info->f.bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
+ size = BITMAP_SIZE(fun_info->f.b.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
size = GET_FUN_LARGE_BITMAP(fun_info)->size;
switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->f.bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
putchar(arrWordsGetChar(obj,i));
} */
for (i=0; i<((StgArrWords *)obj)->words; i++)
- debugBelch("%u", ((StgArrWords *)obj)->payload[i]);
+ debugBelch("%lu", ((StgArrWords *)obj)->payload[i]);
debugBelch("\")\n");
break;
}
case MUT_ARR_PTRS:
- debugBelch("MUT_ARR_PTRS(size=%d)\n", ((StgMutArrPtrs *)obj)->ptrs);
+ debugBelch("MUT_ARR_PTRS(size=%ld)\n", ((StgMutArrPtrs *)obj)->ptrs);
break;
case MUT_ARR_PTRS_FROZEN:
#if !defined(XMLAMBDA)
- debugBelch("MUT_ARR_PTRS_FROZEN(size=%d)\n", ((StgMutArrPtrs *)obj)->ptrs);
+ debugBelch("MUT_ARR_PTRS_FROZEN(size=%ld)\n", ((StgMutArrPtrs *)obj)->ptrs);
break;
#else
{
break;
case STABLE_NAME:
- debugBelch("STABLE_NAME(%d)\n", ((StgStableName*)obj)->sn);
+ debugBelch("STABLE_NAME(%ld)\n", ((StgStableName*)obj)->sn);
break;
case TSO:
p = payload;
for(i = 0; i < size; i++, bitmap >>= 1 ) {
- debugBelch(" stk[%d] (%p) = ", spBottom-(payload+i), payload+i);
+ debugBelch(" stk[%ld] (%p) = ", spBottom-(payload+i), payload+i);
if ((bitmap & 1) == 0) {
printPtr((P_)payload[i]);
debugBelch("\n");
} else {
- debugBelch("Word# %d\n", payload[i]);
+ debugBelch("Word# %ld\n", payload[i]);
}
}
}
StgWord bitmap = large_bitmap->bitmap[bmp];
j = 0;
for(; i < size && j < BITS_IN(W_); j++, i++, bitmap >>= 1 ) {
- debugBelch(" stk[%d] (%p) = ", spBottom-(payload+i), payload+i);
+ debugBelch(" stk[%ld] (%p) = ", spBottom-(payload+i), payload+i);
if ((bitmap & 1) == 0) {
printPtr((P_)payload[i]);
debugBelch("\n");
} else {
- debugBelch("Word# %d\n", payload[i]);
+ debugBelch("Word# %ld\n", payload[i]);
}
}
}
switch (fun_info->f.fun_type) {
case ARG_GEN:
printSmallBitmap(spBottom, sp+1,
- BITMAP_BITS(fun_info->f.bitmap),
- BITMAP_SIZE(fun_info->f.bitmap));
+ BITMAP_BITS(fun_info->f.b.bitmap),
+ BITMAP_SIZE(fun_info->f.b.bitmap));
break;
case ARG_GEN_BIG:
printLargeBitmap(spBottom, sp+2,
p = (P_)&ret_fun->payload;
switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->f.bitmap);
- size = BITMAP_SIZE(fun_info->f.bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
+ size = BITMAP_SIZE(fun_info->f.b.bitmap);
p = retain_small_bitmap(p, size, bitmap, c, c_child_r);
break;
case ARG_GEN_BIG:
switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->f.bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.b.bitmap);
p = retain_small_bitmap(p, pap->n_args, bitmap,
(StgClosure *)pap, c_child_r);
break;
switch (fun_info->f.fun_type) {
case ARG_GEN:
checkSmallBitmap((StgPtr)ret_fun->payload,
- BITMAP_BITS(fun_info->f.bitmap), size);
+ BITMAP_BITS(fun_info->f.b.bitmap), size);
break;
case ARG_GEN_BIG:
checkLargeBitmap((StgPtr)ret_fun->payload,
switch (fun_info->f.fun_type) {
case ARG_GEN:
checkSmallBitmap( (StgPtr)pap->payload,
- BITMAP_BITS(fun_info->f.bitmap), pap->n_args );
+ BITMAP_BITS(fun_info->f.b.bitmap), pap->n_args );
break;
case ARG_GEN_BIG:
checkLargeBitmap( (StgPtr)pap->payload,
if (sn != 0) {
ASSERT(stable_ptr_table[sn].addr == p);
- IF_DEBUG(stable,debugBelch("cached stable name %d at %p\n",sn,p));
+ IF_DEBUG(stable,debugBelch("cached stable name %ld at %p\n",sn,p));
return sn;
} else {
sn = stable_ptr_free - stable_ptr_table;
if (p->sn_obj == NULL) {
// StableName object is dead
freeStableName(p);
- IF_DEBUG(stable, debugBelch("GC'd Stable name %d\n",
+ IF_DEBUG(stable, debugBelch("GC'd Stable name %ld\n",
p - stable_ptr_table));
continue;
} else {
p->addr = (StgPtr)isAlive((StgClosure *)p->addr);
- IF_DEBUG(stable, debugBelch("Stable name %d still alive at %p, ref %d\n", p - stable_ptr_table, p->addr, p->ref));
+ IF_DEBUG(stable, debugBelch("Stable name %ld still alive at %p, ref %ld\n", p - stable_ptr_table, p->addr, p->ref));
}
}
}