xref: /plan9-contrib/sys/src/libmp/amd64/mpvecdigmulsub.s (revision 272efad760864ee41cfe633b56aea9b4f5cf3ae7)
1/*
2 *	mpvecdigmulsub(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 = SI		- can't be BP
17 *		p = DI		- can't be BP
18 *		i = BP
19 *		n = CX		- constrained by LOOP instr
20 *		m = BX
21 *		oldhi = R8
22 *
23 */
24TEXT	mpvecdigmulsub(SB),$0
25
26/*	MOVL	b+0(FP),SI	*/
27	MOVQ	RARG,SI
28	MOVL	n+8(FP),CX
29	MOVL	m+16(FP),BX
30	MOVQ	p+24(FP),DI
31	XORL	BP,BP
32	MOVL	BP,R8
33_mulsubloop:
34	MOVL	(SI)(BP*4),AX		/* lo = b[i] */
35	MULL	BX			/* hi, lo = b[i] * m */
36	ADDL	R8,AX		/* lo += oldhi */
37	JCC	_mulsubnocarry1
38	INCL	DX			/* hi += carry */
39_mulsubnocarry1:
40	SUBL	AX,(DI)(BP*4)
41	JCC	_mulsubnocarry2
42	INCL	DX			/* hi += carry */
43_mulsubnocarry2:
44	MOVL	DX,R8
45	INCL	BP
46	LOOP	_mulsubloop
47	SUBL	R8,(DI)(BP*4)
48	JCC	_mulsubnocarry3
49	MOVQ	$-1,AX
50	RET
51_mulsubnocarry3:
52	MOVQ	$1,AX
53	RET
54