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 * giantPorti486.h - OpenStep-dependent giant definitions. 12 * 13 * Revision History 14 * ---------------- 15 * 06 Apr 1998 at Apple 16 * Created. 17 */ 18 19#ifndef _CK_NSGIANT_PORT_I486_H_ 20#define _CK_NSGIANT_PORT_I486_H_ 21 22#include "giantIntegers.h" 23 24#ifdef __cplusplus 25extern "C" { 26#endif 27 28/* 29 * Add two digits, return sum. Carry bit returned as an out parameter. 30 */ 31static inline giantDigit giantAddDigits( 32 giantDigit dig1, 33 giantDigit dig2, 34 giantDigit *carry) /* RETURNED, 0 or 1 */ 35{ 36 giantDigit _sum; /* r/w %0 */ 37 asm volatile( 38 "movl %2, %0 /* _sum = dig1 */ \n" 39 "addl %3, %0 /* _sum += dig2 */ \n" 40 "jc .+9 \n" 41 "movl $0, %1 /* carry = 0 */ \n" 42 "jmp .+7 \n" 43 "movl $1, %1 /* carry = 1 */ \n" 44 : "=&r" (_sum), "=&r" (*carry) 45 : "r" (dig1), "r" (dig2)); 46 return _sum; 47} 48 49/* 50 * Add a single digit value to a double digit accumulator in place. 51 * Carry out of the MSD of the accumulator is not handled. 52 */ 53static inline void giantAddDouble( 54 giantDigit *accLow, /* IN/OUT */ 55 giantDigit *accHigh, /* IN/OUT */ 56 giantDigit val) 57{ 58 asm volatile( 59 "addl %4, %0 /* accLow += val */ \n" 60 "jnc .+3 \n" 61 "incl %1 /* accHigh++ */ \n" 62 : "=&r" (*accLow), "=&r" (*accHigh) 63 : "0" (*accLow), "1" (*accHigh), "r" (val)); 64} 65 66/* 67 * Subtract a - b, return difference. Borrow bit returned as an out parameter. 68 */ 69static inline giantDigit giantSubDigits( 70 giantDigit a, 71 giantDigit b, 72 giantDigit *borrow) /* RETURNED, 0 or 1 */ 73{ 74 giantDigit _diff; /* r/w %0 */ 75 asm volatile( 76 "movl %2, %0 /* _diff = a */ \n" 77 "subl %3, %0 /* _diff -= b */ \n" 78 "jc .+9 \n" 79 "movl $0, %1 /* borrow = 0 */ \n" 80 "jmp .+7 \n" 81 "movl $1, %1 /* borrow = 1 */ \n" 82 : "=&r" (_diff), "=&r" (*borrow) 83 : "r" (a), "r" (b)); 84 return _diff; 85} 86 87/* 88 * Multiply two digits, return two digits. 89 */ 90static inline void giantMulDigits( 91 giantDigit dig1, 92 giantDigit dig2, 93 giantDigit *lowProduct, // RETURNED, low digit 94 giantDigit *hiProduct) // RETURNED, high digit 95 96{ 97 asm volatile( 98 "movl %2, %%eax /* eax = dig1 */ \n" 99 "movl %3, %%edx /* edx = dig2 */ \n" 100 "mull %%edx /* eax *= dig2 */ \n" 101 : "=&a" (*lowProduct), "=&d" (*hiProduct) 102 : "r" (dig1), "r" (dig2) 103 : "%eax", "%edx" ); 104} 105 106/* 107 * Multiply a vector of giantDigits, candVector, by a single giantDigit, 108 * plierDigit, adding results into prodVector. Returns m.s. digit from 109 * final multiply; only candLength digits of *prodVector will be written. 110 * 111 * This one's implemented in a .s file. 112 */ 113extern giantDigit vectorMult_x86( 114 giantDigit plierDigit, 115 giantDigit *candVector, 116 unsigned candLength, 117 giantDigit *prodVector); 118 119#define VectorMultiply(pd, cv, cl, pv) vectorMult_x86(pd, cv, cl, pv) 120 121 122#ifdef __cplusplus 123} 124#endif 125 126#endif _CK_NSGIANT_PORT_I486_H_ 127