X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_cryptkit/lib/giantPort_PPC.c diff --git a/Security/libsecurity_cryptkit/lib/giantPort_PPC.c b/Security/libsecurity_cryptkit/lib/giantPort_PPC.c new file mode 100644 index 00000000..c9b26450 --- /dev/null +++ b/Security/libsecurity_cryptkit/lib/giantPort_PPC.c @@ -0,0 +1,236 @@ +/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. + * + * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT + * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE + * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE + * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, + * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL + * EXPOSE YOU TO LIABILITY. + *************************************************************************** + * + * giantPort_PPC.c - PPC-dependent giant definitions. + * + * Revision History + * ---------------- + * 10/06/98 ap + * Changed to compile with C++. + * 06 Apr 1998 at Apple + * Created. + */ + +#include "feeDebug.h" +#include "platform.h" +#include "giantPort_PPC.h" + +#if !PPC_GIANT_PORT_INLINE + + +/* + * Multiple-precision arithmetic routines/macros. + */ + +asm giantDigit giantAddDigits( + register giantDigit dig1, + register giantDigit dig2, + register giantDigit *carry) /* RETURNED, 0 or 1 */ + +{ + /* + * dig1 : r3 + * dig2 : r4 + * carry : r5 + * sum : r6 + */ + + /* sum = dig1 + dig2 */ + add r6, dig1, dig2; + + /* if((sum < dig1) || (sum < dig2)) */ + cmpl crf0,0,r6,dig1 + bc 12,0,*+12 + cmpl crf0,0,r6,dig2 + bc 4,0,*+16 + + /* *carry = 1; */ + li r7,1 + stw r7, 0(r5) + b *+12 + + /* else *carry = 0; */ + li r7,0 + stw r7, 0(r5) + + /* return sum in r3 */ + mr. r3,r6 + blr +} + +/* + * Add a single digit value to a double digit accumulator in place. + * Carry out of the MSD of the accumulator is not handled. + * This should work any size giantDigits up to unsigned int. + */ +asm void giantAddDouble( + register giantDigit *accLow, /* IN/OUT */ + register giantDigit *accHigh, /* IN/OUT */ + register giantDigit val) +{ + /* + * r3 : accLow + * r4 : accHi + * r5 : val + * r6 : sumLo + * r7 : *accLow + */ + + /* giantDigit sumLo = *accLow + val; */ + lwz r7,0(accLow) + add r6,r7,val + + /* if((sumLo < *accLow) || (sumLo < val)) { */ + cmpl crf0,0,r6,r7 + bc 12,0,*+12 + cmpl crf0,0,r6,val + bc 4,0,*+16 + + /* (*accHigh)++; */ + lwz r7, 0(accHigh) + addi r7,r7,1 + stw r7, 0(accHigh) + + /* *accLow = sumLo; */ + stw r6,0(accLow) + blr +} + +asm giantDigit giantSubDigits( + register giantDigit a, + register giantDigit b, + register giantDigit *borrow) /* RETURNED, 0 or 1 */ + +{ + /* a : r3 + b : r4 + borrow : r5 + diff : r6 */ + + /* giantDigit diff = a - b; */ + subf r6, b, a; + + /* if(a < b) */ + cmpl crf0,0,a,b + bc 4,0,*+16 + + /* *borrow = 1; */ + li r7,1 + stw r7, 0(borrow) + b *+12 + + /* else *borrow = 0; */ + li r7,0 + stw r7, 0(borrow) + + /* return diff in r3 */ + mr. r3,r6 + blr +} + +asm void giantMulDigits( + register giantDigit dig1, + register giantDigit dig2, + register giantDigit *lowProduct, /* RETURNED, low digit */ + register giantDigit *hiProduct) /* RETURNED, high digit */ +{ + /* r3 : dig1 + r4 : dig2 + r5 : lowProduct + r6 : hiProduct */ + + /* dprod = (unsigned long long)dig1 * (unsigned long long)dig2; */ + mullw r7, dig1, dig2 /* r7 = low(dig1 * dig2) */ + mulhwu r8, dig1, dig2 /* r8 - hi(dig1 * dig2) */ + + /* *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); */ + stw r8, 0(hiProduct) + + /* *lowProduct = (giantDigit)dprod; */ + stw r7, 0(lowProduct) + blr +} + +asm giantDigit VectorMultiply( + register giantDigit plierDigit, /* r3 */ + register giantDigit *candVector, /* r4 */ + register unsigned candLength, /* r5 */ + register giantDigit *prodVector) /* r6 */ +{ + register unsigned candDex; /* index into multiplicandVector */ + register giantDigit lastCarry; + register giantDigit prodLo; + register giantDigit prodHi; + register unsigned scr1; + register unsigned sumLo; + + fralloc + + /* giantDigit lastCarry = 0; */ + li lastCarry,0 + + + /* for(candDex=0; candDex scr1 */ + addi candVector,candVector,4 /* candVector++ */ + + mullw prodLo,scr1,plierDigit /* prodLo = low(*candVector * plierDigit) */ + mulhwu prodHi,scr1,plierDigit /* prodHi = high(*candVector * plierDigit) */ + + /* giantAddDouble(&prodLo, &prodHi, *prodVector); */ + lwz scr1,0(prodVector) /* *prodVector --> r9 */ + add sumLo,prodLo,scr1 /* prodLo + *prodVector --> sumLo */ + cmpl crf0,0,sumLo,prodLo /* sumLo < prodLo? */ + bc 12,0,_carry1 + cmpl crf0,0,sumLo,scr1 /* sumLo < *prodVector? */ + bc 4,0,_noCar1 +_carry1: + addi prodHi,prodHi,1 /* prodHi++ */ +_noCar1: + mr. prodLo,sumLo /* prodLo := sumLo */ + + /* giantAddDouble(&prodLo, &prodHi, lastCarry); */ + add sumLo,sumLo,lastCarry /* sumLo += lastCarry */ + cmpl crf0,0,sumLo,prodLo /* sumLo < prodLo? */ + bc 12,0,_carry2 + cmpl crf0,0,sumLo,lastCarry /* sumLo < lastCarry? */ + bc 4,0,_noCar2 +_carry2: + addi prodHi,prodHi,1 /* prodHi++ */ +_noCar2: + mr. prodLo,sumLo /* prodLo := sumLo */ + + /* *(prodVector++) = prodLo; */ + stw prodLo,0(prodVector) /* prodLo --> *prodVector */ + addi prodVector,prodVector,4 /* prodVector++ */ + + /* lastCarry = prodHi; */ + mr. lastCarry,prodHi + + /* } */ + addi candDex,candDex,1 /* candDex++ */ +_endLoop: + cmpl crf0,0,candDex,candLength /* candDex < candLength? */ + bc 12,0,_topLoop + + /* return lastCarry; */ + mr. r3,lastCarry /* return lastCarry in r3 */ + frfree + blr +} + +#endif // PPC_GIANT_PORT_INLINE