Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 gcl (2.6.9-10) unstable; urgency=high
 .
   * fast-fixnums
Author: Camm Maguire <camm@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- gcl-2.6.9.orig/configure
+++ gcl-2.6.9/configure
@@ -4197,7 +4197,7 @@ if test "$GCC" = "yes" ; then
 	     *mingw*)
 	        echo "WARNING: Remove -fno-zero-initialized-in-bss from makedefs if gcc less than 3.3.1."
 	        echo "         It is ptherwise needed for the Unexec stuff to work."
-		if test "$enable_debug" = "yes" ; then TCFLAGS="$TCFLAGS -gstabs" ; fi
+#		if test "$enable_debug" = "yes" ; then TCFLAGS="$TCFLAGS -gstabs" ; fi
 		TCFLAGS="$TCFLAGS -fno-zero-initialized-in-bss -mms-bitfields";;
         esac
 fi
@@ -7124,7 +7124,7 @@ $as_echo "$as_me: trying to adjust text
 
       n=-1;
       k=0;
-      lim=64;
+      lim=`$AWK 'END {printf("%d\n",m*8-2)}' m=$ac_cv_sizeof_long`;
       max=0;
       min=$lim;
       while test $n -lt $lim ; do
--- gcl-2.6.9.orig/configure.in
+++ gcl-2.6.9/configure.in
@@ -496,7 +496,7 @@ if test "$GCC" = "yes" ; then
 	     *mingw*)
 	        echo "WARNING: Remove -fno-zero-initialized-in-bss from makedefs if gcc less than 3.3.1."
 	        echo "         It is ptherwise needed for the Unexec stuff to work."
-		if test "$enable_debug" = "yes" ; then TCFLAGS="$TCFLAGS -gstabs" ; fi
+#		if test "$enable_debug" = "yes" ; then TCFLAGS="$TCFLAGS -gstabs" ; fi
 		TCFLAGS="$TCFLAGS -fno-zero-initialized-in-bss -mms-bitfields";;
         esac
 fi
@@ -1687,7 +1687,7 @@ if test "$use" != "386-gnu" ; then #hurd
 
       n=-1;
       k=0;
-      lim=64;
+      lim=`$AWK 'END {printf("%d\n",m*8-2)}' m=$ac_cv_sizeof_long`;
       max=0;
       min=$lim;
       while test $n -lt $lim ; do
--- gcl-2.6.9.orig/h/gmp_wrappers.h
+++ gcl-2.6.9/h/gmp_wrappers.h
@@ -118,6 +118,8 @@ MEM_GMP_CALL(3,void,mpz_sub,1,mpz_t,mpz_
 MEM_GMP_CALL(3,void,mpz_sub_ui,1,mpz_t,mpz_t,unsigned long int)
 MEM_GMP_CALL(3,void,mpz_mul,1,mpz_t,mpz_t,mpz_t)
 MEM_GMP_CALL(3,void,mpz_mul_si,1,mpz_t,mpz_t,long int)
+MEM_GMP_CALL(3,void,mpz_pow_ui,1,mpz_t,mpz_t,unsigned long int)
+MEM_GMP_CALL(3,void,mpz_ui_pow_ui,1,mpz_t,unsigned long int,unsigned long int)
 MEM_GMP_CALL(3,void,mpz_mul_2exp,1,mpz_t,mpz_t,unsigned long int)
 MEM_GMP_CALL(2,void,mpz_neg,1,mpz_t,mpz_t)
 MEM_GMP_CALL(4,void,mpz_tdiv_qr,2,mpz_t,mpz_t,mpz_t,mpz_t)
@@ -158,6 +160,8 @@ MEM_GMP_CALL(2,size_t,mpz_sizeinbase,0,m
 #define __gmpz_sub_ui m__gmpz_sub_ui
 #define __gmpz_mul m__gmpz_mul
 #define __gmpz_mul_si m__gmpz_mul_si
+#define __gmpz_pow_ui m__gmpz_pow_ui
+#define __gmpz_ui_pow_ui m__gmpz_ui_pow_ui
 #define __gmpz_mul_2exp m__gmpz_mul_2exp
 #define __gmpz_neg m__gmpz_neg
 #define __gmpz_tdiv_qr m__gmpz_tdiv_qr
--- gcl-2.6.9.orig/o/gmp_big.c
+++ gcl-2.6.9/o/gmp_big.c
@@ -127,6 +127,7 @@ new_bignum(void)
 static object
 make_bignum(__mpz_struct *u) {
   object ans=alloc_object(t_bignum);
+  memset(MP(ans),0,sizeof(*MP(ans)));
   mpz_init_set(MP(ans),u);
   return ans;
 }
--- gcl-2.6.9.orig/o/num_sfun.c
+++ gcl-2.6.9/o/num_sfun.c
@@ -94,87 +94,146 @@ number_exp(object x)
 	}
 }
 
+inline object
+number_fix_iexpt(object x,fixnum y,fixnum ly,fixnum j) {
+  object z;
+  
+  if (j+1==ly) return x;
+  z=number_fix_iexpt(number_times(x,x),y,ly,j+1);
+  return fixnum_bitp(j,y) ? number_times(x,z) : z;
+}
+
+inline object
+number_big_iexpt(object x,object y,fixnum ly,fixnum j) {
+  object z;
+  
+  if (j+1==ly) return x;
+  z=number_big_iexpt(number_times(x,x),y,ly,j+1);
+  return mpz_tstbit(MP(y),j) ? number_times(x,z) : z;
+
+}
+
+inline object
+number_zero_expt(object x,bool promote_short_p) {
+
+  switch (type_of(x)) {
+  case t_fixnum:
+  case t_bignum:
+  case t_ratio:
+    return make_fixnum(1);
+  case t_shortfloat:
+    return promote_short_p ? make_longfloat(1.0) : make_shortfloat(1.0);
+  case t_longfloat:
+    return make_longfloat(1.0);
+  case t_complex:
+    return make_complex(number_zero_expt(x->cmp.cmp_real,promote_short_p),small_fixnum(0));
+  default:
+    FEwrong_type_argument(sLnumber,x);
+    return Cnil;
+  }
+
+}
+
+
+inline object
+number_ui_expt(object x,fixnum fy) {
+
+  switch (type_of(x)) {
+  case t_fixnum:
+    { 
+      fixnum fx=fix(x);
+      object z;
+      MPOP(z=,mpz_ui_pow_ui,labs(fx),fy);
+      if (fx<0&&(fy&0x1)) return number_negate(z); else return z;
+    }
+  case t_bignum:
+    MPOP(return,mpz_pow_ui,MP(x),fy);
+  case t_ratio:
+    {
+      object n=number_ui_expt(x->rat.rat_num,fy),d=number_ui_expt(x->rat.rat_den,fy),z=alloc_object(t_ratio);
+      z->rat.rat_num=n;
+      z->rat.rat_den=d;/*No need to make_ratio as no common factors*/
+      return z;
+    }
+
+  case t_shortfloat:
+  case t_longfloat:
+  case t_complex:
+    {
+      fixnum ly=fixnum_length(fy);
+
+      return ly ? number_fix_iexpt(x,fy,ly,0) : number_zero_expt(x,0);
+
+    }
+	
+  default:
+    FEwrong_type_argument(sLnumber,x);
+    return Cnil;
+  }
+    
+}
+
+inline object
+number_ump_expt(object x,object y) {
+  return number_big_iexpt(x,y,fix(integer_length(y)),0);
+}
+
+inline object
+number_log_expt(object x,object y) {
+  return number_zerop(y) ? number_zero_expt(y,type_of(x)==t_longfloat) : number_exp(number_times(number_nlog(x),y));
+}
+
+inline object
+number_invert(object x,object y,object z) {
+
+  switch (type_of(z)) {
+  case t_shortfloat:
+    if (!ISNORMAL(sf(z))) return number_log_expt(x,y);
+    break;
+  case t_longfloat:
+    if (!ISNORMAL(lf(z))) return number_log_expt(x,y);
+    break;
+  }
+  return number_divide(small_fixnum(1),z);
+}
+    
+
+inline object 
+number_si_expt(object x,object y) {
+  switch (type_of(y)) {
+  case t_fixnum:
+    { 
+      fixnum fy=fix(y);
+      if (fy>=0)
+	return number_ui_expt(x,fy);
+      if (fy==MOST_NEGATIVE_FIX)
+	return number_invert(x,y,number_ump_expt(x,number_negate(y)));
+      return number_invert(x,y,number_ui_expt(x,-fy));
+    }
+  case t_bignum:
+    return big_sign(y)<0 ? number_invert(x,y,number_ump_expt(x,number_negate(y))) : number_ump_expt(x,y);
+  case t_ratio:
+  case t_shortfloat:
+  case t_longfloat:
+  case t_complex:
+    return number_log_expt(x,y);
+  default:
+    FEwrong_type_argument(sLnumber,y);
+    return Cnil;
+  }
+}
+
 object
-number_expt(object x, object y)
-{
-	enum type tx, ty;
-	object z;
-	vs_mark;
-
-	tx = type_of(x);
-	ty = type_of(y);
-	if (ty == t_fixnum && fix(y) == 0)
-		switch (tx) {
-		case t_fixnum:  case t_bignum:  case t_ratio:
-			return(small_fixnum(1));
-
-		case t_shortfloat:
-			return(make_shortfloat((shortfloat)1.0));
-
-		case t_longfloat:
-			return(make_longfloat(1.0));
-
-		case t_complex:
-			z = number_expt(x->cmp.cmp_real, y);
-			vs_push(z);
-			z = make_complex(z, small_fixnum(0));
-			vs_reset;
-			return(z);
-
-		default:
-			FEwrong_type_argument(sLnumber, x);
-		}
-	if (number_zerop(x)) {
-		if (!number_plusp(ty==t_complex?y->cmp.cmp_real:y))
-			FEerror("Cannot raise zero to the power ~S.", 1, y);
-		return(number_times(x, y));
-	}
-	if (ty == t_fixnum || ty == t_bignum) {
-		if (number_minusp(y)) {
-			z = number_negate(y);
-			vs_push(z);
-			z = number_expt(x, z);
-			vs_push(z);
-			if ((type_of(z)==t_shortfloat && !ISNORMAL(z->SF.SFVAL)) ||
-			    (type_of(z)==t_longfloat && !ISNORMAL(z->LF.LFVAL))) {
-			  z = number_nlog(x);
-			  vs_push(z);
-			  z = number_times(z, y);
-			  vs_push(z);
-			  z = number_exp(z);
-			  vs_reset;
-			  return(z);
-			}
-			z = number_divide(small_fixnum(1), z);
-			vs_reset;
-			return(z);
-		}
-		z = small_fixnum(1);
-		vs_push(z);
-		vs_push(Cnil);
-		vs_push(Cnil);
-		while (number_plusp(y))
-			if (number_evenp(y)) {
-				x = number_times(x, x);
-				vs_top[-1] = x;
-				y = integer_divide1(y, small_fixnum(2),0);
-				vs_top[-2] = y;
-			} else {
-				z = number_times(z, x);
-				vs_top[-3] = z;
-				y = number_minus(y, small_fixnum(1));
-				vs_top[-2] = y;
-			}
-		vs_reset;
-		return(z);
-	}
-	z = number_nlog(x);
-	vs_push(z);
-	z = number_times(z, y);
-	vs_push(z);
-	z = number_exp(z);
-	vs_reset;
-	return(z);
+number_expt(object x, object y) {
+
+  if (number_zerop(x)&&y!=small_fixnum(0)) {
+    if (!number_plusp(type_of(y)==t_complex?y->cmp.cmp_real:y))
+      FEerror("Cannot raise zero to the power ~S.", 1, y);
+    return(number_times(x, y));
+  }
+
+  return number_si_expt(x,y);
+
 }
 
 static object
--- gcl-2.6.9.orig/o/predicate.c
+++ gcl-2.6.9/o/predicate.c
@@ -450,8 +450,24 @@ equal1(register object x, register objec
 
   /*x and y are not == and not Cnil and not immfix*/
 
+#ifdef __MINGW32__ /*FIXME mingw compiler cannot do tail recursion and blows out stack*/
+ BEGIN:
+  if (valid_cdr(x)) {
+    if (valid_cdr(y)&&equal(x->c.c_car,y->c.c_car)) {
+      x=x->c.c_cdr;
+      y=y->c.c_cdr;
+      if (x==y) return TRUE;
+      if (IMMNIL(x)||IMMNIL(y)) return FALSE;
+      goto BEGIN;
+    } else
+      return FALSE;
+  }
+#else
+  
   if (valid_cdr(x)) return valid_cdr(y)&&equal(x->c.c_car,y->c.c_car)&&equal(x->c.c_cdr,y->c.c_cdr);
 
+#endif
+
   if (valid_cdr(y)) return FALSE;
   
   if (x->d.t!=y->d.t)
--- gcl-2.6.9.orig/o/sfaslcoff.c
+++ gcl-2.6.9/o/sfaslcoff.c
@@ -408,7 +408,7 @@ fasload(object faslfile) {
 	
   for (sec=sec1;sec<sece;sec++)
     if (sec->s_flags&0xe0)
-      for (rel=st+sec->s_relptr,rele=rel+sec->s_nreloc;rel<rele;rel++)
+      for (rel=st+sec->s_relptr,rele=rel+(sec->s_flags&0x1000000 ? rel->r.r_count : sec->s_nreloc);rel<rele;rel++)
 	relocate(sec,rel,sy1+rel->r_symndx);
   
   fseek(fp,(void *)ste-st,0);
--- gcl-2.6.9.orig/o/unexnt.c
+++ gcl-2.6.9/o/unexnt.c
@@ -326,7 +326,11 @@ unexec (char *new_name, char *old_name,
     dos_header = (PIMAGE_DOS_HEADER) out_file.file_base;
     nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
 
-    
+ 
+    nt_header->OptionalHeader.SizeOfStackReserve=0x800000;
+    /* nt_header->OptionalHeader.SizeOfHeapReserve=0x80000000; */
+    /* nt_header->OptionalHeader.SizeOfHeapCommit=0x80000000; */
+   
     nt_header->OptionalHeader.CheckSum = 0;
 //    nt_header->FileHeader.TimeDateStamp = time (NULL);
 //    dos_header->e_cp = size / 512;
@@ -966,10 +970,11 @@ allocate_heap (void)
      the region below the 256MB line for our malloc arena - 229MB is
      still a pretty decent arena to play in!  */
 
-  void *base = (void *)0x10100000,*ptr;/*FIXME, someday figure out how to let the heap start address default */
+  void *base = (void *)0x20000000,*ptr;/*FIXME, someday figure out how to let the heap start address default *//*(void *)0x10100000*/
 
   reserved_heap_size=probe_heap_size(base,PAGESIZE,(1UL<<31),-1);
   ptr = VirtualAlloc ((void *) base,get_reserved_heap_size (),MEM_RESERVE,PAGE_NOACCESS);
+  printf("probe results: %lu at %p\n",reserved_heap_size,ptr);
 
   DBEGIN = (DBEGIN_TY) ptr;
 
--- gcl-2.6.9.orig/o/unixfsys.c
+++ gcl-2.6.9/o/unixfsys.c
@@ -478,6 +478,13 @@ DEFUN_NEW("STAT",object,fSstat,SI,1,1,NO
 
   bzero(filename,sizeof(filename));
   coerce_to_filename(path,filename);
+#ifdef __MINGW32__
+  {
+    char *p=filename+strlen(filename)-1;
+    for (;p>=filename && *p=='/';p--)
+      *p=0;
+  }
+#endif
   if (lstat(filename,&ss))
     RETURN1(Cnil);
   else {/* ctime_r insufficiently portable */
--- gcl-2.6.9.orig/o/unixtime.c
+++ gcl-2.6.9/o/unixtime.c
@@ -168,6 +168,8 @@ LFD(Lget_internal_run_time)(void)
 	times(&buf);
 	vs_push(make_fixnum(buf.tms_utime));
 	vs_push(make_fixnum(buf.tms_cutime));
+	vs_push(make_fixnum(buf.tms_stime));
+	vs_push(make_fixnum(buf.tms_cstime));
 
 #endif	
 	
