1/* MIPS3 __mpn_submul_1 -- Multiply a limb vector with a single limb and
2 * subtract the product from a second limb vector.
3 *
4 * Copyright (C) 1992-2021 Free Software Foundation, Inc.
5 *
6 * This file is part of the GNU MP Library.
7 *
8 * The GNU MP Library is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or (at your
11 * option) any later version.
12 *
13 * The GNU MP Library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 * License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with the GNU MP Library.  If not, see
20 * <https://www.gnu.org/licenses/>.
21 */
22
23#include <sysdep.h>
24#include <sys/asm.h>
25
26/* INPUT PARAMETERS
27 * res_ptr	$4
28 * s1_ptr	$5
29 * size		$6
30 * s2_limb	$7
31 */
32
33#ifdef __PIC__
34	.option pic2
35#endif
36ENTRY (__mpn_submul_1)
37#ifdef __PIC__
38	SETUP_GP /* ??? unused */
39#endif
40	.set    noreorder
41	.set    nomacro
42
43 # warm up phase 0
44	ld	$8,0($5)
45
46 # warm up phase 1
47	daddiu	$5,$5,8
48#if __mips_isa_rev < 6
49	dmultu	$8,$7
50#else
51	dmulu	$11,$8,$7
52	dmuhu	$12,$8,$7
53#endif
54
55	daddiu	$6,$6,-1
56	beq	$6,$0,L(LC0)
57	move	$2,$0		# zero cy2
58
59	daddiu	$6,$6,-1
60	beq	$6,$0,L(LC1)
61	ld	$8,0($5)	# load new s1 limb as early as possible
62
63L(Loop):	ld	$10,0($4)
64#if __mips_isa_rev < 6
65	mflo	$3
66	mfhi	$9
67#else
68	move	$3,$11
69	move	$9,$12
70#endif
71	daddiu	$5,$5,8
72	daddu	$3,$3,$2	# add old carry limb to low product limb
73#if __mips_isa_rev < 6
74	dmultu	$8,$7
75#else
76	dmulu	$11,$8,$7
77	dmuhu	$12,$8,$7
78#endif
79	ld	$8,0($5)	# load new s1 limb as early as possible
80	daddiu	$6,$6,-1	# decrement loop counter
81	sltu	$2,$3,$2	# carry from previous addition -> $2
82	dsubu	$3,$10,$3
83	sgtu	$10,$3,$10
84	daddu	$2,$2,$10
85	sd	$3,0($4)
86	daddiu	$4,$4,8
87	bne	$6,$0,L(Loop)
88	daddu	$2,$9,$2	# add high product limb and carry from addition
89
90 # cool down phase 1
91L(LC1):	ld	$10,0($4)
92#if __mips_isa_rev < 6
93	mflo	$3
94	mfhi	$9
95#else
96	move	$3,$11
97	move	$9,$12
98#endif
99	daddu	$3,$3,$2
100	sltu	$2,$3,$2
101#if __mips_isa_rev < 6
102	dmultu	$8,$7
103#else
104	dmulu	$11,$8,$7
105	dmuhu	$12,$8,$7
106#endif
107	dsubu	$3,$10,$3
108	sgtu	$10,$3,$10
109	daddu	$2,$2,$10
110	sd	$3,0($4)
111	daddiu	$4,$4,8
112	daddu	$2,$9,$2	# add high product limb and carry from addition
113
114 # cool down phase 0
115L(LC0):	ld	$10,0($4)
116#if __mips_isa_rev < 6
117	mflo	$3
118	mfhi	$9
119#else
120	move	$3,$11
121	move	$9,$12
122#endif
123	daddu	$3,$3,$2
124	sltu	$2,$3,$2
125	dsubu	$3,$10,$3
126	sgtu	$10,$3,$10
127	daddu	$2,$2,$10
128	sd	$3,0($4)
129	j	$31
130	daddu	$2,$9,$2	# add high product limb and carry from addition
131
132END (__mpn_submul_1)
133