lbnppc.c
上传用户:zbbssh
上传日期:2007-01-08
资源大小:196k
文件大小:11k
源码类别:

CA认证

开发平台:

C/C++

  1. #include "lbnppc.h"
  2. #include "ppcasm.h"
  3. /*
  4.  * lbnppc.c - Assembly primitives for the bignum library, PowerPC version.
  5.  *
  6.  * Copyright (c) 1995  Colin Plumb.  All rights reserved.
  7.  * For licensing and other legal details, see the file legal.c.
  8.  *
  9.  * On the PPC 601, unrolling the loops more doesn't seem to speed things
  10.  * up at all.  I'd be curious if other chips differed.
  11.  */
  12. #ifndef UNROLL
  13. #define UNROLL 1
  14. #endif
  15. /*
  16.  * MulN1 expects (*out, *in, len, k), count >= 1
  17.  *                r3    r4   r5   r6
  18.  */
  19. static const unsigned mulN1[] = {
  20. PPC_LWZ(7,4,0),  /* Load first word of in in r7 */
  21. PPC_MTCTR(5), /* Move count into CTR */
  22. PPC_MULLW(8,7,6), /* Low half of multiply in r8 */
  23. PPC_ADDIC(0,0,0), /* Clear carry bit for loop */
  24. PPC_MULHWU(5,7,6), /* High half of multiply in r5 */
  25. PPC_STW(8,3,0),
  26. PPC_BC(18,31,1+6*UNROLL), /* Branch to Label if --ctr == 0 */
  27. #if UNROLL >= 4
  28. /* Loop: */
  29. PPC_LWZU(7,4,4), /* r7 = *++in */
  30. PPC_MULLW(8,7,6), /* r8 = low word of product */
  31. PPC_ADDE(8,8,5), /* Add carry word r5 and bit CF to r8 */
  32. PPC_STWU(8,3,4), /* *++out = r8 */
  33. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  34. PPC_BC(18,31,19), /* Branch to Label if --ctr == 0 */
  35. #endif
  36. #if UNROLL >= 3
  37. /* Loop: */
  38. PPC_LWZU(7,4,4), /* r7 = *++in */
  39. PPC_MULLW(8,7,6), /* r8 = low word of product */
  40. PPC_ADDE(8,8,5), /* Add carry word r5 and bit CF to r8 */
  41. PPC_STWU(8,3,4), /* *++out = r8 */
  42. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  43. PPC_BC(18,31,13), /* Branch to Label if --ctr == 0 */
  44. #endif
  45. #if UNROLL >= 2
  46. /* Loop: */
  47. PPC_LWZU(7,4,4), /* r7 = *++in */
  48. PPC_MULLW(8,7,6), /* r8 = low word of product */
  49. PPC_ADDE(8,8,5), /* Add carry word r5 and bit CF to r8 */
  50. PPC_STWU(8,3,4), /* *++out = r8 */
  51. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  52. PPC_BC(18,31,7), /* Branch to Label if --ctr == 0 */
  53. #endif
  54. /* Loop: */
  55. PPC_LWZU(7,4,4), /* r7 = *++in */
  56. PPC_MULLW(8,7,6), /* r8 = low word of product */
  57. PPC_ADDE(8,8,5), /* Add carry word r5 and bit CF to r8 */
  58. PPC_STWU(8,3,4), /* *++out = r8 */
  59. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  60. PPC_BC(16,31,1-6*UNROLL), /* Branch to Loop if --ctr != 0 */
  61. /* Label: */
  62. PPC_ADDZE(5,5), /* Add carry flag to r5 */
  63. PPC_STW(5,3,4), /* out[1] = r5 */
  64. PPC_BLR()
  65. };
  66. /*
  67.  * MulAdd1 expects (*out, *in, len, k), count >= 1
  68.  *                  r3    r4   r5   r6
  69.  */
  70. static unsigned const mulAdd1[] = {
  71. PPC_LWZ(7,4,0),  /* Load first word of in in r7 */
  72. PPC_LWZ(0,3,0), /* Load first word of out into r0 */
  73. PPC_MTCTR(5), /* Move count into CTR */
  74. PPC_MULLW(8,7,6), /* Low half of multiply in r8 */
  75. PPC_MULHWU(5,7,6), /* High half of multiply in r5 */
  76. PPC_ADDC(8,8,0), /* r8 = r8 + r0 */
  77. PPC_STW(8,3,0), /* Store result to memory */
  78. PPC_BC(18,31,1+9*UNROLL), /* Branch to Label if --ctr == 0 */
  79. #if UNROLL >= 4
  80. /* Loop: */
  81. PPC_LWZU(7,4,4), /* r7 = *++in */
  82. PPC_LWZU(0,3,4), /* r0 = *++out */
  83. PPC_MULLW(8,7,6), /* r8 = low word of product */
  84. PPC_ADDE(8,8,5),  /* Add carry word r5 and carry bit CF to r8 */
  85. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  86. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  87. PPC_ADDC(8,8,0), /* r8 = r8 + r0 */
  88. PPC_STW(8,3,0),  /* *out = r8 */
  89. PPC_BC(18,31,28), /* Branch to Label if --ctr == 0 */
  90. #endif
  91. #if UNROLL >= 3
  92. /* Loop: */
  93. PPC_LWZU(7,4,4), /* r7 = *++in */
  94. PPC_LWZU(0,3,4), /* r0 = *++out */
  95. PPC_MULLW(8,7,6), /* r8 = low word of product */
  96. PPC_ADDE(8,8,5),  /* Add carry word r5 and carry bit CF to r8 */
  97. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  98. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  99. PPC_ADDC(8,8,0), /* r8 = r8 + r0 */
  100. PPC_STW(8,3,0),  /* *out = r8 */
  101. PPC_BC(18,31,19), /* Branch to Label if --ctr == 0 */
  102. #endif
  103. #if UNROLL >= 2
  104. /* Loop: */
  105. PPC_LWZU(7,4,4), /* r7 = *++in */
  106. PPC_LWZU(0,3,4), /* r0 = *++out */
  107. PPC_MULLW(8,7,6), /* r8 = low word of product */
  108. PPC_ADDE(8,8,5),  /* Add carry word r5 and carry bit CF to r8 */
  109. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  110. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  111. PPC_ADDC(8,8,0), /* r8 = r8 + r0 */
  112. PPC_STW(8,3,0),  /* *out = r8 */
  113. PPC_BC(18,31,10), /* Branch to Label if --ctr == 0 */
  114. #endif
  115. /* Loop: */
  116. PPC_LWZU(7,4,4), /* r7 = *++in */
  117. PPC_LWZU(0,3,4), /* r0 = *++out */
  118. PPC_MULLW(8,7,6), /* r8 = low word of product */
  119. PPC_ADDE(8,8,5),  /* Add carry word r5 and carry bit CF to r8 */
  120. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  121. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  122. PPC_ADDC(8,8,0), /* r8 = r8 + r0 */
  123. PPC_STW(8,3,0),  /* *out = r8 */
  124. PPC_BC(16,31,1-9*UNROLL), /* Branch to Loop if --ctr != 0 */
  125. /* Label: */
  126. PPC_ADDZE(3,5), /* Add carry flag to r5 and move to r3 */
  127. PPC_BLR()
  128. };
  129. /*
  130.  * MulSub1 expects (*out, *in, len, k), count >= 1
  131.  *                  r3    r4   r5   r6
  132.  *
  133.  * Multiply and subtract is rather a pain.  If the subtract of the
  134.  * low word of the product from out[i] generates a borrow, we want to
  135.  * increment the carry word (initially in the range 0..0xfffffffe).
  136.  * However, the PPC's carry bit CF is *clear* after a subtract, so
  137.  * we want to add (1-CF) to the carry word.  This is done using two
  138.  * instructions:
  139.  * SUBFME, subtract from minus one extended.  This computes
  140.  * rD = ~rS + 0xffffffff + CF.  Since rS is from 0 to 0xfffffffe,
  141.  * ~rS is from 1 through 0xffffffff, and the sum with 0xffffffff+CF is
  142.  * from 0 through 0xfffffffff, setting the carry flag unconditionally, and
  143.  * NOR, which is used as a bitwise invert NOT instruction.
  144.  * The SUBFME performs the computation rD = ~rS + 0xffffffff + CF,
  145.  * = (-rS - 1) + (CF - 1) = -(rS - CF + 1) - 1 = ~(rS + 1-CF),
  146.  * which is the bitwise complement of the value we want.
  147.  * We want to add the complement of that result to the low word of the
  148.  * product, which is just what a subtract would do, if only we could get
  149.  * the carry flag clear.  But it's always set, except for SUBFE, and the
  150.  * operation we just performed unconditionally *sets* the carry flag.  Ugh.
  151.  * So find the complement in a separate instruction.
  152.  */
  153. static unsigned const mulSub1[] = {
  154. PPC_LWZ(7,4,0),  /* Load first word of in in r7 */
  155. PPC_LWZ(0,3,0), /* Load first word of out into r0 */
  156. PPC_MTCTR(5), /* Move count into CTR */
  157. PPC_MULLW(8,7,6), /* Low half of multiply in r8 */
  158. PPC_MULHWU(5,7,6), /* High half of multiply in r5 */
  159. PPC_SUBFC(8,8,0), /* r8 = r0 - r8, setting CF */
  160. PPC_STW(8,3,0), /* Store result to memory */
  161. PPC_SUBFME(5,5), /* First of two instructions to add (1-CF) to r5 */
  162. PPC_BC(18,31,1+11*UNROLL), /* Branch to Label if --ctr == 0 */
  163. #if UNROLL >= 4
  164. /* Loop: */
  165. PPC_LWZU(7,4,4), /* r7 = *++in */
  166. PPC_LWZU(0,3,4), /* r0 = *++out */
  167. PPC_NOR(5,5,5), /* Second of two instructions to add (1-CF) to r5 */
  168. PPC_MULLW(8,7,6), /* r8 = low word of product */
  169. PPC_ADDC(8,8,5),  /* Add carry word r5 to r8 */
  170. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  171. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  172. PPC_SUBFC(8,8,0), /* r8 = r0 - r8, setting CF */
  173. PPC_STW(8,3,0),  /* *out = r8 */
  174. PPC_SUBFME(5,5), /* First of two instructions to add (1-CF) to r5 */
  175. PPC_BC(18,31,34), /* Branch to Label if --ctr == 0 */
  176. #endif
  177. #if UNROLL >= 3
  178. /* Loop: */
  179. PPC_LWZU(7,4,4), /* r7 = *++in */
  180. PPC_LWZU(0,3,4), /* r0 = *++out */
  181. PPC_NOR(5,5,5), /* Second of two instructions to add (1-CF) to r5 */
  182. PPC_MULLW(8,7,6), /* r8 = low word of product */
  183. PPC_ADDC(8,8,5),  /* Add carry word r5 to r8 */
  184. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  185. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  186. PPC_SUBFC(8,8,0), /* r8 = r0 - r8, setting CF */
  187. PPC_STW(8,3,0),  /* *out = r8 */
  188. PPC_SUBFME(5,5), /* First of two instructions to add (1-CF) to r5 */
  189. PPC_BC(18,31,23), /* Branch to Label if --ctr == 0 */
  190. #endif
  191. #if UNROLL >= 2
  192. /* Loop: */
  193. PPC_LWZU(7,4,4), /* r7 = *++in */
  194. PPC_LWZU(0,3,4), /* r0 = *++out */
  195. PPC_NOR(5,5,5), /* Second of two instructions to add (1-CF) to r5 */
  196. PPC_MULLW(8,7,6), /* r8 = low word of product */
  197. PPC_ADDC(8,8,5),  /* Add carry word r5 to r8 */
  198. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  199. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  200. PPC_SUBFC(8,8,0), /* r8 = r0 - r8, setting CF */
  201. PPC_STW(8,3,0),  /* *out = r8 */
  202. PPC_SUBFME(5,5), /* First of two instructions to add (1-CF) to r5 */
  203. PPC_BC(18,31,12), /* Branch to Label if --ctr == 0 */
  204. #endif
  205. /* Loop: */
  206. PPC_LWZU(7,4,4), /* r7 = *++in */
  207. PPC_LWZU(0,3,4), /* r0 = *++out */
  208. PPC_NOR(5,5,5), /* Second of two instructions to add (1-CF) to r5 */
  209. PPC_MULLW(8,7,6), /* r8 = low word of product */
  210. PPC_ADDC(8,8,5),  /* Add carry word r5 to r8 */
  211. PPC_MULHWU(5,7,6), /* r5 is high word of product, for carry word */
  212. PPC_ADDZE(5,5), /* Add carry bit from low add to r5 */
  213. PPC_SUBFC(8,8,0), /* r8 = r0 - r8, setting CF */
  214. PPC_STW(8,3,0),  /* *out = r8 */
  215. PPC_SUBFME(5,5), /* First of two instructions to add (1-CF) to r5 */
  216. PPC_BC(16,31,1-UNROLL*11), /* Branch to Loop if --ctr != 0 */
  217. /* Label: */
  218. PPC_NOR(3,5,5), /* Finish adding (1-CF) to r5, store in r3 */
  219. PPC_BLR()
  220. };
  221. #if 0
  222. /*
  223.  * Args: BNWORD32 *n, BNWORD32 const *mod, unsigned mlen, BNWORD32 inv)
  224.  *                r3                  r4            r5             r6
  225.  * r7, r8 and r9 are the triple-width accumulator.
  226.  * r0 and r10 are temporary registers.
  227.  * r11 and r12 are temporary pointers into n and mod, respectively. 
  228.  * r2 (!) is another temporary register.
  229.  */
  230. static unsigned const montReduce[] = {
  231. PPC_MTCTR(5), /* ??? */
  232. PPC_LWZ(7,3,0), /* Load low word of n into r7 */
  233. PPC_LWZ(10,4,0), /* Fetch low word of mod */
  234. PPC_MULLW(0,7,6), /* Invert r7 into r0 */
  235. PPC_STW(0,3,0), /* Store back for future use */
  236. PPC_MULHWU(8,10,7), /* Get high word of whatnot */
  237. PPC_MULLW(10,10,7), /* Get low word of it */
  238. PPC_ADDC(7,7,10), /* Add low word of product to r7 */
  239. PPC_ADDZE(8,8), /* Add carry to high word */
  240. PPC_
  241. PPC_MULHW(8,7,6),
  242. PPC_ADDC(7,7,0), /* Add inverse back to r7 */
  243. PPC_ADDZE(8,8),
  244. PPC_
  245. PPC_LWZU(
  246. /* Loop: */
  247. PPC_LWZU(0,11,4),
  248. PPC_LWZU(10,23,-4),
  249. PPC_MULLW(2,0,10),
  250. PPC_ADDC(7,7,2),
  251. PPC_MULHWU(0,0,10),
  252. PPC_ADDE(8,8,0),
  253. PPC_ADDZE(9,9),
  254. PPC_BC(16,31,-7), /* Branch to Loop if --ctr != 0 */
  255. PPC_ADDIC_(count,-1),
  256. PPC_LWZU(0,x,4),
  257. PPC_ADDC(0,7,0),
  258. PPC_STW(0,x,0),
  259. PPC_ADDZE(7,8),
  260. PPC_ADDZE(8,9),
  261. PPC_LI(9,0),
  262. PPC_BC(xx,2,yy),
  263. };
  264. #endif
  265. /*
  266.  * Three overlapped transition vectors for three functions.
  267.  * A PowerPC transition vector for a (potentially) inter-module
  268.  * jump or call consists of two words, an instruction address
  269.  * and a Table Of Contents (TOC) pointer, which is loaded into
  270.  * r1.  Since none of the routines here have global variables,
  271.  * they don't need a TOC pointer, so the value is unimportant.
  272.  * This array places an unintersting 32-bit value after each address.
  273.  */
  274. unsigned const * const lbnPPC_tv[] = {
  275. mulN1,
  276. mulAdd1,
  277. mulSub1,
  278. 0
  279. };
  280. /* 45678901234567890123456789012345678901234567890123456789012345678901234567 */