1// 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 indices 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	MOVDpowrodataL51<>+0(SB), R9
300	LGDR	F0, R3
301	WORD	$0xC0298009	//iilf	%r2,2148095317
302	BYTE	$0x55
303	BYTE	$0x55
304	RISBGNZ	$32, $63, $32, R3, R1
305	SUBW	R1, R2
306	RISBGNZ	$58, $63, $50, R2, R3
307	BYTE	$0x18	//lr	%r5,%r1
308	BYTE	$0x51
309	MOVDpowtabi<>+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	MOVDpowtm<>+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
321	RISBGZ	$40, $63, $56, R2, R3
322	RISBGN	$0, $31, $32, R2, R8
323	ORW	$0x45000000, R3
324	MOVW	R1, R6
325	CMPBLT	R6, $0, L42
326	FMOVD	F0, F4
327L2:
328	VLVGF	$0, R3, V1
329	MOVDpow_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
335	LDGR	R8, F1
336	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	MOVDpowtl<>+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	MOVDpow_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
382	LGDR	F3, R2
383	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
394	RISBGZ	$57, $60, $3, R2, R4
395	WFMADB	V3, V1, V5, V1
396	MOVDpowtexp<>+0(SB), R3
397	WORD	$0x68343000	//ld	%f3,0(%r4,%r3)
398	FMADD	F3, F4, F4
399	RISBGN	$0, $15, $48, R2, R5
400	WFMADB	V4, V1, V3, V4
401	LGDR	F6, R2
402	LDGR	R5, F1
403	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:
417	LTDBR	F0, F0
418	BLTU	L44
419	FMOVD	F0, F3
420L7:
421	MOVDpow_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
429	LTDBR	F2, F2
430	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
440	RISBGNZ	$32, $63, $32, R5, R1
441	LGDR	F6, R2
442	MOVD	$powiadd<>+0(SB), R3
443	RISBGZ	$60, $60, $4, R2, R2
444	WORD	$0x5A123000	//a	%r1,0(%r2,%r3)
445	RISBGN	$0, $31, $32, R1, R5
446	LDGR	R5, F1
447	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:
454	LTDBR	F0, F0
455	BLTU	L46
456	FMOVD	F0, F4
457L3:
458	MOVDpow_x001a<>+0(SB), R2
459	WORD	$0xED402000	//cdb	%f4,0(%r2)
460	BYTE	$0x00
461	BYTE	$0x19
462	BGE	L2
463	BVS	L2
464	MOVDpow_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
471	LGDR	F4, R3
472	RISBGNZ	$32, $63, $32, R3, R3
473	SUBW	R3, R2, R3
474	RISBGZ	$33, $43, $0, R3, R2
475	RISBGNZ	$58, $63, $50, R3, R3
476	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
483	RISBGN	$0, $31, $32, R3, R8
484	ADDW	$0x4000000, R3
485	BLEU	L5
486	RISBGZ	$40, $63, $56, R3, R3
487	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:
509	LTDBR	F6, F6
510	BLEU	L47
511L18:
512	WFMDB	V4, V5, V1
513	BR	L1
514L5:
515	RISBGZ	$33, $50, $63, R3, R3
516	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
525	LTDBR	F0, F0
526	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
539	LDGR	R1, F0
540	WFMDB	V4, V0, V1
541	BR	L1
542L48:
543	LGDR	F0, R3
544	RISBGNZ	$32, $63, $32, R3, R1
545	MOVW	R1, R6
546	CMPBEQ	R6, $0, L29
547	LTDBR	F2, F2
548	BLTU	L50
549	FMOVD	F2, F4
550L14:
551	MOVDpow_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
559	LTDBR	F0, F0
560	FMOVD	8(R9), F4
561	BNE	L16
562L13:
563	LTDBR	F2, F2
564	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	MOVDpow_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:
586	LTDBR	F0, F0
587	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
635