#define BDNZ BC 16,0,
#define BDNE BC 0,2,
#define BLT BC 0xC,0,
/*
* mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
*
* p -= b*m
*
* each step looks like:
* hi,lo = m*b[i]
* lo += oldhi + carry
* hi += carry
* p[i] += lo
* oldhi = hi
*
* the registers are:
* b = R3
* n = R4
* m = R5
* p = R6
* i = R7
* hi = R8 - constrained by hardware
* lo = R9 - constrained by hardware
* oldhi = R10
* tmp = R11
* borrow = R12
*
*/
TEXT mpvecdigmulsub(SB),$0
MOVW n+4(FP),R10
MOVW R10,CTR
MOVW m+8(FP),R5
MOVW p+12(FP),R6
SUB $4, R3 /* pre decrement for MOVWU's */
SUBC $4, R6 /* pre decrement for MOVWU's and set carry */
MOVW XER,R12
MOVW R0, R10
_mulsubloop:
MOVWU 4(R3),R9 /* lo = b[i] */
MOVW 4(R6),R11 /* tmp = p[i] */
MULHWU R9,R5,R8 /* hi = (b[i] * m)>>32 */
MULLW R9,R5,R9 /* lo = b[i] * m */
ADDC R10,R9 /* lo += oldhi */
ADDE R0,R8 /* hi += carry */
MOVW R12,XER
SUBE R9,R11 /* tmp -= lo */
MOVW XER,R12
MOVWU R11,4(R6) /* p[i] = tmp */
MOVW R8,R10 /* oldhi = hi */
BDNZ _mulsubloop
MOVW 4(R6),R11 /* tmp = p[i] */
MOVW R12,XER
SUBE R10,R11 /* tmp -= lo */
MOVWU R11,4(R6) /* p[i] = tmp */
/* return -1 if the result was negative, +1 otherwise */
SUBECC R0,R0,R3
BLT _mulsub2
MOVW $1,R3
_mulsub2:
RETURN
|