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// Minimax polynomial approximation and other constants
8DATA ·expm1rodataL22<> + 0(SB)/8, $-1.0
9DATA ·expm1rodataL22<> + 8(SB)/8, $800.0E+00
10DATA ·expm1rodataL22<> + 16(SB)/8, $1.0
11DATA ·expm1rodataL22<> + 24(SB)/8, $-.231904681384629956E-16
12DATA ·expm1rodataL22<> + 32(SB)/8, $0.50000000000000029671E+00
13DATA ·expm1rodataL22<> + 40(SB)/8, $0.16666666666666676570E+00
14DATA ·expm1rodataL22<> + 48(SB)/8, $0.83333333323590973444E-02
15DATA ·expm1rodataL22<> + 56(SB)/8, $0.13889096526400683566E-02
16DATA ·expm1rodataL22<> + 64(SB)/8, $0.41666666661701152924E-01
17DATA ·expm1rodataL22<> + 72(SB)/8, $0.19841562053987360264E-03
18DATA ·expm1rodataL22<> + 80(SB)/8, $-.693147180559945286E+00
19DATA ·expm1rodataL22<> + 88(SB)/8, $0.144269504088896339E+01
20DATA ·expm1rodataL22<> + 96(SB)/8, $704.0E+00
21GLOBL ·expm1rodataL22<> + 0(SB), RODATA, $104
22
23DATA ·expm1xmone<> + 0(SB)/8, $0xbff0000000000000
24GLOBL ·expm1xmone<> + 0(SB), RODATA, $8
25DATA ·expm1xinf<> + 0(SB)/8, $0x7ff0000000000000
26GLOBL ·expm1xinf<> + 0(SB), RODATA, $8
27DATA ·expm1x4ff<> + 0(SB)/8, $0x4ff0000000000000
28GLOBL ·expm1x4ff<> + 0(SB), RODATA, $8
29DATA ·expm1x2ff<> + 0(SB)/8, $0x2ff0000000000000
30GLOBL ·expm1x2ff<> + 0(SB), RODATA, $8
31DATA ·expm1xaddexp<> + 0(SB)/8, $0xc2f0000100003ff0
32GLOBL ·expm1xaddexp<> + 0(SB), RODATA, $8
33
34// Log multipliers table
35DATA ·expm1tab<> + 0(SB)/8, $0.0
36DATA ·expm1tab<> + 8(SB)/8, $-.171540871271399150E-01
37DATA ·expm1tab<> + 16(SB)/8, $-.306597931864376363E-01
38DATA ·expm1tab<> + 24(SB)/8, $-.410200970469965021E-01
39DATA ·expm1tab<> + 32(SB)/8, $-.486343079978231466E-01
40DATA ·expm1tab<> + 40(SB)/8, $-.538226193725835820E-01
41DATA ·expm1tab<> + 48(SB)/8, $-.568439602538111520E-01
42DATA ·expm1tab<> + 56(SB)/8, $-.579091847395528847E-01
43DATA ·expm1tab<> + 64(SB)/8, $-.571909584179366341E-01
44DATA ·expm1tab<> + 72(SB)/8, $-.548312665987204407E-01
45DATA ·expm1tab<> + 80(SB)/8, $-.509471843643441085E-01
46DATA ·expm1tab<> + 88(SB)/8, $-.456353588448863359E-01
47DATA ·expm1tab<> + 96(SB)/8, $-.389755254243262365E-01
48DATA ·expm1tab<> + 104(SB)/8, $-.310332908285244231E-01
49DATA ·expm1tab<> + 112(SB)/8, $-.218623539150173528E-01
50DATA ·expm1tab<> + 120(SB)/8, $-.115062908917949451E-01
51GLOBL ·expm1tab<> + 0(SB), RODATA, $128
52
53// Expm1 returns e**x - 1, the base-e exponential of x minus 1.
54// It is more accurate than Exp(x) - 1 when x is near zero.
55//
56// Special cases are:
57//      Expm1(+Inf) = +Inf
58//      Expm1(-Inf) = -1
59//      Expm1(NaN) = NaN
60// Very large values overflow to -1 or +Inf.
61// The algorithm used is minimax polynomial approximation using a table of
62// polynomial coefficients determined with a Remez exchange algorithm.
63
64TEXT	·expm1Asm(SB), NOSPLIT, $0-16
65	FMOVD	x+0(FP), F0
66	MOVDexpm1rodataL22<>+0(SB), R5
67	LTDBR	F0, F0
68	BLTU	L20
69	FMOVD	F0, F2
70L2:
71	WORD	$0xED205060	//cdb	%f2,.L23-.L22(%r5)
72	BYTE	$0x00
73	BYTE	$0x19
74	BGE	L16
75	BVS	L16
76	WFCEDBS	V2, V2, V2
77	BVS	LEXITTAGexpm1
78	MOVDexpm1xaddexp<>+0(SB), R1
79	FMOVD	88(R5), F1
80	FMOVD	0(R1), F2
81	WFMSDB	V0, V1, V2, V1
82	FMOVD	80(R5), F6
83	WFADB	V1, V2, V4
84	FMOVD	72(R5), F2
85	FMADD	F6, F4, F0
86	FMOVD	64(R5), F3
87	FMOVD	56(R5), F6
88	FMOVD	48(R5), F5
89	FMADD	F2, F0, F6
90	WFMADB	V0, V5, V3, V5
91	WFMDB	V0, V0, V2
92	LGDR	F1, R1
93	WFMADB	V6, V2, V5, V6
94	FMOVD	40(R5), F3
95	FMOVD	32(R5), F5
96	WFMADB	V0, V3, V5, V3
97	FMOVD	24(R5), F5
98	WFMADB	V2, V6, V3, V2
99	FMADD	F5, F4, F0
100	FMOVD	16(R5), F6
101	WFMADB	V0, V2, V6, V2
102	RISBGZ	$57, $60, $3, R1, R3
103	WORD	$0xB3130022	//lcdbr	%f2,%f2
104	MOVDexpm1tab<>+0(SB), R2
105	WORD	$0x68432000	//ld	%f4,0(%r3,%r2)
106	FMADD	F4, F0, F0
107	SLD	$48, R1, R2
108	WFMSDB	V2, V0, V4, V0
109	LDGR	R2, F4
110	WORD	$0xB3130000	//lcdbr	%f0,%f0
111	FSUB	F4, F6
112	WFMSDB	V0, V4, V6, V0
113	FMOVD	F0, ret+8(FP)
114	RET
115L16:
116	WFCEDBS	V2, V2, V4
117	BVS	LEXITTAGexpm1
118	WORD	$0xED205008	//cdb	%f2,.L34-.L22(%r5)
119	BYTE	$0x00
120	BYTE	$0x19
121	BLT	L6
122	WFCEDBS	V2, V0, V0
123	BVS	L7
124	MOVDexpm1xinf<>+0(SB), R1
125	FMOVD	0(R1), F0
126	FMOVD	F0, ret+8(FP)
127	RET
128L20:
129	WORD	$0xB3130020	//lcdbr	%f2,%f0
130	BR	L2
131L6:
132	MOVDexpm1xaddexp<>+0(SB), R1
133	FMOVD	88(R5), F5
134	FMOVD	0(R1), F4
135	WFMSDB	V0, V5, V4, V5
136	FMOVD	80(R5), F3
137	WFADB	V5, V4, V1
138	VLEG	$0, 48(R5), V16
139	WFMADB	V1, V3, V0, V3
140	FMOVD	56(R5), F4
141	FMOVD	64(R5), F7
142	FMOVD	72(R5), F6
143	WFMADB	V3, V16, V7, V16
144	WFMADB	V3, V6, V4, V6
145	WFMDB	V3, V3, V4
146	MOVDexpm1tab<>+0(SB), R2
147	WFMADB	V6, V4, V16, V6
148	VLEG	$0, 32(R5), V16
149	FMOVD	40(R5), F7
150	WFMADB	V3, V7, V16, V7
151	VLEG	$0, 24(R5), V16
152	WFMADB	V4, V6, V7, V4
153	WFMADB	V1, V16, V3, V1
154	FMOVD	16(R5), F6
155	FMADD	F4, F1, F6
156	LGDR	F5, R1
157	WORD	$0xB3130066	//lcdbr	%f6,%f6
158	RISBGZ	$57, $60, $3, R1, R3
159	WORD	$0x68432000	//ld	%f4,0(%r3,%r2)
160	FMADD	F4, F1, F1
161	MOVD	$0x4086000000000000, R2
162	FMSUB	F1, F6, F4
163	WORD	$0xB3130044	//lcdbr	%f4,%f4
164	WFCHDBS	V2, V0, V0
165	BEQ	L21
166	ADDW	$0xF000, R1
167	RISBGN	$0, $15, $48, R1, R2
168	LDGR	R2, F0
169	FMADD	F0, F4, F0
170	MOVDexpm1x4ff<>+0(SB), R3
171	FMOVD	0(R5), F4
172	FMOVD	0(R3), F2
173	WFMADB	V2, V0, V4, V0
174	FMOVD	F0, ret+8(FP)
175	RET
176L7:
177	MOVDexpm1xmone<>+0(SB), R1
178	FMOVD	0(R1), F0
179	FMOVD	F0, ret+8(FP)
180	RET
181L21:
182	ADDW	$0x1000, R1
183	RISBGN	$0, $15, $48, R1, R2
184	LDGR	R2, F0
185	FMADD	F0, F4, F0
186	MOVDexpm1x2ff<>+0(SB), R3
187	FMOVD	0(R5), F4
188	FMOVD	0(R3), F2
189	WFMADB	V2, V0, V4, V0
190	FMOVD	F0, ret+8(FP)
191	RET
192LEXITTAGexpm1:
193	FMOVD	F0, ret+8(FP)
194	RET
195