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 32asm 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 */ 73asm 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 106asm 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 138asm 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 161asm 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 237