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.
parent a93bbc4a
......@@ -497,6 +497,31 @@ getRegister (CmmReg reg)
getRegister tree@(CmmRegOff _ _)
= getRegister (mangleIndexTree tree)
#if WORD_SIZE_IN_BITS==32
-- for 32-bit architectuers, support some 64 -> 32 bit conversions:
-- TO_W_(x), TO_W_(x >> 32)
getRegister (CmmMachOp (MO_U_Conv I64 I32)
[CmmMachOp (MO_U_Shr I64) [x,CmmLit (CmmInt 32 _)]]) = do
ChildCode64 code rlo <- iselExpr64 x
return $ Fixed I32 (getHiVRegFromLo rlo) code
getRegister (CmmMachOp (MO_S_Conv I64 I32)
[CmmMachOp (MO_U_Shr I64) [x,CmmLit (CmmInt 32 _)]]) = do
ChildCode64 code rlo <- iselExpr64 x
return $ Fixed I32 (getHiVRegFromLo rlo) code
getRegister (CmmMachOp (MO_U_Conv I64 I32) [x]) = do
ChildCode64 code rlo <- iselExpr64 x
return $ Fixed I32 rlo code
getRegister (CmmMachOp (MO_S_Conv I64 I32) [x]) = do
ChildCode64 code rlo <- iselExpr64 x
return $ Fixed I32 rlo code
#endif
-- end of machine-"independent" bit; here we go on the rest...
#if alpha_TARGET_ARCH
......
......@@ -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 */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment