diff options
Diffstat (limited to 'modules/mp_asm64/mp_asm.h')
-rw-r--r-- | modules/mp_asm64/mp_asm.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/modules/mp_asm64/mp_asm.h b/modules/mp_asm64/mp_asm.h new file mode 100644 index 000000000..8c6df078e --- /dev/null +++ b/modules/mp_asm64/mp_asm.h @@ -0,0 +1,119 @@ +/************************************************* +* MPI Multiply-Add Core Header File * +* (C) 1999-2006 The Botan Project * +*************************************************/ + +#ifndef BOTAN_MP_MADD_H__ +#define BOTAN_MP_MADD_H__ + +#include <botan/mp_types.h> + +#if (BOTAN_MP_WORD_BITS != 64) + #error The mp_asm64 module requires that BOTAN_MP_WORD_BITS == 64 +#endif + +#if defined(BOTAN_TARGET_ARCH_IS_AMD64) + +#define BOTAN_WORD_MUL(a,b,z1,z0) do { \ + asm("mulq %3" : "=d" (z0), "=a" (z1) : \ + "a" (a), "rm" (b) : "cc"); \ +} while(0); + +#elif defined(BOTAN_TARGET_ARCH_IS_ALPHA) + +#define BOTAN_WORD_MUL(a,b,z1,z0) do { \ + asm("umulh %1,%2,%0" : "=r" (z0) : "r" (a), "r" (b)); \ + z1 = a * b; \ +} while(0); + +#elif defined(BOTAN_TARGET_ARCH_IS_IA64) + +#define BOTAN_WORD_MUL(a,b,z1,z0) do { \ + asm("xmpy.hu %0=%1,%2" : "=f" (z0) : "f" (a), "f" (b)); \ + z1 = a * b; \ +} while(0); + +#elif defined(BOTAN_TARGET_ARCH_IS_PPC64) + +#define BOTAN_WORD_MUL(a,b,z1,z0) do { \ + asm("mulhdu %0,%1,%2" : "=r" (z0) : "r" (a), "r" (b) : "cc"); \ + z1 = a * b; \ +} while(0); + +#elif defined(BOTAN_TARGET_ARCH_IS_MIPS64) + +#define BOTAN_WORD_MUL(a,b,z1,z0) do { \ + asm("dmultu %2,%3" : "=h" (z0), "=l" (z1) : "r" (a), "r" (b)); \ +} while(0); + +#else + +#include <botan/mp_core.h> + +#define BOTAN_WORD_MUL(a,b,z1,z0) \ + do { bigint_wordmul(a, b, &z1, &z0); } while(0); + +#endif + +namespace Botan { + +/************************************************* +* Word Multiply/Add * +*************************************************/ +inline word word_madd2(word a, word b, word c, word* carry) + { + word z0 = 0, z1 = 0; + + BOTAN_WORD_MUL(a, b, z1, z0); + + z1 += c; if(z1 < c) z0++; + + *carry = z0; + return z1; + } + +/************************************************* +* Word Multiply/Add * +*************************************************/ +inline word word_madd3(word a, word b, word c, word d, word* carry) + { + word z0 = 0, z1 = 0; + + BOTAN_WORD_MUL(a, b, z1, z0); + + z1 += c; if(z1 < c) z0++; + z1 += d; if(z1 < d) z0++; + + *carry = z0; + return z1; + } + +/************************************************* +* Multiply-Add Accumulator * +*************************************************/ +inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b) + { + *w0 = word_madd2(a, b, *w0, &a); + *w1 += a; + *w2 += (*w1 < a) ? 1 : 0; + } + +/************************************************* +* Multiply-Add Accumulator * +*************************************************/ +inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b) + { + a = word_madd2(a, b, 0, &b); + + *w0 += a; + *w1 += b + ((*w0 < a) ? 1 : 0); + *w2 += (*w1 < b) ? 1 : 0; + + *w0 += a; + *w1 += b + ((*w0 < a) ? 1 : 0); + *w2 += (*w1 < b) ? 1 : 0; + } + +} + +#endif |