150276Speterdnl Alpha mpn_addmul_1 -- Multiply a limb vector with a limb and add the
250276Speterdnl result to a second limb vector.
3174993Srafan
450276Speterdnl  Copyright 1992, 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
550276Speter
650276Speterdnl  This file is part of the GNU MP Library.
750276Speter
850276Speterdnl  The GNU MP Library is free software; you can redistribute it and/or modify
950276Speterdnl  it under the terms of the GNU Lesser General Public License as published
1050276Speterdnl  by the Free Software Foundation; either version 3 of the License, or (at
1150276Speterdnl  your option) any later version.
1250276Speter
1350276Speterdnl  The GNU MP Library is distributed in the hope that it will be useful, but
1450276Speterdnl  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1550276Speterdnl  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
1650276Speterdnl  License for more details.
1750276Speter
1850276Speterdnl  You should have received a copy of the GNU Lesser General Public License
1950276Speterdnl  along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.
2050276Speter
2150276Speterinclude(`../config.m4')
2250276Speter
2350276SpeterC      cycles/limb
2450276SpeterC EV4:     42
2550276SpeterC EV5:     18
2650276SpeterC EV6:      7
2750276Speter
2850276SpeterC  INPUT PARAMETERS
2950276SpeterC  rp	r16
30174993SrafanC  up	r17
3150276SpeterC  n	r18
3250276SpeterC  vl	r19
3350276Speter
3450276Speter
3550276SpeterASM_START()
3650276SpeterPROLOGUE(mpn_addmul_1)
37174993Srafan	ldq	r2,0(r17)	C r2 = s1_limb
3850276Speter	addq	r17,8,r17	C s1_ptr++
39174993Srafan	subq	r18,1,r18	C size--
4050276Speter	mulq	r2,r19,r3	C r3 = prod_low
41174993Srafan	ldq	r5,0(r16)	C r5 = *res_ptr
4250276Speter	umulh	r2,r19,r0	C r0 = prod_high
43174993Srafan	beq	r18,$Lend1	C jump if size was == 1
4450276Speter	ldq	r2,0(r17)	C r2 = s1_limb
45174993Srafan	addq	r17,8,r17	C s1_ptr++
4650276Speter	subq	r18,1,r18	C size--
47174993Srafan	addq	r5,r3,r3
4850276Speter	cmpult	r3,r5,r4
49174993Srafan	stq	r3,0(r16)
5050276Speter	addq	r16,8,r16	C res_ptr++
51174993Srafan	beq	r18,$Lend2	C jump if size was == 2
5250276Speter
5350276Speter	ALIGN(8)
5450276Speter$Loop:	mulq	r2,r19,r3	C r3 = prod_low
5550276Speter	ldq	r5,0(r16)	C r5 = *res_ptr
56166124Srafan	addq	r4,r0,r0	C cy_limb = cy_limb + 'cy'
5750276Speter	subq	r18,1,r18	C size--
5850276Speter	umulh	r2,r19,r4	C r4 = cy_limb
5950276Speter	ldq	r2,0(r17)	C r2 = s1_limb
6050276Speter	addq	r17,8,r17	C s1_ptr++
61166124Srafan	addq	r3,r0,r3	C r3 = cy_limb + prod_low
6250276Speter	cmpult	r3,r0,r0	C r0 = carry from (cy_limb + prod_low)
6350276Speter	addq	r5,r3,r3
6450276Speter	cmpult	r3,r5,r5
6550276Speter	stq	r3,0(r16)
66166124Srafan	addq	r16,8,r16	C res_ptr++
6750276Speter	addq	r5,r0,r0	C combine carries
6850276Speter	bne	r18,$Loop
6950276Speter
7050276Speter$Lend2:	mulq	r2,r19,r3	C r3 = prod_low
71166124Srafan	ldq	r5,0(r16)	C r5 = *res_ptr
7250276Speter	addq	r4,r0,r0	C cy_limb = cy_limb + 'cy'
7350276Speter	umulh	r2,r19,r4	C r4 = cy_limb
7450276Speter	addq	r3,r0,r3	C r3 = cy_limb + prod_low
7550276Speter	cmpult	r3,r0,r0	C r0 = carry from (cy_limb + prod_low)
7650276Speter	addq	r5,r3,r3
7750276Speter	cmpult	r3,r5,r5
7850276Speter	stq	r3,0(r16)
7950276Speter	addq	r5,r0,r0	C combine carries
80166124Srafan	addq	r4,r0,r0	C cy_limb = prod_high + cy
8150276Speter	ret	r31,(r26),1
8250276Speter$Lend1:	addq	r5,r3,r3
83166124Srafan	cmpult	r3,r5,r5
8450276Speter	stq	r3,0(r16)
8550276Speter	addq	r0,r5,r0
8650276Speter	ret	r31,(r26),1
8750276SpeterEPILOGUE(mpn_addmul_1)
8850276SpeterASM_END()
8950276Speter