diff options
Diffstat (limited to 'src/compression/widemuldiv.c')
-rw-r--r-- | src/compression/widemuldiv.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/compression/widemuldiv.c b/src/compression/widemuldiv.c index 7d03c57..63056f9 100644 --- a/src/compression/widemuldiv.c +++ b/src/compression/widemuldiv.c @@ -1,7 +1,7 @@ /* This code is part of the tng compression routines. * - * Written by Daniel Spangberg - * Copyright (c) 2010, 2013, The GROMACS development team. + * Written by Daniel Spangberg and Magnus Lundborg + * Copyright (c) 2010, 2013-2014 The GROMACS development team. * * * This program is free software; you can redistribute it and/or @@ -11,6 +11,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "../../include/compression/tng_compress.h" @@ -31,8 +32,14 @@ #endif /* gcc & x86_64 */ #endif /* TRAJNG X86 GCC INLINE MULDIV */ +#ifdef USE_WINDOWS +#define TNG_INLINE __inline +#else +#define TNG_INLINE inline +#endif + /* Multiply two 32 bit unsigned integers returning a 64 bit unsigned value (in two integers) */ -void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned int *olo) +TNG_INLINE void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned int *olo) { #if defined(TRAJNG_X86_GCC_INLINE_MULDIV) __asm__ __volatile__ ("mull %%edx\n\t" @@ -99,7 +106,7 @@ void Ptngc_widemul(unsigned int i1, unsigned int i2, unsigned int *ohi, unsigned /* Divide a 64 bit unsigned value in hi:lo with the 32 bit value i and return the result in result and the remainder in remainder */ -void Ptngc_widediv(unsigned int hi, unsigned int lo, unsigned int i, unsigned int *result, unsigned int *remainder) +TNG_INLINE void Ptngc_widediv(unsigned int hi, unsigned int lo, unsigned int i, unsigned int *result, unsigned int *remainder) { #if defined(TRAJNG_X86_GCC_INLINE_MULDIV) __asm__ __volatile__ ("divl %%ecx\n\t" @@ -163,7 +170,7 @@ void Ptngc_widediv(unsigned int hi, unsigned int lo, unsigned int i, unsigned in /* Add a unsigned int to a largeint. j determines which value in the largeint to add v1 to. */ -static void largeint_add_gen(unsigned int v1, unsigned int *largeint, int n, int j) +TNG_INLINE static void largeint_add_gen(const unsigned int v1, unsigned int *largeint, const int n, int j) { /* Add with carry. unsigned ints in C wrap modulo 2**bits when "overflowed". */ unsigned int v2=(v1+largeint[j])&0xFFFFFFFFU; /* Add and cap at 32 bits */ @@ -184,46 +191,50 @@ static void largeint_add_gen(unsigned int v1, unsigned int *largeint, int n, int } /* Add a unsigned int to a largeint. */ -void Ptngc_largeint_add(unsigned int v1, unsigned int *largeint, int n) +void Ptngc_largeint_add(const unsigned int v1, unsigned int *largeint, const int n) { largeint_add_gen(v1,largeint,n,0); } /* Multiply v1 with largeint_in and return result in largeint_out */ -void Ptngc_largeint_mul(unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, int n) +TNG_INLINE void Ptngc_largeint_mul(const unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, const int n) { int i; - for (i=0; i<n; i++) - largeint_out[i]=0U; - for (i=0; i<n; i++) + unsigned int lo,hi; + + memset(largeint_out, 0U, sizeof(unsigned int) * n); + + for (i=0; i<n-1; i++) { if (largeint_in[i]!=0U) { - unsigned int lo,hi; Ptngc_widemul(v1,largeint_in[i],&hi,&lo); /* 32x32->64 mul */ largeint_add_gen(lo,largeint_out,n,i); - if (i+1<n) - largeint_add_gen(hi,largeint_out,n,i+1); + largeint_add_gen(hi,largeint_out,n,i+1); } } + if (largeint_in[i]!=0U) + { + Ptngc_widemul(v1,largeint_in[i],&hi,&lo); /* 32x32->64 mul */ + largeint_add_gen(lo,largeint_out,n,i); + } } /* Return the remainder from dividing largeint_in with v1. Result of the division is returned in largeint_out */ -unsigned int Ptngc_largeint_div(unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, int n) +TNG_INLINE unsigned int Ptngc_largeint_div(const unsigned int v1, unsigned int *largeint_in, unsigned int *largeint_out, const int n) { unsigned int result,remainder=0; int i; - unsigned int hi, lo; + unsigned int hi; /* Boot */ hi=0U; i=n; while (i) { - lo=largeint_in[i-1]; - Ptngc_widediv(hi,lo,v1,&result,&remainder); - largeint_out[i-1]=result; - hi=remainder; i--; + Ptngc_widediv(hi,largeint_in[i],v1,&result,&remainder); + largeint_out[i]=result; + hi=remainder; } return remainder; } |