Botan  1.11.15
src/lib/math/mp/mp_generic/mp_asmi.h
Go to the documentation of this file.
00001 /*
00002 * Lowest Level MPI Algorithms
00003 * (C) 1999-2010 Jack Lloyd
00004 *     2006 Luca Piccarreta
00005 *
00006 * Botan is released under the Simplified BSD License (see license.txt)
00007 */
00008 
00009 #ifndef BOTAN_MP_ASM_INTERNAL_H__
00010 #define BOTAN_MP_ASM_INTERNAL_H__
00011 
00012 #include <botan/internal/mp_madd.h>
00013 
00014 namespace Botan {
00015 
00016 extern "C" {
00017 
00018 /*
00019 * Word Addition
00020 */
00021 inline word word_add(word x, word y, word* carry)
00022    {
00023    word z = x + y;
00024    word c1 = (z < x);
00025    z += *carry;
00026    *carry = c1 | (z < *carry);
00027    return z;
00028    }
00029 
00030 /*
00031 * Eight Word Block Addition, Two Argument
00032 */
00033 inline word word8_add2(word x[8], const word y[8], word carry)
00034    {
00035    x[0] = word_add(x[0], y[0], &carry);
00036    x[1] = word_add(x[1], y[1], &carry);
00037    x[2] = word_add(x[2], y[2], &carry);
00038    x[3] = word_add(x[3], y[3], &carry);
00039    x[4] = word_add(x[4], y[4], &carry);
00040    x[5] = word_add(x[5], y[5], &carry);
00041    x[6] = word_add(x[6], y[6], &carry);
00042    x[7] = word_add(x[7], y[7], &carry);
00043    return carry;
00044    }
00045 
00046 /*
00047 * Eight Word Block Addition, Three Argument
00048 */
00049 inline word word8_add3(word z[8], const word x[8],
00050                        const word y[8], word carry)
00051    {
00052    z[0] = word_add(x[0], y[0], &carry);
00053    z[1] = word_add(x[1], y[1], &carry);
00054    z[2] = word_add(x[2], y[2], &carry);
00055    z[3] = word_add(x[3], y[3], &carry);
00056    z[4] = word_add(x[4], y[4], &carry);
00057    z[5] = word_add(x[5], y[5], &carry);
00058    z[6] = word_add(x[6], y[6], &carry);
00059    z[7] = word_add(x[7], y[7], &carry);
00060    return carry;
00061    }
00062 
00063 /*
00064 * Word Subtraction
00065 */
00066 inline word word_sub(word x, word y, word* carry)
00067    {
00068    word t0 = x - y;
00069    word c1 = (t0 > x);
00070    word z = t0 - *carry;
00071    *carry = c1 | (z > t0);
00072    return z;
00073    }
00074 
00075 /*
00076 * Eight Word Block Subtraction, Two Argument
00077 */
00078 inline word word8_sub2(word x[8], const word y[8], word carry)
00079    {
00080    x[0] = word_sub(x[0], y[0], &carry);
00081    x[1] = word_sub(x[1], y[1], &carry);
00082    x[2] = word_sub(x[2], y[2], &carry);
00083    x[3] = word_sub(x[3], y[3], &carry);
00084    x[4] = word_sub(x[4], y[4], &carry);
00085    x[5] = word_sub(x[5], y[5], &carry);
00086    x[6] = word_sub(x[6], y[6], &carry);
00087    x[7] = word_sub(x[7], y[7], &carry);
00088    return carry;
00089    }
00090 
00091 /*
00092 * Eight Word Block Subtraction, Two Argument
00093 */
00094 inline word word8_sub2_rev(word x[8], const word y[8], word carry)
00095    {
00096    x[0] = word_sub(y[0], x[0], &carry);
00097    x[1] = word_sub(y[1], x[1], &carry);
00098    x[2] = word_sub(y[2], x[2], &carry);
00099    x[3] = word_sub(y[3], x[3], &carry);
00100    x[4] = word_sub(y[4], x[4], &carry);
00101    x[5] = word_sub(y[5], x[5], &carry);
00102    x[6] = word_sub(y[6], x[6], &carry);
00103    x[7] = word_sub(y[7], x[7], &carry);
00104    return carry;
00105    }
00106 
00107 /*
00108 * Eight Word Block Subtraction, Three Argument
00109 */
00110 inline word word8_sub3(word z[8], const word x[8],
00111                        const word y[8], word carry)
00112    {
00113    z[0] = word_sub(x[0], y[0], &carry);
00114    z[1] = word_sub(x[1], y[1], &carry);
00115    z[2] = word_sub(x[2], y[2], &carry);
00116    z[3] = word_sub(x[3], y[3], &carry);
00117    z[4] = word_sub(x[4], y[4], &carry);
00118    z[5] = word_sub(x[5], y[5], &carry);
00119    z[6] = word_sub(x[6], y[6], &carry);
00120    z[7] = word_sub(x[7], y[7], &carry);
00121    return carry;
00122    }
00123 
00124 /*
00125 * Eight Word Block Linear Multiplication
00126 */
00127 inline word word8_linmul2(word x[8], word y, word carry)
00128    {
00129    x[0] = word_madd2(x[0], y, &carry);
00130    x[1] = word_madd2(x[1], y, &carry);
00131    x[2] = word_madd2(x[2], y, &carry);
00132    x[3] = word_madd2(x[3], y, &carry);
00133    x[4] = word_madd2(x[4], y, &carry);
00134    x[5] = word_madd2(x[5], y, &carry);
00135    x[6] = word_madd2(x[6], y, &carry);
00136    x[7] = word_madd2(x[7], y, &carry);
00137    return carry;
00138    }
00139 
00140 /*
00141 * Eight Word Block Linear Multiplication
00142 */
00143 inline word word8_linmul3(word z[8], const word x[8], word y, word carry)
00144    {
00145    z[0] = word_madd2(x[0], y, &carry);
00146    z[1] = word_madd2(x[1], y, &carry);
00147    z[2] = word_madd2(x[2], y, &carry);
00148    z[3] = word_madd2(x[3], y, &carry);
00149    z[4] = word_madd2(x[4], y, &carry);
00150    z[5] = word_madd2(x[5], y, &carry);
00151    z[6] = word_madd2(x[6], y, &carry);
00152    z[7] = word_madd2(x[7], y, &carry);
00153    return carry;
00154    }
00155 
00156 /*
00157 * Eight Word Block Multiply/Add
00158 */
00159 inline word word8_madd3(word z[8], const word x[8], word y, word carry)
00160    {
00161    z[0] = word_madd3(x[0], y, z[0], &carry);
00162    z[1] = word_madd3(x[1], y, z[1], &carry);
00163    z[2] = word_madd3(x[2], y, z[2], &carry);
00164    z[3] = word_madd3(x[3], y, z[3], &carry);
00165    z[4] = word_madd3(x[4], y, z[4], &carry);
00166    z[5] = word_madd3(x[5], y, z[5], &carry);
00167    z[6] = word_madd3(x[6], y, z[6], &carry);
00168    z[7] = word_madd3(x[7], y, z[7], &carry);
00169    return carry;
00170    }
00171 
00172 /*
00173 * Multiply-Add Accumulator
00174 */
00175 inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b)
00176    {
00177    word carry = *w0;
00178    *w0 = word_madd2(a, b, &carry);
00179    *w1 += carry;
00180    *w2 += (*w1 < carry) ? 1 : 0;
00181    }
00182 
00183 /*
00184 * Multiply-Add Accumulator
00185 */
00186 inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b)
00187    {
00188    word carry = 0;
00189    a = word_madd2(a, b, &carry);
00190    b = carry;
00191 
00192    word top = (b >> (BOTAN_MP_WORD_BITS-1));
00193    b <<= 1;
00194    b |= (a >> (BOTAN_MP_WORD_BITS-1));
00195    a <<= 1;
00196 
00197    carry = 0;
00198    *w0 = word_add(*w0, a, &carry);
00199    *w1 = word_add(*w1, b, &carry);
00200    *w2 = word_add(*w2, top, &carry);
00201    }
00202 
00203 }
00204 
00205 }
00206 
00207 #endif