mpvecdigmuladd.s 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /*
  2. * mpvecdigmul(mpdigit *b, int n, mpdigit m, mpdigit *p)
  3. *
  4. * p += b*m
  5. *
  6. * each step look 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. * hi = DX - constrained by hardware
  15. * lo = AX - constrained by hardware
  16. * b+n = SI - can't be BP
  17. * p+n = DI - can't be BP
  18. * i-n = BP
  19. * m = BX
  20. * oldhi = CX
  21. *
  22. */
  23. TEXT mpvecdigmuladd(SB),$0
  24. /* MOVQ b+0(FP),SI */
  25. MOVQ RARG,SI
  26. MOVL n+8(FP),CX
  27. MOVL m+16(FP),BX
  28. MOVQ p+24(FP),DI
  29. MOVL CX,BP
  30. NEGQ BP /* BP = -n */
  31. SHLL $2,CX
  32. ADDQ CX,SI /* SI = b + n */
  33. ADDQ CX,DI /* DI = p + n */
  34. XORL CX,CX
  35. _muladdloop:
  36. MOVL (SI)(BP*4),AX /* lo = b[i] */
  37. MULL BX /* hi, lo = b[i] * m */
  38. ADDL CX,AX /* lo += oldhi */
  39. JCC _muladdnocarry1
  40. INCL DX /* hi += carry */
  41. _muladdnocarry1:
  42. ADDL AX,(DI)(BP*4) /* p[i] += lo */
  43. JCC _muladdnocarry2
  44. INCL DX /* hi += carry */
  45. _muladdnocarry2:
  46. MOVL DX,CX /* oldhi = hi */
  47. INCQ BP /* i++ */
  48. JNZ _muladdloop
  49. XORL AX,AX
  50. ADDL CX,(DI)(BP*4) /* p[n] + oldhi */
  51. ADCL AX,AX /* return carry out of p[n] */
  52. RET