X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2FPrimOps.cmm;h=4a7d398b6a5e249b939f8155d624f62198f9d60f;hb=4e79709df545c16812b85f2c27ab3411f5a7b54f;hp=06628b96f8ad1b57de4dcb5522555a349495def0;hpb=086bab42386098009471c46139013c41f40856a2;p=ghc-hetmet.git diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index 06628b9..4a7d398 100644 --- a/rts/PrimOps.cmm +++ b/rts/PrimOps.cmm @@ -46,10 +46,10 @@ import __gmpz_xor; import __gmpz_ior; import __gmpz_com; #endif -import base_GHCziIOBase_NestedAtomically_closure; import pthread_mutex_lock; import pthread_mutex_unlock; #endif +import base_GHCziIOBase_NestedAtomically_closure; import EnterCriticalSection; import LeaveCriticalSection; @@ -452,11 +452,11 @@ int64ToIntegerzh_fast hi = TO_W_(val >> 32); lo = TO_W_(val); - if ( hi != 0 && hi != 0xFFFFFFFF ) { - words_needed = 2; - } else { + if ( hi == 0 || (hi == 0xFFFFFFFF && lo != 0) ) { // minimum is one word words_needed = 1; + } else { + words_needed = 2; } ALLOC_PRIM( SIZEOF_StgArrWords + WDS(words_needed), @@ -876,6 +876,23 @@ decodeFloatzh_fast RET_NNP(W_[mp_tmp_w], TO_W_(MP_INT__mp_size(mp_tmp1)), p); } +decodeFloatzuIntzh_fast +{ + W_ p; + F_ arg; + FETCH_MP_TEMP(mp_tmp1); + FETCH_MP_TEMP(mp_tmp_w); + + /* arguments: F1 = Float# */ + arg = F1; + + /* Perform the operation */ + foreign "C" __decodeFloat_Int(mp_tmp1 "ptr", mp_tmp_w "ptr", arg) []; + + /* returns: (Int# (mantissa), Int# (exponent)) */ + RET_NN(W_[mp_tmp1], W_[mp_tmp_w]); +} + #define DOUBLE_MANTISSA_SIZE SIZEOF_DOUBLE #define ARR_SIZE (SIZEOF_StgArrWords + DOUBLE_MANTISSA_SIZE) @@ -905,6 +922,28 @@ decodeDoublezh_fast RET_NNP(W_[mp_tmp_w], TO_W_(MP_INT__mp_size(mp_tmp1)), p); } +decodeDoublezu2Intzh_fast +{ + D_ arg; + W_ p; + FETCH_MP_TEMP(mp_tmp1); + FETCH_MP_TEMP(mp_tmp2); + FETCH_MP_TEMP(mp_result1); + FETCH_MP_TEMP(mp_result2); + + /* arguments: D1 = Double# */ + arg = D1; + + /* Perform the operation */ + foreign "C" __decodeDouble_2Int(mp_tmp1 "ptr", mp_tmp2 "ptr", + mp_result1 "ptr", mp_result2 "ptr", + arg) []; + + /* returns: + (Int# (mant sign), Word# (mant high), Word# (mant low), Int# (expn)) */ + RET_NNNN(W_[mp_tmp1], W_[mp_tmp2], W_[mp_result1], W_[mp_result2]); +} + /* ----------------------------------------------------------------------------- * Concurrency primitives * -------------------------------------------------------------------------- */ @@ -1512,7 +1551,7 @@ takeMVarzh_fast #endif if (info == stg_MVAR_CLEAN_info) { - foreign "C" dirty_MVAR(BaseReg "ptr", mvar "ptr"); + foreign "C" dirty_MVAR(BaseReg "ptr", mvar "ptr") []; } /* If the MVar is empty, put ourselves on its blocking queue, @@ -1522,9 +1561,11 @@ takeMVarzh_fast if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_head(mvar) = CurrentTSO; } else { - StgTSO_link(StgMVar_tail(mvar)) = CurrentTSO; + foreign "C" setTSOLink(MyCapability() "ptr", + StgMVar_tail(mvar) "ptr", + CurrentTSO) []; } - StgTSO_link(CurrentTSO) = stg_END_TSO_QUEUE_closure; + StgTSO__link(CurrentTSO) = stg_END_TSO_QUEUE_closure; StgTSO_why_blocked(CurrentTSO) = BlockedOnMVar::I16; StgTSO_block_info(CurrentTSO) = mvar; StgMVar_tail(mvar) = CurrentTSO; @@ -1545,17 +1586,14 @@ takeMVarzh_fast /* actually perform the putMVar for the thread that we just woke up */ tso = StgMVar_head(mvar); PerformPut(tso,StgMVar_value(mvar)); - dirtyTSO(tso); -#if defined(GRAN) || defined(PAR) - /* ToDo: check 2nd arg (mvar) is right */ - ("ptr" tso) = foreign "C" unblockOne(StgMVar_head(mvar),mvar) []; - StgMVar_head(mvar) = tso; -#else - ("ptr" tso) = foreign "C" unblockOne(MyCapability() "ptr", - StgMVar_head(mvar) "ptr") []; + if (StgTSO_flags(tso) & TSO_DIRTY == 0) { + foreign "C" dirty_TSO(MyCapability() "ptr", tso "ptr") []; + } + + ("ptr" tso) = foreign "C" unblockOne_(MyCapability() "ptr", + StgMVar_head(mvar) "ptr", 1) []; StgMVar_head(mvar) = tso; -#endif if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; @@ -1625,17 +1663,13 @@ tryTakeMVarzh_fast /* actually perform the putMVar for the thread that we just woke up */ tso = StgMVar_head(mvar); PerformPut(tso,StgMVar_value(mvar)); - dirtyTSO(tso); + if (StgTSO_flags(tso) & TSO_DIRTY == 0) { + foreign "C" dirty_TSO(MyCapability() "ptr", tso "ptr") []; + } -#if defined(GRAN) || defined(PAR) - /* ToDo: check 2nd arg (mvar) is right */ - ("ptr" tso) = foreign "C" unblockOne(StgMVar_head(mvar) "ptr", mvar "ptr") []; - StgMVar_head(mvar) = tso; -#else - ("ptr" tso) = foreign "C" unblockOne(MyCapability() "ptr", - StgMVar_head(mvar) "ptr") []; + ("ptr" tso) = foreign "C" unblockOne_(MyCapability() "ptr", + StgMVar_head(mvar) "ptr", 1) []; StgMVar_head(mvar) = tso; -#endif if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; @@ -1682,9 +1716,11 @@ putMVarzh_fast if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_head(mvar) = CurrentTSO; } else { - StgTSO_link(StgMVar_tail(mvar)) = CurrentTSO; + foreign "C" setTSOLink(MyCapability() "ptr", + StgMVar_tail(mvar) "ptr", + CurrentTSO) []; } - StgTSO_link(CurrentTSO) = stg_END_TSO_QUEUE_closure; + StgTSO__link(CurrentTSO) = stg_END_TSO_QUEUE_closure; StgTSO_why_blocked(CurrentTSO) = BlockedOnMVar::I16; StgTSO_block_info(CurrentTSO) = mvar; StgMVar_tail(mvar) = CurrentTSO; @@ -1701,16 +1737,13 @@ putMVarzh_fast /* actually perform the takeMVar */ tso = StgMVar_head(mvar); PerformTake(tso, R2); - dirtyTSO(tso); + if (StgTSO_flags(tso) & TSO_DIRTY == 0) { + foreign "C" dirty_TSO(MyCapability() "ptr", tso "ptr") []; + } -#if defined(GRAN) || defined(PAR) - /* ToDo: check 2nd arg (mvar) is right */ - ("ptr" tso) = foreign "C" unblockOne(MyCapability() "ptr", StgMVar_head(mvar) "ptr",mvar "ptr") []; - StgMVar_head(mvar) = tso; -#else - ("ptr" tso) = foreign "C" unblockOne(MyCapability() "ptr", StgMVar_head(mvar) "ptr") []; + ("ptr" tso) = foreign "C" unblockOne_(MyCapability() "ptr", + StgMVar_head(mvar) "ptr", 1) []; StgMVar_head(mvar) = tso; -#endif if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; @@ -1773,16 +1806,13 @@ tryPutMVarzh_fast /* actually perform the takeMVar */ tso = StgMVar_head(mvar); PerformTake(tso, R2); - dirtyTSO(tso); + if (StgTSO_flags(tso) & TSO_DIRTY == 0) { + foreign "C" dirty_TSO(MyCapability() "ptr", tso "ptr") []; + } -#if defined(GRAN) || defined(PAR) - /* ToDo: check 2nd arg (mvar) is right */ - ("ptr" tso) = foreign "C" unblockOne(MyCapability() "ptr", StgMVar_head(mvar) "ptr",mvar "ptr") []; - StgMVar_head(mvar) = tso; -#else - ("ptr" tso) = foreign "C" unblockOne(MyCapability() "ptr", StgMVar_head(mvar) "ptr") []; + ("ptr" tso) = foreign "C" unblockOne_(MyCapability() "ptr", + StgMVar_head(mvar) "ptr", 1) []; StgMVar_head(mvar) = tso; -#endif if (StgMVar_head(mvar) == stg_END_TSO_QUEUE_closure) { StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; @@ -1998,11 +2028,11 @@ for2: * macro in Schedule.h). */ #define APPEND_TO_BLOCKED_QUEUE(tso) \ - ASSERT(StgTSO_link(tso) == END_TSO_QUEUE); \ + ASSERT(StgTSO__link(tso) == END_TSO_QUEUE); \ if (W_[blocked_queue_hd] == END_TSO_QUEUE) { \ W_[blocked_queue_hd] = tso; \ } else { \ - StgTSO_link(W_[blocked_queue_tl]) = tso; \ + foreign "C" setTSOLink(MyCapability() "ptr", W_[blocked_queue_tl] "ptr", tso) []; \ } \ W_[blocked_queue_tl] = tso; @@ -2083,7 +2113,11 @@ delayzh_fast W_ time; W_ divisor; (time) = foreign "C" getourtimeofday() [R1]; - divisor = TO_W_(RtsFlags_MiscFlags_tickInterval(RtsFlags))*1000; + divisor = TO_W_(RtsFlags_MiscFlags_tickInterval(RtsFlags)); + if (divisor == 0) { + divisor = 50; + } + divisor = divisor * 1000; target = ((R1 + divisor - 1) / divisor) /* divide rounding up */ + time + 1; /* Add 1 as getourtimeofday rounds down */ StgTSO_block_info(CurrentTSO) = target; @@ -2094,15 +2128,15 @@ delayzh_fast while: if (t != END_TSO_QUEUE && StgTSO_block_info(t) < target) { prev = t; - t = StgTSO_link(t); + t = StgTSO__link(t); goto while; } - StgTSO_link(CurrentTSO) = t; + StgTSO__link(CurrentTSO) = t; if (prev == NULL) { W_[sleeping_queue] = CurrentTSO; } else { - StgTSO_link(prev) = CurrentTSO; + foreign "C" setTSOLink(MyCapability() "ptr", prev "ptr", CurrentTSO) []; } jump stg_block_noregs; #endif