1 /*
2 * Lowest Level MPI Algorithms
3 * (C) 1999-2010 Jack Lloyd
4 * 2006 Luca Piccarreta
5 *
6 * Distributed under the terms of the Botan license
7 */
8
9 #ifndef BOTAN_MP_ASM_INTERNAL_H__
10 #define BOTAN_MP_ASM_INTERNAL_H__
11
12 #include <botan/internal/mp_asm.h>
13
14 namespace Botan {
15
16 extern "C" {
17
18 /*
19 * Word Addition
20 */
word_add(word x,word y,word * carry)21 inline word word_add(word x, word y, word* carry)
22 {
23 word z = x + y;
24 word c1 = (z < x);
25 z += *carry;
26 *carry = c1 | (z < *carry);
27 return z;
28 }
29
30 /*
31 * Eight Word Block Addition, Two Argument
32 */
word8_add2(word x[8],const word y[8],word carry)33 inline word word8_add2(word x[8], const word y[8], word carry)
34 {
35 x[0] = word_add(x[0], y[0], &carry);
36 x[1] = word_add(x[1], y[1], &carry);
37 x[2] = word_add(x[2], y[2], &carry);
38 x[3] = word_add(x[3], y[3], &carry);
39 x[4] = word_add(x[4], y[4], &carry);
40 x[5] = word_add(x[5], y[5], &carry);
41 x[6] = word_add(x[6], y[6], &carry);
42 x[7] = word_add(x[7], y[7], &carry);
43 return carry;
44 }
45
46 /*
47 * Eight Word Block Addition, Three Argument
48 */
word8_add3(word z[8],const word x[8],const word y[8],word carry)49 inline word word8_add3(word z[8], const word x[8],
50 const word y[8], word carry)
51 {
52 z[0] = word_add(x[0], y[0], &carry);
53 z[1] = word_add(x[1], y[1], &carry);
54 z[2] = word_add(x[2], y[2], &carry);
55 z[3] = word_add(x[3], y[3], &carry);
56 z[4] = word_add(x[4], y[4], &carry);
57 z[5] = word_add(x[5], y[5], &carry);
58 z[6] = word_add(x[6], y[6], &carry);
59 z[7] = word_add(x[7], y[7], &carry);
60 return carry;
61 }
62
63 /*
64 * Word Subtraction
65 */
word_sub(word x,word y,word * carry)66 inline word word_sub(word x, word y, word* carry)
67 {
68 word t0 = x - y;
69 word c1 = (t0 > x);
70 word z = t0 - *carry;
71 *carry = c1 | (z > t0);
72 return z;
73 }
74
75 /*
76 * Eight Word Block Subtraction, Two Argument
77 */
word8_sub2(word x[8],const word y[8],word carry)78 inline word word8_sub2(word x[8], const word y[8], word carry)
79 {
80 x[0] = word_sub(x[0], y[0], &carry);
81 x[1] = word_sub(x[1], y[1], &carry);
82 x[2] = word_sub(x[2], y[2], &carry);
83 x[3] = word_sub(x[3], y[3], &carry);
84 x[4] = word_sub(x[4], y[4], &carry);
85 x[5] = word_sub(x[5], y[5], &carry);
86 x[6] = word_sub(x[6], y[6], &carry);
87 x[7] = word_sub(x[7], y[7], &carry);
88 return carry;
89 }
90
91 /*
92 * Eight Word Block Subtraction, Two Argument
93 */
word8_sub2_rev(word x[8],const word y[8],word carry)94 inline word word8_sub2_rev(word x[8], const word y[8], word carry)
95 {
96 x[0] = word_sub(y[0], x[0], &carry);
97 x[1] = word_sub(y[1], x[1], &carry);
98 x[2] = word_sub(y[2], x[2], &carry);
99 x[3] = word_sub(y[3], x[3], &carry);
100 x[4] = word_sub(y[4], x[4], &carry);
101 x[5] = word_sub(y[5], x[5], &carry);
102 x[6] = word_sub(y[6], x[6], &carry);
103 x[7] = word_sub(y[7], x[7], &carry);
104 return carry;
105 }
106
107 /*
108 * Eight Word Block Subtraction, Three Argument
109 */
word8_sub3(word z[8],const word x[8],const word y[8],word carry)110 inline word word8_sub3(word z[8], const word x[8],
111 const word y[8], word carry)
112 {
113 z[0] = word_sub(x[0], y[0], &carry);
114 z[1] = word_sub(x[1], y[1], &carry);
115 z[2] = word_sub(x[2], y[2], &carry);
116 z[3] = word_sub(x[3], y[3], &carry);
117 z[4] = word_sub(x[4], y[4], &carry);
118 z[5] = word_sub(x[5], y[5], &carry);
119 z[6] = word_sub(x[6], y[6], &carry);
120 z[7] = word_sub(x[7], y[7], &carry);
121 return carry;
122 }
123
124 /*
125 * Eight Word Block Linear Multiplication
126 */
word8_linmul2(word x[8],word y,word carry)127 inline word word8_linmul2(word x[8], word y, word carry)
128 {
129 x[0] = word_madd2(x[0], y, &carry);
130 x[1] = word_madd2(x[1], y, &carry);
131 x[2] = word_madd2(x[2], y, &carry);
132 x[3] = word_madd2(x[3], y, &carry);
133 x[4] = word_madd2(x[4], y, &carry);
134 x[5] = word_madd2(x[5], y, &carry);
135 x[6] = word_madd2(x[6], y, &carry);
136 x[7] = word_madd2(x[7], y, &carry);
137 return carry;
138 }
139
140 /*
141 * Eight Word Block Linear Multiplication
142 */
word8_linmul3(word z[8],const word x[8],word y,word carry)143 inline word word8_linmul3(word z[8], const word x[8], word y, word carry)
144 {
145 z[0] = word_madd2(x[0], y, &carry);
146 z[1] = word_madd2(x[1], y, &carry);
147 z[2] = word_madd2(x[2], y, &carry);
148 z[3] = word_madd2(x[3], y, &carry);
149 z[4] = word_madd2(x[4], y, &carry);
150 z[5] = word_madd2(x[5], y, &carry);
151 z[6] = word_madd2(x[6], y, &carry);
152 z[7] = word_madd2(x[7], y, &carry);
153 return carry;
154 }
155
156 /*
157 * Eight Word Block Multiply/Add
158 */
word8_madd3(word z[8],const word x[8],word y,word carry)159 inline word word8_madd3(word z[8], const word x[8], word y, word carry)
160 {
161 z[0] = word_madd3(x[0], y, z[0], &carry);
162 z[1] = word_madd3(x[1], y, z[1], &carry);
163 z[2] = word_madd3(x[2], y, z[2], &carry);
164 z[3] = word_madd3(x[3], y, z[3], &carry);
165 z[4] = word_madd3(x[4], y, z[4], &carry);
166 z[5] = word_madd3(x[5], y, z[5], &carry);
167 z[6] = word_madd3(x[6], y, z[6], &carry);
168 z[7] = word_madd3(x[7], y, z[7], &carry);
169 return carry;
170 }
171
172 /*
173 * Multiply-Add Accumulator
174 */
word3_muladd(word * w2,word * w1,word * w0,word a,word b)175 inline void word3_muladd(word* w2, word* w1, word* w0, word a, word b)
176 {
177 word carry = *w0;
178 *w0 = word_madd2(a, b, &carry);
179 *w1 += carry;
180 *w2 += (*w1 < carry) ? 1 : 0;
181 }
182
183 /*
184 * Multiply-Add Accumulator
185 */
word3_muladd_2(word * w2,word * w1,word * w0,word a,word b)186 inline void word3_muladd_2(word* w2, word* w1, word* w0, word a, word b)
187 {
188 word carry = 0;
189 a = word_madd2(a, b, &carry);
190 b = carry;
191
192 word top = (b >> (BOTAN_MP_WORD_BITS-1));
193 b <<= 1;
194 b |= (a >> (BOTAN_MP_WORD_BITS-1));
195 a <<= 1;
196
197 carry = 0;
198 *w0 = word_add(*w0, a, &carry);
199 *w1 = word_add(*w1, b, &carry);
200 *w2 = word_add(*w2, top, &carry);
201 }
202
203 }
204
205 }
206
207 #endif
208