about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc64/addmul_1.S
blob: 657b4ed38c39c481b9a8f06f8f1e5b2ef8e8b8b4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/* PowerPC64 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
   the result to a second limb vector.
   Copyright (C) 1999-2023 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <https://www.gnu.org/licenses/>.  */

#include <sysdep.h>

#ifdef USE_AS_SUBMUL
# define FUNC        __mpn_submul_1
# define ADDSUBC     subfe
# define ADDSUB      subfc
#else
# define FUNC        __mpn_addmul_1
# define ADDSUBC     adde
# define ADDSUB      addc
#endif

#define RP  r3
#define UP  r4
#define N   r5
#define VL  r6

#define R27SAVE  (-40)
#define R28SAVE  (-32)
#define R29SAVE  (-24)
#define R30SAVE  (-16)
#define R31SAVE  (-8)

ENTRY_TOCLESS (FUNC, 5)
	std	r31, R31SAVE(r1)
	rldicl.	r0, N, 0, 62
	std	r30, R30SAVE(r1)
	cmpdi	VL, r0, 2
	std	r29, R29SAVE(r1)
	addi	N, N, 3
	std	r28, R28SAVE(r1)
	srdi	N, N, 2
	std	r27, R27SAVE(r1)
	cfi_offset(r31, R31SAVE)
	cfi_offset(r30, R30SAVE)
	cfi_offset(r29, R29SAVE)
	cfi_offset(r28, R28SAVE)
	cfi_offset(r27, R27SAVE)
	mtctr	N
	beq	cr0, L(b00)
	blt	cr6, L(b01)
	beq	cr6, L(b10)

L(b11):	ld	r9, 0(UP)
	ld	r28, 0(RP)
	mulld	r0, r9, VL
	mulhdu	r12, r9, VL
	ADDSUB	r0, r0, r28
	std	r0, 0(RP)
	addi	RP, RP, 8
	ld	r9, 8(UP)
	ld	r27, 16(UP)
	addi	UP, UP, 24
#ifdef USE_AS_SUBMUL
	subfe	r11, r11, r11
#endif
	b	L(bot)

	.align	4
L(b00):	ld	r9, 0(UP)
	ld	r27, 8(UP)
	ld	r28, 0(RP)
	ld	r29, 8(RP)
	mulld	r0, r9, VL
	mulhdu	N, r9, VL
	mulld	r7, r27, VL
	mulhdu	r8, r27, VL
	addc	r7, r7, N
	addze	r12, r8
	ADDSUB	r0, r0, r28
	std	r0, 0(RP)
	ADDSUBC	r7, r7, r29
	std	r7, 8(RP)
	addi	RP, RP, 16
	ld	r9, 16(UP)
	ld	r27, 24(UP)
	addi	UP, UP, 32
#ifdef USE_AS_SUBMUL
	subfe	r11, r11, r11
#endif
	b	L(bot)

	.align	4
L(b01):	bdnz	L(gt1)
	ld	r9, 0(UP)
	ld	r11, 0(RP)
	mulld	r0, r9, VL
	mulhdu	r8, r9, VL
	ADDSUB	r0, r0, r11
	std	r0, 0(RP)
#ifdef USE_AS_SUBMUL
	subfe	r11, r11, r11
	addic	r11, r11, 1
#endif
	addze	RP, r8
	blr

L(gt1):	ld	r9, 0(UP)
	ld	r27, 8(UP)
	mulld	r0, r9, VL
	mulhdu	N, r9, VL
	mulld	r7, r27, VL
	mulhdu	r8, r27, VL
	ld	r9, 16(UP)
	ld	r28, 0(RP)
	ld	r29, 8(RP)
	ld	r30, 16(RP)
	mulld	r11, r9, VL
	mulhdu	r10, r9, VL
	addc	r7, r7, N
	adde	r11, r11, r8
	addze	r12, r10
	ADDSUB	r0, r0, r28
	std	r0, 0(RP)
	ADDSUBC	r7, r7, r29
	std	r7, 8(RP)
	ADDSUBC	r11, r11, r30
	std	r11, 16(RP)
	addi	RP, RP, 24
	ld	r9, 24(UP)
	ld	r27, 32(UP)
	addi	UP, UP, 40
#ifdef USE_AS_SUBMUL
	subfe	r11, r11, r11
#endif
	b	L(bot)

L(b10):	addic	r0, r0, r0
	li	r12, 0
	ld	r9, 0(UP)
	ld	r27, 8(UP)
	bdz	L(end)
	addi	UP, UP, 16

	.align	4
L(top):	mulld	r0, r9, VL
	mulhdu	N, r9, VL
	mulld	r7, r27, VL
	mulhdu	r8, r27, VL
	ld	r9, 0(UP)
	ld	r28, 0(RP)
	ld	r27, 8(UP)
	ld	r29, 8(RP)
	adde	r0, r0, r12
	adde	r7, r7, N
	mulld	N, r9, VL
	mulhdu	r10, r9, VL
	mulld	r11, r27, VL
	mulhdu	r12, r27, VL
	ld	r9, 16(UP)
	ld	r30, 16(RP)
	ld	r27, 24(UP)
	ld	r31, 24(RP)
	adde	N, N, r8
	adde	r11, r11, r10
	addze	r12, r12
	ADDSUB	r0, r0, r28
	std	r0, 0(RP)
	ADDSUBC	r7, r7, r29
	std	r7, 8(RP)
	ADDSUBC	N, N, r30
	std	N, 16(RP)
	ADDSUBC	r11, r11, r31
	std	r11, 24(RP)
	addi	UP, UP, 32
#ifdef USE_AS_SUBMUL
	subfe	r11, r11, r11
#endif
	addi	RP, RP, 32
L(bot):
#ifdef USE_AS_SUBMUL
	addic	r11, r11, 1
#endif
	bdnz	L(top)

L(end):	mulld	r0, r9, VL
	mulhdu	N, r9, VL
	mulld	r7, r27, VL
	mulhdu	r8, r27, VL
	ld	r28, 0(RP)
	ld	r29, 8(RP)
	adde	r0, r0, r12
	adde	r7, r7, N
	addze	r8, r8
	ADDSUB	r0, r0, r28
	std	r0, 0(RP)
	ADDSUBC	r7, r7, r29
	std	r7, 8(RP)
#ifdef USE_AS_SUBMUL
	subfe	r11, r11, r11
	addic	r11, r11, 1
#endif
	addze	RP, r8
	ld	r31, R31SAVE(r1)
	ld	r30, R30SAVE(r1)
	ld	r29, R29SAVE(r1)
	ld	r28, R28SAVE(r1)
	ld	r27, R27SAVE(r1)
	blr
END(FUNC)