Support I64->I32 casts in the NCG, and use them for I64->Integer conversions
authorwolfgang.thaller@gmx.net <unknown>
Fri, 24 Nov 2006 09:41:29 +0000 (09:41 +0000)
committerwolfgang.thaller@gmx.net <unknown>
Fri, 24 Nov 2006 09:41:29 +0000 (09:41 +0000)
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
rts/PrimOps.cmm

index aaf7cec..9dbe316 100644 (file)
@@ -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
index 075da41..3252993 100644 (file)
@@ -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 */