]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.s
Security-58286.270.3.0.1.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / giantPort_PPC_Gnu.s
1 /*
2 * Copyright (c) 2001,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 /*
26 * As of 3/19/2001, using this module results in no change in runtime
27 * performance compared to using the inline C functions in
28 * giantPort_Generic.h. Examination of the compiled code shows that
29 * the GNU C compiler, when configured for -O2, generates almost
30 * exactly the same code as we have here.
31 * We'll leave this code in, to protect against changes in gcc, changes
32 * in CFLAGS, and to serve as an example for other PPC implementations.
33 */
34
35 #if defined(__ppc__) && defined(__MACH__)
36
37 /*********************************************
38
39 Add two digits, return sum. Carry bit returned as an out parameter.
40
41 giantDigit giantAddDigits(
42 register giantDigit dig1,
43 register giantDigit dig2,
44 register giantDigit *carry) ...RETURNED, 0 or 1
45 **********************************************/
46 .text
47 .align 2
48 .globl _giantAddDigits
49 _giantAddDigits:
50 /*
51 * dig1 : r3
52 * dig2 : r4
53 * carry : r5
54 * sum : r6
55 */
56
57 /* sum = dig1 + dig2 */
58 add r6, r3, r4;
59
60 /* if((sum < dig1) || (sum < dig2)) */
61 cmplw cr0,r6,r3
62 blt L1
63 cmplw cr0,r6,r4
64 bge L2
65
66 L1:
67 /* *carry = 1; */
68 li r7,1
69 stw r7, 0(r5)
70 b L3
71
72 L2:
73 /* else *carry = 0; */
74 li r7,0
75 stw r7, 0(r5)
76
77 L3:
78 /* return sum in r3 */
79 mr. r3,r6
80 blr
81
82 /*********************************************
83
84 Add a single digit value to a double digit accumulator in place.
85 Carry out of the MSD of the accumulator is not handled.
86
87 void giantAddDouble(
88 giantDigit *accLow, -- IN/OUT
89 giantDigit *accHigh, -- IN/OUT
90 giantDigit val);
91 **********************************************/
92
93 .align 2
94 .globl _giantAddDouble
95 _giantAddDouble:
96 /*
97 * r3 : accLow
98 * r4 : accHi
99 * r5 : val
100 * r6 : sumLo
101 * r7 : *accLow
102 */
103
104 /* giantDigit sumLo = *accLow + val; */
105 lwz r7,0(r3)
106 add r6,r7,r5
107
108 /* if((sumLo < *accLow) || (sumLo < val)) { */
109 cmplw cr0,r6,r7
110 blt L10
111 cmplw cr0,r6,r5
112 bge L11
113
114 L10:
115 /* (*accHigh)++; */
116 lwz r7, 0(r4)
117 addi r7,r7,1
118 stw r7, 0(r4)
119
120 L11:
121 /* *accLow = sumLo; */
122 stw r6,0(r3)
123 blr
124
125 /*****************************************************************************
126
127 Subtract a - b, return difference. Borrow bit returned as an out parameter.
128
129 giantDigit giantSubDigits(
130 giantDigit a,
131 giantDigit b,
132 giantDigit *borrow) -- RETURNED, 0 or 1
133
134 ******************************************************************************/
135
136 .align 2
137 .globl _giantSubDigits
138 _giantSubDigits:
139
140 /* a : r3
141 b : r4
142 borrow : r5
143 diff : r6 */
144
145 /* giantDigit diff = a - b; */
146 subf r6, r4, r3;
147
148 /* if(a < b) */
149 cmplw cr0,r3,r4
150 bge L20
151
152 /* *borrow = 1; */
153 li r7,1
154 stw r7, 0(r5)
155 b L21
156
157 L20:
158 /* else *borrow = 0; */
159 li r7,0
160 stw r7, 0(r5)
161
162 L21:
163 /* return diff in r3 */
164 mr. r3,r6
165 blr
166
167 /*****************************************************************************
168
169 Multiply two digits, return two digits.
170
171 void giantMulDigits(
172 giantDigit dig1,
173 giantDigit dig2,
174 giantDigit *lowProduct, -- RETURNED, low digit
175 giantDigit *hiProduct) -- RETURNED, high digit
176
177 ******************************************************************************/
178
179 .align 2
180 .globl _giantMulDigits
181 _giantMulDigits:
182
183 /* r3 : dig1
184 r4 : dig2
185 r5 : lowProduct
186 r6 : hiProduct */
187
188 /* dprod = (unsigned long long)dig1 * (unsigned long long)dig2; */
189 mullw r7, r3, r4 /* r7 = low(dig1 * dig2) */
190 mulhwu r8, r3, r4 /* r8 - hi(dig1 * dig2) */
191
192 /* *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); */
193 stw r8, 0(r6)
194
195 /* *lowProduct = (giantDigit)dprod; */
196 stw r7, 0(r5)
197 blr
198
199
200 /*****************************************************************************
201
202 Multiply a vector of giantDigits, candVector, by a single giantDigit,
203 plierDigit, adding results into prodVector. Returns m.s. digit from
204 final multiply; only candLength digits of *prodVector will be written.
205
206 giantDigit VectorMultiply(
207 giantDigit plierDigit,
208 giantDigit *candVector,
209 unsigned candLength,
210 giantDigit *prodVector)
211
212 ******************************************************************************/
213
214 /*
215 * Register definitions
216 * Input paramters:
217 */
218 #define plierDigit r3
219 #define candVector r4
220 #define candLength r5
221 #define prodVector r6
222
223 /*
224 * PPC ABI specifies:
225 * r3..r10 for parameter passing
226 * r11, r12 volatile (caller saved, we can write)
227 *
228 * We'll use the remainder of the registers normally used for parameter passing
229 * and also the other volatile register for local variables.
230 */
231 #define candDex r7
232 #define lastCarry r8
233 #define prodLo r9
234 #define prodHi r10
235 #define scr1 r11
236 #define sumLo r12
237
238 .align 2
239 .globl _VectorMultiply
240 _VectorMultiply:
241
242 /* giantDigit lastCarry = 0; */
243 li lastCarry,0
244
245
246 /* for(candDex=0; candDex<candLength; ++candDex) { */
247 li candDex,0
248 b L_endLoop
249
250 /*
251 * prod = *(candVector++) * plierDigit + *prodVector + lastCarry
252 */
253 L_topLoop:
254 lwz scr1,0(candVector) /* *candVector --> scr1 */
255 addi candVector,candVector,4 /* candVector++ */
256
257 mullw prodLo,scr1,plierDigit /* prodLo = low(*candVector * plierDigit) */
258 mulhwu prodHi,scr1,plierDigit /* prodHi = high(*candVector * plierDigit) */
259
260 /* giantAddDouble(&prodLo, &prodHi, *prodVector); */
261 lwz scr1,0(prodVector) /* *prodVector --> r9 */
262 add sumLo,prodLo,scr1 /* prodLo + *prodVector --> sumLo */
263 cmplw cr0,sumLo,prodLo /* sumLo < prodLo? */
264 blt L_carry1
265 cmplw cr0,sumLo,scr1 /* sumLo < *prodVector? */
266 bge L_noCar1
267 L_carry1:
268 addi prodHi,prodHi,1 /* prodHi++ */
269 L_noCar1:
270 mr. prodLo,sumLo /* prodLo := sumLo */
271
272 /* giantAddDouble(&prodLo, &prodHi, lastCarry); */
273 add sumLo,sumLo,lastCarry /* sumLo += lastCarry */
274 cmplw cr0,sumLo,prodLo /* sumLo < prodLo? */
275 blt L_carry2
276 cmplw cr0,sumLo,lastCarry /* sumLo < lastCarry? */
277 bge L_noCar2
278 L_carry2:
279 addi prodHi,prodHi,1 /* prodHi++ */
280 L_noCar2:
281 mr. prodLo,sumLo /* prodLo := sumLo */
282
283 /* *(prodVector++) = prodLo; */
284 stw prodLo,0(prodVector) /* prodLo --> *prodVector */
285 addi prodVector,prodVector,4 /* prodVector++ */
286
287 /* lastCarry = prodHi; */
288 mr. lastCarry,prodHi
289
290 /* } */
291 addi candDex,candDex,1 /* candDex++ */
292 L_endLoop:
293 cmplw cr0,candDex,candLength /* candDex < candLength? */
294 blt L_topLoop
295
296 /* return lastCarry; */
297 mr. r3,lastCarry /* return lastCarry in r3 */
298 blr
299
300 #endif /* defined(__ppc__) && defined(__MACH__) */