blob: 9a0fff334b8ee86c7c3cc32bf1dc907d6cbcba59 [file] [log] [blame]
Dan Willemsend2797482017-07-26 13:13:13 -07001// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5#include "textflag.h"
6
7#define PosInf 0x7FF0000000000000
8#define NaN 0x7FF8000000000001
9#define NegInf 0xFFF0000000000000
10#define PosOne 0x3FF0000000000000
11#define NegOne 0xBFF0000000000000
12#define NegZero 0x8000000000000000
13
14// Minimax polynomial approximation
15DATA ·powrodataL51<> + 0(SB)/8, $-1.0
16DATA ·powrodataL51<> + 8(SB)/8, $1.0
17DATA ·powrodataL51<> + 16(SB)/8, $0.24022650695910110361E+00
18DATA ·powrodataL51<> + 24(SB)/8, $0.69314718055994686185E+00
19DATA ·powrodataL51<> + 32(SB)/8, $0.96181291057109484809E-02
20DATA ·powrodataL51<> + 40(SB)/8, $0.15403814778342868389E-03
21DATA ·powrodataL51<> + 48(SB)/8, $0.55504108652095235601E-01
22DATA ·powrodataL51<> + 56(SB)/8, $0.13333818813168698658E-02
23DATA ·powrodataL51<> + 64(SB)/8, $0.68205322933914439200E-12
24DATA ·powrodataL51<> + 72(SB)/8, $-.18466496523378731640E-01
25DATA ·powrodataL51<> + 80(SB)/8, $0.19697596291603973706E-02
26DATA ·powrodataL51<> + 88(SB)/8, $0.23083120654155209200E+00
27DATA ·powrodataL51<> + 96(SB)/8, $0.55324356012093416771E-06
28DATA ·powrodataL51<> + 104(SB)/8, $-.40340677224649339048E-05
29DATA ·powrodataL51<> + 112(SB)/8, $0.30255507904062541562E-04
30DATA ·powrodataL51<> + 120(SB)/8, $-.77453979912413008787E-07
31DATA ·powrodataL51<> + 128(SB)/8, $-.23637115549923464737E-03
32DATA ·powrodataL51<> + 136(SB)/8, $0.11016119077267717198E-07
33DATA ·powrodataL51<> + 144(SB)/8, $0.22608272174486123035E-09
34DATA ·powrodataL51<> + 152(SB)/8, $-.15895808101370190382E-08
35DATA ·powrodataL51<> + 160(SB)/8, $0x4540190000000000
36GLOBL ·powrodataL51<> + 0(SB), RODATA, $168
37
38// Constants
39DATA ·pow_x001a<> + 0(SB)/8, $0x1a000000000000
40GLOBL ·pow_x001a<> + 0(SB), RODATA, $8
41DATA ·pow_xinf<> + 0(SB)/8, $0x7ff0000000000000 //+Inf
42GLOBL ·pow_xinf<> + 0(SB), RODATA, $8
43DATA ·pow_xnan<> + 0(SB)/8, $0x7ff8000000000000 //NaN
44GLOBL ·pow_xnan<> + 0(SB), RODATA, $8
45DATA ·pow_x434<> + 0(SB)/8, $0x4340000000000000
46GLOBL ·pow_x434<> + 0(SB), RODATA, $8
47DATA ·pow_x433<> + 0(SB)/8, $0x4330000000000000
48GLOBL ·pow_x433<> + 0(SB), RODATA, $8
49DATA ·pow_x43f<> + 0(SB)/8, $0x43f0000000000000
50GLOBL ·pow_x43f<> + 0(SB), RODATA, $8
51DATA ·pow_xadd<> + 0(SB)/8, $0xc2f0000100003fef
52GLOBL ·pow_xadd<> + 0(SB), RODATA, $8
53DATA ·pow_xa<> + 0(SB)/8, $0x4019000000000000
54GLOBL ·pow_xa<> + 0(SB), RODATA, $8
55
56// Scale correction tables
57DATA powiadd<> + 0(SB)/8, $0xf000000000000000
58DATA powiadd<> + 8(SB)/8, $0x1000000000000000
59GLOBL powiadd<> + 0(SB), RODATA, $16
60DATA powxscale<> + 0(SB)/8, $0x4ff0000000000000
61DATA powxscale<> + 8(SB)/8, $0x2ff0000000000000
62GLOBL powxscale<> + 0(SB), RODATA, $16
63
64// Fractional powers of 2 table
65DATA ·powtexp<> + 0(SB)/8, $0.442737824274138381E-01
66DATA ·powtexp<> + 8(SB)/8, $0.263602189790660309E-01
67DATA ·powtexp<> + 16(SB)/8, $0.122565642281703586E-01
68DATA ·powtexp<> + 24(SB)/8, $0.143757052860721398E-02
69DATA ·powtexp<> + 32(SB)/8, $-.651375034121276075E-02
70DATA ·powtexp<> + 40(SB)/8, $-.119317678849450159E-01
71DATA ·powtexp<> + 48(SB)/8, $-.150868749549871069E-01
72DATA ·powtexp<> + 56(SB)/8, $-.161992609578469234E-01
73DATA ·powtexp<> + 64(SB)/8, $-.154492360403337917E-01
74DATA ·powtexp<> + 72(SB)/8, $-.129850717389178721E-01
75DATA ·powtexp<> + 80(SB)/8, $-.892902649276657891E-02
76DATA ·powtexp<> + 88(SB)/8, $-.338202636596794887E-02
77DATA ·powtexp<> + 96(SB)/8, $0.357266307045684762E-02
78DATA ·powtexp<> + 104(SB)/8, $0.118665304327406698E-01
79DATA ·powtexp<> + 112(SB)/8, $0.214434994118118914E-01
80DATA ·powtexp<> + 120(SB)/8, $0.322580645161290314E-01
81GLOBL ·powtexp<> + 0(SB), RODATA, $128
82
83// Log multiplier tables
84DATA ·powtl<> + 0(SB)/8, $0xbdf9723a80db6a05
85DATA ·powtl<> + 8(SB)/8, $0x3e0cfe4a0babe862
86DATA ·powtl<> + 16(SB)/8, $0xbe163b42dd33dada
87DATA ·powtl<> + 24(SB)/8, $0xbe0cdf9de2a8429c
88DATA ·powtl<> + 32(SB)/8, $0xbde9723a80db6a05
89DATA ·powtl<> + 40(SB)/8, $0xbdb37fcae081745e
90DATA ·powtl<> + 48(SB)/8, $0xbdd8b2f901ac662c
91DATA ·powtl<> + 56(SB)/8, $0xbde867dc68c36cc9
92DATA ·powtl<> + 64(SB)/8, $0xbdd23e36b47256b7
93DATA ·powtl<> + 72(SB)/8, $0xbde4c9b89fcc7933
94DATA ·powtl<> + 80(SB)/8, $0xbdd16905cad7cf66
95DATA ·powtl<> + 88(SB)/8, $0x3ddb417414aa5529
96DATA ·powtl<> + 96(SB)/8, $0xbdce046f2889983c
97DATA ·powtl<> + 104(SB)/8, $0x3dc2c3865d072897
98DATA ·powtl<> + 112(SB)/8, $0x8000000000000000
99DATA ·powtl<> + 120(SB)/8, $0x3dc1ca48817f8afe
100DATA ·powtl<> + 128(SB)/8, $0xbdd703518a88bfb7
101DATA ·powtl<> + 136(SB)/8, $0x3dc64afcc46942ce
102DATA ·powtl<> + 144(SB)/8, $0xbd9d79191389891a
103DATA ·powtl<> + 152(SB)/8, $0x3ddd563044da4fa0
104DATA ·powtl<> + 160(SB)/8, $0x3e0f42b5e5f8f4b6
105DATA ·powtl<> + 168(SB)/8, $0x3e0dfa2c2cbf6ead
106DATA ·powtl<> + 176(SB)/8, $0x3e14e25e91661293
107DATA ·powtl<> + 184(SB)/8, $0x3e0aac461509e20c
108GLOBL ·powtl<> + 0(SB), RODATA, $192
109
110DATA ·powtm<> + 0(SB)/8, $0x3da69e13
111DATA ·powtm<> + 8(SB)/8, $0x100003d66fcb6
112DATA ·powtm<> + 16(SB)/8, $0x200003d1538df
113DATA ·powtm<> + 24(SB)/8, $0x300003cab729e
114DATA ·powtm<> + 32(SB)/8, $0x400003c1a784c
115DATA ·powtm<> + 40(SB)/8, $0x500003ac9b074
116DATA ·powtm<> + 48(SB)/8, $0x60000bb498d22
117DATA ·powtm<> + 56(SB)/8, $0x68000bb8b29a2
118DATA ·powtm<> + 64(SB)/8, $0x70000bb9a32d4
119DATA ·powtm<> + 72(SB)/8, $0x74000bb9946bb
120DATA ·powtm<> + 80(SB)/8, $0x78000bb92e34b
121DATA ·powtm<> + 88(SB)/8, $0x80000bb6c57dc
122DATA ·powtm<> + 96(SB)/8, $0x84000bb4020f7
123DATA ·powtm<> + 104(SB)/8, $0x8c000ba93832d
124DATA ·powtm<> + 112(SB)/8, $0x9000080000000
125DATA ·powtm<> + 120(SB)/8, $0x940003aa66c4c
126DATA ·powtm<> + 128(SB)/8, $0x980003b2fb12a
127DATA ·powtm<> + 136(SB)/8, $0xa00003bc1def6
128DATA ·powtm<> + 144(SB)/8, $0xa80003c1eb0eb
129DATA ·powtm<> + 152(SB)/8, $0xb00003c64dcec
130DATA ·powtm<> + 160(SB)/8, $0xc00003cc49e4e
131DATA ·powtm<> + 168(SB)/8, $0xd00003d12f1de
132DATA ·powtm<> + 176(SB)/8, $0xe00003d4a9c6f
133DATA ·powtm<> + 184(SB)/8, $0xf00003d846c66
134GLOBL ·powtm<> + 0(SB), RODATA, $192
135
136// Table of indeces into multiplier tables
137// Adjusted from asm to remove offset and convert
138DATA ·powtabi<> + 0(SB)/8, $0x1010101
139DATA ·powtabi<> + 8(SB)/8, $0x101020202020203
140DATA ·powtabi<> + 16(SB)/8, $0x303030404040405
141DATA ·powtabi<> + 24(SB)/8, $0x505050606060708
142DATA ·powtabi<> + 32(SB)/8, $0x90a0b0c0d0e0f10
143DATA ·powtabi<> + 40(SB)/8, $0x1011111212121313
144DATA ·powtabi<> + 48(SB)/8, $0x1314141414151515
145DATA ·powtabi<> + 56(SB)/8, $0x1516161617171717
146GLOBL ·powtabi<> + 0(SB), RODATA, $64
147
148// Pow returns x**y, the base-x exponential of y.
149//
150// Special cases are (in order):
151// Pow(x, ±0) = 1 for any x
152// Pow(1, y) = 1 for any y
153// Pow(x, 1) = x for any x
154// Pow(NaN, y) = NaN
155// Pow(x, NaN) = NaN
156// Pow(±0, y) = ±Inf for y an odd integer < 0
157// Pow(±0, -Inf) = +Inf
158// Pow(±0, +Inf) = +0
159// Pow(±0, y) = +Inf for finite y < 0 and not an odd integer
160// Pow(±0, y) = ±0 for y an odd integer > 0
161// Pow(±0, y) = +0 for finite y > 0 and not an odd integer
162// Pow(-1, ±Inf) = 1
163// Pow(x, +Inf) = +Inf for |x| > 1
164// Pow(x, -Inf) = +0 for |x| > 1
165// Pow(x, +Inf) = +0 for |x| < 1
166// Pow(x, -Inf) = +Inf for |x| < 1
167// Pow(+Inf, y) = +Inf for y > 0
168// Pow(+Inf, y) = +0 for y < 0
169// Pow(-Inf, y) = Pow(-0, -y)
170// Pow(x, y) = NaN for finite x < 0 and finite non-integer y
171
172TEXT ·powAsm(SB), NOSPLIT, $0-24
173 // special case
174 MOVD x+0(FP), R1
175 MOVD y+8(FP), R2
176
177 // special case Pow(1, y) = 1 for any y
178 MOVD $PosOne, R3
179 CMPUBEQ R1, R3, xIsOne
180
181 // special case Pow(x, 1) = x for any x
182 MOVD $PosOne, R4
183 CMPUBEQ R2, R4, yIsOne
184
185 // special case Pow(x, NaN) = NaN for any x
186 MOVD $~(1<<63), R5
187 AND R2, R5 // y = |y|
188 MOVD $PosInf, R4
189 CMPUBLT R4, R5, yIsNan
190
191 MOVD $NegInf, R3
192 CMPUBEQ R1, R3, xIsNegInf
193
194 MOVD $NegOne, R3
195 CMPUBEQ R1, R3, xIsNegOne
196
197 MOVD $PosInf, R3
198 CMPUBEQ R1, R3, xIsPosInf
199
200 MOVD $NegZero, R3
201 CMPUBEQ R1, R3, xIsNegZero
202
203 MOVD $PosInf, R4
204 CMPUBEQ R2, R4, yIsPosInf
205
206 MOVD $0x0, R3
207 CMPUBEQ R1, R3, xIsPosZero
208 CMPBLT R1, R3, xLtZero
209 BR Normal
210xIsPosInf:
211 // special case Pow(+Inf, y) = +Inf for y > 0
212 MOVD $0x0, R4
213 CMPBGT R2, R4, posInfGeZero
214 BR Normal
215xIsNegInf:
216 //Pow(-Inf, y) = Pow(-0, -y)
217 FMOVD y+8(FP), F2
218 FNEG F2, F2 // y = -y
219 BR negZeroNegY // call Pow(-0, -y)
220xIsNegOne:
221 // special case Pow(-1, ±Inf) = 1
222 MOVD $PosInf, R4
223 CMPUBEQ R2, R4, negOnePosInf
224 MOVD $NegInf, R4
225 CMPUBEQ R2, R4, negOneNegInf
226 BR Normal
227xIsPosZero:
228 // special case Pow(+0, -Inf) = +Inf
229 MOVD $NegInf, R4
230 CMPUBEQ R2, R4, zeroNegInf
231
232 // special case Pow(+0, y < 0) = +Inf
233 FMOVD y+8(FP), F2
234 FMOVD $(0.0), F4
235 FCMPU F2, F4
236 BLT posZeroLtZero //y < 0.0
237 BR Normal
238xIsNegZero:
239 // special case Pow(-0, -Inf) = +Inf
240 MOVD $NegInf, R4
241 CMPUBEQ R2, R4, zeroNegInf
242 FMOVD y+8(FP), F2
243negZeroNegY:
244 // special case Pow(x, ±0) = 1 for any x
245 FMOVD $(0.0), F4
246 FCMPU F4, F2
247 BLT negZeroGtZero // y > 0.0
248 BEQ yIsZero // y = 0.0
249
250 FMOVD $(-0.0), F4
251 FCMPU F4, F2
252 BLT negZeroGtZero // y > -0.0
253 BEQ yIsZero // y = -0.0
254
255 // special case Pow(-0, y) = -Inf for y an odd integer < 0
256 // special case Pow(-0, y) = +Inf for finite y < 0 and not an odd integer
257 FIDBR $5, F2, F4 //F2 translate to integer F4
258 FCMPU F2, F4
259 BNE zeroNotOdd // y is not an (odd) integer and y < 0
260 FMOVD $(2.0), F4
261 FDIV F4, F2 // F2 = F2 / 2.0
262 FIDBR $5, F2, F4 //F2 translate to integer F4
263 FCMPU F2, F4
264 BNE negZeroOddInt // y is an odd integer and y < 0
265 BR zeroNotOdd // y is not an (odd) integer and y < 0
266
267negZeroGtZero:
268 // special case Pow(-0, y) = -0 for y an odd integer > 0
269 // special case Pow(±0, y) = +0 for finite y > 0 and not an odd integer
270 FIDBR $5, F2, F4 //F2 translate to integer F4
271 FCMPU F2, F4
272 BNE zeroNotOddGtZero // y is not an (odd) integer and y > 0
273 FMOVD $(2.0), F4
274 FDIV F4, F2 // F2 = F2 / 2.0
275 FIDBR $5, F2, F4 //F2 translate to integer F4
276 FCMPU F2, F4
277 BNE negZeroOddIntGtZero // y is an odd integer and y > 0
278 BR zeroNotOddGtZero // y is not an (odd) integer
279
280xLtZero:
281 // special case Pow(x, y) = NaN for finite x < 0 and finite non-integer y
282 FMOVD y+8(FP), F2
283 FIDBR $5, F2, F4
284 FCMPU F2, F4
285 BNE ltZeroInt
286 BR Normal
287yIsPosInf:
288 // special case Pow(x, +Inf) = +Inf for |x| > 1
289 FMOVD x+0(FP), F1
290 FMOVD $(1.0), F3
291 FCMPU F1, F3
292 BGT gtOnePosInf
293 FMOVD $(-1.0), F3
294 FCMPU F1, F3
295 BLT ltNegOnePosInf
296Normal:
297 FMOVD x+0(FP), F0
298 FMOVD y+8(FP), F2
299 MOVD $·powrodataL51<>+0(SB), R9
Colin Crossd9c6b802019-03-19 21:10:31 -0700300 LGDR F0, R3
Dan Willemsend2797482017-07-26 13:13:13 -0700301 WORD $0xC0298009 //iilf %r2,2148095317
302 BYTE $0x55
303 BYTE $0x55
Colin Cross430342c2019-09-07 08:36:04 -0700304 RISBGNZ $32, $63, $32, R3, R1
Dan Willemsend2797482017-07-26 13:13:13 -0700305 SUBW R1, R2
Colin Cross430342c2019-09-07 08:36:04 -0700306 RISBGNZ $58, $63, $50, R2, R3
Dan Willemsend2797482017-07-26 13:13:13 -0700307 BYTE $0x18 //lr %r5,%r1
308 BYTE $0x51
309 MOVD $·powtabi<>+0(SB), R12
310 WORD $0xE303C000 //llgc %r0,0(%r3,%r12)
311 BYTE $0x00
312 BYTE $0x90
313 SUBW $0x1A0000, R5
314 SLD $3, R0, R3
315 MOVD $·powtm<>+0(SB), R4
316 MOVH $0x0, R8
317 ANDW $0x7FF00000, R2
318 ORW R5, R1
319 WORD $0x5A234000 //a %r2,0(%r3,%r4)
320 MOVD $0x3FF0000000000000, R5
Colin Cross430342c2019-09-07 08:36:04 -0700321 RISBGZ $40, $63, $56, R2, R3
322 RISBGN $0, $31, $32, R2, R8
Dan Willemsend2797482017-07-26 13:13:13 -0700323 ORW $0x45000000, R3
324 MOVW R1, R6
325 CMPBLT R6, $0, L42
326 FMOVD F0, F4
327L2:
328 VLVGF $0, R3, V1
329 MOVD $·pow_xa<>+0(SB), R2
330 WORD $0xED3090A0 //lde %f3,.L52-.L51(%r9)
331 BYTE $0x00
332 BYTE $0x24
333 FMOVD 0(R2), F6
334 FSUBS F1, F3
Colin Crossd9c6b802019-03-19 21:10:31 -0700335 LDGR R8, F1
Dan Willemsend2797482017-07-26 13:13:13 -0700336 WFMSDB V4, V1, V6, V4
337 FMOVD 152(R9), F6
338 WFMDB V4, V4, V7
339 FMOVD 144(R9), F1
340 FMOVD 136(R9), F5
341 WFMADB V4, V1, V6, V1
342 VLEG $0, 128(R9), V16
343 FMOVD 120(R9), F6
344 WFMADB V4, V5, V6, V5
345 FMOVD 112(R9), F6
346 WFMADB V1, V7, V5, V1
347 WFMADB V4, V6, V16, V16
348 SLD $3, R0, R2
349 FMOVD 104(R9), F5
350 WORD $0xED824004 //ldeb %f8,4(%r2,%r4)
351 BYTE $0x00
352 BYTE $0x04
353 LDEBR F3, F3
354 FMOVD 96(R9), F6
355 WFMADB V4, V6, V5, V6
356 FADD F8, F3
357 WFMADB V7, V6, V16, V6
358 FMUL F7, F7
359 FMOVD 88(R9), F5
360 FMADD F7, F1, F6
361 WFMADB V4, V5, V3, V16
362 FMOVD 80(R9), F1
363 WFSDB V16, V3, V3
364 MOVD $·powtl<>+0(SB), R3
365 WFMADB V4, V6, V1, V6
366 FMADD F5, F4, F3
367 FMOVD 72(R9), F1
368 WFMADB V4, V6, V1, V6
369 WORD $0xED323000 //adb %f3,0(%r2,%r3)
370 BYTE $0x00
371 BYTE $0x1A
372 FMOVD 64(R9), F1
373 WFMADB V4, V6, V1, V6
374 MOVD $·pow_xadd<>+0(SB), R2
375 WFMADB V4, V6, V3, V4
376 FMOVD 0(R2), F5
377 WFADB V4, V16, V3
378 VLEG $0, 56(R9), V20
379 WFMSDB V2, V3, V5, V3
380 VLEG $0, 48(R9), V18
381 WFADB V3, V5, V6
Colin Crossd9c6b802019-03-19 21:10:31 -0700382 LGDR F3, R2
Dan Willemsend2797482017-07-26 13:13:13 -0700383 WFMSDB V2, V16, V6, V16
384 FMOVD 40(R9), F1
385 WFMADB V2, V4, V16, V4
386 FMOVD 32(R9), F7
387 WFMDB V4, V4, V3
388 WFMADB V4, V1, V20, V1
389 WFMADB V4, V7, V18, V7
390 VLEG $0, 24(R9), V16
391 WFMADB V1, V3, V7, V1
392 FMOVD 16(R9), F5
393 WFMADB V4, V5, V16, V5
Colin Cross430342c2019-09-07 08:36:04 -0700394 RISBGZ $57, $60, $3, R2, R4
Dan Willemsend2797482017-07-26 13:13:13 -0700395 WFMADB V3, V1, V5, V1
396 MOVD $·powtexp<>+0(SB), R3
397 WORD $0x68343000 //ld %f3,0(%r4,%r3)
398 FMADD F3, F4, F4
Colin Cross430342c2019-09-07 08:36:04 -0700399 RISBGN $0, $15, $48, R2, R5
Dan Willemsend2797482017-07-26 13:13:13 -0700400 WFMADB V4, V1, V3, V4
Colin Crossd9c6b802019-03-19 21:10:31 -0700401 LGDR F6, R2
402 LDGR R5, F1
Dan Willemsend2797482017-07-26 13:13:13 -0700403 SRAD $48, R2, R2
404 FMADD F1, F4, F1
405 RLL $16, R2, R2
406 ANDW $0x7FFF0000, R2
407 WORD $0xC22B3F71 //alfi %r2,1064370176
408 BYTE $0x00
409 BYTE $0x00
410 ORW R2, R1, R3
411 MOVW R3, R6
412 CMPBLT R6, $0, L43
413L1:
414 FMOVD F1, ret+16(FP)
415 RET
416L43:
Dan Willemsenc7413322018-08-27 23:21:26 -0700417 LTDBR F0, F0
Dan Willemsend2797482017-07-26 13:13:13 -0700418 BLTU L44
419 FMOVD F0, F3
420L7:
421 MOVD $·pow_xinf<>+0(SB), R3
422 FMOVD 0(R3), F5
423 WFCEDBS V3, V5, V7
424 BVS L8
425 WFMDB V3, V2, V6
426L8:
427 WFCEDBS V2, V2, V3
428 BVS L9
Dan Willemsenc7413322018-08-27 23:21:26 -0700429 LTDBR F2, F2
Dan Willemsend2797482017-07-26 13:13:13 -0700430 BEQ L26
431 MOVW R1, R6
432 CMPBLT R6, $0, L45
433L11:
434 WORD $0xC0190003 //iilf %r1,262143
435 BYTE $0xFF
436 BYTE $0xFF
437 MOVW R2, R7
438 MOVW R1, R6
439 CMPBLE R7, R6, L34
Colin Cross430342c2019-09-07 08:36:04 -0700440 RISBGNZ $32, $63, $32, R5, R1
Colin Crossd9c6b802019-03-19 21:10:31 -0700441 LGDR F6, R2
Dan Willemsend2797482017-07-26 13:13:13 -0700442 MOVD $powiadd<>+0(SB), R3
Colin Cross430342c2019-09-07 08:36:04 -0700443 RISBGZ $60, $60, $4, R2, R2
Dan Willemsend2797482017-07-26 13:13:13 -0700444 WORD $0x5A123000 //a %r1,0(%r2,%r3)
Colin Cross430342c2019-09-07 08:36:04 -0700445 RISBGN $0, $31, $32, R1, R5
Colin Crossd9c6b802019-03-19 21:10:31 -0700446 LDGR R5, F1
Dan Willemsend2797482017-07-26 13:13:13 -0700447 FMADD F1, F4, F1
448 MOVD $powxscale<>+0(SB), R1
449 WORD $0xED121000 //mdb %f1,0(%r2,%r1)
450 BYTE $0x00
451 BYTE $0x1C
452 BR L1
453L42:
Dan Willemsenc7413322018-08-27 23:21:26 -0700454 LTDBR F0, F0
Dan Willemsend2797482017-07-26 13:13:13 -0700455 BLTU L46
456 FMOVD F0, F4
457L3:
458 MOVD $·pow_x001a<>+0(SB), R2
459 WORD $0xED402000 //cdb %f4,0(%r2)
460 BYTE $0x00
461 BYTE $0x19
462 BGE L2
463 BVS L2
464 MOVD $·pow_x43f<>+0(SB), R2
465 WORD $0xED402000 //mdb %f4,0(%r2)
466 BYTE $0x00
467 BYTE $0x1C
468 WORD $0xC0298009 //iilf %r2,2148095317
469 BYTE $0x55
470 BYTE $0x55
Colin Crossd9c6b802019-03-19 21:10:31 -0700471 LGDR F4, R3
Colin Cross430342c2019-09-07 08:36:04 -0700472 RISBGNZ $32, $63, $32, R3, R3
Dan Willemsend2797482017-07-26 13:13:13 -0700473 SUBW R3, R2, R3
Colin Cross430342c2019-09-07 08:36:04 -0700474 RISBGZ $33, $43, $0, R3, R2
475 RISBGNZ $58, $63, $50, R3, R3
Dan Willemsend2797482017-07-26 13:13:13 -0700476 WORD $0xE303C000 //llgc %r0,0(%r3,%r12)
477 BYTE $0x00
478 BYTE $0x90
479 SLD $3, R0, R3
480 WORD $0x5A234000 //a %r2,0(%r3,%r4)
481 BYTE $0x18 //lr %r3,%r2
482 BYTE $0x32
Colin Cross430342c2019-09-07 08:36:04 -0700483 RISBGN $0, $31, $32, R3, R8
Dan Willemsend2797482017-07-26 13:13:13 -0700484 ADDW $0x4000000, R3
485 BLEU L5
Colin Cross430342c2019-09-07 08:36:04 -0700486 RISBGZ $40, $63, $56, R3, R3
Dan Willemsend2797482017-07-26 13:13:13 -0700487 ORW $0x45000000, R3
488 BR L2
489L9:
490 WFCEDBS V0, V0, V4
491 BVS L35
492 FMOVD F2, F1
493 BR L1
494L46:
495 WORD $0xB3130040 //lcdbr %f4,%f0
496 BR L3
497L44:
498 WORD $0xB3130030 //lcdbr %f3,%f0
499 BR L7
500L35:
501 FMOVD F0, F1
502 BR L1
503L26:
504 FMOVD 8(R9), F1
505 BR L1
506L34:
507 FMOVD 8(R9), F4
508L19:
Dan Willemsenc7413322018-08-27 23:21:26 -0700509 LTDBR F6, F6
Dan Willemsend2797482017-07-26 13:13:13 -0700510 BLEU L47
511L18:
512 WFMDB V4, V5, V1
513 BR L1
514L5:
Colin Cross430342c2019-09-07 08:36:04 -0700515 RISBGZ $33, $50, $63, R3, R3
Dan Willemsend2797482017-07-26 13:13:13 -0700516 WORD $0xC23B4000 //alfi %r3,1073741824
517 BYTE $0x00
518 BYTE $0x00
519 RLL $24, R3, R3
520 ORW $0x45000000, R3
521 BR L2
522L45:
523 WFCEDBS V0, V0, V4
524 BVS L35
Dan Willemsenc7413322018-08-27 23:21:26 -0700525 LTDBR F0, F0
Dan Willemsend2797482017-07-26 13:13:13 -0700526 BLEU L48
527 FMOVD 8(R9), F4
528L12:
529 MOVW R2, R6
530 CMPBLT R6, $0, L19
531 FMUL F4, F1
532 BR L1
533L47:
534 BLT L40
535 WFCEDBS V0, V0, V2
536 BVS L49
537L16:
538 MOVD ·pow_xnan<>+0(SB), R1
Colin Crossd9c6b802019-03-19 21:10:31 -0700539 LDGR R1, F0
Dan Willemsend2797482017-07-26 13:13:13 -0700540 WFMDB V4, V0, V1
541 BR L1
542L48:
Colin Crossd9c6b802019-03-19 21:10:31 -0700543 LGDR F0, R3
Colin Cross430342c2019-09-07 08:36:04 -0700544 RISBGNZ $32, $63, $32, R3, R1
Dan Willemsend2797482017-07-26 13:13:13 -0700545 MOVW R1, R6
546 CMPBEQ R6, $0, L29
Dan Willemsenc7413322018-08-27 23:21:26 -0700547 LTDBR F2, F2
Dan Willemsend2797482017-07-26 13:13:13 -0700548 BLTU L50
549 FMOVD F2, F4
550L14:
551 MOVD $·pow_x433<>+0(SB), R1
552 FMOVD 0(R1), F7
553 WFCHDBS V4, V7, V3
554 BEQ L15
555 WFADB V7, V4, V3
556 FSUB F7, F3
557 WFCEDBS V4, V3, V3
558 BEQ L15
Dan Willemsenc7413322018-08-27 23:21:26 -0700559 LTDBR F0, F0
Dan Willemsend2797482017-07-26 13:13:13 -0700560 FMOVD 8(R9), F4
561 BNE L16
562L13:
Dan Willemsenc7413322018-08-27 23:21:26 -0700563 LTDBR F2, F2
Dan Willemsend2797482017-07-26 13:13:13 -0700564 BLT L18
565L40:
566 FMOVD $0, F0
567 WFMDB V4, V0, V1
568 BR L1
569L49:
570 WFMDB V0, V4, V1
571 BR L1
572L29:
573 FMOVD 8(R9), F4
574 BR L13
575L15:
576 MOVD $·pow_x434<>+0(SB), R1
577 FMOVD 0(R1), F7
578 WFCHDBS V4, V7, V3
579 BEQ L32
580 WFADB V7, V4, V3
581 FSUB F7, F3
582 WFCEDBS V4, V3, V4
583 BEQ L32
584 FMOVD 0(R9), F4
585L17:
Dan Willemsenc7413322018-08-27 23:21:26 -0700586 LTDBR F0, F0
Dan Willemsend2797482017-07-26 13:13:13 -0700587 BNE L12
588 BR L13
589L32:
590 FMOVD 8(R9), F4
591 BR L17
592L50:
593 WORD $0xB3130042 //lcdbr %f4,%f2
594 BR L14
595xIsOne: // Pow(1, y) = 1 for any y
596yIsOne: // Pow(x, 1) = x for any x
597posInfGeZero: // Pow(+Inf, y) = +Inf for y > 0
598 MOVD R1, ret+16(FP)
599 RET
600yIsNan: // Pow(NaN, y) = NaN
601ltZeroInt: // Pow(x, y) = NaN for finite x < 0 and finite non-integer y
602 MOVD $NaN, R2
603 MOVD R2, ret+16(FP)
604 RET
605negOnePosInf: // Pow(-1, ±Inf) = 1
606negOneNegInf:
607 MOVD $PosOne, R3
608 MOVD R3, ret+16(FP)
609 RET
610negZeroOddInt:
611 MOVD $NegInf, R3
612 MOVD R3, ret+16(FP)
613 RET
614zeroNotOdd: // Pow(±0, y) = +Inf for finite y < 0 and not an odd integer
615posZeroLtZero: // special case Pow(+0, y < 0) = +Inf
616zeroNegInf: // Pow(±0, -Inf) = +Inf
617 MOVD $PosInf, R3
618 MOVD R3, ret+16(FP)
619 RET
620gtOnePosInf: //Pow(x, +Inf) = +Inf for |x| > 1
621ltNegOnePosInf:
622 MOVD R2, ret+16(FP)
623 RET
624yIsZero: //Pow(x, ±0) = 1 for any x
625 MOVD $PosOne, R4
626 MOVD R4, ret+16(FP)
627 RET
628negZeroOddIntGtZero: // Pow(-0, y) = -0 for y an odd integer > 0
629 MOVD $NegZero, R3
630 MOVD R3, ret+16(FP)
631 RET
632zeroNotOddGtZero: // Pow(±0, y) = +0 for finite y > 0 and not an odd integer
633 MOVD $0, ret+16(FP)
634 RET