]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/giantPort_PPC.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / giantPort_PPC.c
1 /* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved.
2 *
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
10 *
11 * giantPort_PPC.c - PPC-dependent giant definitions.
12 *
13 * Revision History
14 * ----------------
15 * 10/06/98 ap
16 * Changed to compile with C++.
17 * 06 Apr 1998 at Apple
18 * Created.
19 */
20
21 #include "feeDebug.h"
22 #include "platform.h"
23 #include "giantPort_PPC.h"
24
25 #if !PPC_GIANT_PORT_INLINE
26
27
28 /*
29 * Multiple-precision arithmetic routines/macros.
30 */
31
32 asm giantDigit giantAddDigits(
33 register giantDigit dig1,
34 register giantDigit dig2,
35 register giantDigit *carry) /* RETURNED, 0 or 1 */
36
37 {
38 /*
39 * dig1 : r3
40 * dig2 : r4
41 * carry : r5
42 * sum : r6
43 */
44
45 /* sum = dig1 + dig2 */
46 add r6, dig1, dig2;
47
48 /* if((sum < dig1) || (sum < dig2)) */
49 cmpl crf0,0,r6,dig1
50 bc 12,0,*+12
51 cmpl crf0,0,r6,dig2
52 bc 4,0,*+16
53
54 /* *carry = 1; */
55 li r7,1
56 stw r7, 0(r5)
57 b *+12
58
59 /* else *carry = 0; */
60 li r7,0
61 stw r7, 0(r5)
62
63 /* return sum in r3 */
64 mr. r3,r6
65 blr
66 }
67
68 /*
69 * Add a single digit value to a double digit accumulator in place.
70 * Carry out of the MSD of the accumulator is not handled.
71 * This should work any size giantDigits up to unsigned int.
72 */
73 asm void giantAddDouble(
74 register giantDigit *accLow, /* IN/OUT */
75 register giantDigit *accHigh, /* IN/OUT */
76 register giantDigit val)
77 {
78 /*
79 * r3 : accLow
80 * r4 : accHi
81 * r5 : val
82 * r6 : sumLo
83 * r7 : *accLow
84 */
85
86 /* giantDigit sumLo = *accLow + val; */
87 lwz r7,0(accLow)
88 add r6,r7,val
89
90 /* if((sumLo < *accLow) || (sumLo < val)) { */
91 cmpl crf0,0,r6,r7
92 bc 12,0,*+12
93 cmpl crf0,0,r6,val
94 bc 4,0,*+16
95
96 /* (*accHigh)++; */
97 lwz r7, 0(accHigh)
98 addi r7,r7,1
99 stw r7, 0(accHigh)
100
101 /* *accLow = sumLo; */
102 stw r6,0(accLow)
103 blr
104 }
105
106 asm giantDigit giantSubDigits(
107 register giantDigit a,
108 register giantDigit b,
109 register giantDigit *borrow) /* RETURNED, 0 or 1 */
110
111 {
112 /* a : r3
113 b : r4
114 borrow : r5
115 diff : r6 */
116
117 /* giantDigit diff = a - b; */
118 subf r6, b, a;
119
120 /* if(a < b) */
121 cmpl crf0,0,a,b
122 bc 4,0,*+16
123
124 /* *borrow = 1; */
125 li r7,1
126 stw r7, 0(borrow)
127 b *+12
128
129 /* else *borrow = 0; */
130 li r7,0
131 stw r7, 0(borrow)
132
133 /* return diff in r3 */
134 mr. r3,r6
135 blr
136 }
137
138 asm void giantMulDigits(
139 register giantDigit dig1,
140 register giantDigit dig2,
141 register giantDigit *lowProduct, /* RETURNED, low digit */
142 register giantDigit *hiProduct) /* RETURNED, high digit */
143 {
144 /* r3 : dig1
145 r4 : dig2
146 r5 : lowProduct
147 r6 : hiProduct */
148
149 /* dprod = (unsigned long long)dig1 * (unsigned long long)dig2; */
150 mullw r7, dig1, dig2 /* r7 = low(dig1 * dig2) */
151 mulhwu r8, dig1, dig2 /* r8 - hi(dig1 * dig2) */
152
153 /* *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); */
154 stw r8, 0(hiProduct)
155
156 /* *lowProduct = (giantDigit)dprod; */
157 stw r7, 0(lowProduct)
158 blr
159 }
160
161 asm giantDigit VectorMultiply(
162 register giantDigit plierDigit, /* r3 */
163 register giantDigit *candVector, /* r4 */
164 register unsigned candLength, /* r5 */
165 register giantDigit *prodVector) /* r6 */
166 {
167 register unsigned candDex; /* index into multiplicandVector */
168 register giantDigit lastCarry;
169 register giantDigit prodLo;
170 register giantDigit prodHi;
171 register unsigned scr1;
172 register unsigned sumLo;
173
174 fralloc
175
176 /* giantDigit lastCarry = 0; */
177 li lastCarry,0
178
179
180 /* for(candDex=0; candDex<candLength; ++candDex) { */
181 li candDex,0
182 b _endLoop
183
184 /*
185 * prod = *(candVector++) * plierDigit + *prodVector + lastCarry
186 */
187 _topLoop:
188 lwz scr1,0(candVector) /* *candVector --> scr1 */
189 addi candVector,candVector,4 /* candVector++ */
190
191 mullw prodLo,scr1,plierDigit /* prodLo = low(*candVector * plierDigit) */
192 mulhwu prodHi,scr1,plierDigit /* prodHi = high(*candVector * plierDigit) */
193
194 /* giantAddDouble(&prodLo, &prodHi, *prodVector); */
195 lwz scr1,0(prodVector) /* *prodVector --> r9 */
196 add sumLo,prodLo,scr1 /* prodLo + *prodVector --> sumLo */
197 cmpl crf0,0,sumLo,prodLo /* sumLo < prodLo? */
198 bc 12,0,_carry1
199 cmpl crf0,0,sumLo,scr1 /* sumLo < *prodVector? */
200 bc 4,0,_noCar1
201 _carry1:
202 addi prodHi,prodHi,1 /* prodHi++ */
203 _noCar1:
204 mr. prodLo,sumLo /* prodLo := sumLo */
205
206 /* giantAddDouble(&prodLo, &prodHi, lastCarry); */
207 add sumLo,sumLo,lastCarry /* sumLo += lastCarry */
208 cmpl crf0,0,sumLo,prodLo /* sumLo < prodLo? */
209 bc 12,0,_carry2
210 cmpl crf0,0,sumLo,lastCarry /* sumLo < lastCarry? */
211 bc 4,0,_noCar2
212 _carry2:
213 addi prodHi,prodHi,1 /* prodHi++ */
214 _noCar2:
215 mr. prodLo,sumLo /* prodLo := sumLo */
216
217 /* *(prodVector++) = prodLo; */
218 stw prodLo,0(prodVector) /* prodLo --> *prodVector */
219 addi prodVector,prodVector,4 /* prodVector++ */
220
221 /* lastCarry = prodHi; */
222 mr. lastCarry,prodHi
223
224 /* } */
225 addi candDex,candDex,1 /* candDex++ */
226 _endLoop:
227 cmpl crf0,0,candDex,candLength /* candDex < candLength? */
228 bc 12,0,_topLoop
229
230 /* return lastCarry; */
231 mr. r3,lastCarry /* return lastCarry in r3 */
232 frfree
233 blr
234 }
235
236 #endif // PPC_GIANT_PORT_INLINE