Ilya Zakharevich on Wed, 15 Mar 2006 06:25:13 +0100


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

[PATCH CVS] Minimal support for register calling convention


How to apply: Change to the GP/PARI build directory, then run the
attached script.  (To do so, you need a pfind script, available on
  ilyaz.org/software/tmp/pfind
).  It also helps to apply the small manual-edit patch put at the end
of the script (the anal.h edit removes duplicate declarations).

This does not change the default behaviour of GP/PARI; all what is
done is to add #define'able directive on a declaration of extern
functions (this declaration defaults to empty).  However, when one
compiles it with

  -DPARI_FUNCDECL=PARI_FUNCDECL_ix86

it is built with register calling conventions (with a lot of warnings
- about 200) and can run only *very* primitive stuff ;-).

I think this is the maximum one can do with an automatic edit.  The
rest of warnings (I think they are about wrong calling convention of
static functions passed as pointers to extern functions) should be
manually edited to mark them as PARI_FUNCDECL too (I think M-x compile
in Emacs should help this a lot); then the rest of GP/PARI should
start working as well.

It is hard to estimate the expected speedup of GP/PARI, but I hope it
might be substantial.

Enjoy,
Ilya
#!/bin/sh
cd src/headers/
echo <<'EOP' > xxxx.pm
  my @d = <DATA>;
  chomp @d;
  $xxx::req = join '|', @d;
  $xxx::req = qr($xxx::req);
  sub decl {
    my ($full, $post) = (shift, shift);
    my $pre = substr $full, 0, -length $post;
    my ($b, $n, $a) = ($post =~ /^(\s+)(\w+)(.*)/s);
    $a =~ s/\)(?=\w*[,)])/) PARI_FUNCDECL/g;
    "$pre PARI_FUNCDECL$b$n$a"
  }
__DATA__
EOP

cp xxxx.pm xxx.pm
perl -i.aa -pwle 's/\)\s*;\s*?$/) PARI_FUNCDECL;/; s/\)(?=\s*[,)])/) PARI_FUNCDECL/; s/PARI_FUNCDECL/PARI_FUNCDECL_null/g if /\b(os_signal|checkbell)\b/' paridecl.h
perl -lnwe 'next unless /^([\w*]+(?:\s+[\w*]+)*)\s+(\w+)\(.* PARI_FUNCDECL/; my ($p,$n) = ($1,$2); $p =~ s/\s*\*/ */g; $p =~ s/ \*/\\s*\\*/g; my @w = split /\s+/, $p; print join(q(\\s+), @w), q{(\s+}, $n, q{\s*\\((?:[^()]|\([^()]*\))*\\))}' paridecl.h >>xxx.pm

pfind -bak=.aac .. '/\.c$/' 'use xxx' '=~ s/^(\s*$xxx::req)/decl($1, $+)/mge'

# Undo by
#   pfind .. 's/\.c\.aac$/.c/'

exit;

--- pari.h-ini  2006-02-02 11:16:19.000000000 -0800
+++ pari.h      2006-03-14 19:08:32.000000000 -0800
@@ -71,6 +71,11 @@ Foundation, Inc., 59 Temple Place - Suit
 #include "paricom.h"
 #include "parierr.h"
 BEGINEXTERN
+#define PARI_FUNCDECL_ix86 __attribute__((__regparm__(3)))
+#define PARI_FUNCDECL_null
+#ifndef PARI_FUNCDECL
+#  define PARI_FUNCDECL PARI_FUNCDECL_null
+#endif
 #include "paridecl.h"
 #include "paritune.h"
 #ifndef DISABLE_INLINE
--- ./src/headers/paridecl.h-auto	2006-03-14 19:24:30.000000000 -0800
+++ ./src/headers/paridecl.h	2006-03-14 19:26:41.000000000 -0800
@@ -1806,7 +1806,10 @@ void    forpari(entree *ep, GEN a, GEN b
 void    forprime(entree *ep, GEN a, GEN b, char *ch) PARI_FUNCDECL;
 void    forstep(entree *ep, GEN a, GEN b, GEN s, char *ch) PARI_FUNCDECL;
 void    forvec(entree *ep, GEN x, char *ch, long flag) PARI_FUNCDECL;
-GEN     forvec_start(GEN x, long flag, GEN *d, GEN (**next)(GEN,GEN) PARI_FUNCDECL) PARI_FUNCDECL;
+
+typedef GEN (*func_gen_gen_2gen_t)(GEN,GEN) PARI_FUNCDECL;
+
+GEN     forvec_start(GEN x, long flag, GEN *d, func_gen_gen_2gen_t *next) PARI_FUNCDECL;
 GEN     matrice(GEN nlig, GEN ncol,entree *ep1, entree *ep2, char *ch) PARI_FUNCDECL;
 GEN     polzag(long n, long m) PARI_FUNCDECL;
 GEN     polzagreel(long n, long m, long prec) PARI_FUNCDECL;
--- src/language/sumiter.c	2006-03-14 19:32:37.000000000 -0800
+++ src/language/sumiter.c-new	2006-03-14 19:32:09.000000000 -0800
@@ -365,7 +365,7 @@ forvec_next_lt(GEN gd, GEN v0)
  *   if flag = 1: m[i-1] <= m[i] <= M[i] <= M[i+1]
  *   if flag = 2: m[i-1] <  m[i] <= M[i] <  M[i+1] */
 GEN PARI_FUNCDECL
-forvec_start(GEN x, long flag, GEN *gd, GEN (**next)(GEN,GEN) PARI_FUNCDECL)
+forvec_start(GEN x, long flag, GEN *gd, func_gen_gen_2gen_t *next)
 {
   long i, tx = typ(x), l = lg(x), t = t_INT;
   forvec_data *d;
--- ./src/language/anal.h.~1.80.~	2005-12-12 00:27:19.000000000 -0800
+++ ./src/language/anal.h	2006-03-14 16:42:39.000000000 -0800
@@ -161,20 +161,8 @@ void print_prefixed_text(char *s, char *
 /* GP output && output format */
 enum { f_RAW, f_PRETTYMAT, f_PRETTYOLD, f_PRETTY, f_TEX };
 
-void error0(GEN g);
 void gpwritebin(char *s, GEN x);
-void print   (GEN g);
 void print0(GEN g, long flag);
-void print1  (GEN g);
-void printp  (GEN g);
-void printp1 (GEN g);
-void printtex(GEN g);
-void write0  (const char *s, GEN g);
-void write1  (const char *s, GEN g);
-void writetex(const char *s, GEN g);
-GEN Str(GEN g);
-GEN Strexpand(GEN g);
-GEN Strtex(GEN g);
 
 /* gp specific routines */
 void alias0(char *s, char *old);
@@ -183,7 +171,6 @@ GEN  break0(long n);
 GEN  extern0(char *cmd);
 void gp_quit(void);
 GEN  input0(void);
-void kill0(entree *ep);
 GEN  next0(long n);
 GEN  read0(char *s);
 GEN  return0(GEN x);