xref: /plan9/sys/src/libmp/386/mpvecdigmulsub.s (revision 1a4050f5b2ddf426a278e3233ccd7b6bcb0639b8)
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 = EX
22 *
23 */
24TEXT	mpvecdigmulsub(SB),$4
25
26	MOVL	b+0(FP),SI
27	MOVL	n+4(FP),CX
28	MOVL	m+8(FP),BX
29	MOVL	p+12(FP),DI
30	XORL	BP,BP
31	MOVL	BP,0(SP)
32_mulsubloop:
33	MOVL	(SI)(BP*4),AX		/* lo = b[i] */
34	MULL	BX			/* hi, lo = b[i] * m */
35	ADDL	0(SP),AX		/* lo += oldhi */
36	JCC	_mulsubnocarry1
37	INCL	DX			/* hi += carry */
38_mulsubnocarry1:
39	SUBL	AX,(DI)(BP*4)
40	JCC	_mulsubnocarry2
41	INCL	DX			/* hi += carry */
42_mulsubnocarry2:
43	MOVL	DX,0(SP)
44	INCL	BP
45	LOOP	_mulsubloop
46	MOVL	0(SP),AX
47	SUBL	AX,(DI)(BP*4)
48	JCC	_mulsubnocarry3
49	MOVL	$-1,AX
50	RET
51_mulsubnocarry3:
52	MOVL	$1,AX
53	RET
54