mpvecdigmuladd.s 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p)
  3. *
  4. * p += b*m
  5. *
  6. * each step looks like:
  7. * hi,lo = m*b[i]
  8. * lo += oldhi + carry
  9. * hi += carry
  10. * p[i] += lo
  11. * oldhi = hi
  12. *
  13. * the registers are:
  14. * b = R1
  15. * n = R4
  16. * m = R5
  17. * p = R6
  18. * i = R7
  19. * hi = R8 - constrained by hardware
  20. * lo = R9 - constrained by hardware
  21. * oldhi = R10
  22. * tmp = R11
  23. *
  24. */
  25. TEXT mpvecdigmuladd(SB),$0
  26. MOVW n+4(FP),R4
  27. MOVW m+8(FP),R5
  28. MOVW p+12(FP),R6
  29. MOVW R0, R10 /* oldhi = 0 */
  30. BEQ R6, _muladd1
  31. _muladdloop:
  32. MOVW 0(R1), R9 /* lo = b[i] */
  33. ADDU $4, R1
  34. MOVW 0(R6), R11 /* tmp = p[i] */
  35. MULU R9, R5
  36. MOVW HI, R8 /* hi = (b[i] * m)>>32 */
  37. MOVW LO, R9 /* lo = b[i] * m */
  38. ADDU R10, R9 /* lo += oldhi */
  39. SGTU R10, R9, R2
  40. ADDU R2, R8 /* hi += carry */
  41. ADDU R9, R11 /* tmp += lo */
  42. SGTU R9, R11, R2
  43. ADDU R2, R8 /* hi += carry */
  44. MOVW R11, 0(R6) /* p[i] = tmp */
  45. ADDU $4, R6
  46. MOVW R8, R10 /* oldhi = hi */
  47. SUBU $1, R4
  48. BNE R4, _muladdloop
  49. _muladd1:
  50. MOVW 0(R6), R11 /* tmp = p[i] */
  51. ADDU R10, R11 /* tmp += oldhi */
  52. MOVW R11, 0(R6) /* p[i] = tmp */
  53. RET