/* -----------------------------------------------------------------------------
- * $Id: PrimOps.hc,v 1.91 2002/01/29 16:24:08 simonmar Exp $
+ * $Id: PrimOps.hc,v 1.99 2002/06/26 08:18:41 stolz Exp $
*
* (c) The GHC Team, 1998-2000
*
#define BYTES_TO_STGWORDS(n) ((n) + sizeof(W_) - 1)/sizeof(W_)
-FN_(newByteArrayzh_fast) \
- { \
- W_ size, stuff_size, n; \
- StgArrWords* p; \
- FB_ \
- MAYBE_GC(NO_PTRS,newByteArrayzh_fast); \
- n = R1.w; \
- stuff_size = BYTES_TO_STGWORDS(n); \
- size = sizeofW(StgArrWords)+ stuff_size; \
- p = (StgArrWords *)RET_STGCALL1(P_,allocate,size); \
- TICK_ALLOC_PRIM(sizeofW(StgArrWords),stuff_size,0); \
- SET_HDR(p, &stg_ARR_WORDS_info, CCCS); \
- p->words = stuff_size; \
- TICK_RET_UNBOXED_TUP(1) \
- RET_P(p); \
- FE_ \
+FN_(newByteArrayzh_fast)
+ {
+ W_ size, stuff_size, n;
+ StgArrWords* p;
+ FB_
+ MAYBE_GC(NO_PTRS,newByteArrayzh_fast);
+ n = R1.w;
+ stuff_size = BYTES_TO_STGWORDS(n);
+ size = sizeofW(StgArrWords)+ stuff_size;
+ p = (StgArrWords *)RET_STGCALL1(P_,allocate,size);
+ TICK_ALLOC_PRIM(sizeofW(StgArrWords),stuff_size,0);
+ SET_HDR(p, &stg_ARR_WORDS_info, CCCS);
+ p->words = stuff_size;
+ TICK_RET_UNBOXED_TUP(1)
+ RET_P(p);
+ FE_
}
-FN_(newPinnedByteArrayzh_fast) \
- { \
- W_ size, stuff_size, n; \
- StgArrWords* p; \
- FB_ \
- MAYBE_GC(NO_PTRS,newPinnedByteArrayzh_fast); \
- n = R1.w; \
- stuff_size = BYTES_TO_STGWORDS(n); \
- size = sizeofW(StgArrWords)+ stuff_size; \
- p = (StgArrWords *)RET_STGCALL1(P_,allocatePinned,size); \
- TICK_ALLOC_PRIM(sizeofW(StgArrWords),stuff_size,0); \
- SET_HDR(p, &stg_ARR_WORDS_info, CCCS); \
- p->words = stuff_size; \
- TICK_RET_UNBOXED_TUP(1) \
- RET_P(p); \
- FE_ \
+FN_(newPinnedByteArrayzh_fast)
+ {
+ W_ size, stuff_size, n;
+ StgArrWords* p;
+ FB_
+ MAYBE_GC(NO_PTRS,newPinnedByteArrayzh_fast);
+ n = R1.w;
+ stuff_size = BYTES_TO_STGWORDS(n);
+
+ // We want an 8-byte aligned array. allocatePinned() gives us
+ // 8-byte aligned memory by default, but we want to align the
+ // *goods* inside the ArrWords object, so we have to check the
+ // size of the ArrWords header and adjust our size accordingly.
+ size = sizeofW(StgArrWords)+ stuff_size;
+ if ((sizeof(StgArrWords) & 7) != 0) {
+ size++;
+ }
+
+ p = (StgArrWords *)RET_STGCALL1(P_,allocatePinned,size);
+ TICK_ALLOC_PRIM(sizeofW(StgArrWords),stuff_size,0);
+
+ // Again, if the ArrWords header isn't a multiple of 8 bytes, we
+ // have to push the object forward one word so that the goods
+ // fall on an 8-byte boundary.
+ if ((sizeof(StgArrWords) & 7) != 0) {
+ ((StgPtr)p)++;
+ }
+
+ SET_HDR(p, &stg_ARR_WORDS_info, CCCS);
+ p->words = stuff_size;
+ TICK_RET_UNBOXED_TUP(1)
+ RET_P(p);
+ FE_
}
FN_(newArrayzh_fast)
{
/* R1 = the first Int#; R2 = the second Int# */
mp_limb_t aa;
- I_ r;
+ I_ r;
FB_
aa = (mp_limb_t)(R1.i);
r = RET_STGCALL3(StgInt, mpn_gcd_1, (mp_limb_t *)(&aa), 1, (mp_limb_t)(R2.i));
- RET_N(r);
+
+ R1.i = r;
+ /* Result parked in R1, return via info-pointer at TOS */
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
/* R1 = s1; R2 = d1; R3 = the int */
I_ r;
FB_
- r = RET_STGCALL3(I_,mpn_gcd_1,(mp_limb_t *)(BYTE_ARR_CTS(R2.p)), R1.i, R3.i);
- RET_N(r);
+ r = RET_STGCALL3(StgInt,mpn_gcd_1,(mp_limb_t *)(BYTE_ARR_CTS(R2.p)), R1.i, R3.i);
+
+ R1.i = r;
+ /* Result parked in R1, return via info-pointer at TOS */
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
}
if (usize != vsize) {
- RET_N(usize - vsize);
+ R1.i = usize - vsize; JMP_(ENTRY_CODE(Sp[0]));
}
if (usize == 0) {
- RET_N(0);
+ R1.i = 0; JMP_(ENTRY_CODE(Sp[0]));
}
u_digit = *(mp_limb_t *)(BYTE_ARR_CTS(R2.p));
if (u_digit == (mp_limb_t) (unsigned long) v_digit) {
- RET_N(0);
+ R1.i = 0; JMP_(ENTRY_CODE(Sp[0]));
}
if (u_digit > (mp_limb_t) (unsigned long) v_digit) {
- RET_N(usize);
+ R1.i = usize;
} else {
- RET_N(-usize);
+ R1.i = -usize;
}
+
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
vsize = R3.i;
if (usize != vsize) {
- RET_N(usize - vsize);
+ R1.i = usize - vsize; JMP_(ENTRY_CODE(Sp[0]));
}
if (usize == 0) {
- RET_N(0);
+ R1.i = 0; JMP_(ENTRY_CODE(Sp[0]));
}
size = abs(usize);
cmp = RET_STGCALL3(I_, mpn_cmp, (mp_limb_t *)up, (mp_limb_t *)vp, size);
if (cmp == 0) {
- RET_N(0);
+ R1.i = 0; JMP_(ENTRY_CODE(Sp[0]));
}
if ((cmp < 0) == (usize < 0)) {
- RET_N(1);
+ R1.i = 1;
} else {
- RET_N(-1);
+ R1.i = (-1);
}
+ /* Result parked in R1, return via info-pointer at TOS */
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
r = ((mp_limb_t *) (BYTE_ARR_CTS(R2.p)))[0];
if (s < 0) r = -r;
}
- RET_N(r);
+ /* Result parked in R1, return via info-pointer at TOS */
+ R1.i = r;
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
r = ((mp_limb_t *) (BYTE_ARR_CTS(R2.p)))[0];
if (s < 0) r = -r;
}
- RET_N(r);
+ /* Result parked in R1, return via info-pointer at TOS */
+ R1.w = r;
+ JMP_(ENTRY_CODE(Sp[0]));
FE_
}
/* create it right now, return ThreadID in R1 */
R1.t = RET_STGCALL2(StgTSO *, createIOThread,
- RtsFlags.GcFlags.initialStkSize, R1.cl);
+ RtsFlags.GcFlags.initialStkSize, R1.cl);
STGCALL1(scheduleThread, R1.t);
/* switch at the earliest opportunity */
context_switch = 1;
+ RET_P(R1.t);
+ FE_
+}
+
+FN_(forkProcesszh_fast)
+{
+ pid_t pid;
+
+ FB_
+ /* args: none */
+ /* result: Pid */
+
+ R1.i = RET_STGCALL1(StgInt, forkProcess, CurrentTSO);
+
JMP_(ENTRY_CODE(Sp[0]));
+
FE_
}
FE_
}
+FN_(myThreadIdzh_fast)
+{
+ /* no args. */
+ FB_
+ RET_P((P_)CurrentTSO);
+ FE_
+}
+
+FN_(labelThreadzh_fast)
+{
+ FB_
+ /* args:
+ R1.p = ThreadId#
+ R2.p = Addr# */
+#ifdef DEBUG
+ STGCALL2(labelThread,(StgTSO *)R1.p,(char *)R2.p);
+#endif
+ JMP_(ENTRY_CODE(Sp[0]));
+ FE_
+}
+
+
/* -----------------------------------------------------------------------------
* MVar primitives
*
FE_
}
-#define PerformTake(tso, value) ({ \
- (tso)->sp[1] = (W_)value; \
+/* If R1 isn't available, pass it on the stack */
+#ifdef REG_R1
+#define PerformTake(tso, value) ({ \
+ (tso)->sp[1] = (W_)value; \
(tso)->sp[0] = (W_)&stg_gc_unpt_r1_info; \
})
+#else
+#define PerformTake(tso, value) ({ \
+ (tso)->sp[1] = (W_)value; \
+ (tso)->sp[0] = (W_)&stg_ut_1_0_unreg_info; \
+ })
+#endif
+
#define PerformPut(tso) ({ \
StgClosure *val = (StgClosure *)(tso)->sp[2]; \