diff options
-rw-r--r-- | acconfig.h | 15 | ||||
-rw-r--r-- | cipher/dsa.c | 4 | ||||
-rw-r--r-- | cipher/elgamal.c | 22 | ||||
-rw-r--r-- | cipher/gost.c | 4 | ||||
-rw-r--r-- | cipher/primegen.c | 319 | ||||
-rw-r--r-- | cipher/rmd160.c | 2 | ||||
-rw-r--r-- | cipher/sha1.c | 4 | ||||
-rw-r--r-- | config.h.in | 22 | ||||
-rw-r--r-- | configure.in | 10 | ||||
-rw-r--r-- | g10/g10.c | 57 | ||||
-rw-r--r-- | g10/kbnode.c | 9 | ||||
-rw-r--r-- | g10/keydb.h | 2 | ||||
-rw-r--r-- | g10/keygen.c | 9 | ||||
-rw-r--r-- | g10/ringedit.c | 75 | ||||
-rw-r--r-- | g10/sig-check.c | 15 | ||||
-rw-r--r-- | include/cipher.h | 1 | ||||
-rw-r--r-- | include/iobuf.h | 1 | ||||
-rw-r--r-- | include/mpi.h | 1 | ||||
-rw-r--r-- | include/types.h | 61 | ||||
-rw-r--r-- | mpi/longlong.h | 1123 | ||||
-rw-r--r-- | mpi/mpi-bit.c | 56 | ||||
-rw-r--r-- | util/iobuf.c | 28 |
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) @@ -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; |