~ chicken-core (chicken-5) e60b22543240b91f71b2bf34df4c1ef3b92fa8b5


commit e60b22543240b91f71b2bf34df4c1ef3b92fa8b5
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Mon Sep 6 06:07:02 2010 -0400
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Mon Sep 6 06:07:02 2010 -0400

    better version of fx*?

diff --git a/runtime.c b/runtime.c
index 45e1822e..7a8242bf 100644
--- a/runtime.c
+++ b/runtime.c
@@ -8616,42 +8616,24 @@ C_regparm C_word C_fcall C_i_o_fixnum_difference(C_word n1, C_word n2)
 C_regparm C_word C_fcall C_i_o_fixnum_times(C_word n1, C_word n2)
 {
   C_word x1, x2;
-  /* otherwise gcc tries to be smart in constant-folding and screws up the signs */
+  C_uword x1u, x2u;
 #ifdef C_SIXTY_FOUR
-  static int seven_f = 0x7fffffffffffffff;
-  static int eight_0 = 0x8000000000000000;
+  C_uword c = 1UL<<63UL;
 #else
-  static int seven_f = 0x7fffffff;
-  static int eight_0 = 0x80000000;
+  C_uword c = 1UL<<31UL;
 #endif
 
-  if((n1 & C_FIXNUM_BIT) == 0 || (n2 & C_FIXNUM_BIT) == 0) return C_SCHEME_FALSE;
+  if((n1 & C_INT_SIGN_BIT) == (n2 & C_INT_SIGN_BIT)) --c;
 
   x1 = C_unfix(n1);
   x2 = C_unfix(n2);
+  x1u = x1 < 0 ? -x1 : x1;
+  x2u = x2 < 0 ? -x2 : x2;
 
-  if(x1 > 0) {
-    if(x2 > 0) {
-      if(x1 > (seven_f / x2)) return C_SCHEME_FALSE;
-      else goto ok;
-    }
-    else {
-      /*XXX gives SIGFPE on x86 with x2 == -1 */
-      if(x2 < (eight_0 / x2)) return C_SCHEME_FALSE;
-      else goto ok;
-    }
-  }
-  else if(x2 > 0) {
-    if(x1 < (eight_0 / x2)) return C_SCHEME_FALSE;
-    else goto ok;
-  }
-  else {
-    if(x1 != 0 && x2 < (seven_f / x1)) return C_SCHEME_FALSE;
-  }
-
- ok:
-  x1 = x1 * x2;
+  if(x2u != 0 && x1u > (c / x2u)) return C_SCHEME_FALSE;
   
+  x1 = x1 * x2;
+
   if(C_fitsinfixnump(x1)) return C_fix(x1);
   else return C_SCHEME_FALSE;
 }
Trap