xref: /plan9/sys/src/libmp/386/mpvecdigmuladd.s (revision 59cc4ca53493a3c6d2349fe2b7f7c40f7dce7294)
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 */
23TEXT	mpvecdigmuladd(SB),$0
24
25	MOVL	b+0(FP),SI
26	MOVL	n+4(FP),CX
27	MOVL	m+8(FP),BX
28	MOVL	p+12(FP),DI
29	MOVL	CX,BP
30	NEGL	BP		/* BP = -n */
31	SHLL	$2,CX
32	ADDL	CX,SI		/* SI = b + n */
33	ADDL	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	INCL	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
53