Botan  1.10.9
mp_asmi.h
Go to the documentation of this file.
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 * Helper Macros for x86-64 Assembly
20 */
21 #ifndef ASM
22  #define ASM(x) x "\n\t"
23 #endif
24 
25 #define ADDSUB2_OP(OPERATION, INDEX) \
26  ASM("movq 8*" #INDEX "(%[y]), %[carry]") \
27  ASM(OPERATION " %[carry], 8*" #INDEX "(%[x])") \
28 
29 #define ADDSUB3_OP(OPERATION, INDEX) \
30  ASM("movq 8*" #INDEX "(%[x]), %[carry]") \
31  ASM(OPERATION " 8*" #INDEX "(%[y]), %[carry]") \
32  ASM("movq %[carry], 8*" #INDEX "(%[z])") \
33 
34 #define LINMUL_OP(WRITE_TO, INDEX) \
35  ASM("movq 8*" #INDEX "(%[x]),%%rax") \
36  ASM("mulq %[y]") \
37  ASM("addq %[carry],%%rax") \
38  ASM("adcq $0,%%rdx") \
39  ASM("movq %%rdx,%[carry]") \
40  ASM("movq %%rax, 8*" #INDEX "(%[" WRITE_TO "])")
41 
42 #define MULADD_OP(IGNORED, INDEX) \
43  ASM("movq 8*" #INDEX "(%[x]),%%rax") \
44  ASM("mulq %[y]") \
45  ASM("addq %[carry],%%rax") \
46  ASM("adcq $0,%%rdx") \
47  ASM("addq 8*" #INDEX "(%[z]),%%rax") \
48  ASM("adcq $0,%%rdx") \
49  ASM("movq %%rdx,%[carry]") \
50  ASM("movq %%rax, 8*" #INDEX " (%[z])")
51 
52 #define DO_8_TIMES(MACRO, ARG) \
53  MACRO(ARG, 0) \
54  MACRO(ARG, 1) \
55  MACRO(ARG, 2) \
56  MACRO(ARG, 3) \
57  MACRO(ARG, 4) \
58  MACRO(ARG, 5) \
59  MACRO(ARG, 6) \
60  MACRO(ARG, 7)
61 
62 #define ADD_OR_SUBTRACT(CORE_CODE) \
63  ASM("rorq %[carry]") \
64  CORE_CODE \
65  ASM("sbbq %[carry],%[carry]") \
66  ASM("negq %[carry]")
67 
68 /*
69 * Word Addition
70 */
71 inline word word_add(word x, word y, word* carry)
72  {
73  asm(
74  ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]"))
75  : [x]"=r"(x), [carry]"=r"(*carry)
76  : "0"(x), [y]"rm"(y), "1"(*carry)
77  : "cc");
78  return x;
79  }
80 
81 /*
82 * Eight Word Block Addition, Two Argument
83 */
84 inline word word8_add2(word x[8], const word y[8], word carry)
85  {
86  asm(
88  : [carry]"=r"(carry)
89  : [x]"r"(x), [y]"r"(y), "0"(carry)
90  : "cc", "memory");
91  return carry;
92  }
93 
94 /*
95 * Eight Word Block Addition, Three Argument
96 */
97 inline word word8_add3(word z[8], const word x[8], const word y[8], word carry)
98  {
99  asm(
101  : [carry]"=r"(carry)
102  : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry)
103  : "cc", "memory");
104  return carry;
105  }
106 
107 /*
108 * Word Subtraction
109 */
110 inline word word_sub(word x, word y, word* carry)
111  {
112  asm(
113  ADD_OR_SUBTRACT(ASM("sbbq %[y],%[x]"))
114  : [x]"=r"(x), [carry]"=r"(*carry)
115  : "0"(x), [y]"rm"(y), "1"(*carry)
116  : "cc");
117  return x;
118  }
119 
120 /*
121 * Eight Word Block Subtraction, Two Argument
122 */
123 inline word word8_sub2(word x[8], const word y[8], word carry)
124  {
125  asm(
127  : [carry]"=r"(carry)
128  : [x]"r"(x), [y]"r"(y), "0"(carry)
129  : "cc", "memory");
130  return carry;
131  }
132 
133 /*
134 * Eight Word Block Subtraction, Two Argument
135 */
136 inline word word8_sub2_rev(word x[8], const word y[8], word carry)
137  {
138  asm(
140  : [carry]"=r"(carry)
141  : [x]"r"(y), [y]"r"(x), [z]"r"(x), "0"(carry)
142  : "cc", "memory");
143  return carry;
144  }
145 
146 /*
147 * Eight Word Block Subtraction, Three Argument
148 */
149 inline word word8_sub3(word z[8], const word x[8], const word y[8], word carry)
150  {
151  asm(
153  : [carry]"=r"(carry)
154  : [x]"r"(x), [y]"r"(y), [z]"r"(z), "0"(carry)
155  : "cc", "memory");
156  return carry;
157  }
158 
159 /*
160 * Eight Word Block Linear Multiplication
161 */
162 inline word word8_linmul2(word x[8], word y, word carry)
163  {
164  asm(
165  DO_8_TIMES(LINMUL_OP, "x")
166  : [carry]"=r"(carry)
167  : [x]"r"(x), [y]"rm"(y), "0"(carry)
168  : "cc", "%rax", "%rdx");
169  return carry;
170  }
171 
172 /*
173 * Eight Word Block Linear Multiplication
174 */
175 inline word word8_linmul3(word z[8], const word x[8], word y, word carry)
176  {
177  asm(
178  DO_8_TIMES(LINMUL_OP, "z")
179  : [carry]"=r"(carry)
180  : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry)
181  : "cc", "%rax", "%rdx");
182  return carry;
183  }
184 
185 /*
186 * Eight Word Block Multiply/Add
187 */
188 inline word word8_madd3(word z[8], const word x[8], word y, word carry)
189  {
190  asm(
191  DO_8_TIMES(MULADD_OP, "")
192  : [carry]"=r"(carry)
193  : [z]"r"(z), [x]"r"(x), [y]"rm"(y), "0"(carry)
194  : "cc", "%rax", "%rdx");
195  return carry;
196  }
197 
198 /*
199 * Multiply-Add Accumulator
200 */
201 inline void word3_muladd(word* w2, word* w1, word* w0, word x, word y)
202  {
203  asm(
204  ASM("mulq %[y]")
205 
206  ASM("addq %[x],%[w0]")
207  ASM("adcq %[y],%[w1]")
208  ASM("adcq $0,%[w2]")
209 
210  : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2)
211  : [x]"a"(x), [y]"d"(y), "0"(*w0), "1"(*w1), "2"(*w2)
212  : "cc");
213  }
214 
215 /*
216 * Multiply-Add Accumulator
217 */
218 inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y)
219  {
220  asm(
221  ASM("mulq %[y]")
222 
223  ASM("addq %[x],%[w0]")
224  ASM("adcq %[y],%[w1]")
225  ASM("adcq $0,%[w2]")
226 
227  ASM("addq %[x],%[w0]")
228  ASM("adcq %[y],%[w1]")
229  ASM("adcq $0,%[w2]")
230 
231  : [w0]"=r"(*w0), [w1]"=r"(*w1), [w2]"=r"(*w2)
232  : [x]"a"(x), [y]"d"(y), "0"(*w0), "1"(*w1), "2"(*w2)
233  : "cc");
234  }
235 
236 
237 #undef ASM
238 #undef DO_8_TIMES
239 #undef ADD_OR_SUBTRACT
240 #undef ADDSUB2_OP
241 #undef ADDSUB3_OP
242 #undef LINMUL_OP
243 #undef MULADD_OP
244 
245 }
246 
247 }
248 #endif
#define ADDSUB3_OP(OPERATION, INDEX)
Definition: mp_asmi.h:29
#define ADD_OR_SUBTRACT(CORE_CODE)
Definition: mp_asmi.h:62
word word8_sub2_rev(word x[8], const word y[8], word carry)
Definition: mp_asmi.h:94
word word8_add2(word x[8], const word y[8], word carry)
Definition: mp_asmi.h:33
word word8_linmul3(word z[8], const word x[8], word y, word carry)
Definition: mp_asmi.h:143
word word8_sub2(word x[8], const word y[8], word carry)
Definition: mp_asmi.h:78
word word8_madd3(word z[8], const word x[8], word y, word carry)
Definition: mp_asmi.h:159
word word8_linmul2(word x[8], word y, word carry)
Definition: mp_asmi.h:127
#define ASM(x)
Definition: mp_asmi.h:22
void word3_muladd(word *w2, word *w1, word *w0, word a, word b)
Definition: mp_asmi.h:175
word word8_add3(word z[8], const word x[8], const word y[8], word carry)
Definition: mp_asmi.h:49
word word_sub(word x, word y, word *carry)
Definition: mp_asmi.h:66
void word3_muladd_2(word *w2, word *w1, word *w0, word a, word b)
Definition: mp_asmi.h:186
BigInt r
Definition: numthry.cpp:26
#define LINMUL_OP(WRITE_TO, INDEX)
Definition: mp_asmi.h:34
word word_add(word x, word y, word *carry)
Definition: mp_asmi.h:21
#define MULADD_OP(IGNORED, INDEX)
Definition: mp_asmi.h:42
#define ADDSUB2_OP(OPERATION, INDEX)
Definition: mp_asmi.h:25
word word8_sub3(word z[8], const word x[8], const word y[8], word carry)
Definition: mp_asmi.h:110
#define DO_8_TIMES(MACRO, ARG)
Definition: mp_asmi.h:52