aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--acconfig.h15
-rw-r--r--cipher/dsa.c4
-rw-r--r--cipher/elgamal.c22
-rw-r--r--cipher/gost.c4
-rw-r--r--cipher/primegen.c319
-rw-r--r--cipher/rmd160.c2
-rw-r--r--cipher/sha1.c4
-rw-r--r--config.h.in22
-rw-r--r--configure.in10
-rw-r--r--g10/g10.c57
-rw-r--r--g10/kbnode.c9
-rw-r--r--g10/keydb.h2
-rw-r--r--g10/keygen.c9
-rw-r--r--g10/ringedit.c75
-rw-r--r--g10/sig-check.c15
-rw-r--r--include/cipher.h1
-rw-r--r--include/iobuf.h1
-rw-r--r--include/mpi.h1
-rw-r--r--include/types.h61
-rw-r--r--mpi/longlong.h1123
-rw-r--r--mpi/mpi-bit.c56
-rw-r--r--util/iobuf.c28
22 files changed, 1221 insertions, 619 deletions
diff --git a/acconfig.h b/acconfig.h
index fa6f986cd..334d6ad84 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -21,16 +21,25 @@
#define G10_CONFIG_H
-@@TOP@@
+@TOP@
+
#undef M_DEBUG
#undef VERSION
#undef PACKAGE
/* RSA is only compiled in if you have these files. You can use
- * RSA with out any restrictions, if your not in the U.S. or
+ * RSA without any restrictions, if your not in the U.S. or
* wait until sep 20, 2000
*/
#undef HAVE_RSA_CIPHER
-@@BOTTOM@@
+
+@BOTTOM@
+
+#ifdef WORDS_BIGENDIAN
+ #define BIG_ENDIAN_HOST
+#else
+ #define LITTLE_ENDIAN_HOST
+#endif
+
#endif /*G10_CONFIG_H*/
diff --git a/cipher/dsa.c b/cipher/dsa.c
index dd9100dfb..9d0a018a3 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -86,7 +86,7 @@ gen_k( MPI p )
if( DBG_CIPHER )
fputc('.', stderr);
mpi_set_bytes( k, nbits, get_random_byte, 1 );
- mpi_set_bit( k, nbits-1 ); /* make sure it's high (really needed?) */
+ mpi_set_highbit( k, nbits-1 ); /* make sure it's high (really needed?) */
if( mpi_cmp( k, p_1 ) >= 0 )
continue; /* is not smaller than (p-1) */
if( mpi_gcd( temp, k, p_1 ) )
@@ -126,7 +126,7 @@ dsa_generate( DSA_public_key *pk, DSA_secret_key *sk, unsigned nbits )
if( DBG_CIPHER )
fputc('.', stderr);
mpi_set_bytes( x, nbits, get_random_byte, 1 ); /* fixme: should be 2 */
- mpi_set_bit( x, nbits-1 ); /* make sure it's high (needed?) */
+ mpi_set_highbit( x, nbits-1 ); /* make sure it's high (needed?) */
} while( mpi_cmp( x, p ) >= 0 ); /* x must be smaller than p */
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index 4252b48d1..3cc632525 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -94,7 +94,7 @@ gen_k( MPI p )
for(;;) {
if( DBG_CIPHER )
fputc('.', stderr);
- mpi_set_bytes( k, nbits, get_random_byte, 1 );
+ mpi_set_bytes( k, nbits , get_random_byte, 1 );
if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
continue; /* no */
if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
@@ -123,19 +123,23 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits )
MPI x; /* the secret exponent */
MPI y;
MPI temp;
+ unsigned qbits;
- p = NULL;
p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
- /*do {*/
- mpi_free(p);
- /* FIXME!!!! Should generate a strong prime */
- p = generate_public_prime( nbits );
- mpi_sub_ui(p_min1, p, 1);
- /*} while if( mpi_gcd( temp, k, p_1 ) )*/
+ if( nbits < 512 )
+ qbits = 120;
+ else if( nbits <= 1024 )
+ qbits = 160;
+ else if( nbits <= 2048 )
+ qbits = 200;
+ else
+ qbits = 240;
+ g = mpi_alloc(1);
+ p = generate_elg_prime( nbits, qbits, g );
+ mpi_sub_ui(p_min1, p, 1);
- g = mpi_alloc_set_ui(3); /* fixme: 3 is bad (but better than 2)*/
/* select a random number which has these properties:
* 0 < x < p-1
*/
diff --git a/cipher/gost.c b/cipher/gost.c
index 21b63cbc9..b890bc5e1 100644
--- a/cipher/gost.c
+++ b/cipher/gost.c
@@ -153,7 +153,7 @@ cipher( byte *inbuf, byte *outbuf, u16 *key )
x2 = *in++;
x3 = *in++;
x4 = *in;
- #ifdef HAVE_LITTLE_ENDIAN
+ #ifdef LITTLE_ENDIAN_HOST
x1 = (x1>>8) | (x1<<8);
x2 = (x2>>8) | (x2<<8);
x3 = (x3>>8) | (x3<<8);
@@ -186,7 +186,7 @@ cipher( byte *inbuf, byte *outbuf, u16 *key )
MUL(x4, *key);
out = (u16*)outbuf;
- #ifdef HAVE_LITTLE_ENDIAN
+ #ifdef LITTLE_ENDIAN_HOST
*out++ = (x1>>8) | (x1<<8);
*out++ = (x3>>8) | (x3<<8);
*out++ = (x2>>8) | (x2<<8);
diff --git a/cipher/primegen.c b/cipher/primegen.c
index 49ec8f659..b7029c4a4 100644
--- a/cipher/primegen.c
+++ b/cipher/primegen.c
@@ -28,8 +28,10 @@
#include "cipher.h"
static int no_of_small_prime_numbers;
-static int is_not_prime( MPI n, unsigned nbits, int steps, int *count );
-static MPI gen_prime( unsigned nbits, int mode );
+static MPI gen_prime( unsigned nbits, int mode, int randomlevel );
+static int check_prime( MPI prime );
+static int is_prime( MPI n, int steps, int *count );
+static void m_out_of_n( char *array, int m, int n );
/****************
@@ -38,17 +40,149 @@ static MPI gen_prime( unsigned nbits, int mode );
MPI
generate_secret_prime( unsigned nbits )
{
- return gen_prime( nbits, 1 );
+ MPI prime;
+
+ prime = gen_prime( nbits, 1, 2 );
+ fputc('\n', stderr);
+ return prime;
}
MPI
generate_public_prime( unsigned nbits )
{
- return gen_prime( nbits, 0 );
+ MPI prime;
+
+ prime = gen_prime( nbits, 0, 1 ); /* fixme: change to 2 */
+ fputc('\n', stderr);
+ return prime;
+}
+
+
+MPI
+generate_elg_prime( unsigned pbits, unsigned qbits, MPI g )
+{
+ int n; /* number of factors */
+ int m; /* number of primes in pool */
+ unsigned fbits; /* length of prime factors */
+ MPI *factors; /* curent factors */
+ MPI *pool; /* pool of primes */
+ MPI q; /* first prime factor */
+ MPI prime; /* prime test value */
+ byte *perms = NULL;
+ int i, j;
+
+ /* find number of needed prime factors */
+ for(n=1; (pbits - qbits - 1) / n >= qbits; n++ )
+ ;
+ n--;
+ if( !n )
+ log_fatal("can't gen prime with pbits=%u qbits=%u\n", pbits, qbits );
+ fbits = (pbits - qbits -1) / n;
+ while( qbits + n*fbits < pbits )
+ qbits++;
+ qbits++; /* one mpre to increase tzhe chance to get a weel formed prime*/
+ log_debug("gen prime: pbits=%u qbits=%u fbits=%u n=%d\n",
+ pbits, qbits, fbits, n );
+
+ prime = mpi_alloc( (pbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB );
+ q = gen_prime( qbits, 0, 0 ); /* fixme: should be 2 */
+ fputc('\n', stderr);
+
+ /* allocate an array to hold the factors + 2 for later usage */
+ factors = m_alloc_clear( (n+2) * sizeof *factors );
+
+ /* make a pool of 2n+5 primes (this is an arbitrary value) */
+ m = n*2+5;
+ if( m < 20 )
+ m = 20;
+ pool = m_alloc_clear( m * sizeof *pool );
+
+ /* permutate over the pool of primes */
+ do {
+ next_try:
+ if( !perms ) {
+ /* allocate new primes */
+ for(i=0; i < m; i++ ) {
+ mpi_free(pool[i]);
+ pool[i] = gen_prime( fbits, 0, 0 ); /* fixme: should be 2 */
+ }
+ fputc('\n', stderr);
+ /* init m_out_of_n() */
+ perms = m_alloc_clear( m );
+ for(i=0; i < n; i++ ) {
+ perms[i] = 1;
+ factors[i] = pool[i];
+ }
+ }
+ else {
+ m_out_of_n( perms, n, m );
+ for(i=j=0; i < m && j < n ; i++ )
+ if( perms[i] )
+ factors[j++] = pool[i];
+ if( i == n ) {
+ m_free(perms); perms = NULL;
+ fputc('!', stderr);
+ goto next_try; /* allocate new primes */
+ }
+ }
+
+ mpi_set( prime, q );
+ mpi_mul_ui( prime, prime, 2 );
+ for(i=0; i < n; i++ )
+ mpi_mul( prime, prime, factors[i] );
+ mpi_add_ui( prime, prime, 1 );
+ } while( !( mpi_get_nbits( prime ) == pbits && check_prime( prime )) );
+ putc('\n', stderr);
+
+
+ log_mpidump( "prime : ", prime );
+ log_mpidump( "factor q: ", q );
+ for(i=0; i < n; i++ )
+ log_mpidump( "factor pi: ", factors[i] );
+ log_debug("bit sizes: prime=%u, q=%u",mpi_get_nbits(prime), mpi_get_nbits(q) );
+ for(i=0; i < n; i++ )
+ fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
+ putc('\n', stderr);
+
+ if( g ) { /* create a generator (start with 3)*/
+ MPI tmp = mpi_alloc( mpi_get_nlimbs(prime) );
+ MPI b = mpi_alloc( mpi_get_nlimbs(prime) );
+ MPI pmin1 = mpi_alloc( mpi_get_nlimbs(prime) );
+
+ factors[n] = q;
+ factors[n+1] = mpi_alloc_set_ui(2);
+ mpi_sub_ui( pmin1, prime, 1 );
+ mpi_set_ui(g,2);
+ do {
+ mpi_add_ui(g, g, 1);
+ log_mpidump("checking g: ", g );
+ for(i=0; i < n+2; i++ ) {
+ log_mpidump(" against: ", factors[i] );
+ mpi_fdiv_q(tmp, pmin1, factors[i] );
+ /* (no mpi_pow(), but it is okay to use this with mod prime) */
+ mpi_powm(b, g, tmp, prime );
+ if( !mpi_cmp_ui(b, 1) )
+ break;
+ }
+ } while( i < n );
+ mpi_free(factors[n+1]);
+ mpi_free(tmp);
+ mpi_free(b);
+ mpi_free(pmin1);
+ log_mpidump("found g: ", g );
+ }
+
+ m_free( factors ); /* (factors are shallow copies) */
+ for(i=0; i < m; i++ )
+ mpi_free( pool[i] );
+ m_free( pool );
+ m_free(perms);
+ return prime;
}
+
static MPI
-gen_prime( unsigned nbits, int secret )
+gen_prime( unsigned nbits, int secret, int randomlevel )
{
unsigned nlimbs;
MPI prime, val_2, val_3, result;
@@ -57,7 +191,7 @@ gen_prime( unsigned nbits, int secret )
unsigned count1, count2;
int *mods;
- if( DBG_CIPHER )
+ if( 0 && DBG_CIPHER )
log_debug("generate a prime of %u bits ", nbits );
if( !no_of_small_prime_numbers ) {
@@ -78,9 +212,9 @@ gen_prime( unsigned nbits, int secret )
/* enter (endless) loop */
for(;;) {
/* generate a random number */
- mpi_set_bytes( prime, nbits, get_random_byte, 2 );
+ mpi_set_bytes( prime, nbits, get_random_byte, randomlevel );
/* set high order bit to 1, set low order bit to 1 */
- mpi_set_bit( prime, nbits-1 );
+ mpi_set_highbit( prime, nbits-1 );
mpi_set_bit( prime, 0 );
/* calculate all remainders */
@@ -102,25 +236,26 @@ gen_prime( unsigned nbits, int secret )
mpi_add_ui( prime, prime, step );
+ #if 0
/* do a Fermat test */
count2++;
mpi_powm( result, val_2, prime, prime );
if( mpi_cmp_ui(result, 2) )
continue; /* stepping (fermat test failed) */
fputc('+', stderr);
+ #endif
/* perform stronger tests */
- if( !is_not_prime(prime, nbits, 5, &count2 ) ) {
+ if( is_prime(prime, 5, &count2 ) ) {
if( !mpi_test_bit( prime, nbits-1 ) ) {
- if( DBG_CIPHER ) {
+ if( 0 && DBG_CIPHER ) {
fputc('\n', stderr);
log_debug("overflow in prime generation\n");
break; /* step loop, cont with a new prime */
}
}
- fputc('\n', stderr);
- if( DBG_CIPHER ) {
+ if( 0 && DBG_CIPHER ) {
log_debug("performed %u simple and %u stronger tests\n",
count1, count2 );
log_mpidump("found prime: ", prime );
@@ -137,12 +272,51 @@ gen_prime( unsigned nbits, int secret )
}
}
+/****************
+ * Returns: true if this is may me a prime
+ */
+static int
+check_prime( MPI prime )
+{
+ int i;
+ unsigned x;
+ int count=0;
+ MPI result;
+ MPI val_2;
+
+ /* check against small primes */
+ for(i=0; (x = small_prime_numbers[i]); i++ ) {
+ if( mpi_divisible_ui( prime, x ) )
+ return 0;
+ }
+ fputc('.', stderr);
+
+ #if 0
+ result = mpi_alloc( mpi_get_nlimbs(prime) );
+ val_2 = mpi_alloc_set_ui( 2 );
+ mpi_powm( result, val_2, prime, prime );
+ if( mpi_cmp_ui(result, 2) ) {
+ mpi_free(result);
+ mpi_free(val_2);
+ return 0;
+ }
+ mpi_free(result);
+ mpi_free(val_2);
+ fputc('+', stderr);
+ #endif
+
+ /* perform stronger tests */
+ if( is_prime(prime, 5, &count ) )
+ return 1; /* is probably a prime */
+ return 0;
+}
+
/****************
- * Return 1 if n is not a prime
+ * Return true if n is propably a prime
*/
static int
-is_not_prime( MPI n, unsigned nbits, int steps, int *count )
+is_prime( MPI n, int steps, int *count )
{
MPI x = mpi_alloc( mpi_get_nlimbs( n ) );
MPI y = mpi_alloc( mpi_get_nlimbs( n ) );
@@ -151,7 +325,8 @@ is_not_prime( MPI n, unsigned nbits, int steps, int *count )
MPI a2 = mpi_alloc_set_ui( 2 );
MPI q;
unsigned i, j, k;
- int rc = 1;
+ int rc = 0;
+ unsigned nbits = mpi_get_nbits( n );
mpi_sub_ui( nminus1, n, 1 );
@@ -162,24 +337,33 @@ is_not_prime( MPI n, unsigned nbits, int steps, int *count )
for(i=0 ; i < steps; i++ ) {
++*count;
- do {
- mpi_set_bytes( x, nbits, get_random_byte, 0 );
- } while( mpi_cmp( x, n ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
+ if( !i ) {
+ mpi_set_ui( x, 2 );
+ }
+ else {
+ mpi_set_bytes( x, nbits-1, get_random_byte, 0 );
+ /* work around a bug in mpi_set_bytes */
+ if( mpi_test_bit( x, nbits-2 ) )
+ mpi_set_highbit( x, nbits-2 ); /* clear all higher bits */
+ else {
+ mpi_set_highbit( x, nbits-2 );
+ mpi_clear_bit( x, nbits-2 );
+ }
+ assert( mpi_cmp( x, nminus1 ) < 0 && mpi_cmp_ui( x, 1 ) > 0 );
+ }
mpi_powm( y, x, q, n);
if( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) ) {
- for( j=1; j < k; j++ ) {
+ for( j=1; j < k && mpi_cmp( y, nminus1 ); j++ ) {
mpi_powm(y, y, a2, n);
if( !mpi_cmp_ui( y, 1 ) )
goto leave; /* not a prime */
- if( !mpi_cmp( y, nminus1 ) )
- break; /* may be a prime */
}
- if( j == k )
- goto leave;
+ if( mpi_cmp( y, nminus1 ) )
+ goto leave; /* not a prime */
}
fputc('+', stderr);
}
- rc = 0; /* may be a prime */
+ rc = 1; /* may be a prime */
leave:
mpi_free( x );
@@ -191,3 +375,90 @@ is_not_prime( MPI n, unsigned nbits, int steps, int *count )
return rc;
}
+
+static void
+m_out_of_n( char *array, int m, int n )
+{
+ int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
+
+ if( !m || m >= n )
+ return;
+
+ if( m == 1 ) { /* special case */
+ for(i=0; i < n; i++ )
+ if( array[i] ) {
+ array[i++] = 0;
+ if( i >= n )
+ i = 0;
+ array[i] = 1;
+ return;
+ }
+ log_bug(NULL);
+ }
+
+ for(j=1; j < n; j++ ) {
+ if( array[n-1] == array[n-j-1] )
+ continue;
+ j1 = j;
+ break;
+ }
+
+ if( m & 1 ) { /* m is odd */
+ if( array[n-1] ) {
+ if( j1 & 1 ) {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ goto scan;
+ }
+ k2 = n - j1 - 1;
+ if( k2 == 0 ) {
+ k1 = i;
+ k2 = n - j1;
+ }
+ else if( array[k2] && array[k2-1] )
+ k1 = n;
+ else
+ k1 = k2 + 1;
+ }
+ else { /* m is even */
+ if( !array[n-1] ) {
+ k1 = n - j1;
+ k2 = k1 + 1;
+ goto leave;
+ }
+
+ if( !(j1 & 1) ) {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ scan:
+ jp = n - j1 - 1;
+ for(i=1; i <= jp; i++ ) {
+ i1 = jp + 2 - i;
+ if( array[i1-1] ) {
+ if( array[i1-2] ) {
+ k1 = i1 - 1;
+ k2 = n - j1;
+ }
+ else {
+ k1 = i1 - 1;
+ k2 = n + 1 - j1;
+ }
+ goto leave;
+ }
+ }
+ k1 = 1;
+ k2 = n + 1 - m;
+ }
+ leave:
+ array[k1-1] = !array[k1-1];
+ array[k2-1] = !array[k2-1];
+}
+
diff --git a/cipher/rmd160.c b/cipher/rmd160.c
index 2c583d576..2b2b34c9e 100644
--- a/cipher/rmd160.c
+++ b/cipher/rmd160.c
@@ -368,7 +368,7 @@ rmd160_final(RMDHANDLE hd)
transform( hd, (u32*)hd->buffer );
p = hd->buffer;
- #ifdef HAVE_BIG_ENDIAN
+ #ifdef BIG_ENDIAN_HOST
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
#else /* little endian */
diff --git a/cipher/sha1.c b/cipher/sha1.c
index 95d6cc949..afb815e44 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -139,7 +139,7 @@ transform( SHA1HANDLE hd, byte *data )
D = hd->h3;
E = hd->h4;
- #ifdef HAVE_BIG_ENDIAN
+ #ifdef BIG_ENDIAN_HOST
memcpy( eData, data, 64 );
#else
{ int i;
@@ -379,7 +379,7 @@ sha1_final(SHA1HANDLE hd)
transform( hd, hd->buffer );
p = hd->buffer;
- #ifdef HAVE_BIG_ENDIAN
+ #ifdef BIG_ENDIAN_HOST
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#else /* little endian */
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
diff --git a/config.h.in b/config.h.in
index 8f3ed5927..54a2fcb9c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -41,15 +41,28 @@
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
+
#undef M_DEBUG
#undef VERSION
#undef PACKAGE
/* RSA is only compiled in if you have these files. You can use
- * RSA with out any restrictions, if your not in the U.S. or
+ * RSA without any restrictions, if your not in the U.S. or
* wait until sep 20, 2000
*/
#undef HAVE_RSA_CIPHER
+/* The number of bytes in a unsigned int. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The number of bytes in a unsigned long. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The number of bytes in a unsigned short. */
+#undef SIZEOF_UNSIGNED_SHORT
+
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
@@ -65,4 +78,11 @@
/* Define if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
+#ifdef WORDS_BIGENDIAN
+ #define BIG_ENDIAN_HOST
+#else
+ #define LITTLE_ENDIAN_HOST
+#endif
+
+
#endif /*G10_CONFIG_H*/
diff --git a/configure.in b/configure.in
index 2c09e1a18..3b1d5352a 100644
--- a/configure.in
+++ b/configure.in
@@ -63,6 +63,12 @@ AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
+AC_C_BIGENDIAN
+AC_CHECK_SIZEOF(unsigned short)
+AC_CHECK_SIZEOF(unsigned int)
+AC_CHECK_SIZEOF(unsigned long)
+
+
dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(strerror strtol strtoul)
@@ -79,12 +85,12 @@ fi
-dnl checking wether we have the RSA source
+dnl checking whether we have the RSA source
dnl fixme: I found no way (aside of using Makefile.am.in)
dnl to add the requeired source int Makefile.am
dnl I used: add_cipher_SOURCES="rsa.c rsa.h"
dnl but of cource it can't work
-AC_MSG_CHECKING(wether we have the rsa source)
+AC_MSG_CHECKING(whether we have the rsa source)
if test -f cipher/rsa.c && test -f cipher/rsa.h; then
AC_DEFINE(HAVE_RSA_CIPHER)
AC_MSG_RESULT(yes)
diff --git a/g10/g10.c b/g10/g10.c
index 777220aa1..aab502ede 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -125,7 +125,7 @@ main( int argc, char **argv )
{ 510, "debug" ,4|16, "set debugging flags" },
{ 511, "debug-all" ,0, "enable full debugging"},
{ 512, "cache-all" ,0, "hold everything in memory"},
- { 513, "gen-prime" , 1, "\r" },
+ { 513, "gen-prime" , 0, "\r" },
{ 514, "test" , 0, "\r" },
{ 515, "change-passphrase", 0, "change the passphrase of your secret keyring"},
{ 515, "fingerprint", 0, "show the fingerprints"},
@@ -345,10 +345,26 @@ main( int argc, char **argv )
case aPrimegen:
- if( argc )
+ if( argc == 1 ) {
+ mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
+ putchar('\n');
+ }
+ else if( argc == 2 ) {
+ mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
+ atoi(argv[1]), NULL ), 1);
+ putchar('\n');
+ }
+ else if( argc == 3 ) {
+ MPI g = mpi_alloc(1);
+ mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
+ atoi(argv[1]), g ), 1);
+ printf("\nGenerator: ");
+ mpi_print( stdout, g, 1 );
+ putchar('\n');
+ mpi_free(g);
+ }
+ else
usage(1);
- mpi_print( stdout, generate_public_prime( pargs.r.ret_int ), 1);
- putchar('\n');
break;
case aPrintMDs:
@@ -366,7 +382,7 @@ main( int argc, char **argv )
generate_keypair();
break;
- case aTest: do_test( atoi(*argv) ); break;
+ case aTest: do_test( argc? atoi(*argv): 0 ); break;
default:
if( argc > 1 )
@@ -463,9 +479,11 @@ print_mds( const char *fname )
}
+
static void
do_test(int times)
{
+ #if 0
MPI t = mpi_alloc( 50 );
MPI m = mpi_alloc( 50 );
MPI a = mpi_alloc( 50 );
@@ -486,7 +504,34 @@ do_test(int times)
m_check(NULL);
-
+ #endif
+ #if 0
+ char *array;
+ int i, j;
+ int n = 6;
+ int m = times;
+
+ if( m > n )
+ abort();
+ array = m_alloc_clear( n );
+ memset( array, 1, m );
+
+ for(i=0;; i++) {
+ printf("i=%3d: ", i );
+ for(j=0; j < n ; j++ )
+ if( array[j] )
+ putchar( 'X' );
+ else
+ putchar( '-' );
+ putchar('\n');
+ m_out_of_n( array, m, n );
+ for(j=0; j < n; j++ )
+ if( !array[j] )
+ break;
+ if( j == m )
+ break;
+ }
+ #endif
}
diff --git a/g10/kbnode.c b/g10/kbnode.c
index a4ac40dc5..844bafe6c 100644
--- a/g10/kbnode.c
+++ b/g10/kbnode.c
@@ -37,6 +37,7 @@ new_kbnode( PACKET *pkt )
n->next = NULL;
n->pkt = pkt;
n->child = NULL;
+ n->flag = 0;
return n;
}
@@ -138,3 +139,11 @@ walk_kbtree( KBNODE root, KBNODE *context )
return n;
}
+void
+clear_kbnode_flags( KBNODE n )
+{
+ for( ; n; n = n->next ) {
+ clear_kbnode_flags( n->child );
+ n->flag = 0;
+ }
+}
diff --git a/g10/keydb.h b/g10/keydb.h
index 58e62da48..fe093205b 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -40,6 +40,7 @@ struct kbnode_struct {
PACKET *pkt;
KBNODE next; /* used to form a link list */
KBNODE child;
+ int flag;
};
/****************
@@ -92,6 +93,7 @@ void add_kbnode( KBNODE root, KBNODE node );
void add_kbnode_as_child( KBNODE root, KBNODE node );
KBNODE find_kbparent( KBNODE root, KBNODE node );
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
+void clear_kbnode_flags( KBNODE n );
/*-- ringedit.c --*/
int add_keyblock_resource( const char *filename, int force );
diff --git a/g10/keygen.c b/g10/keygen.c
index 47bc2b14f..b171b0676 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -174,17 +174,14 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
skc->d.elg.g = sk.g;
skc->d.elg.y = sk.y;
skc->d.elg.x = sk.x;
+ skc->d.elg.is_protected = 0;
+ skc->d.elg.protect_algo = 0;
skc->d.elg.csum = checksum_mpi( skc->d.elg.x );
/* return an unprotected version of the skc */
*ret_skc = copy_secret_cert( NULL, skc );
- if( !dek ) {
- skc->d.elg.is_protected = 0;
- skc->d.elg.protect_algo = 0;
- }
- else {
- skc->d.elg.is_protected = 0;
+ if( dek ) {
skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
rc = protect_secret_key( skc, dek );
diff --git a/g10/ringedit.c b/g10/ringedit.c
index 10aa7c947..f1b18d24d 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -53,6 +53,7 @@
#include "mpi.h"
#include "iobuf.h"
#include "keydb.h"
+#include <unistd.h> /* for truncate */
struct resource_table_struct {
@@ -383,6 +384,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
KBNODE root = NULL;
KBNODE node, n1, n2;
IOBUF a;
+ u32 offset, last_offset;
if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL;
@@ -399,7 +401,6 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
return G10ERR_KEYRING_OPEN;
}
-
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
while( (rc=parse_packet(a, pkt)) != -1 ) {
@@ -407,11 +408,13 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
free_packet( pkt );
continue;
}
+ if( root && ( pkt->pkttype == PKT_PUBLIC_CERT
+ || pkt->pkttype == PKT_SECRET_CERT ) )
+ goto ready;
+ offset = iobuf_tell(a);
switch( pkt->pkttype ) {
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
- if( root )
- goto ready;
root = new_kbnode( pkt );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
@@ -423,6 +426,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
rc = G10ERR_INV_KEYRING; /* or wrong kbpos */
goto ready;
}
+ offset = last_offset;
/* append the user id */
node = new_kbnode( pkt );
if( !(n1=root->child) )
@@ -477,7 +481,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
release_kbnode( root );
else {
*ret_root = root;
- kbpos->length = iobuf_tell( a ) - kbpos->offset;
+ kbpos->length = offset - kbpos->offset;
}
free_packet( pkt );
m_free( pkt );
@@ -529,7 +533,68 @@ keyring_insert( KBPOS *kbpos, KBNODE root )
static int
keyring_delete( KBPOS *kbpos )
{
- return -1;
+ RESTBL *rentry;
+ IOBUF fp;
+ KBNODE kbctx, node;
+ int rc;
+ u32 len;
+ int ctb;
+
+ if( !(rentry = check_pos( kbpos )) )
+ return G10ERR_GENERAL;
+
+
+ /* open the file for read/write */
+ fp = iobuf_openrw( rentry->fname );
+ if( !fp ) {
+ log_error("can't open '%s' for writing\n", rentry->fname );
+ return G10ERR_OPEN_FILE;
+ }
+
+ if( iobuf_seek( fp, kbpos->offset ) ) {
+ log_error("can't seek to %lu: %s\n", kbpos->offset, g10_errstr(rc));
+ iobuf_close(fp);
+ return G10ERR_WRITE_FILE;
+ }
+
+ len = kbpos->length;
+ log_debug("writing a dummy packet of length %lu\n", (ulong)len);
+
+ if( len < 2 )
+ log_bug(NULL);
+
+ if( len < 256 ) {
+ ctb = 0x80;
+ len -= 2;
+ }
+ else if( len < 65536 ) {
+ ctb = 0x81;
+ len -= 3;
+ }
+ else {
+ ctb = 0x82;
+ len -= 5;
+ }
+ iobuf_put(fp, ctb );
+ if( ctb & 2 ) {
+ iobuf_put(fp, len >> 24 );
+ iobuf_put(fp, len >> 16 );
+ }
+ if( ctb & 3 )
+ iobuf_put(fp, len >> 8 );
+ if( iobuf_put(fp, len ) ) {
+ iobuf_close(fp);
+ return G10ERR_WRITE_FILE;
+ }
+ for( ; len; len-- )
+ if( iobuf_put(fp, 0xff ) ) {
+ iobuf_close(fp);
+ return G10ERR_WRITE_FILE;
+ }
+
+ iobuf_close(fp);
+
+ return 0;
}
diff --git a/g10/sig-check.c b/g10/sig-check.c
index d5f0afb9e..040c969f5 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -213,4 +213,19 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
}
+/****************
+ * check the signature pointed to by NODE. This is a key signatures
+ */
+int
+check_key_signature( KBNODE root, KBNODE node )
+{
+ assert( node->pkt->pkttype == PKT_SIGNATURE );
+ assert( (node->pkt->pkt.signature->sig_class&~3) == 0x10 );
+ assert( root->pkt->pkttype == PKT_PUBLIC_CERT );
+
+ /*FIXME!!!!!!*/
+
+ return 0;
+}
+
diff --git a/include/cipher.h b/include/cipher.h
index 2fab4daa2..ed553dcb2 100644
--- a/include/cipher.h
+++ b/include/cipher.h
@@ -113,6 +113,7 @@ extern ushort small_prime_numbers[];
/*-- primegen.c --*/
MPI generate_secret_prime( unsigned nbits );
MPI generate_public_prime( unsigned nbits );
+MPI generate_elg_prime( unsigned pbits, unsigned qbits, MPI g );
#endif /*G10_CIPHER_H*/
diff --git a/include/iobuf.h b/include/iobuf.h
index 71819c805..d29e0a06e 100644
--- a/include/iobuf.h
+++ b/include/iobuf.h
@@ -65,6 +65,7 @@ IOBUF iobuf_temp(void);
IOBUF iobuf_open( const char *fname );
IOBUF iobuf_create( const char *fname );
IOBUF iobuf_append( const char *fname );
+IOBUF iobuf_openrw( const char *fname );
int iobuf_close( IOBUF iobuf );
int iobuf_cancel( IOBUF iobuf );
diff --git a/include/mpi.h b/include/mpi.h
index ce60f16a8..fd93f3075 100644
--- a/include/mpi.h
+++ b/include/mpi.h
@@ -148,6 +148,7 @@ unsigned mpi_trailing_zeros( MPI a );
unsigned mpi_get_nbits( MPI a );
int mpi_test_bit( MPI a, unsigned n );
void mpi_set_bit( MPI a, unsigned n );
+void mpi_set_highbit( MPI a, unsigned n );
void mpi_clear_bit( MPI a, unsigned n );
void mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque );
void mpi_rshift( MPI x, MPI a, unsigned n );
diff --git a/include/types.h b/include/types.h
index 7db849f41..575f15224 100644
--- a/include/types.h
+++ b/include/types.h
@@ -22,55 +22,56 @@
#define G10_TYPES_H
#ifdef __linux__
+ /* FIXME: add stuff to configure to detect for typedefs */
#include <linux/types.h>
#define HAVE_ULONG_TYPEDEF
#define HAVE_USHORT_TYPEDEF
#endif
-
-/* Common code */
-#ifndef HAVE_ULONG_TYPEDEF
- #define HAVE_ULONG_TYPEDEF
- typedef unsigned long ulong;
+#ifndef HAVE_BYTE_TYPEDEF
+ typedef unsigned char byte;
+ #define HAVE_BYTE_TYPEDEF
#endif
+
#ifndef HAVE_USHORT_TYPEDEF
- #define HAVE_USHORT_TYPEDEF
typedef unsigned short ushort;
+ #define HAVE_USHORT_TYPEDEF
#endif
-
-typedef struct string_list {
- struct string_list *next;
- char d[1];
-} *STRLIST;
-
-
-
-/****************************************
- ******** machine dependent stuff *******
- ****************************************/
-
-#if defined(__hpux)
- #define HAVE_BIG_ENDIAN 1
-#else
- #define HAVE_LITTLE_ENDIAN 1
+#ifndef HAVE_ULONG_TYPEDEF
+ typedef unsigned long ulong;
+ #define HAVE_ULONG_TYPEDEF
#endif
-
-/*** some defaults ***/
-#ifndef HAVE_BYTE_TYPEDEF
- #define HAVE_BYTE_TYPEDEF
- typedef unsigned char byte;
-#endif
#ifndef HAVE_U16_TYPEDEF
+ #if SIZEOF_UNSIGNED_INT == 2
+ typedef unsigned int u16;
+ #elif SIZEOF_UNSIGNED_SHORT == 2
+ typedef unsigned short u16;
+ #else
+ #error no typedef for u16
+ #endif
#define HAVE_U16_TYPEDEF
- typedef unsigned short u16;
#endif
+
#ifndef HAVE_U32_TYPEDEF
+ #if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned long u32;
+ #elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned int u32;
+ #else
+ #error no typedef for u32
+ #endif
#define HAVE_U32_TYPEDEF
- typedef unsigned long u32;
#endif
+
+typedef struct string_list {
+ struct string_list *next;
+ char d[1];
+} *STRLIST;
+
+
#endif /*G10_TYPES_H*/
diff --git a/mpi/longlong.h b/mpi/longlong.h
index 006f69edd..c341c3d19 100644
--- a/mpi/longlong.h
+++ b/mpi/longlong.h
@@ -54,7 +54,7 @@ MA 02111-1307, USA. */
3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
denominator) divides a UDWtype, composed by the UWtype integers
HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
- in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
than DENOMINATOR for correct operation. If, in addition, the most
significant bit of DENOMINATOR must be 1, then the pre-processor symbol
UDIV_NEEDS_NORMALIZATION is defined to 1.
@@ -81,7 +81,7 @@ MA 02111-1307, USA. */
high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
- and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
and is lost.
If any of these macros are left undefined for a particular CPU,
@@ -90,12 +90,12 @@ MA 02111-1307, USA. */
/* The CPUs come in alphabetical order below.
Please add support for more CPUs here, or improve the current support
- for the CPUs below! */
+ for the CPUs below! */
#if defined (__GNUC__) && !defined (NO_ASM)
/* We sometimes need to clobber "cc" with gcc2, but that would not be
- understood by gcc1. Use cpp to avoid major code duplication. */
+ understood by gcc1. Use cpp to avoid major code duplication. */
#if __GNUC__ < 2
#define __CLOBBER_CC
#define __AND_CLOBBER_CC
@@ -104,66 +104,71 @@ MA 02111-1307, USA. */
#define __AND_CLOBBER_CC , "cc"
#endif /* __GNUC__ < 2 */
+
+/***************************************
+ ************** A29K *****************
+ ***************************************/
#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("add %1,%4,%5
- addc %0,%2,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%r" ((USItype)(ah)), \
- "rI" ((USItype)(bh)), \
- "%r" ((USItype)(al)), \
+ addc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
"rI" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("sub %1,%4,%5
- subc %0,%2,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(ah)), \
- "rI" ((USItype)(bh)), \
- "r" ((USItype)(al)), \
+ subc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
"rI" ((USItype)(bl)))
#define umul_ppmm(xh, xl, m0, m1) \
do { \
USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("multiplu %0,%1,%2" \
- : "=r" ((USItype)(xl)) \
- : "r" (__m0), \
- "r" (__m1)); \
- __asm__ ("multmu %0,%1,%2" \
- : "=r" ((USItype)(xh)) \
- : "r" (__m0), \
- "r" (__m1)); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" ((USItype)(xh)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
} while (0)
#define udiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("dividu %0,%3,%4" \
- : "=r" ((USItype)(q)), \
- "=q" ((USItype)(r)) \
- : "1" ((USItype)(n1)), \
- "r" ((USItype)(n0)), \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" ((USItype)(q)), \
+ "=q" ((USItype)(r)) \
+ : "1" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
"r" ((USItype)(d)))
#define count_leading_zeros(count, x) \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype)(count)) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
: "r" ((USItype)(x)))
#define COUNT_LEADING_ZEROS_0 32
#endif /* __a29k__ */
+
#if defined (__alpha) && W_TYPE_SIZE == 64
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("umulh %r1,%2,%0" \
- : "=r" ((UDItype) ph) \
- : "%rJ" (__m0), \
- "rI" (__m1)); \
- (pl) = __m0 * __m1; \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" ((UDItype) ph) \
+ : "%rJ" (__m0), \
+ "rI" (__m1)); \
+ (pl) = __m0 * __m1; \
} while (0)
#define UMUL_TIME 46
#ifndef LONGLONG_STANDALONE
#define udiv_qrnnd(q, r, n1, n0, d) \
do { UDItype __r; \
- (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
(r) = __r; \
} while (0)
extern UDItype __udiv_qrnnd ();
@@ -171,24 +176,27 @@ extern UDItype __udiv_qrnnd ();
#endif /* LONGLONG_STANDALONE */
#endif /* __alpha */
+/***************************************
+ ************** ARM ******************
+ ***************************************/
#if defined (__arm__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("adds %1, %4, %5
- adc %0, %2, %3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%r" ((USItype)(ah)), \
- "rI" ((USItype)(bh)), \
- "%r" ((USItype)(al)), \
+ __asm__ ("adds %1, %4, %5
+ adc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
"rI" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subs %1, %4, %5
- sbc %0, %2, %3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(ah)), \
- "rI" ((USItype)(bh)), \
- "r" ((USItype)(al)), \
+ __asm__ ("subs %1, %4, %5
+ sbc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
"rI" ((USItype)(bl)))
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("%@ Inlined umul_ppmm
@@ -203,101 +211,112 @@ extern UDItype __udiv_qrnnd ();
adds %|r1, %|r2, %|r1
addcs %0, %0, #65536
adds %1, %1, %|r1, lsl #16
- adc %0, %0, %|r1, lsr #16" \
- : "=&r" ((USItype)(xh)), \
- "=r" ((USItype)(xl)) \
- : "r" ((USItype)(a)), \
- "r" ((USItype)(b)) \
+ adc %0, %0, %|r1, lsr #16" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
: "r0", "r1", "r2")
#define UMUL_TIME 20
#define UDIV_TIME 100
#endif /* __arm__ */
+/***************************************
+ ************** CLIPPER **************
+ ***************************************/
#if defined (__clipper__) && W_TYPE_SIZE == 32
#define umul_ppmm(w1, w0, u, v) \
({union {UDItype __ll; \
struct {USItype __l, __h;} __i; \
} __xx; \
- __asm__ ("mulwux %2,%0" \
- : "=r" (__xx.__ll) \
- : "%0" ((USItype)(u)), \
- "r" ((USItype)(v))); \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
#define smul_ppmm(w1, w0, u, v) \
- ({union {DItype __ll; \
+ ({union {DItype __ll; \
struct {SItype __l, __h;} __i; \
} __xx; \
- __asm__ ("mulwx %2,%0" \
- : "=r" (__xx.__ll) \
- : "%0" ((SItype)(u)), \
- "r" ((SItype)(v))); \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((SItype)(u)), \
+ "r" ((SItype)(v))); \
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
#define __umulsidi3(u, v) \
({UDItype __w; \
- __asm__ ("mulwux %2,%0" \
- : "=r" (__w) \
- : "%0" ((USItype)(u)), \
- "r" ((USItype)(v))); \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
__w; })
#endif /* __clipper__ */
+
+/***************************************
+ ************** GMICRO ***************
+ ***************************************/
#if defined (__gmicro__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("add.w %5,%1
- addx %3,%0" \
- : "=g" ((USItype)(sh)), \
- "=&g" ((USItype)(sl)) \
- : "%0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "%1" ((USItype)(al)), \
+ addx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("sub.w %5,%1
- subx %3,%0" \
- : "=g" ((USItype)(sh)), \
- "=&g" ((USItype)(sl)) \
- : "0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "1" ((USItype)(al)), \
+ subx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define umul_ppmm(ph, pl, m0, m1) \
- __asm__ ("mulx %3,%0,%1" \
- : "=g" ((USItype)(ph)), \
- "=r" ((USItype)(pl)) \
- : "%0" ((USItype)(m0)), \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%0" ((USItype)(m0)), \
"g" ((USItype)(m1)))
#define udiv_qrnnd(q, r, nh, nl, d) \
- __asm__ ("divx %4,%0,%1" \
- : "=g" ((USItype)(q)), \
- "=r" ((USItype)(r)) \
- : "1" ((USItype)(nh)), \
- "0" ((USItype)(nl)), \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "1" ((USItype)(nh)), \
+ "0" ((USItype)(nl)), \
"g" ((USItype)(d)))
#define count_leading_zeros(count, x) \
- __asm__ ("bsch/1 %1,%0" \
- : "=g" (count) \
- : "g" ((USItype)(x)), \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) \
+ : "g" ((USItype)(x)), \
"0" ((USItype)0))
#endif
+
+/***************************************
+ ************** HPPA *****************
+ ***************************************/
#if defined (__hppa) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("add %4,%5,%1
- addc %2,%3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%rM" ((USItype)(ah)), \
- "rM" ((USItype)(bh)), \
- "%rM" ((USItype)(al)), \
+ addc %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "%rM" ((USItype)(al)), \
"rM" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("sub %4,%5,%1
- subb %2,%3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "rM" ((USItype)(ah)), \
- "rM" ((USItype)(bh)), \
- "rM" ((USItype)(al)), \
+ subb %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "rM" ((USItype)(al)), \
"rM" ((USItype)(bl)))
#if defined (_PA_RISC1_1)
#define umul_ppmm(wh, wl, u, v) \
@@ -305,10 +324,10 @@ extern UDItype __udiv_qrnnd ();
union {UDItype __ll; \
struct {USItype __h, __l;} __i; \
} __xx; \
- __asm__ ("xmpyu %1,%2,%0" \
- : "=*f" (__xx.__ll) \
- : "*f" ((USItype)(u)), \
- "*f" ((USItype)(v))); \
+ __asm__ ("xmpyu %1,%2,%0" \
+ : "=*f" (__xx.__ll) \
+ : "*f" ((USItype)(u)), \
+ "*f" ((USItype)(v))); \
(wh) = __xx.__i.__h; \
(wl) = __xx.__i.__l; \
} while (0)
@@ -321,7 +340,7 @@ extern UDItype __udiv_qrnnd ();
#ifndef LONGLONG_STANDALONE
#define udiv_qrnnd(q, r, n1, n0, d) \
do { USItype __r; \
- (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
(r) = __r; \
} while (0)
extern USItype __udiv_qrnnd ();
@@ -330,25 +349,29 @@ extern USItype __udiv_qrnnd ();
do { \
USItype __tmp; \
__asm__ ( \
- "ldi 1,%0
- extru,= %1,15,16,%%r0 ; Bits 31..16 zero?
+ "ldi 1,%0
+ extru,= %1,15,16,%%r0 ; Bits 31..16 zero?
extru,tr %1,15,16,%1 ; No. Shift down, skip add.
- ldo 16(%0),%0 ; Yes. Perform add.
- extru,= %1,23,8,%%r0 ; Bits 15..8 zero?
+ ldo 16(%0),%0 ; Yes. Perform add.
+ extru,= %1,23,8,%%r0 ; Bits 15..8 zero?
extru,tr %1,23,8,%1 ; No. Shift down, skip add.
- ldo 8(%0),%0 ; Yes. Perform add.
- extru,= %1,27,4,%%r0 ; Bits 7..4 zero?
+ ldo 8(%0),%0 ; Yes. Perform add.
+ extru,= %1,27,4,%%r0 ; Bits 7..4 zero?
extru,tr %1,27,4,%1 ; No. Shift down, skip add.
- ldo 4(%0),%0 ; Yes. Perform add.
- extru,= %1,29,2,%%r0 ; Bits 3..2 zero?
+ ldo 4(%0),%0 ; Yes. Perform add.
+ extru,= %1,29,2,%%r0 ; Bits 3..2 zero?
extru,tr %1,29,2,%1 ; No. Shift down, skip add.
- ldo 2(%0),%0 ; Yes. Perform add.
+ ldo 2(%0),%0 ; Yes. Perform add.
extru %1,30,1,%1 ; Extract bit 1.
sub %0,%1,%0 ; Subtract it.
- " : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ " : "=r" (count), "=r" (__tmp) : "1" (x)); \
} while (0)
#endif /* hppa */
+
+/***************************************
+ ************** I370 *****************
+ ***************************************/
#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
#define umul_ppmm(xh, xl, m0, m1) \
do { \
@@ -356,77 +379,81 @@ extern USItype __udiv_qrnnd ();
struct {USItype __h, __l;} __i; \
} __xx; \
USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mr %0,%3" \
- : "=r" (__xx.__i.__h), \
- "=r" (__xx.__i.__l) \
- : "%1" (__m0), \
- "r" (__m1)); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "r" (__m1)); \
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
(xh) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
+ + (((SItype) __m1 >> 31) & __m0)); \
} while (0)
#define smul_ppmm(xh, xl, m0, m1) \
do { \
- union {DItype __ll; \
+ union {DItype __ll; \
struct {USItype __h, __l;} __i; \
} __xx; \
- __asm__ ("mr %0,%3" \
- : "=r" (__xx.__i.__h), \
- "=r" (__xx.__i.__l) \
- : "%1" (m0), \
- "r" (m1)); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (m0), \
+ "r" (m1)); \
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
} while (0)
#define sdiv_qrnnd(q, r, n1, n0, d) \
do { \
- union {DItype __ll; \
+ union {DItype __ll; \
struct {USItype __h, __l;} __i; \
} __xx; \
__xx.__i.__h = n1; __xx.__i.__l = n0; \
- __asm__ ("dr %0,%2" \
- : "=r" (__xx.__ll) \
- : "0" (__xx.__ll), "r" (d)); \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__xx.__ll) \
+ : "0" (__xx.__ll), "r" (d)); \
(q) = __xx.__i.__l; (r) = __xx.__i.__h; \
} while (0)
#endif
+
+/***************************************
+ ************** I386 *****************
+ ***************************************/
#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl %5,%1
- adcl %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "%1" ((USItype)(al)), \
+ adcl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subl %5,%1
- sbbl %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "1" ((USItype)(al)), \
+ sbbl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("mull %3" \
- : "=a" ((USItype)(w0)), \
- "=d" ((USItype)(w1)) \
- : "%0" ((USItype)(u)), \
+ __asm__ ("mull %3" \
+ : "=a" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
"rm" ((USItype)(v)))
#define udiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("divl %4" \
- : "=a" ((USItype)(q)), \
- "=d" ((USItype)(r)) \
- : "0" ((USItype)(n0)), \
- "1" ((USItype)(n1)), \
+ __asm__ ("divl %4" \
+ : "=a" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
"rm" ((USItype)(d)))
#define count_leading_zeros(count, x) \
do { \
USItype __cbtmp; \
- __asm__ ("bsrl %1,%0" \
- : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
(count) = __cbtmp ^ 31; \
} while (0)
#define count_trailing_zeros(count, x) \
@@ -439,44 +466,51 @@ extern USItype __udiv_qrnnd ();
#endif
#endif /* 80x86 */
+
+/***************************************
+ ************** I860 *****************
+ ***************************************/
#if defined (__i860__) && W_TYPE_SIZE == 32
#define rshift_rhlc(r,h,l,c) \
- __asm__ ("shr %3,r0,r0\;shrd %1,%2,%0" \
+ __asm__ ("shr %3,r0,r0\;shrd %1,%2,%0" \
"=r" (r) : "r" (h), "r" (l), "rn" (c))
#endif /* i860 */
+/***************************************
+ ************** I960 *****************
+ ***************************************/
#if defined (__i960__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("cmpo 1,0\;addc %5,%4,%1\;addc %3,%2,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%dI" ((USItype)(ah)), \
- "dI" ((USItype)(bh)), \
- "%dI" ((USItype)(al)), \
+ __asm__ ("cmpo 1,0\;addc %5,%4,%1\;addc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "%dI" ((USItype)(al)), \
"dI" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("cmpo 0,0\;subc %5,%4,%1\;subc %3,%2,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "dI" ((USItype)(ah)), \
- "dI" ((USItype)(bh)), \
- "dI" ((USItype)(al)), \
+ __asm__ ("cmpo 0,0\;subc %5,%4,%1\;subc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "dI" ((USItype)(al)), \
"dI" ((USItype)(bl)))
#define umul_ppmm(w1, w0, u, v) \
({union {UDItype __ll; \
struct {USItype __l, __h;} __i; \
} __xx; \
- __asm__ ("emul %2,%1,%0" \
- : "=d" (__xx.__ll) \
- : "%dI" ((USItype)(u)), \
- "dI" ((USItype)(v))); \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__xx.__ll) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
#define __umulsidi3(u, v) \
({UDItype __w; \
- __asm__ ("emul %2,%1,%0" \
- : "=d" (__w) \
- : "%dI" ((USItype)(u)), \
- "dI" ((USItype)(v))); \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__w) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
__w; })
#define udiv_qrnnd(q, r, nh, nl, d) \
do { \
@@ -484,18 +518,18 @@ extern USItype __udiv_qrnnd ();
struct {USItype __l, __h;} __i; \
} __nn; \
__nn.__i.__h = (nh); __nn.__i.__l = (nl); \
- __asm__ ("ediv %d,%n,%0" \
- : "=d" (__rq.__ll) \
- : "dI" (__nn.__ll), \
- "dI" ((USItype)(d))); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) \
+ : "dI" (__nn.__ll), \
+ "dI" ((USItype)(d))); \
(r) = __rq.__i.__l; (q) = __rq.__i.__h; \
} while (0)
#define count_leading_zeros(count, x) \
do { \
USItype __cbtmp; \
- __asm__ ("scanbit %1,%0" \
- : "=r" (__cbtmp) \
- : "r" ((USItype)(x))); \
+ __asm__ ("scanbit %1,%0" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
(count) = __cbtmp ^ 31; \
} while (0)
#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
@@ -506,66 +540,70 @@ extern USItype __udiv_qrnnd ();
struct {USItype __l, __h;} __i; \
} __nn; \
__nn.__i.__h = (h); __nn.__i.__l = (l); \
- __asm__ ("shre %2,%1,%0" \
- : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ __asm__ ("shre %2,%1,%0" \
+ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
}
#endif /* i960mx */
#endif /* i960 */
+
+/***************************************
+ ************** 68000 ****************
+ ***************************************/
#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("add%.l %5,%1
- addx%.l %3,%0" \
- : "=d" ((USItype)(sh)), \
- "=&d" ((USItype)(sl)) \
- : "%0" ((USItype)(ah)), \
- "d" ((USItype)(bh)), \
- "%1" ((USItype)(al)), \
+ addx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("sub%.l %5,%1
- subx%.l %3,%0" \
- : "=d" ((USItype)(sh)), \
- "=&d" ((USItype)(sl)) \
- : "0" ((USItype)(ah)), \
- "d" ((USItype)(bh)), \
- "1" ((USItype)(al)), \
+ subx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("mulu%.l %3,%1:%0" \
- : "=d" ((USItype)(w0)), \
- "=d" ((USItype)(w1)) \
- : "%0" ((USItype)(u)), \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
"dmi" ((USItype)(v)))
#define UMUL_TIME 45
#define udiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("divu%.l %4,%1:%0" \
- : "=d" ((USItype)(q)), \
- "=d" ((USItype)(r)) \
- : "0" ((USItype)(n0)), \
- "1" ((USItype)(n1)), \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
"dmi" ((USItype)(d)))
#define UDIV_TIME 90
#define sdiv_qrnnd(q, r, n1, n0, d) \
- __asm__ ("divs%.l %4,%1:%0" \
- : "=d" ((USItype)(q)), \
- "=d" ((USItype)(r)) \
- : "0" ((USItype)(n0)), \
- "1" ((USItype)(n1)), \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
"dmi" ((USItype)(d)))
#define count_leading_zeros(count, x) \
- __asm__ ("bfffo %1{%b2:%b2},%0" \
- : "=d" ((USItype)(count)) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" ((USItype)(count)) \
: "od" ((USItype)(x)), "n" (0))
#define COUNT_LEADING_ZEROS_0 32
#else /* not mc68020 */
#define umul_ppmm(xh, xl, a, b) \
do { USItype __umul_tmp1, __umul_tmp2; \
__asm__ ("| Inlined umul_ppmm
- move%.l %5,%3
- move%.l %2,%0
- move%.w %3,%1
+ move%.l %5,%3
+ move%.l %2,%0
+ move%.w %3,%1
swap %3
swap %0
mulu %2,%1
@@ -576,48 +614,52 @@ extern USItype __udiv_qrnnd ();
add%.l %3,%2
jcc 1f
add%.l %#0x10000,%0
-1: move%.l %2,%3
+1: move%.l %2,%3
clr%.w %2
swap %2
swap %3
clr%.w %3
add%.l %3,%1
- addx%.l %2,%0
- | End inlined umul_ppmm" \
- : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
- "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
- : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ addx%.l %2,%0
+ | End inlined umul_ppmm" \
+ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
} while (0)
#define UMUL_TIME 100
#define UDIV_TIME 400
#endif /* not mc68020 */
#endif /* mc68000 */
+
+/***************************************
+ ************** 88000 ****************
+ ***************************************/
#if defined (__m88000__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addu.co %1,%r4,%r5
- addu.ci %0,%r2,%r3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%rJ" ((USItype)(ah)), \
- "rJ" ((USItype)(bh)), \
- "%rJ" ((USItype)(al)), \
+ addu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
"rJ" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subu.co %1,%r4,%r5
- subu.ci %0,%r2,%r3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "rJ" ((USItype)(ah)), \
- "rJ" ((USItype)(bh)), \
- "rJ" ((USItype)(al)), \
+ subu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
"rJ" ((USItype)(bl)))
#define count_leading_zeros(count, x) \
do { \
USItype __cbtmp; \
- __asm__ ("ff1 %0,%1" \
- : "=r" (__cbtmp) \
- : "r" ((USItype)(x))); \
+ __asm__ ("ff1 %0,%1" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
(count) = __cbtmp ^ 31; \
} while (0)
#define COUNT_LEADING_ZEROS_0 63 /* sic */
@@ -627,17 +669,17 @@ extern USItype __udiv_qrnnd ();
union {UDItype __ll; \
struct {USItype __h, __l;} __i; \
} __x; \
- __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
- (wh) = __x.__i.__h; \
- (wl) = __x.__i.__l; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
} while (0)
#define udiv_qrnnd(q, r, n1, n0, d) \
({union {UDItype __ll; \
struct {USItype __h, __l;} __i; \
} __x, __q; \
__x.__i.__h = (n1); __x.__i.__l = (n0); \
- __asm__ ("divu.d %0,%1,%2" \
- : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
(r) = (n0) - __q.__l * (d); (q) = __q.__l; })
#define UMUL_TIME 5
#define UDIV_TIME 25
@@ -647,175 +689,190 @@ extern USItype __udiv_qrnnd ();
#endif /* __m88110__ */
#endif /* __m88000__ */
+
+/***************************************
+ ************** MIPS *****************
+ ***************************************/
#if defined (__mips__) && W_TYPE_SIZE == 32
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("multu %2,%3" \
- : "=l" ((USItype)(w0)), \
- "=h" ((USItype)(w1)) \
- : "d" ((USItype)(u)), \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
"d" ((USItype)(v)))
#else
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("multu %2,%3
mflo %0
- mfhi %1" \
- : "=d" ((USItype)(w0)), \
- "=d" ((USItype)(w1)) \
- : "d" ((USItype)(u)), \
+ mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
"d" ((USItype)(v)))
#endif
#define UMUL_TIME 10
#define UDIV_TIME 100
#endif /* __mips__ */
+/***************************************
+ ************** MIPS/64 **************
+ ***************************************/
#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
#if __GNUC__ > 2 || __GNUC_MINOR__ >= 7
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("dmultu %2,%3" \
- : "=l" ((UDItype)(w0)), \
- "=h" ((UDItype)(w1)) \
- : "d" ((UDItype)(u)), \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
"d" ((UDItype)(v)))
#else
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("dmultu %2,%3
mflo %0
- mfhi %1" \
- : "=d" ((UDItype)(w0)), \
- "=d" ((UDItype)(w1)) \
- : "d" ((UDItype)(u)), \
+ mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
"d" ((UDItype)(v)))
#endif
#define UMUL_TIME 20
#define UDIV_TIME 140
#endif /* __mips__ */
+
+/***************************************
+ ************** 32000 ****************
+ ***************************************/
#if defined (__ns32000__) && W_TYPE_SIZE == 32
#define umul_ppmm(w1, w0, u, v) \
({union {UDItype __ll; \
struct {USItype __l, __h;} __i; \
} __xx; \
- __asm__ ("meid %2,%0" \
- : "=g" (__xx.__ll) \
- : "%0" ((USItype)(u)), \
- "g" ((USItype)(v))); \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
#define __umulsidi3(u, v) \
({UDItype __w; \
- __asm__ ("meid %2,%0" \
- : "=g" (__w) \
- : "%0" ((USItype)(u)), \
- "g" ((USItype)(v))); \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
__w; })
#define udiv_qrnnd(q, r, n1, n0, d) \
({union {UDItype __ll; \
struct {USItype __l, __h;} __i; \
} __xx; \
__xx.__i.__h = (n1); __xx.__i.__l = (n0); \
- __asm__ ("deid %2,%0" \
- : "=g" (__xx.__ll) \
- : "0" (__xx.__ll), \
- "g" ((USItype)(d))); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "0" (__xx.__ll), \
+ "g" ((USItype)(d))); \
(r) = __xx.__i.__l; (q) = __xx.__i.__h; })
#define count_trailing_zeros(count,x) \
do {
- __asm__ ("ffsd %2,%0" \
- : "=r" ((USItype) (count)) \
- : "0" ((USItype) 0), \
- "r" ((USItype) (x))); \
+ __asm__ ("ffsd %2,%0" \
+ : "=r" ((USItype) (count)) \
+ : "0" ((USItype) 0), \
+ "r" ((USItype) (x))); \
} while (0)
#endif /* __ns32000__ */
+
+/***************************************
+ ************** PPC ******************
+ ***************************************/
#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
do { \
- if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%r" ((USItype)(ah)), \
- "%r" ((USItype)(al)), \
- "rI" ((USItype)(bl))); \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
- __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%r" ((USItype)(ah)), \
- "%r" ((USItype)(al)), \
- "rI" ((USItype)(bl))); \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
else \
- __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%r" ((USItype)(ah)), \
- "r" ((USItype)(bh)), \
- "%r" ((USItype)(al)), \
- "rI" ((USItype)(bl))); \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
} while (0)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
- if (__builtin_constant_p (ah) && (ah) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(bh)), \
- "rI" ((USItype)(al)), \
- "r" ((USItype)(bl))); \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(bh)), \
- "rI" ((USItype)(al)), \
- "r" ((USItype)(bl))); \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(ah)), \
- "rI" ((USItype)(al)), \
- "r" ((USItype)(bl))); \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
- __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(ah)), \
- "rI" ((USItype)(al)), \
- "r" ((USItype)(bl))); \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
else \
- __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "r" ((USItype)(ah)), \
- "r" ((USItype)(bh)), \
- "rI" ((USItype)(al)), \
- "r" ((USItype)(bl))); \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
} while (0)
#define count_leading_zeros(count, x) \
- __asm__ ("{cntlz|cntlzw} %0,%1" \
- : "=r" ((USItype)(count)) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" \
+ : "=r" ((USItype)(count)) \
: "r" ((USItype)(x)))
#define COUNT_LEADING_ZEROS_0 32
#if defined (_ARCH_PPC)
#define umul_ppmm(ph, pl, m0, m1) \
do { \
USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhwu %0,%1,%2" \
- : "=r" ((USItype) ph) \
- : "%r" (__m0), \
- "r" (__m1)); \
- (pl) = __m0 * __m1; \
+ __asm__ ("mulhwu %0,%1,%2" \
+ : "=r" ((USItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
} while (0)
#define UMUL_TIME 15
#define smul_ppmm(ph, pl, m0, m1) \
do { \
SItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mulhw %0,%1,%2" \
- : "=r" ((SItype) ph) \
- : "%r" (__m0), \
- "r" (__m1)); \
- (pl) = __m0 * __m1; \
+ __asm__ ("mulhw %0,%1,%2" \
+ : "=r" ((SItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
} while (0)
#define SMUL_TIME 14
#define UDIV_TIME 120
@@ -823,48 +880,52 @@ extern USItype __udiv_qrnnd ();
#define umul_ppmm(xh, xl, m0, m1) \
do { \
USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("mul %0,%2,%3" \
- : "=r" ((USItype)(xh)), \
- "=q" ((USItype)(xl)) \
- : "r" (__m0), \
- "r" (__m1)); \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((USItype)(xh)), \
+ "=q" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
(xh) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
+ + (((SItype) __m1 >> 31) & __m0)); \
} while (0)
#define UMUL_TIME 8
#define smul_ppmm(xh, xl, m0, m1) \
- __asm__ ("mul %0,%2,%3" \
- : "=r" ((SItype)(xh)), \
- "=q" ((SItype)(xl)) \
- : "r" (m0), \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((SItype)(xh)), \
+ "=q" ((SItype)(xl)) \
+ : "r" (m0), \
"r" (m1))
#define SMUL_TIME 4
#define sdiv_qrnnd(q, r, nh, nl, d) \
- __asm__ ("div %0,%2,%4" \
- : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
+ __asm__ ("div %0,%2,%4" \
+ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
: "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
#define UDIV_TIME 100
#endif
-#endif /* Power architecture variants. */
+#endif /* Power architecture variants. */
+
+/***************************************
+ ************** PYR ******************
+ ***************************************/
#if defined (__pyr__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("addw %5,%1
- addwc %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "%1" ((USItype)(al)), \
+ __asm__ ("addw %5,%1
+ addwc %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("subw %5,%1
- subwb %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "1" ((USItype)(al)), \
+ __asm__ ("subw %5,%1
+ subwb %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
"g" ((USItype)(bl)))
/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
#define umul_ppmm(w1, w0, u, v) \
@@ -872,37 +933,41 @@ extern USItype __udiv_qrnnd ();
struct {USItype __h, __l;} __i; \
} __xx; \
__asm__ ("movw %1,%R0
- uemul %2,%0" \
- : "=&r" (__xx.__ll) \
- : "g" ((USItype) (u)), \
- "g" ((USItype)(v))); \
+ uemul %2,%0" \
+ : "=&r" (__xx.__ll) \
+ : "g" ((USItype) (u)), \
+ "g" ((USItype)(v))); \
(w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
#endif /* __pyr__ */
-#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+
+/***************************************
+ ************** RT/ROMP **************
+ ***************************************/
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("a %1,%5
- ae %0,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%0" ((USItype)(ah)), \
- "r" ((USItype)(bh)), \
- "%1" ((USItype)(al)), \
+ ae %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
"r" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("s %1,%5
- se %0,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "0" ((USItype)(ah)), \
- "r" ((USItype)(bh)), \
- "1" ((USItype)(al)), \
+ se %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
"r" ((USItype)(bl)))
#define umul_ppmm(ph, pl, m0, m1) \
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ( \
- "s r2,r2
+ "s r2,r2
mts r10,%2
m r2,%3
m r2,%3
@@ -921,67 +986,74 @@ extern USItype __udiv_qrnnd ();
m r2,%3
m r2,%3
cas %0,r2,r0
- mfs r10,%1" \
- : "=r" ((USItype)(ph)), \
- "=r" ((USItype)(pl)) \
- : "%r" (__m0), \
- "r" (__m1) \
- : "r2"); \
+ mfs r10,%1" \
+ : "=r" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%r" (__m0), \
+ "r" (__m1) \
+ : "r2"); \
(ph) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
+ + (((SItype) __m1 >> 31) & __m0)); \
} while (0)
#define UMUL_TIME 20
#define UDIV_TIME 200
#define count_leading_zeros(count, x) \
do { \
- if ((x) >= 0x10000) \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype)(count)) \
- : "r" ((USItype)(x) >> 16)); \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x) >> 16)); \
else \
- { \
- __asm__ ("clz %0,%1" \
- : "=r" ((USItype)(count)) \
- : "r" ((USItype)(x))); \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x))); \
(count) += 16; \
- } \
+ } \
} while (0)
#endif /* RT/ROMP */
+
+/***************************************
+ ************** SH2 ******************
+ ***************************************/
#if defined (__sh2__) && W_TYPE_SIZE == 32
#define umul_ppmm(w1, w0, u, v) \
__asm__ ( \
- "dmulu.l %2,%3
+ "dmulu.l %2,%3
sts macl,%1
- sts mach,%0" \
- : "=r" ((USItype)(w1)), \
- "=r" ((USItype)(w0)) \
- : "r" ((USItype)(u)), \
- "r" ((USItype)(v)) \
+ sts mach,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
: "macl", "mach")
#define UMUL_TIME 5
#endif
+/***************************************
+ ************** SPARC ****************
+ ***************************************/
#if defined (__sparc__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addcc %r4,%5,%1
- addx %r2,%3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "%rJ" ((USItype)(ah)), \
- "rI" ((USItype)(bh)), \
- "%rJ" ((USItype)(al)), \
- "rI" ((USItype)(bl)) \
+ addx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
__CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subcc %r4,%5,%1
- subx %r2,%3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
- : "rJ" ((USItype)(ah)), \
- "rI" ((USItype)(bh)), \
- "rJ" ((USItype)(al)), \
- "rI" ((USItype)(bl)) \
+ subx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
__CLOBBER_CC)
#if defined (__sparc_v8__)
/* Don't match immediate range because, 1) it is not often useful,
@@ -989,21 +1061,21 @@ extern USItype __udiv_qrnnd ();
while we want to match a 13 bit interval, sign extended to 32 bits,
but INTERPRETED AS UNSIGNED. */
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("umul %2,%3,%1;rd %%y,%0" \
- : "=r" ((USItype)(w1)), \
- "=r" ((USItype)(w0)) \
- : "r" ((USItype)(u)), \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
"r" ((USItype)(v)))
#define UMUL_TIME 5
#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */
#define udiv_qrnnd(q, r, n1, n0, d) \
do { \
USItype __q; \
- __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
- : "=r" ((USItype)(__q)) \
- : "r" ((USItype)(n1)), \
- "r" ((USItype)(n0)), \
- "r" ((USItype)(d))); \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" ((USItype)(__q)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d))); \
(r) = (n0) - __q * (d); \
(q) = __q; \
} while (0)
@@ -1014,10 +1086,10 @@ extern USItype __udiv_qrnnd ();
/* This has hardware multiply but not divide. It also has two additional
instructions scan (ffs from high bit) and divscc. */
#define umul_ppmm(w1, w0, u, v) \
- __asm__ ("umul %2,%3,%1;rd %%y,%0" \
- : "=r" ((USItype)(w1)), \
- "=r" ((USItype)(w0)) \
- : "r" ((USItype)(u)), \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
"r" ((USItype)(v)))
#define UMUL_TIME 5
#define udiv_qrnnd(q, r, n1, n0, d) \
@@ -1059,17 +1131,17 @@ extern USItype __udiv_qrnnd ();
rd %%y,%1
bl,a 1f
add %1,%4,%1
-1: ! End of inline udiv_qrnnd" \
- : "=r" ((USItype)(q)), \
- "=r" ((USItype)(r)) \
- : "r" ((USItype)(n1)), \
- "r" ((USItype)(n0)), \
- "rI" ((USItype)(d)) \
+1: ! End of inline udiv_qrnnd" \
+ : "=r" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "rI" ((USItype)(d)) \
: "%g1" __AND_CLOBBER_CC)
#define UDIV_TIME 37
#define count_leading_zeros(count, x) \
- __asm__ ("scan %1,0,%0" \
- : "=r" ((USItype)(x)) \
+ __asm__ ("scan %1,0,%0" \
+ : "=r" ((USItype)(x)) \
: "r" ((USItype)(count)))
/* Early sparclites return 63 for an argument of 0, but they warn that future
implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
@@ -1118,11 +1190,11 @@ extern USItype __udiv_qrnnd ();
mulscc %%g1,%3,%%g1
mulscc %%g1,0,%%g1
add %%g1,%%g2,%0
- rd %%y,%1" \
- : "=r" ((USItype)(w1)), \
- "=r" ((USItype)(w0)) \
- : "%rI" ((USItype)(u)), \
- "r" ((USItype)(v)) \
+ rd %%y,%1" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
: "%g1", "%g2" __AND_CLOBBER_CC)
#define UMUL_TIME 39 /* 39 instructions */
#endif
@@ -1130,7 +1202,7 @@ extern USItype __udiv_qrnnd ();
#ifndef LONGLONG_STANDALONE
#define udiv_qrnnd(q, r, n1, n0, d) \
do { USItype __r; \
- (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
(r) = __r; \
} while (0)
extern USItype __udiv_qrnnd ();
@@ -1139,24 +1211,28 @@ extern USItype __udiv_qrnnd ();
#endif /* udiv_qrnnd */
#endif /* __sparc__ */
+
+/***************************************
+ ************** VAX ******************
+ ***************************************/
#if defined (__vax__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl2 %5,%1
- adwc %3,%0" \
- : "=g" ((USItype)(sh)), \
- "=&g" ((USItype)(sl)) \
- : "%0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "%1" ((USItype)(al)), \
+ adwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subl2 %5,%1
- sbwc %3,%0" \
- : "=g" ((USItype)(sh)), \
- "=&g" ((USItype)(sl)) \
- : "0" ((USItype)(ah)), \
- "g" ((USItype)(bh)), \
- "1" ((USItype)(al)), \
+ sbwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
"g" ((USItype)(bl)))
#define umul_ppmm(xh, xl, m0, m1) \
do { \
@@ -1164,56 +1240,60 @@ extern USItype __udiv_qrnnd ();
struct {USItype __l, __h;} __i; \
} __xx; \
USItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("emul %1,%2,$0,%0" \
- : "=g" (__xx.__ll) \
- : "g" (__m0), \
- "g" (__m1)); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__xx.__ll) \
+ : "g" (__m0), \
+ "g" (__m1)); \
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
(xh) += ((((SItype) __m0 >> 31) & __m1) \
- + (((SItype) __m1 >> 31) & __m0)); \
+ + (((SItype) __m1 >> 31) & __m0)); \
} while (0)
#define sdiv_qrnnd(q, r, n1, n0, d) \
do { \
- union {DItype __ll; \
+ union {DItype __ll; \
struct {SItype __l, __h;} __i; \
} __xx; \
__xx.__i.__h = n1; __xx.__i.__l = n0; \
- __asm__ ("ediv %3,%2,%0,%1" \
- : "=g" (q), "=g" (r) \
- : "g" (__xx.__ll), "g" (d)); \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) \
+ : "g" (__xx.__ll), "g" (d)); \
} while (0)
#endif /* __vax__ */
+
+/***************************************
+ ************** Z8000 ****************
+ ***************************************/
#if defined (__z8000__) && W_TYPE_SIZE == 16
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
- __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
- : "=r" ((unsigned int)(sh)), \
- "=&r" ((unsigned int)(sl)) \
- : "%0" ((unsigned int)(ah)), \
- "r" ((unsigned int)(bh)), \
- "%1" ((unsigned int)(al)), \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "%0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), \
"rQR" ((unsigned int)(bl)))
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
- __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
- : "=r" ((unsigned int)(sh)), \
- "=&r" ((unsigned int)(sl)) \
- : "0" ((unsigned int)(ah)), \
- "r" ((unsigned int)(bh)), \
- "1" ((unsigned int)(al)), \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), \
"rQR" ((unsigned int)(bl)))
#define umul_ppmm(xh, xl, m0, m1) \
do { \
union {long int __ll; \
- struct {unsigned int __h, __l;} __i; \
+ struct {unsigned int __h, __l;} __i; \
} __xx; \
unsigned int __m0 = (m0), __m1 = (m1); \
- __asm__ ("mult %S0,%H3" \
- : "=r" (__xx.__i.__h), \
- "=r" (__xx.__i.__l) \
- : "%1" (__m0), \
- "rQR" (__m1)); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "rQR" (__m1)); \
(xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
- (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ (((signed int) __m1 >> 15) & __m0)); \
} while (0)
#endif /* __z8000__ */
@@ -1221,12 +1301,15 @@ extern USItype __udiv_qrnnd ();
#endif /* __GNUC__ */
+/***************************************
+ *********** Generic Versions ********
+ ***************************************/
#if !defined (umul_ppmm) && defined (__umulsidi3)
#define umul_ppmm(ph, pl, m0, m1) \
{ \
UDWtype __ll = __umulsidi3 (m0, m1); \
ph = (UWtype) (__ll >> W_TYPE_SIZE); \
- pl = (UWtype) __ll; \
+ pl = (UWtype) __ll; \
}
#endif
@@ -1242,57 +1325,57 @@ extern USItype __udiv_qrnnd ();
#if !defined (add_ssaaaa)
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
do { \
- UWtype __x; \
+ UWtype __x; \
__x = (al) + (bl); \
(sh) = (ah) + (bh) + (__x < (al)); \
- (sl) = __x; \
+ (sl) = __x; \
} while (0)
#endif
#if !defined (sub_ddmmss)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
do { \
- UWtype __x; \
+ UWtype __x; \
__x = (al) - (bl); \
(sh) = (ah) - (bh) - (__x > (al)); \
- (sl) = __x; \
+ (sl) = __x; \
} while (0)
#endif
#if !defined (umul_ppmm)
-#define umul_ppmm(w1, w0, u, v) \
+#define umul_ppmm(w1, w0, u, v) \
do { \
UWtype __x0, __x1, __x2, __x3; \
UHWtype __ul, __vl, __uh, __vh; \
UWtype __u = (u), __v = (v); \
\
__ul = __ll_lowpart (__u); \
- __uh = __ll_highpart (__u); \
+ __uh = __ll_highpart (__u); \
__vl = __ll_lowpart (__v); \
- __vh = __ll_highpart (__v); \
+ __vh = __ll_highpart (__v); \
\
__x0 = (UWtype) __ul * __vl; \
__x1 = (UWtype) __ul * __vh; \
__x2 = (UWtype) __uh * __vl; \
__x3 = (UWtype) __uh * __vh; \
\
- __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
__x1 += __x2; /* but this indeed can */ \
if (__x1 < __x2) /* did we get it? */ \
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
\
- (w1) = __x3 + __ll_highpart (__x1); \
+ (w1) = __x3 + __ll_highpart (__x1); \
(w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
} while (0)
#endif
#if !defined (umul_ppmm)
-#define smul_ppmm(w1, w0, u, v) \
+#define smul_ppmm(w1, w0, u, v) \
do { \
UWtype __w1; \
UWtype __m0 = (u), __m1 = (v); \
umul_ppmm (__w1, w0, __m0, __m1); \
- (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
+ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
- (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
} while (0)
#endif
@@ -1304,34 +1387,34 @@ extern USItype __udiv_qrnnd ();
__d1 = __ll_highpart (d); \
__d0 = __ll_lowpart (d); \
\
- __r1 = (n1) % __d1; \
- __q1 = (n1) / __d1; \
- __m = (UWtype) __q1 * __d0; \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
__r1 = __r1 * __ll_B | __ll_highpart (n0); \
if (__r1 < __m) \
- { \
+ { \
__q1--, __r1 += (d); \
if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
if (__r1 < __m) \
__q1--, __r1 += (d); \
- } \
+ } \
__r1 -= __m; \
\
- __r0 = __r1 % __d1; \
- __q0 = __r1 / __d1; \
- __m = (UWtype) __q0 * __d0; \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
__r0 = __r0 * __ll_B | __ll_lowpart (n0); \
if (__r0 < __m) \
- { \
+ { \
__q0--, __r0 += (d); \
if (__r0 >= (d)) \
if (__r0 < __m) \
__q0--, __r0 += (d); \
- } \
+ } \
__r0 -= __m; \
\
(q) = (UWtype) __q1 * __ll_B | __q0; \
- (r) = __r0; \
+ (r) = __r0; \
} while (0)
/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
@@ -1339,8 +1422,8 @@ extern USItype __udiv_qrnnd ();
#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
#define udiv_qrnnd(q, r, nh, nl, d) \
do { \
- UWtype __r; \
- (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
(r) = __r; \
} while (0)
#endif
@@ -1360,20 +1443,20 @@ unsigned char __clz_tab[];
#define count_leading_zeros(count, x) \
do { \
UWtype __xr = (x); \
- UWtype __a; \
+ UWtype __a; \
\
if (W_TYPE_SIZE <= 32) \
- { \
+ { \
__a = __xr < ((UWtype) 1 << 2*__BITS4) \
? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
: (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
- } \
+ } \
else \
- { \
+ { \
for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
if (((__xr >> __a) & 0xff) != 0) \
break; \
- } \
+ } \
\
(count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
} while (0)
diff --git a/mpi/mpi-bit.c b/mpi/mpi-bit.c
index 9bde9f0fb..1eb63a02d 100644
--- a/mpi/mpi-bit.c
+++ b/mpi/mpi-bit.c
@@ -23,16 +23,29 @@
#include <stdlib.h>
#include <assert.h>
#include "mpi-internal.h"
+#include "longlong.h"
/****************
* Return the number of bits in A.
- * fixme: we should not count leading zero bits
*/
unsigned
mpi_get_nbits( MPI a )
{
- return a->nlimbs * BITS_PER_MPI_LIMB;
+ unsigned nbits;
+ unsigned n, count = 0;
+
+ if( a->nlimbs ) {
+ mpi_limb_t alimb = a->d[a->nlimbs-1];
+ if( alimb )
+ count_leading_zeros( n, alimb );
+ else
+ n = BITS_PER_MPI_LIMB;
+ n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
+ }
+ else
+ n = 0;
+ return n;
}
@@ -75,6 +88,28 @@ mpi_set_bit( MPI a, unsigned n )
}
/****************
+ * Set bit N of A. and clear all bits above
+ */
+void
+mpi_set_highbit( MPI a, unsigned n )
+{
+ unsigned limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs ) { /* resize */
+ if( a->alloced >= limbno )
+ mpi_resize(a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (1<<bitno);
+ for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
* Clear bit N of A.
*/
void
@@ -109,7 +144,7 @@ mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque )
a->nlimbs = nlimbs2;
for(n=0; n < nlimbs; n++ ) {
p = (byte*)(a->d+n);
- #ifdef HAVE_LITTLE_ENDIAN
+ #ifdef LITTLE_ENDIAN_HOST
for(i=0; i < BYTES_PER_MPI_LIMB; i++ )
p[i] = fnc(opaque);
#else
@@ -119,7 +154,18 @@ mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque )
}
if( xbytes ) {
p = (byte*)(a->d+n);
- #ifdef HAVE_LITTLE_ENDIAN
+ #ifdef LITTLE_ENDIAN_HOST
+ for(i=0; i < xbytes; i++ )
+ p[i] = fnc(opaque);
+ #else
+ for(i=xbytes-1; i>=0; i-- )
+ p[i] = fnc(opaque);
+ #endif
+ }
+ #if 0 /* fixme: set complete random byte and clear out the unwanted ones*/
+ if( xbits ) {
+ p = (byte*)(a->d+n);
+ #ifdef LITTLE_ENDIAN_HOST
for(i=0; i < xbytes; i++ )
p[i] = fnc(opaque);
#else
@@ -127,7 +173,7 @@ mpi_set_bytes( MPI a, unsigned nbits, byte (*fnc)(int), int opaque )
p[i] = fnc(opaque);
#endif
}
- assert(!xbits);
+ #endif
}
/****************
diff --git a/util/iobuf.c b/util/iobuf.c
index 1c35db6a8..b4b9c195e 100644
--- a/util/iobuf.c
+++ b/util/iobuf.c
@@ -400,6 +400,32 @@ iobuf_append( const char *fname )
return a;
}
+IOBUF
+iobuf_openrw( const char *fname )
+{
+ IOBUF a;
+ FILE *fp;
+ file_filter_ctx_t *fcx;
+ size_t len;
+
+ if( !fname )
+ return NULL;
+ else if( !(fp = fopen(fname, "r+b")) )
+ return NULL;
+ a = iobuf_alloc(2, 8192 );
+ fcx = m_alloc( sizeof *fcx + strlen(fname) );
+ fcx->fp = fp;
+ strcpy(fcx->fname, fname );
+ a->filter = file_filter;
+ a->filter_ov = fcx;
+ file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
+ file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
+ if( DBG_IOBUF )
+ log_debug("iobuf-%d.%d: openrw '%s'\n", a->no, a->subno, a->desc );
+
+ return a;
+}
+
/****************
* Register an i/o filter.
*/
@@ -754,7 +780,7 @@ iobuf_seek( IOBUF a, ulong newpos )
log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
return -1;
}
-
+ a->ntotal = newpos;
/* FIXME: flush all buffers (and remove filters?)*/
return 0;