mpvecdigmulsub.s 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /*
  2. * mpvecdigmulsub(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 mpvecdigmulsub(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. _mulsubloop:
  31. MOVW 0(R1), R9 /* lo = b[i] */
  32. ADDU $4, R1
  33. MOVW 0(R6), R11 /* tmp = p[i] */
  34. MULU R9, R5
  35. MOVW HI, R8 /* hi = (b[i] * m)>>32 */
  36. MOVW LO, R9 /* lo = b[i] * m */
  37. ADDU R10, R9 /* lo += oldhi */
  38. SGTU R10, R9, R2
  39. ADDU R2, R8 /* hi += carry */
  40. SUBU R9, R11, R3 /* tmp -= lo */
  41. SGTU R3, R11, R2
  42. ADDU R2, R8 /* hi += carry */
  43. MOVW R3, 0(R6) /* p[i] = tmp */
  44. ADDU $4, R6
  45. MOVW R8, R10 /* oldhi = hi */
  46. SUBU $1, R4
  47. BNE R4, _mulsubloop
  48. MOVW 0(R6), R11 /* tmp = p[i] */
  49. SUBU R10, R11, R3 /* tmp -= oldhi */
  50. MOVW R3, 0(R6) /* p[i] = tmp */
  51. SGTU R3, R11, R1
  52. BNE R1, _mulsub2
  53. MOVW $1, R1 /* return +1 for positive result */
  54. RET
  55. _mulsub2:
  56. MOVW $-1, R1 /* return -1 for negative result */
  57. RET