summaryrefslogtreecommitdiff
path: root/rts/PrimOps.cmm
diff options
context:
space:
mode:
authorwolfgang.thaller@gmx.net <unknown>2006-11-24 09:41:29 +0000
committerwolfgang.thaller@gmx.net <unknown>2006-11-24 09:41:29 +0000
commit08560cf0e3a2a1928650ca5d5d0bb44fbac2ea44 (patch)
treec5fcfc3aec5dfab36a90b3ea7da772ecb65095b1 /rts/PrimOps.cmm
parenta93bbc4a03ae34d6ef36e4576799d2152c25989b (diff)
downloadhaskell-08560cf0e3a2a1928650ca5d5d0bb44fbac2ea44.tar.gz
Support I64->I32 casts in the NCG, and use them for I64->Integer conversions
We can avoid using any other long long operations in PrimOps.cmm. One more step towards compiling the RTS using the NCG.
Diffstat (limited to 'rts/PrimOps.cmm')
-rw-r--r--rts/PrimOps.cmm42
1 files changed, 25 insertions, 17 deletions
diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm
index 075da4192d..3252993b1d 100644
--- a/rts/PrimOps.cmm
+++ b/rts/PrimOps.cmm
@@ -418,12 +418,15 @@ int64ToIntegerzh_fast
/* arguments: L1 = Int64# */
L_ val;
- W_ hi, s, neg, words_needed, p;
+ W_ hi, lo, s, neg, words_needed, p;
val = L1;
neg = 0;
- if ( %ge(val,0x100000000::L_) || %le(val,-0x100000000::L_) ) {
+ hi = TO_W_(val >> 32);
+ lo = TO_W_(val);
+
+ if ( hi != 0 && hi != 0xFFFFFFFF ) {
words_needed = 2;
} else {
// minimum is one word
@@ -437,21 +440,24 @@ int64ToIntegerzh_fast
SET_HDR(p, stg_ARR_WORDS_info, W_[CCCS]);
StgArrWords_words(p) = words_needed;
- if ( %lt(val,0::L_) ) {
+ if ( %lt(hi,0) ) {
neg = 1;
- val = -val;
+ lo = -lo;
+ if(lo == 0) {
+ hi = -hi;
+ } else {
+ hi = -hi - 1;
+ }
}
- hi = TO_W_(val >> 32);
-
if ( words_needed == 2 ) {
s = 2;
- Hp(-1) = TO_W_(val);
+ Hp(-1) = lo;
Hp(0) = hi;
} else {
- if ( val != 0::L_ ) {
+ if ( lo != 0 ) {
s = 1;
- Hp(0) = TO_W_(val);
+ Hp(0) = lo;
} else /* val==0 */ {
s = 0;
}
@@ -465,16 +471,18 @@ int64ToIntegerzh_fast
*/
RET_NP(s,p);
}
-
word64ToIntegerzh_fast
{
/* arguments: L1 = Word64# */
L_ val;
- W_ hi, s, words_needed, p;
+ W_ hi, lo, s, words_needed, p;
val = L1;
- if ( val >= 0x100000000::L_ ) {
+ hi = TO_W_(val >> 32);
+ lo = TO_W_(val);
+
+ if ( hi != 0 ) {
words_needed = 2;
} else {
words_needed = 1;
@@ -487,15 +495,14 @@ word64ToIntegerzh_fast
SET_HDR(p, stg_ARR_WORDS_info, W_[CCCS]);
StgArrWords_words(p) = words_needed;
- hi = TO_W_(val >> 32);
- if ( val >= 0x100000000::L_ ) {
+ if ( hi != 0 ) {
s = 2;
- Hp(-1) = TO_W_(val);
+ Hp(-1) = lo;
Hp(0) = hi;
} else {
- if ( val != 0::L_ ) {
+ if ( lo != 0 ) {
s = 1;
- Hp(0) = TO_W_(val);
+ Hp(0) = lo;
} else /* val==0 */ {
s = 0;
}
@@ -508,6 +515,7 @@ word64ToIntegerzh_fast
}
+
#endif /* SUPPORT_LONG_LONGS */
/* ToDo: this is shockingly inefficient */