floating-point fix for x86_64
[ghc-hetmet.git] / ghc / includes / Stg.h
index 924610c..a63b7ec 100644 (file)
@@ -1,5 +1,4 @@
 /* -----------------------------------------------------------------------------
- * $Id: Stg.h,v 1.64 2004/09/02 12:45:25 simonmar Exp $
  *
  * (c) The GHC Team, 1998-2004
  *
@@ -35,9 +34,7 @@
 #endif
 
 #if IN_STG_CODE == 0
-# ifndef NO_REGS
-#  define NO_REGS                      /* don't define fixed registers */
-# endif
+# define NO_GLOBAL_REG_DECLS   /* don't define fixed registers */
 #endif
 
 /* Configuration */
 # error "Don't know how to inline functions with your C compiler."
 #endif
 
+/*
+ * GCC attributes
+ */
+#if defined(__GNUC__)
+#define GNU_ATTRIBUTE(at) __attribute__((at))
+#else
+#define GNU_ATTRIBUTE(at)
+#endif
+
+#if __GNUC__ >= 3 
+#define GNUC3_ATTRIBUTE(at) __attribute__((at))
+#else
+#define GNUC3_ATTRIBUTE(at)
+#endif
+
+#define STG_UNUSED    GNUC3_ATTRIBUTE(__unused__)
+
 /* -----------------------------------------------------------------------------
    Global type definitions
    -------------------------------------------------------------------------- */
@@ -108,7 +122,7 @@ typedef StgClosurePtr   L_;
 typedef StgInt64        LI_;
 typedef StgWord64       LW_;
 
-#define IF_(f)         static F_ f(void)
+#define IF_(f)         static F_ GNUC3_ATTRIBUTE(used) f(void) 
 #define FN_(f)         F_ f(void)
 #define EF_(f)         extern F_ f(void)
 
@@ -197,7 +211,7 @@ INLINE_HEADER StgDouble PK_DBL    (W_ p_src[])                 { return *(StgDou
  * independently - unfortunately this code isn't writable in C, we
  * have to use inline assembler.
  */
-#if sparc_TARGET_ARCH
+#if sparc_HOST_ARCH
 
 #define ASSIGN_DBL(dst0,src) \
     { StgPtr dst = (StgPtr)(dst0); \
@@ -212,7 +226,7 @@ INLINE_HEADER StgDouble PK_DBL    (W_ p_src[])                 { return *(StgDou
        "m" (((P_)(src))[0]), "m" (((P_)(src))[1])); d; \
     } )
 
-#else /* ! sparc_TARGET_ARCH */
+#else /* ! sparc_HOST_ARCH */
 
 INLINE_HEADER void       ASSIGN_DBL (W_ [], StgDouble);
 INLINE_HEADER StgDouble   PK_DBL     (W_ []);
@@ -251,7 +265,7 @@ INLINE_HEADER StgDouble PK_DBL(W_ p_src[])
     return(y.d);
 }
 
-#endif /* ! sparc_TARGET_ARCH */
+#endif /* ! sparc_HOST_ARCH */
 
 #endif /* ALIGNMENT_DOUBLE > ALIGNMENT_UNSIGNED_INT */
 
@@ -353,6 +367,24 @@ INLINE_HEADER StgInt64 PK_Int64(W_ p_src[])
 #endif
 
 /* -----------------------------------------------------------------------------
+   Write-combining store
+   -------------------------------------------------------------------------- */
+
+INLINE_HEADER void
+wcStore (StgPtr p, StgWord w)
+{
+#ifdef x86_64_HOST_ARCH    
+    __asm__(
+       "movnti\t%1, %0"
+       : "=m" (*p)
+       : "r" (w)
+       );
+#else
+      *p = w;
+#endif
+}
+
+/* -----------------------------------------------------------------------------
    Integer multiply with overflow
    -------------------------------------------------------------------------- */
 
@@ -408,15 +440,16 @@ typedef union {
 
 #else
 
-#define HALF_INT  (((I_)1) << (BITS_IN (I_) / 2))
+/* Approximate version when we don't have long arithmetic (on 64-bit archs) */
 
-#define stg_abs(a) (((I_)(a)) < 0 ? -((I_)(a)) : ((I_)(a)))
+#define HALF_POS_INT  (((I_)1) << (BITS_IN (I_) / 2))
+#define HALF_NEG_INT  (-HALF_POS_INT)
 
 #define mulIntMayOflo(a,b)                     \
 ({                                              \
   I_ c;                                        \
-  if (stg_abs(a) >= HALF_INT ||                        \
-      stg_abs(b) >= HALF_INT) {                        \
+  if ((I_)a <= HALF_NEG_INT || a >= HALF_POS_INT    \
+      || (I_)b <= HALF_NEG_INT || b >= HALF_POS_INT) {\
     c = 1;                                     \
   } else {                                     \
     c = 0;                                     \