From 08560cf0e3a2a1928650ca5d5d0bb44fbac2ea44 Mon Sep 17 00:00:00 2001 From: "wolfgang.thaller@gmx.net" Date: Fri, 24 Nov 2006 09:41:29 +0000 Subject: [PATCH] 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. --- compiler/nativeGen/MachCodeGen.hs | 25 ++++++++++++++++++++++ rts/PrimOps.cmm | 42 ++++++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/compiler/nativeGen/MachCodeGen.hs b/compiler/nativeGen/MachCodeGen.hs index aaf7cec..9dbe316 100644 --- a/compiler/nativeGen/MachCodeGen.hs +++ b/compiler/nativeGen/MachCodeGen.hs @@ -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 diff --git a/rts/PrimOps.cmm b/rts/PrimOps.cmm index 075da41..3252993 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 */ -- 1.7.10.4