1// Copyright 2016 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
6#include "textflag.h"
7
8// Constants
9DATA sinhrodataL21<>+0(SB)/8, $0.231904681384629956E-16
10DATA sinhrodataL21<>+8(SB)/8, $0.693147180559945286E+00
11DATA sinhrodataL21<>+16(SB)/8, $704.E0
12GLOBL sinhrodataL21<>+0(SB), RODATA, $24
13DATA sinhrlog2<>+0(SB)/8, $0x3ff7154760000000
14GLOBL sinhrlog2<>+0(SB), RODATA, $8
15DATA sinhxinf<>+0(SB)/8, $0x7ff0000000000000
16GLOBL sinhxinf<>+0(SB), RODATA, $8
17DATA sinhxinit<>+0(SB)/8, $0x3ffb504f333f9de6
18GLOBL sinhxinit<>+0(SB), RODATA, $8
19DATA sinhxlim1<>+0(SB)/8, $800.E0
20GLOBL sinhxlim1<>+0(SB), RODATA, $8
21DATA sinhxadd<>+0(SB)/8, $0xc3200001610007fb
22GLOBL sinhxadd<>+0(SB), RODATA, $8
23DATA sinhx4ff<>+0(SB)/8, $0x4ff0000000000000
24GLOBL sinhx4ff<>+0(SB), RODATA, $8
25
26// Minimax polynomial approximations
27DATA sinhe0<>+0(SB)/8, $0.11715728752538099300E+01
28GLOBL sinhe0<>+0(SB), RODATA, $8
29DATA sinhe1<>+0(SB)/8, $0.11715728752538099300E+01
30GLOBL sinhe1<>+0(SB), RODATA, $8
31DATA sinhe2<>+0(SB)/8, $0.58578643762688526692E+00
32GLOBL sinhe2<>+0(SB), RODATA, $8
33DATA sinhe3<>+0(SB)/8, $0.19526214587563004497E+00
34GLOBL sinhe3<>+0(SB), RODATA, $8
35DATA sinhe4<>+0(SB)/8, $0.48815536475176217404E-01
36GLOBL sinhe4<>+0(SB), RODATA, $8
37DATA sinhe5<>+0(SB)/8, $0.97631072948627397816E-02
38GLOBL sinhe5<>+0(SB), RODATA, $8
39DATA sinhe6<>+0(SB)/8, $0.16271839297756073153E-02
40GLOBL sinhe6<>+0(SB), RODATA, $8
41DATA sinhe7<>+0(SB)/8, $0.23245485387271142509E-03
42GLOBL sinhe7<>+0(SB), RODATA, $8
43DATA sinhe8<>+0(SB)/8, $0.29080955860869629131E-04
44GLOBL sinhe8<>+0(SB), RODATA, $8
45DATA sinhe9<>+0(SB)/8, $0.32311267157667725278E-05
46GLOBL sinhe9<>+0(SB), RODATA, $8
47
48// Sinh returns the hyperbolic sine of the argument.
49//
50// Special cases are:
51//      Sinh(±0) = ±0
52//      Sinh(±Inf) = ±Inf
53//      Sinh(NaN) = NaN
54// The algorithm used is minimax polynomial approximation
55// with coefficients determined with a Remez exchange algorithm.
56
57TEXT ·sinhAsm(SB),NOSPLIT,$0-16
58	FMOVD   x+0(FP), F0
59	//special case Sinh(±0) = ±0
60	FMOVD   $(0.0), F1
61	FCMPU   F0, F1
62	BEQ     sinhIsZero
63	//special case Sinh(±Inf) = ±Inf
64	FMOVD   $1.797693134862315708145274237317043567981e+308, F1
65	FCMPU   F1, F0
66	BLEU    sinhIsInf
67	FMOVD   $-1.797693134862315708145274237317043567981e+308, F1
68	FCMPU   F1, F0
69	BGT             sinhIsInf
70
71	MOVD    $sinhrodataL21<>+0(SB), R5
72	LTDBR	F0, F0
73	MOVD    sinhxinit<>+0(SB), R1
74	FMOVD   F0, F4
75	MOVD    R1, R3
76	BLTU    L19
77	FMOVD   F0, F2
78L2:
79	WORD    $0xED205010     //cdb %f2,.L22-.L21(%r5)
80	BYTE    $0x00
81	BYTE    $0x19
82	BGE     L15     //jnl   .L15
83	BVS     L15
84	WFCEDBS V2, V2, V0
85	BEQ     L20
86L12:
87	FMOVD   F4, F0
88	FMOVD   F0, ret+8(FP)
89	RET
90
91L15:
92	WFCEDBS V2, V2, V0
93	BVS     L12
94	MOVD    $sinhxlim1<>+0(SB), R2
95	FMOVD   0(R2), F0
96	WFCHDBS V0, V2, V0
97	BEQ     L6
98	WFCHEDBS        V4, V2, V6
99	MOVD    $sinhxinf<>+0(SB), R1
100	FMOVD   0(R1), F0
101	BNE     LEXITTAGsinh
102	WFCHDBS V2, V4, V2
103	BNE     L16
104	FNEG    F0, F0
105	FMOVD   F0, ret+8(FP)
106	RET
107
108L19:
109	FNEG    F0, F2
110	BR      L2
111L6:
112	MOVD    $sinhxadd<>+0(SB), R2
113	FMOVD   0(R2), F0
114	MOVD    sinhrlog2<>+0(SB), R2
115	LDGR    R2, F6
116	WFMSDB  V4, V6, V0, V16
117	FMOVD   sinhrodataL21<>+8(SB), F6
118	WFADB   V0, V16, V0
119	FMOVD   sinhrodataL21<>+0(SB), F3
120	WFMSDB  V0, V6, V4, V6
121	MOVD    $sinhe9<>+0(SB), R2
122	WFMADB  V0, V3, V6, V0
123	FMOVD   0(R2), F1
124	MOVD    $sinhe7<>+0(SB), R2
125	WFMDB   V0, V0, V6
126	FMOVD   0(R2), F5
127	MOVD    $sinhe8<>+0(SB), R2
128	FMOVD   0(R2), F3
129	MOVD    $sinhe6<>+0(SB), R2
130	WFMADB  V6, V1, V5, V1
131	FMOVD   0(R2), F5
132	MOVD    $sinhe5<>+0(SB), R2
133	FMOVD   0(R2), F7
134	MOVD    $sinhe3<>+0(SB), R2
135	WFMADB  V6, V3, V5, V3
136	FMOVD   0(R2), F5
137	MOVD    $sinhe4<>+0(SB), R2
138	WFMADB  V6, V7, V5, V7
139	FMOVD   0(R2), F5
140	MOVD    $sinhe2<>+0(SB), R2
141	VLEG    $0, 0(R2), V20
142	WFMDB   V6, V6, V18
143	WFMADB  V6, V5, V20, V5
144	WFMADB  V1, V18, V7, V1
145	FNEG    F0, F0
146	WFMADB  V3, V18, V5, V3
147	MOVD    $sinhe1<>+0(SB), R3
148	WFCEDBS V2, V4, V2
149	FMOVD   0(R3), F5
150	MOVD    $sinhe0<>+0(SB), R3
151	WFMADB  V6, V1, V5, V1
152	FMOVD   0(R3), F5
153	VLGVG   $0, V16, R2
154	WFMADB  V6, V3, V5, V6
155	RLL     $3, R2, R2
156	RISBGN	$0, $15, $48, R2, R1
157	BEQ     L9
158	WFMSDB  V0, V1, V6, V0
159	MOVD    $sinhx4ff<>+0(SB), R3
160	FNEG    F0, F0
161	FMOVD   0(R3), F2
162	FMUL    F2, F0
163	ANDW    $0xFFFF, R2
164	WORD    $0xA53FEFB6     //llill %r3,61366
165	SUBW    R2, R3, R2
166	RISBGN	$0, $15, $48, R2, R1
167	LDGR    R1, F2
168	FMUL    F2, F0
169	FMOVD   F0, ret+8(FP)
170	RET
171
172L20:
173	MOVD    $sinhxadd<>+0(SB), R2
174	FMOVD   0(R2), F2
175	MOVD    sinhrlog2<>+0(SB), R2
176	LDGR    R2, F0
177	WFMSDB  V4, V0, V2, V6
178	FMOVD   sinhrodataL21<>+8(SB), F0
179	FADD    F6, F2
180	MOVD    $sinhe9<>+0(SB), R2
181	FMSUB   F0, F2, F4
182	FMOVD   0(R2), F1
183	FMOVD   sinhrodataL21<>+0(SB), F3
184	MOVD    $sinhe7<>+0(SB), R2
185	FMADD   F3, F2, F4
186	FMOVD   0(R2), F0
187	MOVD    $sinhe8<>+0(SB), R2
188	WFMDB   V4, V4, V2
189	FMOVD   0(R2), F3
190	MOVD    $sinhe6<>+0(SB), R2
191	FMOVD   0(R2), F5
192	LGDR    F6, R2
193	RLL     $3, R2, R2
194	RISBGN	$0, $15, $48, R2, R1
195	WFMADB  V2, V1, V0, V1
196	LDGR    R1, F0
197	MOVD    $sinhe5<>+0(SB), R1
198	WFMADB  V2, V3, V5, V3
199	FMOVD   0(R1), F5
200	MOVD    $sinhe3<>+0(SB), R1
201	FMOVD   0(R1), F6
202	WFMDB   V2, V2, V7
203	WFMADB  V2, V5, V6, V5
204	WORD    $0xA7487FB6     //lhi %r4,32694
205	FNEG    F4, F4
206	ANDW    $0xFFFF, R2
207	SUBW    R2, R4, R2
208	RISBGN	$0, $15, $48, R2, R3
209	LDGR    R3, F6
210	WFADB   V0, V6, V16
211	MOVD    $sinhe4<>+0(SB), R1
212	WFMADB  V1, V7, V5, V1
213	WFMDB   V4, V16, V4
214	FMOVD   0(R1), F5
215	MOVD    $sinhe2<>+0(SB), R1
216	VLEG    $0, 0(R1), V16
217	MOVD    $sinhe1<>+0(SB), R1
218	WFMADB  V2, V5, V16, V5
219	VLEG    $0, 0(R1), V16
220	WFMADB  V3, V7, V5, V3
221	WFMADB  V2, V1, V16, V1
222	FSUB    F6, F0
223	FMUL    F1, F4
224	MOVD    $sinhe0<>+0(SB), R1
225	FMOVD   0(R1), F6
226	WFMADB  V2, V3, V6, V2
227	WFMADB  V0, V2, V4, V0
228	FMOVD   F0, ret+8(FP)
229	RET
230
231L9:
232	WFMADB  V0, V1, V6, V0
233	MOVD    $sinhx4ff<>+0(SB), R3
234	FMOVD   0(R3), F2
235	FMUL    F2, F0
236	WORD    $0xA72AF000     //ahi   %r2,-4096
237	RISBGN	$0, $15, $48, R2, R1
238	LDGR    R1, F2
239	FMUL    F2, F0
240	FMOVD   F0, ret+8(FP)
241	RET
242
243L16:
244	FMOVD   F0, ret+8(FP)
245	RET
246
247LEXITTAGsinh:
248sinhIsInf:
249sinhIsZero:
250	FMOVD   F0, ret+8(FP)
251	RET
252