Bill Allombert on Thu, 21 Nov 2002 21:10:53 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: CVS branch gmp-kernel-2-2-5


Hello PARI/GP developers,

Here a patch to apply to the gmp-kernel-2-2-5 branch.
Please do
chmod a+x config/kernel-name
after applying.

This patch allows to use the assemby level 0 kernel code
when available. With this patch, pari and pari-gmp are
comparable performance on the benchmark.

Please test thoroughly so that I can commit it with confidence.

This patch split cleanly the kernel Makefile.SH in
level 0: (MakeLVL0.SH) and
level 1: (MakeLVL1.SH).

level 0 are currently : 
ix86 alpha sparcv7 sparcv8_micro sparcv8_super hppa m68k none
level 1 are currently :
m68k none gmp.

The way to specify the kernel to use to the --kernel=
switch or interactively is as follow:

-- A fully qualified kernel name (fqkn) is of the form
<level 0>-<level 1>.

The special <level 0> value 'auto' is accepted and stand for the auto-detected
value.

A name without dash '-' is an alias. Alias stands for name-none,
but gmp stand for auto-gmp.

The default kernel is auto-none.

This patch has been tested on x86, alpha, sparcv8_micro.
It is supposed to run on hppa but it is not tested.
It will *not* work on m68k. This is trivial to fix but pointless,
since it cannot work with the gmp kernel.

Cheers,
Bill.
Index: Configure
===================================================================
RCS file: /home/megrez/cvsroot/pari/Configure,v
retrieving revision 1.95.2.1
diff -u -r1.95.2.1 Configure
--- Configure	2002/11/06 09:50:46	1.95.2.1
+++ Configure	2002/11/21 17:34:34
@@ -339,24 +339,38 @@
 esac
 
 if test  -n "$kernel"; then
-  asmarch="$kernel";
+  tmp_kern=`./kernel-name $kernel $asmarch`
+  kernlvl0=`echo "$tmp_kern" | sed -e 's/\(.*\)-.*/\1/'`
+  kernlvl1=`echo "$tmp_kern" | sed -e 's/.*-\(.*\)/\1/'`
 else
   if test "$fastread" != yes; then
   cat << EOM
 ==========================================================================
 An optimized Pari kernel is available for these architectures
 ("none" means that we will use the portable C version of GP/PARI)
+("-gmp" means we will use the GMP library (that need to be installed))
 EOM
-  rep='none sparcv7 sparcv8_super sparcv8_micro m68k ix86 alpha hppa gmp'
+  rep='none sparcv7 sparcv8_super sparcv8_micro m68k ix86 alpha hppa
+  none-gmp sparcv7-gmp sparcv8_super-gmp sparcv8_micro-gmp ix86-gmp alpha-gmp hppa-gmp'
   . ./display
   echo $n ..."Which of these apply, if any ? $c"
-  dflt=$asmarch; . ./myread; asmarch=$ans
+  dflt=$asmarch; . ./myread; 
+  tmp_kern=`./kernel-name $ans $asmarch`
+  kernlvl0=`echo "$tmp_kern" | sed -e 's/\(.*\)-.*/\1/'`
+  kernlvl1=`echo "$tmp_kern" | sed -e 's/.*-\(.*\)/\1/'`
+  
   cat << EOM
 ==========================================================================
 EOM
+  else
+    tmp_kern=`./kernel-name auto $asmarch`
+    kernlvl0=`echo "$tmp_kern" | sed -e 's/\(.*\)-.*/\1/'`
+    kernlvl1=`echo "$tmp_kern" | sed -e 's/.*-\(.*\)/\1/'`
   fi
 fi
-case "$asmarch" in
+
+
+case "$kernlvl0" in
   none)          prettyk="C portable";;
   sparcv7)       prettyk=SparcV7;;
   sparcv8_super) prettyk=SuperSparc;;
@@ -366,10 +380,17 @@
   hppa)          prettyk=HPPA;;
   alpha)         prettyk=Alpha;;
   ppc)           prettyk=PPC;;
-  *)             prettyk="$asmarch";;
+  *)             prettyk="$kernlvl0";;
 esac
+
+case "$kernlvl1" in
+  gmp) prettyk="$prettyk/GMP";;
+  none) ;;
+  *) prettyk="$prettyk/$kernlvl1";;
+esac
+
 # 'i386 (running ix86 kernel)'  looks ugly
-if test "$arch" != "$asmarch" -a \( "$arch" != "i386" -o "$asmarch" != "ix86" \)
+if test "$arch" != "$kernlvl0" -a \( "$arch" != "i386" -o "$prettyk" != "ix86" \)
 then
   pretty="$pretty ($prettyk kernel)"
 fi
@@ -698,12 +719,12 @@
 if test -n "$DLLD"; then
 # Which Dynamic Lib Linker?
 #
-  if test $DLLD = ld -a -n "$ld"; then
+  if test "$DLLD" = ld -a -n "$ld"; then
     DLLD=$ld;
   fi
   if test "$fastread" != yes; then
     echo $n ..."Which linker for building dynamic libs? $c"
-    dflt=$DLLD; rep=; . ./myread
+    dflt="$DLLD"; rep=; . ./myread
     DLLD=$ans
   fi
 
@@ -820,7 +841,7 @@
 #
 # GMP
 #
-if test "$asmarch" = "gmp"; then
+if test "$kernlvl1" = "gmp"; then
   LIBS="$LIBS -lgmp"
 fi
 #
@@ -1391,7 +1412,8 @@
   libpari_base version TOP config_dir src_dir emacs_dir doc_dir\
   bindir includedir mandir miscdir libdir datadir\
   optimization objdir static suffix\
-  ASMINLINE arch asmarch osname pretty prefix share_prefix\
+  ASMINLINE arch asmarch osname kernlvl0 kernlvl1\
+  pretty prefix share_prefix\
   __gnuc__ gnuas CPP AS ASFLAGS CC cflags DBGFLAGS OPTFLAGS LD LDFLAGS\
   DLLD DLSUFFIX soname sodest KERNELCPPFLAGS DLLDFLAGS EXTRADLLDFLAGS\
   runpath runpathprefix LDDYN LIBS DYNLIBS DYNFLAGS DYNRELOC\
Index: config/Makefile.SH
===================================================================
RCS file: /home/megrez/cvsroot/pari/config/Makefile.SH,v
retrieving revision 1.50
diff -u -r1.50 Makefile.SH
--- config/Makefile.SH	2002/10/22 22:07:51	1.50
+++ config/Makefile.SH	2002/11/21 17:34:34
@@ -1,10 +1,5 @@
 file=$objdir/Makefile
 
-case "$asmarch" in
-  sparcv8*) ASMARCH=sparcv8;;
-  *) ASMARCH=$asmarch;;
-esac
-
 echo Extracting $file
 rm -f $file
 
@@ -43,12 +38,20 @@
 	dlld_ignore=- ;;
   *)   systems=;;
 esac
+#FIXME:
+#This is a kludge to work around the fact that there is two kernels
+#in the sparcv8 directory...
+ 
+case "$kernlvl0" in
+  sparcv8*) dirlvl0=sparcv8;;
+  *) dirlvl0="$kernlvl0";;
+esac
 
-if test -s $src_dir/kernel/$ASMARCH/MakeVar.SH; then
-  . $src_dir/kernel/$ASMARCH/MakeVar.SH
+if test -s $src_dir/kernel/$dirlvl0/MakeVar.SH; then
+  . $src_dir/kernel/$dirlvl0/MakeVar.SH
 fi
 
-case "$ASMARCH" in
+case "$kernlvl0" in
   m68k) hlist=pari68k
   kerntest=kernel.old;; # OLD_CODES should be defined
   *) hlist=pariport
@@ -381,7 +384,7 @@
 	@$doexec -g
 
 cleanobj: cleantest
-	-\$(RM) *\$(_O) *.s pariinl.h libpari* tune* $exec
+	-\$(RM) *\$(_O) *.s pariinl.h parilvl0.h parilvl1.h libpari* tune* $exec
 
 clean: cleanobj
 
@@ -588,12 +591,33 @@
 	\$(INSTALL_DATA)    $emx/pariemacs.txt  \$(EMACSDIR)
 	\$(INSTALL_DATA)    $emx/with-syntax.el     \$(EMACSDIR)
 	\$(INSTALL_DATA)    $emx/pari-translator.el \$(EMACSDIR)
+	
 EOT
 fi
+
+cat >> $file << EOT
+pariinl.h: parilvl0.h parilvl1.h
+	cat parilvl0.h parilvl1.h > pariinl.h
+
+EOT
 
-if test -s $src_dir/kernel/$ASMARCH/Makefile.SH; then
-  . $src_dir/kernel/$ASMARCH/Makefile.SH
+#FIXME:
+#This is a kludge to work around the fact that there is two kernels
+#in the sparcv8 directory...
+
+case "$kernlvl0" in
+  sparcv8*) dirlvl0=sparcv8;;
+  *) dirlvl0=$kernlvl0;;
+esac
+
+if test -s $src_dir/kernel/$dirlvl0/MakeLVL0.SH; then
+  . $src_dir/kernel/$dirlvl0/MakeLVL0.SH
 fi
+
+if test -s $src_dir/kernel/$kernlvl1/MakeLVL1.SH; then
+  . $src_dir/kernel/$kernlvl1/MakeLVL1.SH
+fi
+
 HUGELINE=
 for dir in basemath modules language gp graph gpdyn graphdyn systems; do
   eval list='$'$dir
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ config/kernel-name	Thu Nov 21 12:42:40 2002
@@ -0,0 +1,24 @@
+#! /bin/sh
+name=$1;
+arch=$2;
+
+case "$name" in
+  *-*) 
+  kernlvl0=`echo "$name" | sed -e 's/\(.*\)-.*/\1/'`
+  kernlvl1=`echo "$name" | sed -e 's/.*-\(.*\)/\1/'`
+  ;;
+  gmp) #Alias for auto-gmp
+  kernlvl0="$arch"; kernlvl1="gmp";;
+  *)
+  kernlvl0="$name"; kernlvl1="none";;
+esac
+
+if [ "$kernlvl0" = "auto" ]; then
+  kernlvl0="$arch";
+fi
+
+case "$kernlvl0" in
+  m68k)	kernlvl1="m68k";;
+esac
+
+echo "$kernlvl0-$kernlvl1"
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/alpha/MakeLVL0.SH	Wed Nov 20 12:12:38 2002
@@ -0,0 +1,9 @@
+kern=$src/kernel/$kernlvl0
+
+cat >> $file << EOT
+parilvl0.h: $kern/asm0.h $kern/asm1.h  
+	cat $kern/asm0.h $kern/asm1.h > parilvl0.h
+kernel\$(_O): $kern/level0.s
+	\$(AS) \$(ASFLAGS) -o kernel\$(_O) $kern/level0.s
+
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/hppa/MakeLVL0.SH	Thu Nov 21 16:39:37 2002
@@ -0,0 +1,12 @@
+# Level 0 kernel is "asm extern"
+# Level 1 kernel is the C generic one
+
+$kern=$src/kernel/$asmarch
+
+cat >> $file << EOT
+parilvl0.h: $src/kernel/none/asm0.h 
+	cat $src/kernel/none/asm0.h > parilvl0.h
+kernel\$(_O):  $kern/level0.s
+	\$(AS) \$(ASFLAGS) -o kernel\$(_O) $kern/level0.s
+
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/ix86/MakeLVL0.SH	Wed Nov 20 12:19:44 2002
@@ -0,0 +1,13 @@
+# Level 0 kernel is "asm inline" if gcc and "asm extern" if not
+
+level0=$src/kernel/$kernlvl0
+
+cat >> $file << EOT
+parilvl0.h: $level0/level0.h 
+	cat $level0/level0.h > parilvl0.h
+level0.s: $level0/l0asm.c $level0/l0asm.h
+	\$(CPP) $level0/l0asm.c | sed -e '/^#/d' -e '/^ *#line/d' -e 's/%  */%/g' > level0.s
+kernel\$(_O):  level0.s
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o kernel\$(_O) level0.s
+
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/m68k/MakeLVL0.SH	Thu Nov 21 18:11:06 2002
@@ -0,0 +1,21 @@
+# Level 0 kernel is the C generic one.
+
+# Level 1 kernel is in assembly (mp.s), except the new functions that
+# were only written in C (karatsuba and others).
+# The assembly file is compiled in mpasm.o
+
+kernel="$kernel mpasm"
+
+cat >> $file << EOT
+pariinl.h: $src/kernel/none/level0.h $src/kernel/none/level1.h
+	cat $src/kernel/none/level0.h $src/kernel/none/level1.h > \$@
+kernel.o: .headers $src/kernel/none/level0.h
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o kernel.o $src/kernel/none/level0.c
+mpasm.o: $src/kernel/m68k/mp.s
+	\$(AS) \$(ASFLAGS) -o mpasm.o $src/kernel/m68k/mp.s
+mp.o: .headers $src/kernel/none/mp.c
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o mp.o $src/kernel/none/mp.c
+mpinl.o: .headers $src/kernel/none/level1.h
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o mpinl.o $src/kernel/none/level1.c
+
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/none/MakeLVL1.SH	Wed Nov 20 12:09:41 2002
@@ -0,0 +1,13 @@
+# Functions that can be inlined are externally defined too
+# This is done with level0.c and level1.c
+
+kern=$src/kernel/$kernlvl1
+
+cat >> $file << EOT
+parilvl1.h: $kern/level1.h
+	cat $kern/level1.h > parilvl1.h
+mp\$(_O): .headers $kern/mp.c
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o mp\$(_O) $kern/mp.c
+mpinl\$(_O): .headers $kern/level1.h
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o mpinl\$(_O) $kern/level1.c
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/none/MakeLVL0.SH	Wed Nov 20 12:11:15 2002
@@ -0,0 +1,11 @@
+# Functions that can be inlined are externally defined too
+# This is done with level0.c and level1.c
+
+kern=$src/kernel/$kernlvl0
+
+cat >> $file << EOT
+parilvl0.h: $kern/level0.h 
+	cat $kern/level0.h > parilvl0.h
+kernel\$(_O): .headers $kern/level0.h
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o kernel\$(_O) $kern/level0.c
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/sparcv7/MakeLVL0.SH	Wed Nov 20 11:09:27 2002
@@ -0,0 +1,20 @@
+# Level 0 kernel is "asm extern"
+# Level 1 kernel is the C generic one
+level0=$src/kernel/none/asm0.h
+kernel1=$src/kernel/$asmarch/level0.S
+if test "$osname" = "nextstep" -o "$osname" = "linux" -o "$gnuas" = "yes";
+then
+cat >> $file << EOT
+kernel1.s: $kernel1
+	\$(CPP) $KERNELCPPFLAGS $kernel1 > \$@
+EOT
+kernel1=kernel1.s
+fi
+
+cat >> $file << EOT
+parilvl0.h: $level0 
+	cat \$^ > \$@
+kernel.o:  $kernel1
+	\$(AS) \$(ASFLAGS) -o \$@ $kernel1
+
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/sparcv8/MakeLVL0.SH	Thu Nov 21 12:30:15 2002
@@ -0,0 +1,43 @@
+# For SunOS
+#   If __GNUC__, most level0 functions are "asm inline"
+#   If not, they are "asm extern"
+#   The object kernel.o (resp. kernel2.o) contains entries for the functions
+#   that can (resp. cannot) be inline.
+#   Problem: "divll" uses "overflow", so kernel2.o is not the same when
+#   compiled with gcc or with cc. We should try to find a workaround.
+# For NextStep or Linux
+#   We don't accept "asm inline" since it does not work (Ptitboul)
+if test "$gnuas" = "yes"; then do_cpp=yes; fi
+
+ker=$src/kernel/sparcv8
+kernel1=$ker/level0_$asmarch.S
+kernel2=$ker/level0.S
+
+if test "$osname" = "nextstep" -o "$osname" = "linux"
+then
+  level0=$src/kernel/none/asm0.h
+else
+  level0=$ker/level0.h
+fi
+
+if test "$osname" = "nextstep" -o "$osname" = "linux" -o "$do_cpp" = "yes"
+then
+cat >> $file << EOT
+kernel1.s: $kernel1
+	\$(CPP) $KERNELCPPFLAGS $kernel1 > \$@
+kernel2.s: $kernel2
+	\$(CPP) $KERNELCPPFLAGS $kernel2 > \$@
+EOT
+kernel1=kernel1.s
+kernel2=kernel2.s
+fi
+
+cat >> $file << EOT
+parilvl0.h: $level0 
+	cat $level0 > parilvl0.h
+kernel\$(_O):  $kernel1
+	\$(AS) \$(ASFLAGS) -o \$@ $kernel1
+kernel2\$(_O): $kernel2
+	\$(AS) \$(ASFLAGS) -o \$@ $kernel2
+
+EOT
--- /dev/null	Sat Feb 23 10:50:49 2002
+++ src/kernel/gmp/MakeLVL1.SH	Wed Nov 20 12:09:27 2002
@@ -0,0 +1,13 @@
+# Functions that can be inlined are externally defined too
+# This is done with level0.c and level1.c
+
+kern=$src/kernel/$kernlvl1
+
+cat >> $file << EOT
+parilvl1.h: $kern/level1.h
+	cat $kern/level1.h > parilvl1.h
+mp\$(_O): .headers $kern/mp.c
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o mp\$(_O) $kern/mp.c
+mpinl\$(_O): .headers $kern/level1.h
+	\$(CC) -c \$(CFLAGS) \$(CPPFLAGS) -o mpinl\$(_O) $kern/level1.c
+EOT