pcpbnu32arith.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (C) 2016 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "owncp.h"
  32. #include "pcpbnumisc.h"
  33. #include "pcpbnu32misc.h"
  34. #include "pcpbnu32arith.h"
  35. /*
  36. // BNU32 addition
  37. */
  38. Ipp32u cpAdd_BNU32(Ipp32u* pR, const Ipp32u* pA, const Ipp32u* pB, cpSize ns)
  39. {
  40. Ipp32u carry = 0;
  41. cpSize i;
  42. for(i=0; i<ns; i++) {
  43. Ipp64u t = (Ipp64u)carry +pA[i] + pB[i];
  44. pR[i] = LODWORD(t);
  45. carry = HIDWORD(t);
  46. }
  47. return carry;
  48. }
  49. /*
  50. // BNU32 subtraction
  51. */
  52. Ipp32u cpSub_BNU32(Ipp32u* pR, const Ipp32u* pA, const Ipp32u* pB, cpSize ns)
  53. {
  54. Ipp32u borrow = 0;
  55. cpSize i;
  56. for(i=0; i<ns; i++) {
  57. Ipp64u t = (Ipp64u)(pA[i]) - pB[i] - borrow;
  58. pR[i] = LODWORD(t);
  59. borrow = 0-HIDWORD(t);
  60. }
  61. return borrow;
  62. }
  63. /*
  64. // BNU32 decrement
  65. */
  66. Ipp32u cpDec_BNU32(Ipp32u* pR, const Ipp32u* pA, cpSize ns, Ipp32u v)
  67. {
  68. Ipp32u borrow = v;
  69. int n;
  70. for(n=0; n<ns; n++) {
  71. Ipp64u t = (Ipp64u)(pA[n]) - (Ipp64u)borrow;
  72. pR[n] = LODWORD(t);
  73. borrow = HIDWORD(t)>>(32-1);
  74. }
  75. return borrow;
  76. }
  77. /*
  78. // BNU32 mul_by_digit
  79. */
  80. Ipp32u cpMulDgt_BNU32(Ipp32u* pR, const Ipp32u* pA, cpSize nsA, Ipp32u val)
  81. {
  82. Ipp32u carry = 0;
  83. cpSize i;
  84. for(i=0; i<nsA; i++) {
  85. Ipp64u t = (Ipp64u)val * (Ipp64u)pA[i] + carry;
  86. pR[i] = LODWORD(t);
  87. carry = HIDWORD(t);
  88. }
  89. return carry;
  90. }
  91. /*
  92. // BNU32 mul_by_digit_subtract
  93. */
  94. Ipp32u cpSubMulDgt_BNU32(Ipp32u* pR, const Ipp32u* pA, cpSize nsA, Ipp32u val)
  95. {
  96. Ipp32u carry = 0;
  97. for(; nsA>0; nsA--) {
  98. Ipp64u r = (Ipp64u)*pR - (Ipp64u)(*pA++) * val - carry;
  99. *pR++ = LODWORD(r);
  100. carry = 0-HIDWORD(r);
  101. }
  102. return carry;
  103. }
  104. /*
  105. // BNU32 division
  106. */
  107. int cpDiv_BNU32(Ipp32u* pQ, cpSize* sizeQ,
  108. Ipp32u* pX, cpSize sizeX,
  109. Ipp32u* pY, cpSize sizeY)
  110. {
  111. FIX_BNU(pY,sizeY);
  112. FIX_BNU(pX,sizeX);
  113. /* special case */
  114. if(sizeX < sizeY) {
  115. if(pQ) {
  116. pQ[0] = 0;
  117. *sizeQ = 1;
  118. }
  119. return sizeX;
  120. }
  121. /* special case */
  122. if(1 == sizeY) {
  123. int i;
  124. Ipp32u r = 0;
  125. for(i=(int)sizeX-1; i>=0; i--) {
  126. Ipp64u tmp = MAKEDWORD(pX[i],r);
  127. Ipp32u q = LODWORD(tmp / pY[0]);
  128. r = LODWORD(tmp - q*pY[0]);
  129. if(pQ) pQ[i] = q;
  130. }
  131. pX[0] = r;
  132. if(pQ) {
  133. FIX_BNU(pQ,sizeX);
  134. *sizeQ = sizeX;
  135. }
  136. return 1;
  137. }
  138. /* common case */
  139. {
  140. cpSize qs = sizeX-sizeY+1;
  141. cpSize nlz = cpNLZ_BNU32(pY[sizeY-1]);
  142. /* normalization */
  143. pX[sizeX] = 0;
  144. if(nlz) {
  145. cpSize ni;
  146. pX[sizeX] = pX[sizeX-1] >> (32-nlz);
  147. for(ni=sizeX-1; ni>0; ni--)
  148. pX[ni] = (pX[ni]<<nlz) | (pX[ni-1]>>(32-nlz));
  149. pX[0] <<= nlz;
  150. for(ni=sizeY-1; ni>0; ni--)
  151. pY[ni] = (pY[ni]<<nlz) | (pY[ni-1]>>(32-nlz));
  152. pY[0] <<= nlz;
  153. }
  154. /*
  155. // division
  156. */
  157. {
  158. Ipp32u yHi = pY[sizeY-1];
  159. int i;
  160. for(i=(int)qs-1; i>=0; i--) {
  161. Ipp32u extend;
  162. /* estimate digit of quotient */
  163. Ipp64u tmp = MAKEDWORD(pX[i+sizeY-1], pX[i+sizeY]);
  164. Ipp64u q = tmp / yHi;
  165. Ipp64u r = tmp - q*yHi;
  166. /* tune estimation above */
  167. for(; HIDWORD(q) || (Ipp64u)q*pY[sizeY-2] > MAKEDWORD(pX[i+sizeY-2],r); ) {
  168. q -= 1;
  169. r += yHi;
  170. if( HIDWORD(r) )
  171. break;
  172. }
  173. /* multiply and subtract */
  174. extend = cpSubMulDgt_BNU32(pX+i, pY, sizeY, (Ipp32u)q);
  175. extend = (pX[i+sizeY] -= extend);
  176. if(extend) { /* subtracted too much */
  177. q -= 1;
  178. extend = cpAdd_BNU32(pX+i, pY, pX+i, sizeY);
  179. pX[i+sizeY] += extend;
  180. }
  181. /* store quotation digit */
  182. if(pQ) pQ[i] = LODWORD(q);
  183. }
  184. }
  185. /* de-normalization */
  186. if(nlz) {
  187. cpSize ni;
  188. for(ni=0; ni<sizeX; ni++)
  189. pX[ni] = (pX[ni]>>nlz) | (pX[ni+1]<<(32-nlz));
  190. for(ni=0; ni<sizeY-1; ni++)
  191. pY[ni] = (pY[ni]>>nlz) | (pY[ni+1]<<(32-nlz));
  192. pY[sizeY-1] >>= nlz;
  193. }
  194. FIX_BNU(pX,sizeX);
  195. if(pQ) {
  196. FIX_BNU(pQ,qs);
  197. *sizeQ = qs;
  198. }
  199. return sizeX;
  200. }
  201. }