xref: /reactos/sdk/lib/crt/math/libm_sse2/pow.asm (revision 105426b8)
1;
2; MIT License
3; -----------
4;
5; Copyright (c) 2002-2019 Advanced Micro Devices, Inc.
6;
7; Permission is hereby granted, free of charge, to any person obtaining a copy
8; of this Software and associated documentaon files (the "Software"), to deal
9; in the Software without restriction, including without limitation the rights
10; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11; copies of the Software, and to permit persons to whom the Software is
12; furnished to do so, subject to the following conditions:
13;
14; The above copyright notice and this permission notice shall be included in
15; all copies or substantial portions of the Software.
16;
17; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23; THE SOFTWARE.
24;
25; pow.asm
26;
27; An implementation of the pow libm function.
28;
29; Prototype:
30;
31;     double pow(double x, double y);
32;
33
34;
35;   Algorithm:
36;       x^y = e^(y*ln(x))
37;
38;       Look in exp, log for the respective algorithms
39;
40
41.const
42
43ALIGN 16
44
45; these codes and the ones in the corresponding .c file have to match
46__flag_x_one_y_snan             DD 00000001
47__flag_x_zero_z_inf             DD 00000002
48__flag_x_nan                    DD 00000003
49__flag_y_nan                    DD 00000004
50__flag_x_nan_y_nan              DD 00000005
51__flag_x_neg_y_notint           DD 00000006
52__flag_z_zero                   DD 00000007
53__flag_z_denormal               DD 00000008
54__flag_z_inf                    DD 00000009
55
56ALIGN 16
57
58__ay_max_bound              DQ 43e0000000000000h
59__ay_min_bound              DQ 3c00000000000000h
60__sign_mask                 DQ 8000000000000000h
61__sign_and_exp_mask         DQ 0fff0000000000000h
62__exp_mask                  DQ 7ff0000000000000h
63__neg_inf                   DQ 0fff0000000000000h
64__pos_inf                   DQ 7ff0000000000000h
65__pos_one                   DQ 3ff0000000000000h
66__pos_zero                  DQ 0000000000000000h
67__exp_mant_mask             DQ 7fffffffffffffffh
68__mant_mask                 DQ 000fffffffffffffh
69__ind_pattern               DQ 0fff8000000000000h
70
71
72__neg_qnan                  DQ 0fff8000000000000h
73__qnan                      DQ 7ff8000000000000h
74__qnan_set                  DQ 0008000000000000h
75
76__neg_one                   DQ 0bff0000000000000h
77__neg_zero                  DQ 8000000000000000h
78
79__exp_shift                 DQ 0000000000000034h ; 52
80__exp_bias                  DQ 00000000000003ffh ; 1023
81__exp_bias_m1               DQ 00000000000003feh ; 1022
82
83__yexp_53                   DQ 0000000000000035h ; 53
84__mant_full                 DQ 000fffffffffffffh
85__1_before_mant             DQ 0010000000000000h
86
87__mask_mant_all8            DQ 000ff00000000000h
88__mask_mant9                DQ 0000080000000000h
89
90
91
92ALIGN 16
93__real_fffffffff8000000     DQ 0fffffffff8000000h
94                            DQ 0fffffffff8000000h
95
96__mask_8000000000000000     DQ 8000000000000000h
97                            DQ 8000000000000000h
98
99__real_4090040000000000     DQ 4090040000000000h
100                            DQ 4090040000000000h
101
102__real_C090C80000000000     DQ 0C090C80000000000h
103                            DQ 0C090C80000000000h
104
105;---------------------
106; log data
107;---------------------
108
109ALIGN 16
110
111__real_ninf     DQ 0fff0000000000000h   ; -inf
112                DQ 0000000000000000h
113__real_inf      DQ 7ff0000000000000h    ; +inf
114                DQ 0000000000000000h
115__real_nan      DQ 7ff8000000000000h    ; NaN
116                DQ 0000000000000000h
117__real_mant     DQ 000FFFFFFFFFFFFFh    ; mantissa bits
118                DQ 0000000000000000h
119__mask_1023     DQ 00000000000003ffh
120                DQ 0000000000000000h
121__mask_001      DQ 0000000000000001h
122                DQ 0000000000000000h
123
124__real_log2_lead    DQ 3fe62e42e0000000h ; log2_lead  6.93147122859954833984e-01
125                    DQ 0000000000000000h
126__real_log2_tail    DQ 3e6efa39ef35793ch ; log2_tail  5.76999904754328540596e-08
127                    DQ 0000000000000000h
128
129__real_two          DQ 4000000000000000h ; 2
130                    DQ 0000000000000000h
131
132__real_one          DQ 3ff0000000000000h ; 1
133                    DQ 0000000000000000h
134
135__real_half         DQ 3fe0000000000000h ; 1/2
136                    DQ 0000000000000000h
137
138__mask_100          DQ 0000000000000100h
139                    DQ 0000000000000000h
140
141__real_1_over_2     DQ 3fe0000000000000h
142                    DQ 0000000000000000h
143__real_1_over_3     DQ 3fd5555555555555h
144                    DQ 0000000000000000h
145__real_1_over_4     DQ 3fd0000000000000h
146                    DQ 0000000000000000h
147__real_1_over_5     DQ 3fc999999999999ah
148                    DQ 0000000000000000h
149__real_1_over_6     DQ 3fc5555555555555h
150                    DQ 0000000000000000h
151__real_1_over_7     DQ 3fc2492492492494h
152                    DQ 0000000000000000h
153
154__mask_1023_f       DQ 0c08ff80000000000h
155                    DQ 0000000000000000h
156
157__mask_2045         DQ 00000000000007fdh
158                    DQ 0000000000000000h
159
160__real_threshold    DQ 3fc0000000000000h ; 0.125
161                    DQ 3fc0000000000000h
162
163__real_notsign      DQ 7ffFFFFFFFFFFFFFh ; ^sign bit
164                    DQ 0000000000000000h
165
166
167EXTRN __log_256_lead:QWORD
168EXTRN __log_256_tail:QWORD
169EXTRN __use_fma3_lib:DWORD
170
171; This table differs from the tables in log_256_lead_tail_table.asm:
172; the heads have fewer significant bits (hence the tails also differ).
173ALIGN 16
174__log_F_inv_head    DQ 4000000000000000h
175                    DQ 3fffe00000000000h
176                    DQ 3fffc00000000000h
177                    DQ 3fffa00000000000h
178                    DQ 3fff800000000000h
179                    DQ 3fff600000000000h
180                    DQ 3fff400000000000h
181                    DQ 3fff200000000000h
182                    DQ 3fff000000000000h
183                    DQ 3ffee00000000000h
184                    DQ 3ffec00000000000h
185                    DQ 3ffea00000000000h
186                    DQ 3ffe900000000000h
187                    DQ 3ffe700000000000h
188                    DQ 3ffe500000000000h
189                    DQ 3ffe300000000000h
190                    DQ 3ffe100000000000h
191                    DQ 3ffe000000000000h
192                    DQ 3ffde00000000000h
193                    DQ 3ffdc00000000000h
194                    DQ 3ffda00000000000h
195                    DQ 3ffd900000000000h
196                    DQ 3ffd700000000000h
197                    DQ 3ffd500000000000h
198                    DQ 3ffd400000000000h
199                    DQ 3ffd200000000000h
200                    DQ 3ffd000000000000h
201                    DQ 3ffcf00000000000h
202                    DQ 3ffcd00000000000h
203                    DQ 3ffcb00000000000h
204                    DQ 3ffca00000000000h
205                    DQ 3ffc800000000000h
206                    DQ 3ffc700000000000h
207                    DQ 3ffc500000000000h
208                    DQ 3ffc300000000000h
209                    DQ 3ffc200000000000h
210                    DQ 3ffc000000000000h
211                    DQ 3ffbf00000000000h
212                    DQ 3ffbd00000000000h
213                    DQ 3ffbc00000000000h
214                    DQ 3ffba00000000000h
215                    DQ 3ffb900000000000h
216                    DQ 3ffb700000000000h
217                    DQ 3ffb600000000000h
218                    DQ 3ffb400000000000h
219                    DQ 3ffb300000000000h
220                    DQ 3ffb200000000000h
221                    DQ 3ffb000000000000h
222                    DQ 3ffaf00000000000h
223                    DQ 3ffad00000000000h
224                    DQ 3ffac00000000000h
225                    DQ 3ffaa00000000000h
226                    DQ 3ffa900000000000h
227                    DQ 3ffa800000000000h
228                    DQ 3ffa600000000000h
229                    DQ 3ffa500000000000h
230                    DQ 3ffa400000000000h
231                    DQ 3ffa200000000000h
232                    DQ 3ffa100000000000h
233                    DQ 3ffa000000000000h
234                    DQ 3ff9e00000000000h
235                    DQ 3ff9d00000000000h
236                    DQ 3ff9c00000000000h
237                    DQ 3ff9a00000000000h
238                    DQ 3ff9900000000000h
239                    DQ 3ff9800000000000h
240                    DQ 3ff9700000000000h
241                    DQ 3ff9500000000000h
242                    DQ 3ff9400000000000h
243                    DQ 3ff9300000000000h
244                    DQ 3ff9200000000000h
245                    DQ 3ff9000000000000h
246                    DQ 3ff8f00000000000h
247                    DQ 3ff8e00000000000h
248                    DQ 3ff8d00000000000h
249                    DQ 3ff8b00000000000h
250                    DQ 3ff8a00000000000h
251                    DQ 3ff8900000000000h
252                    DQ 3ff8800000000000h
253                    DQ 3ff8700000000000h
254                    DQ 3ff8600000000000h
255                    DQ 3ff8400000000000h
256                    DQ 3ff8300000000000h
257                    DQ 3ff8200000000000h
258                    DQ 3ff8100000000000h
259                    DQ 3ff8000000000000h
260                    DQ 3ff7f00000000000h
261                    DQ 3ff7e00000000000h
262                    DQ 3ff7d00000000000h
263                    DQ 3ff7b00000000000h
264                    DQ 3ff7a00000000000h
265                    DQ 3ff7900000000000h
266                    DQ 3ff7800000000000h
267                    DQ 3ff7700000000000h
268                    DQ 3ff7600000000000h
269                    DQ 3ff7500000000000h
270                    DQ 3ff7400000000000h
271                    DQ 3ff7300000000000h
272                    DQ 3ff7200000000000h
273                    DQ 3ff7100000000000h
274                    DQ 3ff7000000000000h
275                    DQ 3ff6f00000000000h
276                    DQ 3ff6e00000000000h
277                    DQ 3ff6d00000000000h
278                    DQ 3ff6c00000000000h
279                    DQ 3ff6b00000000000h
280                    DQ 3ff6a00000000000h
281                    DQ 3ff6900000000000h
282                    DQ 3ff6800000000000h
283                    DQ 3ff6700000000000h
284                    DQ 3ff6600000000000h
285                    DQ 3ff6500000000000h
286                    DQ 3ff6400000000000h
287                    DQ 3ff6300000000000h
288                    DQ 3ff6200000000000h
289                    DQ 3ff6100000000000h
290                    DQ 3ff6000000000000h
291                    DQ 3ff5f00000000000h
292                    DQ 3ff5e00000000000h
293                    DQ 3ff5d00000000000h
294                    DQ 3ff5c00000000000h
295                    DQ 3ff5b00000000000h
296                    DQ 3ff5a00000000000h
297                    DQ 3ff5900000000000h
298                    DQ 3ff5800000000000h
299                    DQ 3ff5800000000000h
300                    DQ 3ff5700000000000h
301                    DQ 3ff5600000000000h
302                    DQ 3ff5500000000000h
303                    DQ 3ff5400000000000h
304                    DQ 3ff5300000000000h
305                    DQ 3ff5200000000000h
306                    DQ 3ff5100000000000h
307                    DQ 3ff5000000000000h
308                    DQ 3ff5000000000000h
309                    DQ 3ff4f00000000000h
310                    DQ 3ff4e00000000000h
311                    DQ 3ff4d00000000000h
312                    DQ 3ff4c00000000000h
313                    DQ 3ff4b00000000000h
314                    DQ 3ff4a00000000000h
315                    DQ 3ff4a00000000000h
316                    DQ 3ff4900000000000h
317                    DQ 3ff4800000000000h
318                    DQ 3ff4700000000000h
319                    DQ 3ff4600000000000h
320                    DQ 3ff4600000000000h
321                    DQ 3ff4500000000000h
322                    DQ 3ff4400000000000h
323                    DQ 3ff4300000000000h
324                    DQ 3ff4200000000000h
325                    DQ 3ff4200000000000h
326                    DQ 3ff4100000000000h
327                    DQ 3ff4000000000000h
328                    DQ 3ff3f00000000000h
329                    DQ 3ff3e00000000000h
330                    DQ 3ff3e00000000000h
331                    DQ 3ff3d00000000000h
332                    DQ 3ff3c00000000000h
333                    DQ 3ff3b00000000000h
334                    DQ 3ff3b00000000000h
335                    DQ 3ff3a00000000000h
336                    DQ 3ff3900000000000h
337                    DQ 3ff3800000000000h
338                    DQ 3ff3800000000000h
339                    DQ 3ff3700000000000h
340                    DQ 3ff3600000000000h
341                    DQ 3ff3500000000000h
342                    DQ 3ff3500000000000h
343                    DQ 3ff3400000000000h
344                    DQ 3ff3300000000000h
345                    DQ 3ff3200000000000h
346                    DQ 3ff3200000000000h
347                    DQ 3ff3100000000000h
348                    DQ 3ff3000000000000h
349                    DQ 3ff3000000000000h
350                    DQ 3ff2f00000000000h
351                    DQ 3ff2e00000000000h
352                    DQ 3ff2e00000000000h
353                    DQ 3ff2d00000000000h
354                    DQ 3ff2c00000000000h
355                    DQ 3ff2b00000000000h
356                    DQ 3ff2b00000000000h
357                    DQ 3ff2a00000000000h
358                    DQ 3ff2900000000000h
359                    DQ 3ff2900000000000h
360                    DQ 3ff2800000000000h
361                    DQ 3ff2700000000000h
362                    DQ 3ff2700000000000h
363                    DQ 3ff2600000000000h
364                    DQ 3ff2500000000000h
365                    DQ 3ff2500000000000h
366                    DQ 3ff2400000000000h
367                    DQ 3ff2300000000000h
368                    DQ 3ff2300000000000h
369                    DQ 3ff2200000000000h
370                    DQ 3ff2100000000000h
371                    DQ 3ff2100000000000h
372                    DQ 3ff2000000000000h
373                    DQ 3ff2000000000000h
374                    DQ 3ff1f00000000000h
375                    DQ 3ff1e00000000000h
376                    DQ 3ff1e00000000000h
377                    DQ 3ff1d00000000000h
378                    DQ 3ff1c00000000000h
379                    DQ 3ff1c00000000000h
380                    DQ 3ff1b00000000000h
381                    DQ 3ff1b00000000000h
382                    DQ 3ff1a00000000000h
383                    DQ 3ff1900000000000h
384                    DQ 3ff1900000000000h
385                    DQ 3ff1800000000000h
386                    DQ 3ff1800000000000h
387                    DQ 3ff1700000000000h
388                    DQ 3ff1600000000000h
389                    DQ 3ff1600000000000h
390                    DQ 3ff1500000000000h
391                    DQ 3ff1500000000000h
392                    DQ 3ff1400000000000h
393                    DQ 3ff1300000000000h
394                    DQ 3ff1300000000000h
395                    DQ 3ff1200000000000h
396                    DQ 3ff1200000000000h
397                    DQ 3ff1100000000000h
398                    DQ 3ff1100000000000h
399                    DQ 3ff1000000000000h
400                    DQ 3ff0f00000000000h
401                    DQ 3ff0f00000000000h
402                    DQ 3ff0e00000000000h
403                    DQ 3ff0e00000000000h
404                    DQ 3ff0d00000000000h
405                    DQ 3ff0d00000000000h
406                    DQ 3ff0c00000000000h
407                    DQ 3ff0c00000000000h
408                    DQ 3ff0b00000000000h
409                    DQ 3ff0a00000000000h
410                    DQ 3ff0a00000000000h
411                    DQ 3ff0900000000000h
412                    DQ 3ff0900000000000h
413                    DQ 3ff0800000000000h
414                    DQ 3ff0800000000000h
415                    DQ 3ff0700000000000h
416                    DQ 3ff0700000000000h
417                    DQ 3ff0600000000000h
418                    DQ 3ff0600000000000h
419                    DQ 3ff0500000000000h
420                    DQ 3ff0500000000000h
421                    DQ 3ff0400000000000h
422                    DQ 3ff0400000000000h
423                    DQ 3ff0300000000000h
424                    DQ 3ff0300000000000h
425                    DQ 3ff0200000000000h
426                    DQ 3ff0200000000000h
427                    DQ 3ff0100000000000h
428                    DQ 3ff0100000000000h
429                    DQ 3ff0000000000000h
430                    DQ 3ff0000000000000h
431
432ALIGN 16
433__log_F_inv_tail    DQ 0000000000000000h
434                    DQ 3effe01fe01fe020h
435                    DQ 3f1fc07f01fc07f0h
436                    DQ 3f31caa01fa11caah
437                    DQ 3f3f81f81f81f820h
438                    DQ 3f48856506ddaba6h
439                    DQ 3f5196792909c560h
440                    DQ 3f57d9108c2ad433h
441                    DQ 3f5f07c1f07c1f08h
442                    DQ 3f638ff08b1c03ddh
443                    DQ 3f680f6603d980f6h
444                    DQ 3f6d00f57403d5d0h
445                    DQ 3f331abf0b7672a0h
446                    DQ 3f506a965d43919bh
447                    DQ 3f5ceb240795ceb2h
448                    DQ 3f6522f3b834e67fh
449                    DQ 3f6c3c3c3c3c3c3ch
450                    DQ 3f3e01e01e01e01eh
451                    DQ 3f575b8fe21a291ch
452                    DQ 3f6403b9403b9404h
453                    DQ 3f6cc0ed7303b5cch
454                    DQ 3f479118f3fc4da2h
455                    DQ 3f5ed952e0b0ce46h
456                    DQ 3f695900eae56404h
457                    DQ 3f3d41d41d41d41dh
458                    DQ 3f5cb28ff16c69aeh
459                    DQ 3f696b1edd80e866h
460                    DQ 3f4372e225fe30d9h
461                    DQ 3f60ad12073615a2h
462                    DQ 3f6cdb2c0397cdb3h
463                    DQ 3f52cc157b864407h
464                    DQ 3f664cb5f7148404h
465                    DQ 3f3c71c71c71c71ch
466                    DQ 3f6129a21a930b84h
467                    DQ 3f6f1e0387f1e038h
468                    DQ 3f5ad4e4ba80709bh
469                    DQ 3f6c0e070381c0e0h
470                    DQ 3f560fba1a362bb0h
471                    DQ 3f6a5713280dee96h
472                    DQ 3f53f59620f9ece9h
473                    DQ 3f69f22983759f23h
474                    DQ 3f5478ac63fc8d5ch
475                    DQ 3f6ad87bb4671656h
476                    DQ 3f578b8efbb8148ch
477                    DQ 3f6d0369d0369d03h
478                    DQ 3f5d212b601b3748h
479                    DQ 3f0b2036406c80d9h
480                    DQ 3f629663b24547d1h
481                    DQ 3f4435e50d79435eh
482                    DQ 3f67d0ff2920bc03h
483                    DQ 3f55c06b15c06b16h
484                    DQ 3f6e3a5f0fd7f954h
485                    DQ 3f61dec0d4c77b03h
486                    DQ 3f473289870ac52eh
487                    DQ 3f6a034da034da03h
488                    DQ 3f5d041da2292856h
489                    DQ 3f3a41a41a41a41ah
490                    DQ 3f68550f8a39409dh
491                    DQ 3f5b4fe5e92c0686h
492                    DQ 3f3a01a01a01a01ah
493                    DQ 3f691d2a2067b23ah
494                    DQ 3f5e7c5dada0b4e5h
495                    DQ 3f468a7725080ce1h
496                    DQ 3f6c49d4aa21b490h
497                    DQ 3f63333333333333h
498                    DQ 3f54bc363b03fccfh
499                    DQ 3f2c9f01970e4f81h
500                    DQ 3f697617c6ef5b25h
501                    DQ 3f6161f9add3c0cah
502                    DQ 3f5319fe6cb39806h
503                    DQ 3f2f693a1c451ab3h
504                    DQ 3f6a9e240321a9e2h
505                    DQ 3f63831f3831f383h
506                    DQ 3f5949ebc4dcfc1ch
507                    DQ 3f480c6980c6980ch
508                    DQ 3f6f9d00c5fe7403h
509                    DQ 3f69721ed7e75347h
510                    DQ 3f6381ec0313381fh
511                    DQ 3f5b97c2aec12653h
512                    DQ 3f509ef3024ae3bah
513                    DQ 3f38618618618618h
514                    DQ 3f6e0184f00c2780h
515                    DQ 3f692ef5657dba52h
516                    DQ 3f64940305494030h
517                    DQ 3f60303030303030h
518                    DQ 3f58060180601806h
519                    DQ 3f5017f405fd017fh
520                    DQ 3f412a8ad278e8ddh
521                    DQ 3f17d05f417d05f4h
522                    DQ 3f6d67245c02f7d6h
523                    DQ 3f6a4411c1d986a9h
524                    DQ 3f6754d76c7316dfh
525                    DQ 3f649902f149902fh
526                    DQ 3f621023358c1a68h
527                    DQ 3f5f7390d2a6c406h
528                    DQ 3f5b2b0805d5b2b1h
529                    DQ 3f5745d1745d1746h
530                    DQ 3f53c31507fa32c4h
531                    DQ 3f50a1fd1b7af017h
532                    DQ 3f4bc36ce3e0453ah
533                    DQ 3f4702e05c0b8170h
534                    DQ 3f4300b79300b793h
535                    DQ 3f3f76b4337c6cb1h
536                    DQ 3f3a62681c860fb0h
537                    DQ 3f36c16c16c16c17h
538                    DQ 3f3490aa31a3cfc7h
539                    DQ 3f33cd153729043eh
540                    DQ 3f3473a88d0bfd2eh
541                    DQ 3f36816816816817h
542                    DQ 3f39f36016719f36h
543                    DQ 3f3ec6a5122f9016h
544                    DQ 3f427c29da5519cfh
545                    DQ 3f4642c8590b2164h
546                    DQ 3f4ab5c45606f00bh
547                    DQ 3f4fd3b80b11fd3ch
548                    DQ 3f52cda0c6ba4eaah
549                    DQ 3f56058160581606h
550                    DQ 3f5990d0a4b7ef87h
551                    DQ 3f5d6ee340579d6fh
552                    DQ 3f60cf87d9c54a69h
553                    DQ 3f6310572620ae4ch
554                    DQ 3f65798c8ff522a2h
555                    DQ 3f680ad602b580adh
556                    DQ 3f6ac3e24799546fh
557                    DQ 3f6da46102b1da46h
558                    DQ 3f15805601580560h
559                    DQ 3f3ed3c506b39a23h
560                    DQ 3f4cbdd3e2970f60h
561                    DQ 3f55555555555555h
562                    DQ 3f5c979aee0bf805h
563                    DQ 3f621291e81fd58eh
564                    DQ 3f65fead500a9580h
565                    DQ 3f6a0fd5c5f02a3ah
566                    DQ 3f6e45c223898adch
567                    DQ 3f35015015015015h
568                    DQ 3f4c7b16ea64d422h
569                    DQ 3f57829cbc14e5e1h
570                    DQ 3f60877db8589720h
571                    DQ 3f65710e4b5edceah
572                    DQ 3f6a7dbb4d1fc1c8h
573                    DQ 3f6fad40a57eb503h
574                    DQ 3f43fd6bb00a5140h
575                    DQ 3f54e78ecb419ba9h
576                    DQ 3f600a44029100a4h
577                    DQ 3f65c28f5c28f5c3h
578                    DQ 3f6b9c68b2c0cc4ah
579                    DQ 3f2978feb9f34381h
580                    DQ 3f4ecf163bb6500ah
581                    DQ 3f5be1958b67ebb9h
582                    DQ 3f644e6157dc9a3bh
583                    DQ 3f6acc4baa3f0ddfh
584                    DQ 3f26a4cbcb2a247bh
585                    DQ 3f50505050505050h
586                    DQ 3f5e0b4439959819h
587                    DQ 3f66027f6027f602h
588                    DQ 3f6d1e854b5e0db4h
589                    DQ 3f4165e7254813e2h
590                    DQ 3f576646a9d716efh
591                    DQ 3f632b48f757ce88h
592                    DQ 3f6ac1b24652a906h
593                    DQ 3f33b13b13b13b14h
594                    DQ 3f5490e1eb208984h
595                    DQ 3f62385830fec66eh
596                    DQ 3f6a45a6cc111b7eh
597                    DQ 3f33813813813814h
598                    DQ 3f556f472517b708h
599                    DQ 3f631be7bc0e8f2ah
600                    DQ 3f6b9cbf3e55f044h
601                    DQ 3f40e7d95bc609a9h
602                    DQ 3f59e6b3804d19e7h
603                    DQ 3f65c8b6af7963c2h
604                    DQ 3f6eb9dad43bf402h
605                    DQ 3f4f1a515885fb37h
606                    DQ 3f60eeb1d3d76c02h
607                    DQ 3f6a320261a32026h
608                    DQ 3f3c82ac40260390h
609                    DQ 3f5a12f684bda12fh
610                    DQ 3f669d43fda2962ch
611                    DQ 3f02e025c04b8097h
612                    DQ 3f542804b542804bh
613                    DQ 3f63f69b02593f6ah
614                    DQ 3f6df31cb46e21fah
615                    DQ 3f5012b404ad012bh
616                    DQ 3f623925e7820a7fh
617                    DQ 3f6c8253c8253c82h
618                    DQ 3f4b92ddc02526e5h
619                    DQ 3f61602511602511h
620                    DQ 3f6bf471439c9adfh
621                    DQ 3f4a85c40939a85ch
622                    DQ 3f6166f9ac024d16h
623                    DQ 3f6c44e10125e227h
624                    DQ 3f4cebf48bbd90e5h
625                    DQ 3f62492492492492h
626                    DQ 3f6d6f2e2ec0b673h
627                    DQ 3f5159e26af37c05h
628                    DQ 3f64024540245402h
629                    DQ 3f6f6f0243f6f024h
630                    DQ 3f55e60121579805h
631                    DQ 3f668e18cf81b10fh
632                    DQ 3f32012012012012h
633                    DQ 3f5c11f7047dc11fh
634                    DQ 3f69e878ff70985eh
635                    DQ 3f4779d9fdc3a219h
636                    DQ 3f61eace5c957907h
637                    DQ 3f6e0d5b450239e1h
638                    DQ 3f548bf073816367h
639                    DQ 3f6694808dda5202h
640                    DQ 3f37c67f2bae2b21h
641                    DQ 3f5ee58469ee5847h
642                    DQ 3f6c0233c0233c02h
643                    DQ 3f514e02328a7012h
644                    DQ 3f6561072057b573h
645                    DQ 3f31811811811812h
646                    DQ 3f5e28646f5a1060h
647                    DQ 3f6c0d1284e6f1d7h
648                    DQ 3f523543f0c80459h
649                    DQ 3f663cbeea4e1a09h
650                    DQ 3f3b9a3fdd5c8cb8h
651                    DQ 3f60be1c159a76d2h
652                    DQ 3f6e1d1a688e4838h
653                    DQ 3f572044d72044d7h
654                    DQ 3f691713db81577bh
655                    DQ 3f4ac73ae9819b50h
656                    DQ 3f6460334e904cf6h
657                    DQ 3f31111111111111h
658                    DQ 3f5feef80441fef0h
659                    DQ 3f6de021fde021feh
660                    DQ 3f57b7eacc9686a0h
661                    DQ 3f69ead7cd391fbch
662                    DQ 3f50195609804390h
663                    DQ 3f6641511e8d2b32h
664                    DQ 3f4222b1acf1ce96h
665                    DQ 3f62e29f79b47582h
666                    DQ 3f24f0d1682e11cdh
667                    DQ 3f5f9bb096771e4dh
668                    DQ 3f6e5ee45dd96ae2h
669                    DQ 3f5a0429a0429a04h
670                    DQ 3f6bb74d5f06c021h
671                    DQ 3f54fce404254fceh
672                    DQ 3f695766eacbc402h
673                    DQ 3f50842108421084h
674                    DQ 3f673e5371d5c338h
675                    DQ 3f4930523fbe3368h
676                    DQ 3f656b38f225f6c4h
677                    DQ 3f426e978d4fdf3bh
678                    DQ 3f63dd40e4eb0cc6h
679                    DQ 3f397f7d73404146h
680                    DQ 3f6293982cc98af1h
681                    DQ 3f30410410410410h
682                    DQ 3f618d6f048ff7e4h
683                    DQ 3f2236a3ebc349deh
684                    DQ 3f60c9f8ee53d18ch
685                    DQ 3f10204081020408h
686                    DQ 3f60486ca2f46ea6h
687                    DQ 3ef0101010101010h
688                    DQ 3f60080402010080h
689                    DQ 0000000000000000h
690
691;---------------------
692; exp data
693;---------------------
694
695ALIGN 16
696
697__denormal_threshold            DD 0fffffc02h ; -1022
698                                DD 0
699                                DQ 0
700
701__enable_almost_inf             DQ 7fe0000000000000h
702                                DQ 0
703
704__real_zero                     DQ 0000000000000000h
705                                DQ 0
706
707__real_smallest_denormal        DQ 0000000000000001h
708                                DQ 0
709__denormal_tiny_threshold       DQ 0c0874046dfefd9d0h
710                                DQ 0
711
712__real_p65536                   DQ 40f0000000000000h    ; 65536
713                                DQ 0
714__real_m68800                   DQ 0c0f0cc0000000000h   ; -68800
715                                DQ 0
716__real_64_by_log2               DQ 40571547652b82feh    ; 64/ln(2)
717                                DQ 0
718__real_log2_by_64_head          DQ 3f862e42f0000000h    ; log2_by_64_head
719                                DQ 0
720__real_log2_by_64_tail          DQ 0bdfdf473de6af278h   ; -log2_by_64_tail
721                                DQ 0
722__real_1_by_720                 DQ 3f56c16c16c16c17h    ; 1/720
723                                DQ 0
724__real_1_by_120                 DQ 3f81111111111111h    ; 1/120
725                                DQ 0
726__real_1_by_24                  DQ 3fa5555555555555h    ; 1/24
727                                DQ 0
728__real_1_by_6                   DQ 3fc5555555555555h    ; 1/6
729                                DQ 0
730__real_1_by_2                   DQ 3fe0000000000000h    ; 1/2
731                                DQ 0
732
733
734EXTRN __two_to_jby64_head_table:QWORD
735EXTRN __two_to_jby64_tail_table:QWORD
736EXTRN __use_fma3_lib:DWORD
737
738fname           TEXTEQU <pow>
739fname_special   TEXTEQU <_pow_special>
740
741; define local variable storage offsets
742
743save_x          EQU     10h
744save_y          EQU     20h
745p_temp_exp      EQU     30h
746negate_result   EQU     40h
747save_ax         EQU     50h
748y_head          EQU     60h
749p_temp_log      EQU     70h
750save_xmm6       EQU     080h
751save_xmm7       EQU     090h
752dummy_space     EQU     0a0h
753
754stack_size      EQU     0c8h
755
756include fm.inc
757
758; external function
759EXTERN fname_special:PROC
760
761.code
762ALIGN 16
763PUBLIC fname
764fname PROC FRAME
765    StackAllocate stack_size
766    SaveXmm xmm6, save_xmm6
767    SaveXmm xmm7, save_xmm7
768    .ENDPROLOG
769    cmp          DWORD PTR __use_fma3_lib, 0
770    jne          Lpow_fma3
771
772ALIGN 16
773Lpow_sse2:
774    movsd       QWORD PTR [save_x+rsp], xmm0
775    movsd       QWORD PTR [save_y+rsp], xmm1
776
777    mov         rdx, QWORD PTR [save_x+rsp]
778    mov         r8, QWORD PTR [save_y+rsp]
779
780    mov         r10, QWORD PTR __exp_mant_mask
781    and         r10, r8
782    jz          Lpow_sse2_y_is_zero
783
784    cmp         r8, QWORD PTR __pos_one
785    je          Lpow_sse2_y_is_one
786
787    mov         r9, QWORD PTR __sign_mask
788    and         r9, rdx
789    mov         rax, QWORD PTR __pos_zero
790    mov         QWORD PTR [negate_result+rsp], rax
791    cmp         r9, QWORD PTR __sign_mask
792    je          Lpow_sse2_x_is_neg
793
794    cmp         rdx, QWORD PTR __pos_one
795    je          Lpow_sse2_x_is_pos_one
796
797    cmp         rdx, QWORD PTR __pos_zero
798    je          Lpow_sse2_x_is_zero
799
800    mov         r9, QWORD PTR __exp_mask
801    and         r9, rdx
802    cmp         r9, QWORD PTR __exp_mask
803    je          Lpow_sse2_x_is_inf_or_nan
804
805    mov         r10, QWORD PTR __exp_mask
806    and         r10, r8
807    cmp         r10, QWORD PTR __ay_max_bound
808    jg          Lpow_sse2_ay_is_very_large
809
810    mov         r10, QWORD PTR __exp_mask
811    and         r10, r8
812    cmp         r10, QWORD PTR __ay_min_bound
813    jl          Lpow_sse2_ay_is_very_small
814
815    ; -----------------------------
816    ; compute log(x) here
817    ; -----------------------------
818Lpow_sse2_log_x:
819
820    ; compute exponent part
821    xor         r8, r8
822    movdqa      xmm3, xmm0
823    psrlq       xmm3, 52
824    movd        r8, xmm0
825    psubq       xmm3, XMMWORD PTR __mask_1023
826    movdqa      xmm2, xmm0
827    cvtdq2pd    xmm6, xmm3 ; xexp
828    pand        xmm2, XMMWORD PTR __real_mant
829
830    comisd      xmm6, QWORD PTR __mask_1023_f
831    je          Lpow_sse2_denormal_adjust
832
833Lpow_sse2_continue_common:
834
835    ; compute index into the log tables
836    movsd       xmm7, xmm0
837    mov         r9, r8
838    and         r8, QWORD PTR __mask_mant_all8
839    and         r9, QWORD PTR __mask_mant9
840    subsd       xmm7, __real_one
841    shl         r9, 1
842    add         r8, r9
843    mov         QWORD PTR [p_temp_log+rsp], r8
844    andpd       xmm7, __real_notsign
845
846    ; F, Y, switch to near-one codepath
847    movsd       xmm1, QWORD PTR [p_temp_log+rsp]
848    shr         r8, 44
849    por         xmm2, XMMWORD PTR __real_half
850    por         xmm1, XMMWORD PTR __real_half
851    lea         r9, QWORD PTR __log_F_inv_head
852    lea         rdx, QWORD PTR __log_F_inv_tail
853    comisd      xmm7, __real_threshold
854    jb          Lpow_sse2_near_one
855
856    ; f = F - Y, r = f * inv
857    subsd       xmm1, xmm2
858    movsd       xmm4, xmm1
859    mulsd       xmm1, QWORD PTR [r9+r8*8]
860    movsd       xmm5, xmm1
861    mulsd       xmm4, QWORD PTR [rdx+r8*8]
862    movsd       xmm7, xmm4
863    addsd       xmm1, xmm4
864
865    movsd       xmm2, xmm1
866    movsd       xmm0, xmm1
867    lea         r9, __log_256_lead
868
869    ; poly
870    movsd       xmm3, QWORD PTR __real_1_over_6
871    movsd       xmm1, QWORD PTR __real_1_over_3
872    mulsd       xmm3, xmm2
873    mulsd       xmm1, xmm2
874    mulsd       xmm0, xmm2
875    subsd       xmm5, xmm2
876    movsd       xmm4, xmm0
877    addsd       xmm3, QWORD PTR __real_1_over_5
878    addsd       xmm1, QWORD PTR __real_1_over_2
879    mulsd       xmm4, xmm0
880    mulsd       xmm3, xmm2
881    mulsd       xmm1, xmm0
882    addsd       xmm3, QWORD PTR __real_1_over_4
883    addsd       xmm7, xmm5
884    mulsd       xmm3, xmm4
885    addsd       xmm1, xmm3
886    addsd       xmm1, xmm7
887
888    movsd       xmm5, QWORD PTR __real_log2_tail
889    lea         rdx, __log_256_tail
890    mulsd       xmm5, xmm6
891    movsd       xmm0, QWORD PTR [r9+r8*8]
892    subsd       xmm5, xmm1
893
894    movsd       xmm3, QWORD PTR [rdx+r8*8]
895    addsd       xmm3, xmm5
896    movsd       xmm1, xmm3
897    subsd       xmm3, xmm2
898
899    movsd       xmm7, QWORD PTR __real_log2_lead
900    mulsd       xmm7, xmm6
901    addsd       xmm0, xmm7
902
903    ; result of ln(x) is computed from head and tail parts, resH and resT
904    ; res = ln(x) = resH + resT
905    ; resH and resT are in full precision
906
907    ; resT is computed from head and tail parts, resT_h and resT_t
908    ; resT = resT_h + resT_t
909
910    ; now
911    ; xmm3 - resT
912    ; xmm0 - resH
913    ; xmm1 - (resT_t)
914    ; xmm2 - (-resT_h)
915
916Lpow_sse2_log_x_continue:
917
918    movsd       xmm7, xmm0
919    addsd       xmm0, xmm3
920    movsd       xmm5, xmm0
921    andpd       xmm0, XMMWORD PTR __real_fffffffff8000000
922
923    ; xmm0 - H
924    ; xmm7 - resH
925    ; xmm5 - res
926
927    mov         rax, QWORD PTR [save_y+rsp]
928    and         rax, QWORD PTR __real_fffffffff8000000
929
930    addsd       xmm2, xmm3
931    subsd       xmm7, xmm5
932    subsd       xmm1, xmm2
933    addsd       xmm7, xmm3
934    subsd       xmm5, xmm0
935
936    mov         QWORD PTR [y_head+rsp], rax
937    movsd       xmm4, QWORD PTR [save_y+rsp]
938
939    addsd       xmm7, xmm1
940    addsd       xmm7, xmm5
941
942    ; res = H + T
943    ; H has leading 26 bits of precision
944    ; T has full precision
945
946    ; xmm0 - H
947    ; xmm7 - T
948
949    movsd       xmm2, QWORD PTR [y_head+rsp]
950    subsd       xmm4, xmm2
951
952    ; y is split into head and tail
953    ; for y * ln(x) computation
954
955    ; xmm4 - Yt
956    ; xmm2 - Yh
957    ; xmm0 - H
958    ; xmm7 - T
959
960    movsd   xmm3, xmm4
961    movsd   xmm5, xmm7
962    movsd   xmm6, xmm0
963    mulsd   xmm3, xmm7 ; YtRt
964    mulsd   xmm4, xmm0 ; YtRh
965    mulsd   xmm5, xmm2 ; YhRt
966    mulsd   xmm6, xmm2 ; YhRh
967
968    movsd   xmm1, xmm6
969    addsd   xmm3, xmm4
970    addsd   xmm3, xmm5
971
972    addsd   xmm1, xmm3
973    movsd   xmm0, xmm1
974
975    subsd   xmm6, xmm1
976    addsd   xmm6, xmm3
977
978    ; y * ln(x) = v + vt
979    ; v and vt are in full precision
980
981    ; xmm0 - v
982    ; xmm6 - vt
983
984    ; -----------------------------
985    ; compute exp( y * ln(x) ) here
986    ; -----------------------------
987
988    ; v * (64/ln(2))
989    movsd       xmm7, QWORD PTR __real_64_by_log2
990    movsd       QWORD PTR [p_temp_exp+rsp], xmm0
991    mulsd       xmm7, xmm0
992    mov         rdx, QWORD PTR [p_temp_exp+rsp]
993
994    ; v < 1024*ln(2), ( v * (64/ln(2)) ) < 64*1024
995    ; v >= -1075*ln(2), ( v * (64/ln(2)) ) >= 64*(-1075)
996    comisd      xmm7, QWORD PTR __real_p65536
997    ja          Lpow_sse2_process_result_inf
998
999    comisd      xmm7, QWORD PTR __real_m68800
1000    jb          Lpow_sse2_process_result_zero
1001
1002    ; n = int( v * (64/ln(2)) )
1003    cvtpd2dq    xmm4, xmm7
1004    lea         r10, __two_to_jby64_head_table
1005    lea         r11, __two_to_jby64_tail_table
1006    cvtdq2pd    xmm1, xmm4
1007
1008    ; r1 = x - n * ln(2)/64 head
1009    movsd       xmm2, QWORD PTR __real_log2_by_64_head
1010    mulsd       xmm2, xmm1
1011    movd        ecx, xmm4
1012    mov         rax, 3fh
1013    and         eax, ecx
1014    subsd       xmm0, xmm2
1015
1016    ; r2 = - n * ln(2)/64 tail
1017    mulsd       xmm1, QWORD PTR __real_log2_by_64_tail
1018    movsd       xmm2, xmm0
1019
1020    ; m = (n - j) / 64
1021    sub         ecx, eax
1022    sar         ecx, 6
1023
1024    ; r1+r2
1025    addsd       xmm2, xmm1
1026    addsd       xmm2, xmm6 ; add vt here
1027    movsd       xmm1, xmm2
1028
1029    ; q
1030    movsd       xmm0, QWORD PTR __real_1_by_2
1031    movsd       xmm3, QWORD PTR __real_1_by_24
1032    movsd       xmm4, QWORD PTR __real_1_by_720
1033    mulsd       xmm1, xmm2
1034    mulsd       xmm0, xmm2
1035    mulsd       xmm3, xmm2
1036    mulsd       xmm4, xmm2
1037
1038    movsd       xmm5, xmm1
1039    mulsd       xmm1, xmm2
1040    addsd       xmm0, QWORD PTR __real_one
1041    addsd       xmm3, QWORD PTR __real_1_by_6
1042    mulsd       xmm5, xmm1
1043    addsd       xmm4, QWORD PTR __real_1_by_120
1044    mulsd       xmm0, xmm2
1045    mulsd       xmm3, xmm1
1046
1047    mulsd       xmm4, xmm5
1048
1049    ; deal with denormal results
1050    xor         r9d, r9d
1051
1052    addsd       xmm3, xmm4
1053    addsd       xmm0, xmm3
1054
1055    cmp         ecx, DWORD PTR __denormal_threshold
1056    cmovle      r9d, ecx
1057    add         rcx, 1023
1058    shl         rcx, 52
1059
1060    ; f1, f2
1061    movsd       xmm5, QWORD PTR [r11+rax*8]
1062    movsd       xmm1, QWORD PTR [r10+rax*8]
1063    mulsd       xmm5, xmm0
1064    mulsd       xmm1, xmm0
1065
1066
1067    ; (f1+f2)*(1+q)
1068    addsd       xmm5, QWORD PTR [r11+rax*8]
1069    addsd       xmm1, xmm5
1070    addsd       xmm1, QWORD PTR [r10+rax*8]
1071    movsd       xmm0, xmm1
1072
1073    cmp         rcx, QWORD PTR __real_inf
1074    je          Lpow_sse2_process_almost_inf
1075
1076    mov         QWORD PTR [p_temp_exp+rsp], rcx
1077    test        r9d, r9d
1078    jnz         Lpow_sse2_process_denormal
1079    mulsd       xmm0, QWORD PTR [p_temp_exp+rsp]
1080    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1081
1082Lpow_sse2_final_check:
1083    RestoreXmm   xmm7, save_xmm7
1084    RestoreXmm   xmm6, save_xmm6
1085    StackDeallocate stack_size
1086    ret
1087
1088ALIGN 16
1089Lpow_sse2_process_almost_inf:
1090    comisd      xmm0, QWORD PTR __real_one
1091    jae         Lpow_sse2_process_result_inf
1092
1093    orpd        xmm0, XMMWORD PTR __enable_almost_inf
1094    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1095    jmp         Lpow_sse2_final_check
1096
1097ALIGN 16
1098Lpow_sse2_process_denormal:
1099    mov         ecx, r9d
1100    xor         r11d, r11d
1101    comisd      xmm0, QWORD PTR __real_one
1102    cmovae      r11d, ecx
1103    cmp         r11d, DWORD PTR __denormal_threshold
1104    jne         Lpow_sse2_process_true_denormal
1105
1106    mulsd       xmm0, QWORD PTR [p_temp_exp+rsp]
1107    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1108    jmp         Lpow_sse2_final_check
1109
1110ALIGN 16
1111Lpow_sse2_process_true_denormal:
1112    xor         r8, r8
1113    mov         r9, 1
1114    cmp         rdx, QWORD PTR __denormal_tiny_threshold
1115    jg          Lpow_sse2_process_denormal_tiny
1116    add         ecx, 1074
1117    cmovs       rcx, r8
1118    shl         r9, cl
1119    mov         rcx, r9
1120
1121    mov         QWORD PTR [p_temp_exp+rsp], rcx
1122    mulsd       xmm0, QWORD PTR [p_temp_exp+rsp]
1123    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1124    jmp         Lpow_sse2_z_denormal
1125
1126ALIGN 16
1127Lpow_sse2_process_denormal_tiny:
1128    movsd       xmm0, QWORD PTR __real_smallest_denormal
1129    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1130    jmp         Lpow_sse2_z_denormal
1131
1132ALIGN 16
1133Lpow_sse2_process_result_zero:
1134    mov         r11, QWORD PTR __real_zero
1135    or          r11, QWORD PTR [negate_result+rsp]
1136    jmp         Lpow_sse2_z_is_zero_or_inf
1137
1138ALIGN 16
1139Lpow_sse2_process_result_inf:
1140    mov         r11, QWORD PTR __real_inf
1141    or          r11, QWORD PTR [negate_result+rsp]
1142    jmp         Lpow_sse2_z_is_zero_or_inf
1143
1144ALIGN 16
1145Lpow_sse2_denormal_adjust:
1146    por         xmm2, XMMWORD PTR __real_one
1147    subsd       xmm2, QWORD PTR __real_one
1148    movsd       xmm5, xmm2
1149    pand        xmm2, XMMWORD PTR __real_mant
1150    movd        r8, xmm2
1151    psrlq       xmm5, 52
1152    psubd       xmm5, XMMWORD PTR __mask_2045
1153    cvtdq2pd    xmm6, xmm5
1154    jmp         Lpow_sse2_continue_common
1155
1156ALIGN 16
1157Lpow_sse2_x_is_neg:
1158
1159    mov         r10, QWORD PTR __exp_mask
1160    and         r10, r8
1161    cmp         r10, QWORD PTR __ay_max_bound
1162    jg          Lpow_sse2_ay_is_very_large
1163
1164    ; determine if y is an integer
1165    mov         r10, QWORD PTR __exp_mant_mask
1166    and         r10, r8
1167    mov         r11, r10
1168    mov         rcx, QWORD PTR __exp_shift
1169    shr         r10, cl
1170    sub         r10, QWORD PTR __exp_bias
1171    js          Lpow_sse2_x_is_neg_y_is_not_int
1172
1173    mov         rax, QWORD PTR __exp_mant_mask
1174    and         rax, rdx
1175    mov         QWORD PTR [save_ax+rsp], rax
1176
1177    mov         rcx, r10
1178    cmp         r10, QWORD PTR __yexp_53
1179    jg          Lpow_sse2_continue_after_y_int_check
1180
1181    mov         r9, QWORD PTR __mant_full
1182    shr         r9, cl
1183    and         r9, r11
1184    jnz         Lpow_sse2_x_is_neg_y_is_not_int
1185
1186    mov         r9, QWORD PTR __1_before_mant
1187    shr         r9, cl
1188    and         r9, r11
1189    jz          Lpow_sse2_continue_after_y_int_check
1190
1191    mov         rax, QWORD PTR __sign_mask
1192    mov         QWORD PTR [negate_result+rsp], rax
1193
1194Lpow_sse2_continue_after_y_int_check:
1195
1196    cmp         rdx, QWORD PTR __neg_zero
1197    je          Lpow_sse2_x_is_zero
1198
1199    cmp         rdx, QWORD PTR __neg_one
1200    je          Lpow_sse2_x_is_neg_one
1201
1202    mov         r9, QWORD PTR __exp_mask
1203    and         r9, rdx
1204    cmp         r9, QWORD PTR __exp_mask
1205    je          Lpow_sse2_x_is_inf_or_nan
1206
1207    movsd       xmm0, QWORD PTR [save_ax+rsp]
1208    jmp         Lpow_sse2_log_x
1209
1210
1211ALIGN 16
1212Lpow_sse2_near_one:
1213
1214    ; f = F - Y, r = f * inv
1215    movsd       xmm0, xmm1
1216    subsd       xmm1, xmm2
1217    movsd       xmm4, xmm1
1218
1219    movsd       xmm3, QWORD PTR [r9+r8*8]
1220    addsd       xmm3, QWORD PTR [rdx+r8*8]
1221    mulsd       xmm4, xmm3
1222    andpd       xmm4, XMMWORD PTR __real_fffffffff8000000
1223    movsd       xmm5, xmm4 ; r1
1224    mulsd       xmm4, xmm0
1225    subsd       xmm1, xmm4
1226    mulsd       xmm1, xmm3
1227    movsd       xmm7, xmm1 ; r2
1228    addsd       xmm1, xmm5
1229
1230    movsd       xmm2, xmm1
1231    movsd       xmm0, xmm1
1232
1233    lea         r9, __log_256_lead
1234
1235    ; poly
1236    movsd       xmm3, QWORD PTR __real_1_over_7
1237    movsd       xmm1, QWORD PTR __real_1_over_4
1238    mulsd       xmm3, xmm2
1239    mulsd       xmm1, xmm2
1240    mulsd       xmm0, xmm2
1241    movsd       xmm4, xmm0
1242    addsd       xmm3, QWORD PTR __real_1_over_6
1243    addsd       xmm1, QWORD PTR __real_1_over_3
1244    mulsd       xmm4, xmm0
1245    mulsd       xmm3, xmm2
1246    mulsd       xmm1, xmm2
1247    addsd       xmm3, QWORD PTR __real_1_over_5
1248    mulsd       xmm3, xmm2
1249    mulsd       xmm1, xmm0
1250    mulsd       xmm3, xmm4
1251
1252    movsd       xmm2, xmm5
1253    movsd       xmm0, xmm7
1254    mulsd       xmm0, xmm0
1255    mulsd       xmm0, QWORD PTR __real_1_over_2
1256    mulsd       xmm5, xmm7
1257    addsd       xmm5, xmm0
1258    addsd       xmm5, xmm7
1259
1260    movsd       xmm0, xmm2
1261    movsd       xmm7, xmm2
1262    mulsd       xmm0, xmm0
1263    mulsd       xmm0, QWORD PTR __real_1_over_2
1264    movsd       xmm4, xmm0
1265    addsd       xmm2, xmm0 ; r1 + r1^2/2
1266    subsd       xmm7, xmm2
1267    addsd       xmm7, xmm4
1268
1269    addsd       xmm3, xmm7
1270    movsd       xmm4, QWORD PTR __real_log2_tail
1271    addsd       xmm1, xmm3
1272    mulsd       xmm4, xmm6
1273    lea         rdx, __log_256_tail
1274    addsd       xmm1, xmm5
1275    addsd       xmm4, QWORD PTR [rdx+r8*8]
1276    subsd       xmm4, xmm1
1277
1278    movsd       xmm3, xmm4
1279    movsd       xmm1, xmm4
1280    subsd       xmm3, xmm2
1281
1282    movsd       xmm0, QWORD PTR [r9+r8*8]
1283    movsd       xmm7, QWORD PTR __real_log2_lead
1284    mulsd       xmm7, xmm6
1285    addsd       xmm0, xmm7
1286
1287    jmp         Lpow_sse2_log_x_continue
1288
1289
1290ALIGN 16
1291Lpow_sse2_x_is_pos_one:
1292    jmp         Lpow_sse2_final_check
1293
1294ALIGN 16
1295Lpow_sse2_y_is_zero:
1296    movsd       xmm0, QWORD PTR __real_one
1297    jmp         Lpow_sse2_final_check
1298
1299ALIGN 16
1300Lpow_sse2_y_is_one:
1301    xor         rax, rax
1302    mov         r11, rdx
1303    mov         r9, QWORD PTR __exp_mask
1304    ;or          r11, QWORD PTR __qnan_set
1305    and         r9, rdx
1306    cmp         r9, QWORD PTR __exp_mask
1307    cmove       rax, rdx
1308    mov         r9, QWORD PTR __mant_mask
1309    and         r9, rax
1310    jnz         Lpow_sse2_x_is_nan
1311
1312    movd        xmm0, rdx
1313    jmp         Lpow_sse2_final_check
1314
1315ALIGN 16
1316Lpow_sse2_x_is_neg_one:
1317    mov         rdx, QWORD PTR __pos_one
1318    or          rdx, QWORD PTR [negate_result+rsp]
1319    xor         rax, rax
1320    mov         r11, r8
1321    mov         r10, QWORD PTR __exp_mask
1322    ;or          r11, QWORD PTR __qnan_set
1323    and         r10, r8
1324    cmp         r10, QWORD PTR __exp_mask
1325    cmove       rax, r8
1326    mov         r10, QWORD PTR __mant_mask
1327    and         r10, rax
1328    jnz         Lpow_sse2_y_is_nan
1329
1330    movd        xmm0, rdx
1331    jmp         Lpow_sse2_final_check
1332
1333ALIGN 16
1334Lpow_sse2_x_is_neg_y_is_not_int:
1335    mov         r9, QWORD PTR __exp_mask
1336    and         r9, rdx
1337    cmp         r9, QWORD PTR __exp_mask
1338    je          Lpow_sse2_x_is_inf_or_nan
1339
1340    cmp         rdx, QWORD PTR __neg_zero
1341    je          Lpow_sse2_x_is_zero
1342
1343    movsd       xmm0, QWORD PTR [save_x+rsp]
1344    movsd       xmm1, QWORD PTR [save_y+rsp]
1345    movsd       xmm2, QWORD PTR __neg_qnan
1346    mov         r9d, DWORD PTR __flag_x_neg_y_notint
1347
1348    call        fname_special
1349    jmp         Lpow_sse2_final_check
1350
1351ALIGN 16
1352Lpow_sse2_ay_is_very_large:
1353    mov         r9, QWORD PTR __exp_mask
1354    and         r9, rdx
1355    cmp         r9, QWORD PTR __exp_mask
1356    je          Lpow_sse2_x_is_inf_or_nan
1357
1358    mov         r9, QWORD PTR __exp_mant_mask
1359    and         r9, rdx
1360    jz          Lpow_sse2_x_is_zero
1361
1362    cmp         rdx, QWORD PTR __neg_one
1363    je          Lpow_sse2_x_is_neg_one
1364
1365    mov         r9, rdx
1366    and         r9, QWORD PTR __exp_mant_mask
1367    cmp         r9, QWORD PTR __pos_one
1368    jl          Lpow_sse2_ax_lt1_y_is_large_or_inf_or_nan
1369
1370    jmp         Lpow_sse2_ax_gt1_y_is_large_or_inf_or_nan
1371
1372ALIGN 16
1373Lpow_sse2_x_is_zero:
1374    mov         r10, QWORD PTR __exp_mask
1375    xor         rax, rax
1376    and         r10, r8
1377    cmp         r10, QWORD PTR __exp_mask
1378    je          Lpow_sse2_x_is_zero_y_is_inf_or_nan
1379
1380    mov         r10, QWORD PTR __sign_mask
1381    and         r10, r8
1382    cmovnz      rax, QWORD PTR __pos_inf
1383    jnz         Lpow_sse2_x_is_zero_z_is_inf
1384
1385    movd        xmm0, rax
1386    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1387    jmp         Lpow_sse2_final_check
1388
1389ALIGN 16
1390Lpow_sse2_x_is_zero_z_is_inf:
1391
1392    movsd       xmm0, QWORD PTR [save_x+rsp]
1393    movsd       xmm1, QWORD PTR [save_y+rsp]
1394    movd        xmm2, rax
1395    orpd        xmm2, XMMWORD PTR [negate_result+rsp]
1396    mov         r9d, DWORD PTR __flag_x_zero_z_inf
1397
1398    call        fname_special
1399    jmp         Lpow_sse2_final_check
1400
1401ALIGN 16
1402Lpow_sse2_x_is_zero_y_is_inf_or_nan:
1403    mov         r11, r8
1404    cmp         r8, QWORD PTR __neg_inf
1405    cmove       rax, QWORD PTR __pos_inf
1406    je          Lpow_sse2_x_is_zero_z_is_inf
1407
1408    ;or          r11, QWORD PTR __qnan_set
1409    mov         r10, QWORD PTR __mant_mask
1410    and         r10, r8
1411    jnz         Lpow_sse2_y_is_nan
1412
1413    movd        xmm0, rax
1414    jmp         Lpow_sse2_final_check
1415
1416ALIGN 16
1417Lpow_sse2_x_is_inf_or_nan:
1418    xor         r11, r11
1419    mov         r10, QWORD PTR __sign_mask
1420    and         r10, r8
1421    cmovz       r11, QWORD PTR __pos_inf
1422    mov         rax, rdx
1423    mov         r9, QWORD PTR __mant_mask
1424    ;or          rax, QWORD PTR __qnan_set
1425    and         r9, rdx
1426    cmovnz      r11, rax
1427    jnz         Lpow_sse2_x_is_nan
1428
1429    xor         rax, rax
1430    mov         r9, r8
1431    mov         r10, QWORD PTR __exp_mask
1432    ;or          r9, QWORD PTR __qnan_set
1433    and         r10, r8
1434    cmp         r10, QWORD PTR __exp_mask
1435    cmove       rax, r8
1436    mov         r10, QWORD PTR __mant_mask
1437    and         r10, rax
1438    cmovnz      r11, r9
1439    jnz         Lpow_sse2_y_is_nan
1440
1441    movd        xmm0, r11
1442    orpd        xmm0, XMMWORD PTR [negate_result+rsp]
1443    jmp         Lpow_sse2_final_check
1444
1445ALIGN 16
1446Lpow_sse2_ay_is_very_small:
1447    movsd       xmm0, QWORD PTR __pos_one
1448    addsd       xmm0, xmm1
1449    jmp         Lpow_sse2_final_check
1450
1451
1452ALIGN 16
1453Lpow_sse2_ax_lt1_y_is_large_or_inf_or_nan:
1454    xor         r11, r11
1455    mov         r10, QWORD PTR __sign_mask
1456    and         r10, r8
1457    cmovnz      r11, QWORD PTR __pos_inf
1458    jmp         Lpow_sse2_adjust_for_nan
1459
1460ALIGN 16
1461Lpow_sse2_ax_gt1_y_is_large_or_inf_or_nan:
1462    xor         r11, r11
1463    mov         r10, QWORD PTR __sign_mask
1464    and         r10, r8
1465    cmovz       r11, QWORD PTR __pos_inf
1466
1467ALIGN 16
1468Lpow_sse2_adjust_for_nan:
1469
1470    xor         rax, rax
1471    mov         r9, r8
1472    mov         r10, QWORD PTR __exp_mask
1473    ;or          r9, QWORD PTR __qnan_set
1474    and         r10, r8
1475    cmp         r10, QWORD PTR __exp_mask
1476    cmove       rax, r8
1477    mov         r10, QWORD PTR __mant_mask
1478    and         r10, rax
1479    cmovnz      r11, r9
1480    jnz         Lpow_sse2_y_is_nan
1481
1482    test        rax, rax
1483    jnz         Lpow_sse2_y_is_inf
1484
1485ALIGN 16
1486Lpow_sse2_z_is_zero_or_inf:
1487
1488    mov         r9d, DWORD PTR __flag_z_zero
1489    test        r11, QWORD PTR __exp_mant_mask
1490    cmovnz      r9d, DWORD PTR __flag_z_inf
1491
1492    movsd       xmm0, QWORD PTR [save_x+rsp]
1493    movsd       xmm1, QWORD PTR [save_y+rsp]
1494    movd        xmm2, r11
1495
1496    call        fname_special
1497    jmp         Lpow_sse2_final_check
1498
1499ALIGN 16
1500Lpow_sse2_y_is_inf:
1501
1502    movd        xmm0, r11
1503    jmp         Lpow_sse2_final_check
1504
1505ALIGN 16
1506Lpow_sse2_x_is_nan:
1507
1508    xor         rax, rax
1509    mov         r10, QWORD PTR __exp_mask
1510    and         r10, r8
1511    cmp         r10, QWORD PTR __exp_mask
1512    cmove       rax, r8
1513    mov         r10, QWORD PTR __mant_mask
1514    and         r10, rax
1515    jnz         Lpow_sse2_x_is_nan_y_is_nan
1516
1517    movsd       xmm0, QWORD PTR [save_x+rsp]
1518    movsd       xmm1, QWORD PTR [save_y+rsp]
1519    movd        xmm2, r11
1520    mov         r9d, DWORD PTR __flag_x_nan
1521
1522    call        fname_special
1523    jmp         Lpow_sse2_final_check
1524
1525ALIGN 16
1526Lpow_sse2_y_is_nan:
1527
1528    movsd       xmm0, QWORD PTR [save_x+rsp]
1529    movsd       xmm1, QWORD PTR [save_y+rsp]
1530    movd        xmm2, r11
1531    mov         r9d, DWORD PTR __flag_y_nan
1532
1533    call        fname_special
1534    jmp         Lpow_sse2_final_check
1535
1536ALIGN 16
1537Lpow_sse2_x_is_nan_y_is_nan:
1538
1539    mov         r9, r8
1540
1541    cmp         r11, QWORD PTR __ind_pattern
1542    cmove       r11, r9
1543    je          Lpow_sse2_continue_xy_nan
1544
1545    cmp         r9, QWORD PTR __ind_pattern
1546    cmove       r9, r11
1547
1548    mov         r10, r9
1549    and         r10, QWORD PTR __sign_mask
1550    cmovnz      r9, r11
1551
1552    mov         r10, r11
1553    and         r10, QWORD PTR __sign_mask
1554    cmovnz      r11, r9
1555
1556Lpow_sse2_continue_xy_nan:
1557    ;or          r11, QWORD PTR __qnan_set
1558    movsd       xmm0, QWORD PTR [save_x+rsp]
1559    movsd       xmm1, QWORD PTR [save_y+rsp]
1560    movd        xmm2, r11
1561    mov         r9d, DWORD PTR __flag_x_nan_y_nan
1562
1563    call        fname_special
1564    jmp         Lpow_sse2_final_check
1565
1566ALIGN 16
1567Lpow_sse2_z_denormal:
1568
1569    movsd       xmm2, xmm0
1570    movsd       xmm0, QWORD PTR [save_x+rsp]
1571    movsd       xmm1, QWORD PTR [save_y+rsp]
1572    mov         r9d, DWORD PTR __flag_z_denormal
1573
1574    call        fname_special
1575    jmp         Lpow_sse2_final_check
1576
1577Lpow_fma3:
1578    vmovsd       QWORD PTR [save_x+rsp], xmm0
1579    vmovsd       QWORD PTR [save_y+rsp], xmm1
1580
1581    mov          rdx, QWORD PTR [save_x+rsp]
1582    mov          r8, QWORD PTR [save_y+rsp]
1583
1584    mov          r10, QWORD PTR __exp_mant_mask
1585    and          r10, r8
1586    jz           Lpow_fma3_y_is_zero
1587
1588    cmp          r8, QWORD PTR __pos_one
1589    je           Lpow_fma3_y_is_one
1590
1591    mov          r9, QWORD PTR __sign_mask
1592    and          r9, rdx
1593    cmp          r9, QWORD PTR __sign_mask
1594    mov          rax, QWORD PTR __pos_zero
1595    mov          QWORD PTR [negate_result+rsp], rax
1596    je           Lpow_fma3_x_is_neg
1597
1598    cmp          rdx, QWORD PTR __pos_one
1599    je           Lpow_fma3_x_is_pos_one
1600
1601    cmp          rdx, QWORD PTR __pos_zero
1602    je           Lpow_fma3_x_is_zero
1603
1604    mov          r9, QWORD PTR __exp_mask
1605    and          r9, rdx
1606    cmp          r9, QWORD PTR __exp_mask
1607    je           Lpow_fma3_x_is_inf_or_nan
1608
1609    mov          r10, QWORD PTR __exp_mask
1610    and          r10, r8
1611    cmp          r10, QWORD PTR __ay_max_bound
1612    jg           Lpow_fma3_ay_is_very_large
1613
1614    mov          r10, QWORD PTR __exp_mask
1615    and          r10, r8
1616    cmp          r10, QWORD PTR __ay_min_bound
1617    jl           Lpow_fma3_ay_is_very_small
1618
1619    ; -----------------------------
1620    ; compute log(x) here
1621    ; -----------------------------
1622Lpow_fma3_log_x:
1623
1624    ; compute exponent part
1625    vpsrlq       xmm3, xmm0, 52
1626    vmovq        r8, xmm0
1627    vpsubq       xmm3, xmm3, XMMWORD PTR __mask_1023
1628    vcvtdq2pd    xmm6, xmm3 ; xexp
1629    vpand        xmm2, xmm0, XMMWORD PTR __real_mant
1630
1631    vcomisd      xmm6, QWORD PTR __mask_1023_f
1632    je           Lpow_fma3_denormal_adjust
1633
1634Lpow_fma3_continue_common:
1635
1636    ; compute index into the log tables
1637    mov          r9, r8
1638    and          r8, QWORD PTR __mask_mant_all8
1639    and          r9, QWORD PTR __mask_mant9
1640    vsubsd       xmm7, xmm0, __real_one
1641    shl          r9, 1
1642    add          r8, r9
1643    vmovq        xmm1, r8
1644    vandpd       xmm7, xmm7, __real_notsign
1645
1646    ; F, Y, switch to near-one codepath
1647    shr          r8, 44
1648    vpor         xmm2, xmm2, XMMWORD PTR __real_half
1649    vpor         xmm1, xmm1, XMMWORD PTR __real_half
1650    vcomisd      xmm7, __real_threshold
1651    lea          r9, QWORD PTR __log_F_inv_head
1652    lea          rdx, QWORD PTR __log_F_inv_tail
1653    jb           Lpow_fma3_near_one
1654
1655    ; f = F - Y, r = f * inv
1656    vsubsd       xmm4, xmm1, xmm2          ; xmm4 <-- f = F - Y
1657    vmulsd       xmm1, xmm4, QWORD PTR [r9+r8*8] ; xmm1 <-- rhead = f*inv_head
1658    vmovapd      xmm5, xmm1                ; xmm5 <-- copy of rhead
1659    vmulsd       xmm4, xmm4, QWORD PTR [rdx+r8*8] ; xmm4 <-- rtail = f*inv_tail
1660    vmovapd      xmm7, xmm4                ; xmm7 <-- copy of rtail
1661    vaddsd       xmm1, xmm1, xmm4          ; xmm1 <-- r = rhead + rtail
1662
1663    vmovapd      xmm2, xmm1                ; xmm2 <-- copy of r
1664    vmovapd      xmm0, xmm1                ; xmm1 <-- copy of r
1665    lea          r9, __log_256_lead
1666
1667    ; poly
1668;    movsd       xmm3, QWORD PTR __real_1_over_6
1669;    movsd       xmm1, QWORD PTR __real_1_over_3
1670;    mulsd       xmm3, xmm2               ; r*1/6
1671;    mulsd       xmm1, xmm2               ; r*1/3
1672;    mulsd       xmm0, xmm2               ; r^2
1673;    subsd       xmm5, xmm2               ; xmm5 <-- rhead - r
1674;    movsd       xmm4, xmm0               ; xmm4 <-- copy of r^2
1675;    addsd       xmm3, QWORD PTR __real_1_over_5 ; xmm3 <-- r*1/6 + 1/5
1676;    addsd       xmm1, QWORD PTR __real_1_over_2 ; xmm1 <-- r*1/3 + 1/2
1677;    mulsd       xmm4, xmm0               ; xmm4 <-- r^4
1678;    mulsd       xmm3, xmm2               ; xmm3 <-- (r*1/6 + 1/5)*r
1679;    mulsd       xmm1, xmm0               ; xmm1 <-- (r*1/3 + 1/2)*r^2
1680;    addsd       xmm3, QWORD PTR __real_1_over_4 ; xmm3 <-- (r*1/6+1/5)*r + 1/4
1681;    addsd       xmm7, xmm5               ; xmm7 <-- rtail + (rhead - r)
1682;    mulsd       xmm3, xmm4               ; xmm3 <-- (r*1/6 + 1/5)*r^5 + r^4*1/4
1683;    addsd       xmm1, xmm3               ; xmm1 <-- poly down to r^2
1684;    addsd       xmm1, xmm7               ; xmm1 <-- poly + correction
1685
1686
1687    vsubsd       xmm3, xmm5, xmm2
1688    vmovsd       xmm1, QWORD PTR __real_1_over_6
1689    vmulsd       xmm0,xmm0,xmm0
1690    vaddsd       xmm3, xmm3, xmm7
1691    vfmadd213sd  xmm1, xmm2, QWORD PTR __real_1_over_5
1692    vfmadd213sd  xmm1, xmm2, QWORD PTR __real_1_over_4
1693    vfmadd213sd  xmm1, xmm2, QWORD PTR __real_1_over_3
1694    vfmadd213sd  xmm1, xmm2, QWORD PTR __real_1_over_2
1695    vfmadd213sd  xmm1, xmm0, xmm3
1696
1697    vmovsd       xmm5, QWORD PTR __real_log2_tail
1698    lea          rdx, __log_256_tail
1699    vfmsub213sd  xmm5, xmm6, xmm1
1700    vmovsd       xmm0, QWORD PTR [r9+r8*8]
1701
1702    vaddsd       xmm3, xmm5, QWORD PTR [rdx+r8*8]
1703    vmovapd      xmm1, xmm3
1704    vsubsd       xmm3, xmm3, xmm2
1705
1706    vfmadd231sd  xmm0, xmm6, QWORD PTR __real_log2_lead
1707
1708    ; result of ln(x) is computed from head and tail parts, resH and resT
1709    ; res = ln(x) = resH + resT
1710    ; resH and resT are in full precision
1711
1712    ; resT is computed from head and tail parts, resT_h and resT_t
1713    ; resT = resT_h + resT_t
1714
1715    ; now
1716    ; xmm3 - resT
1717    ; xmm0 - resH
1718    ; xmm1 - (resT_t)
1719    ; xmm2 - (-resT_h)
1720
1721Lpow_fma3_log_x_continue:
1722
1723    vmovapd      xmm7, xmm0
1724    vaddsd       xmm0, xmm0, xmm3
1725    vmovapd      xmm5, xmm0
1726    vandpd       xmm0, xmm0, XMMWORD PTR __real_fffffffff8000000
1727
1728    ; xmm0 - H
1729    ; xmm7 - resH
1730    ; xmm5 - res
1731
1732    mov          rax, QWORD PTR [save_y+rsp]
1733    and          rax, QWORD PTR __real_fffffffff8000000
1734
1735    vaddsd       xmm2, xmm2, xmm3
1736    vsubsd       xmm7, xmm7, xmm5
1737    vsubsd       xmm1, xmm1, xmm2
1738    vaddsd       xmm7, xmm7, xmm3
1739    vsubsd       xmm5, xmm5, xmm0
1740
1741    mov          QWORD PTR [y_head+rsp], rax
1742    vmovsd       xmm4, QWORD PTR [save_y+rsp]
1743
1744    vaddsd       xmm7, xmm7, xmm1
1745    vaddsd       xmm7, xmm7, xmm5
1746
1747    ; res = H + T
1748    ; H has leading 26 bits of precision
1749    ; T has full precision
1750
1751    ; xmm0 - H
1752    ; xmm7 - T
1753
1754    vmovsd       xmm2, QWORD PTR [y_head+rsp]
1755    vsubsd       xmm4, xmm4, xmm2
1756
1757    ; y is split into head and tail
1758    ; for y * ln(x) computation
1759
1760    ; xmm4 - Yt
1761    ; xmm2 - Yh
1762    ; xmm0 - H
1763    ; xmm7 - T
1764
1765    vmulsd       xmm3, xmm4, xmm7 ; YtRt
1766    vmulsd       xmm4, xmm4, xmm0 ; YtRh
1767    vmulsd       xmm5, xmm7, xmm2 ; YhRt
1768    vmulsd       xmm6, xmm0, xmm2 ; YhRh
1769
1770    vmovapd      xmm1, xmm6
1771    vaddsd       xmm3, xmm3, xmm4
1772    vaddsd       xmm3, xmm3, xmm5
1773
1774    vaddsd       xmm1, xmm1, xmm3
1775    vmovapd      xmm0, xmm1
1776
1777    vsubsd       xmm6, xmm6, xmm1
1778    vaddsd       xmm6, xmm6, xmm3
1779
1780    ; y * ln(x) = v + vt
1781    ; v and vt are in full precision
1782
1783    ; xmm0 - v
1784    ; xmm6 - vt
1785
1786    ; -----------------------------
1787    ; compute exp( y * ln(x) ) here
1788    ; -----------------------------
1789
1790    ; v * (64/ln(2))
1791    vmovsd       QWORD PTR [p_temp_exp+rsp], xmm0
1792    vmulsd       xmm7, xmm0, QWORD PTR __real_64_by_log2
1793    mov          rdx, QWORD PTR [p_temp_exp+rsp]
1794
1795    ; v < 1024*ln(2), ( v * (64/ln(2)) ) < 64*1024
1796    ; v >= -1075*ln(2), ( v * (64/ln(2)) ) >= 64*(-1075)
1797    vcomisd      xmm7, QWORD PTR __real_p65536
1798    ja           Lpow_fma3_process_result_inf
1799
1800    vcomisd      xmm7, QWORD PTR __real_m68800
1801    jb           Lpow_fma3_process_result_zero
1802
1803    ; n = int( v * (64/ln(2)) )
1804    vcvtpd2dq    xmm4, xmm7
1805    lea          r10, __two_to_jby64_head_table
1806    lea          r11, __two_to_jby64_tail_table
1807    vcvtdq2pd    xmm1, xmm4
1808
1809    ; r1 = x - n * ln(2)/64 head
1810    vfnmadd231sd xmm0, xmm1, QWORD PTR __real_log2_by_64_head
1811    vmovd        ecx, xmm4
1812    mov          rax, 3fh
1813    and          eax, ecx
1814
1815    ; r2 = - n * ln(2)/64 tail
1816    vmulsd       xmm1, xmm1, QWORD PTR __real_log2_by_64_tail
1817    vmovapd      xmm2, xmm0
1818
1819    ; m = (n - j) / 64
1820    sub          ecx, eax
1821    sar          ecx, 6
1822
1823    ; r1+r2
1824    vaddsd       xmm2, xmm2, xmm1
1825    vaddsd       xmm2, xmm2, xmm6 ; add vt here
1826    vmovapd      xmm1, xmm2
1827
1828    ; q
1829    vmovsd       xmm0, QWORD PTR __real_1_by_720
1830    xor         r9d, r9d
1831    vfmadd213sd  xmm0, xmm2,  QWORD PTR __real_1_by_120
1832    cmp         ecx, DWORD PTR __denormal_threshold
1833    vfmadd213sd  xmm0, xmm2,  QWORD PTR __real_1_by_24
1834    cmovle      r9d, ecx
1835    vfmadd213sd  xmm0, xmm2,  QWORD PTR __real_1_by_6
1836    add         rcx, 1023
1837    vfmadd213sd  xmm0, xmm2,  QWORD PTR __real_1_by_2
1838    shl         rcx, 52
1839    vfmadd213sd  xmm0, xmm2,  QWORD PTR __real_one
1840    vmulsd       xmm0, xmm0, xmm2         ; xmm0 <-- q
1841;    movsd       xmm0, QWORD PTR __real_1_by_2
1842;    movsd       xmm3, QWORD PTR __real_1_by_24
1843;    movsd       xmm4, QWORD PTR __real_1_by_720
1844;    mulsd       xmm1, xmm2                ; xmm1 <-- r^2
1845;    mulsd       xmm0, xmm2                ; xmm0 <-- r/2
1846;    mulsd       xmm3, xmm2                ; xmm3 <-- r/24
1847;    mulsd       xmm4, xmm2                ; xmm4 <-- r/720
1848
1849;    movsd       xmm5, xmm1                ; xmm5 <-- copy of r^2
1850;    mulsd       xmm1, xmm2                ; xmm1 <-- r^3
1851;    addsd       xmm0, QWORD PTR __real_one ; xmm0 <-- r/2 + 1
1852;    addsd       xmm3, QWORD PTR __real_1_by_6 ; xmm3 <-- r/24 + 1/6
1853;    mulsd       xmm5, xmm1                ; xmm5 <-- r^5
1854;    addsd       xmm4, QWORD PTR __real_1_by_120 ; xmm4 <-- r/720 + 1/120
1855;    mulsd       xmm0, xmm2                ; xmm0 <-- (r/2 + 1)*r
1856;    mulsd       xmm3, xmm1                ; xmm3 <-- (r/24 + 1/6)*r^3
1857
1858;    mulsd       xmm4, xmm5                ; xmm4 <-- (r/720 + 1/120)*r^5
1859
1860;   ; deal with denormal results
1861;   xor         r9d, r9d
1862;   cmp         ecx, DWORD PTR __denormal_threshold
1863
1864;    addsd       xmm3, xmm4  ; xmm3 <-- (r/720 + 1/120)*r^5 + (r/24 + 1/6)*r^3
1865;    addsd       xmm0, xmm3  ; xmm0 <-- poly
1866
1867;   cmovle      r9d, ecx
1868;   add         rcx, 1023
1869;   shl         rcx, 52
1870
1871    ; f1, f2
1872    vmulsd       xmm5, xmm0, QWORD PTR [r11+rax*8]
1873    vmulsd       xmm1, xmm0, QWORD PTR [r10+rax*8]
1874
1875    cmp          rcx, QWORD PTR __real_inf
1876
1877    ; (f1+f2)*(1+q)
1878    vaddsd       xmm5, xmm5, QWORD PTR [r11+rax*8]
1879    vaddsd       xmm1, xmm1, xmm5
1880    vaddsd       xmm1, xmm1, QWORD PTR [r10+rax*8]
1881    vmovapd      xmm0, xmm1
1882
1883    je           Lpow_fma3_process_almost_inf
1884
1885    test         r9d, r9d
1886    mov          QWORD PTR [p_temp_exp+rsp], rcx
1887    jnz          Lpow_fma3_process_denormal
1888    vmulsd       xmm0, xmm0, QWORD PTR [p_temp_exp+rsp]
1889    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
1890
1891Lpow_fma3_final_check:
1892    AVXRestoreXmm  xmm7, save_xmm7
1893    AVXRestoreXmm  xmm6, save_xmm6
1894    StackDeallocate stack_size
1895    ret
1896
1897ALIGN 16
1898Lpow_fma3_process_almost_inf:
1899    vcomisd      xmm0, QWORD PTR __real_one
1900    jae          Lpow_fma3_process_result_inf
1901
1902    vorpd        xmm0, xmm0, XMMWORD PTR __enable_almost_inf
1903    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
1904    jmp          Lpow_fma3_final_check
1905
1906ALIGN 16
1907Lpow_fma3_process_denormal:
1908    mov          ecx, r9d
1909    xor          r11d, r11d
1910    vcomisd      xmm0, QWORD PTR __real_one
1911    cmovae       r11d, ecx
1912    cmp          r11d, DWORD PTR __denormal_threshold
1913    jne          Lpow_fma3_process_true_denormal
1914
1915    vmulsd       xmm0, xmm0, QWORD PTR [p_temp_exp+rsp]
1916    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
1917    jmp          Lpow_fma3_final_check
1918
1919ALIGN 16
1920Lpow_fma3_process_true_denormal:
1921    xor          r8, r8
1922    cmp          rdx, QWORD PTR __denormal_tiny_threshold
1923    mov          r9, 1
1924    jg           Lpow_fma3_process_denormal_tiny
1925    add          ecx, 1074
1926    cmovs        rcx, r8
1927    shl          r9, cl
1928    mov          rcx, r9
1929
1930    mov          QWORD PTR [p_temp_exp+rsp], rcx
1931    vmulsd       xmm0, xmm0, QWORD PTR [p_temp_exp+rsp]
1932    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
1933    jmp          Lpow_fma3_z_denormal
1934
1935ALIGN 16
1936Lpow_fma3_process_denormal_tiny:
1937    vmovsd       xmm0, QWORD PTR __real_smallest_denormal
1938    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
1939    jmp          Lpow_fma3_z_denormal
1940
1941ALIGN 16
1942Lpow_fma3_process_result_zero:
1943    mov          r11, QWORD PTR __real_zero
1944    or           r11, QWORD PTR [negate_result+rsp]
1945    jmp          Lpow_fma3_z_is_zero_or_inf
1946
1947ALIGN 16
1948Lpow_fma3_process_result_inf:
1949    mov          r11, QWORD PTR __real_inf
1950    or           r11, QWORD PTR [negate_result+rsp]
1951    jmp          Lpow_fma3_z_is_zero_or_inf
1952
1953ALIGN 16
1954Lpow_fma3_denormal_adjust:
1955    vpor         xmm2, xmm2, XMMWORD PTR __real_one
1956    vsubsd       xmm2, xmm2, QWORD PTR __real_one
1957    vmovapd      xmm5, xmm2
1958    vpand        xmm2, xmm2, XMMWORD PTR __real_mant
1959    vmovq        r8, xmm2
1960    vpsrlq       xmm5, xmm5, 52
1961    vpsubd       xmm5, xmm5, XMMWORD PTR __mask_2045
1962    vcvtdq2pd    xmm6, xmm5
1963    jmp          Lpow_fma3_continue_common
1964
1965ALIGN 16
1966Lpow_fma3_x_is_neg:
1967
1968    mov          r10, QWORD PTR __exp_mask
1969    and          r10, r8
1970    cmp          r10, QWORD PTR __ay_max_bound
1971    jg           Lpow_fma3_ay_is_very_large
1972
1973    ; determine if y is an integer
1974    mov          r10, QWORD PTR __exp_mant_mask
1975    and          r10, r8
1976    mov          r11, r10
1977    mov          rcx, QWORD PTR __exp_shift
1978    shr          r10, cl
1979    sub          r10, QWORD PTR __exp_bias
1980    js           Lpow_fma3_x_is_neg_y_is_not_int
1981
1982    mov          rax, QWORD PTR __exp_mant_mask
1983    and          rax, rdx
1984    mov          QWORD PTR [save_ax+rsp], rax
1985
1986    cmp          r10, QWORD PTR __yexp_53
1987    mov          rcx, r10
1988    jg           Lpow_fma3_continue_after_y_int_check
1989
1990    mov          r9, QWORD PTR __mant_full
1991    shr          r9, cl
1992    and          r9, r11
1993    jnz          Lpow_fma3_x_is_neg_y_is_not_int
1994
1995    mov          r9, QWORD PTR __1_before_mant
1996    shr          r9, cl
1997    and          r9, r11
1998    jz           Lpow_fma3_continue_after_y_int_check
1999
2000    mov          rax, QWORD PTR __sign_mask
2001    mov          QWORD PTR [negate_result+rsp], rax
2002
2003Lpow_fma3_continue_after_y_int_check:
2004
2005    cmp          rdx, QWORD PTR __neg_zero
2006    je           Lpow_fma3_x_is_zero
2007
2008    cmp          rdx, QWORD PTR __neg_one
2009    je           Lpow_fma3_x_is_neg_one
2010
2011    mov          r9, QWORD PTR __exp_mask
2012    and          r9, rdx
2013    cmp          r9, QWORD PTR __exp_mask
2014    je           Lpow_fma3_x_is_inf_or_nan
2015
2016    vmovsd       xmm0, QWORD PTR [save_ax+rsp]
2017    jmp          Lpow_fma3_log_x
2018
2019
2020ALIGN 16
2021Lpow_fma3_near_one:
2022
2023    ; f = F - Y, r = f * inv
2024    vmovapd      xmm0, xmm1
2025    vsubsd       xmm1, xmm1, xmm2         ; xmm1 <-- f
2026    vmovapd      xmm4, xmm1               ; xmm4 <-- copy of f
2027
2028    vmovsd       xmm3, QWORD PTR [r9+r8*8]
2029    vaddsd       xmm3, xmm3, QWORD PTR [rdx+r8*8]
2030    vmulsd       xmm4, xmm4, xmm3         ; xmm4 <-- r = f*inv
2031    vandpd       xmm4, xmm4, XMMWORD PTR __real_fffffffff8000000 ; r1
2032    vmovapd      xmm5, xmm4               ; xmm5 <-- copy of r1
2033;   mulsd        xmm4, xmm0               ; xmm4 <-- F*r1
2034;   subsd        xmm1, xmm4               ; xmm1 <-- f - F*r1
2035    vfnmadd231sd xmm1, xmm4, xmm0         ; xmm1 <-- f - F*r1
2036    vmulsd       xmm1, xmm1, xmm3         ; xmm1 <-- r2 = (f - F*r1)*inv
2037    vmovapd      xmm7, xmm1               ; xmm7 <-- copy of r2
2038    vaddsd       xmm1, xmm1, xmm5         ; xmm1 <-- r = r1 + r2
2039
2040    vmovapd      xmm2, xmm1               ; xmm2 <-- copy of r
2041    vmovapd      xmm0, xmm1               ; xmm0 <-- copy of r
2042
2043    lea          r9, __log_256_lead
2044
2045    ; poly
2046    ; NOTE: Given the complicated corrections here,
2047    ; I'm afraid to mess with it too much - WAT
2048    vmovsd       xmm3, QWORD PTR __real_1_over_7
2049    vmovsd       xmm1, QWORD PTR __real_1_over_4
2050    vmulsd       xmm0, xmm0, xmm2         ; xmm0 <-- r^2
2051    vmovapd      xmm4, xmm0               ; xmm4 <-- copy of r^2
2052    vfmadd213sd  xmm3, xmm2, QWORD PTR __real_1_over_6 ; xmm3 <-- r/7 + 1/6
2053    vfmadd213sd  xmm1, xmm2, QWORD PTR __real_1_over_3 ; xmm1 <-- r/4 + 1/3
2054    vmulsd       xmm4, xmm4, xmm0         ; xmm4 <-- r^4
2055    vmulsd       xmm1, xmm1, xmm2         ; xmm1 <-- (r/4 + 1/3)*r
2056    vfmadd213sd  xmm3, xmm2, QWORD PTR __real_1_over_5 ; xmm3 <-- ((r/7 + 1/6)*r) + 1/5
2057    vmulsd       xmm3, xmm3, xmm2         ; xmm3 <-- (((r/7 + 1/6)*r) + 1/5)*r
2058    vmulsd       xmm1, xmm1, xmm0         ; xmm1 <-- ((r/4 + 1/3)*r)*r^2
2059    vmulsd       xmm3, xmm3, xmm4         ; xmm3 <-- ((((r/7 + 1/6)*r) + 1/5)*r)*r^4
2060
2061    vmovapd      xmm2, xmm5               ; xmm2 <-- copy of r1
2062    vmovapd      xmm0, xmm7               ; xmm0 <-- copy of r2
2063    vmulsd       xmm0, xmm0, xmm0         ; xmm0 <-- r2^2
2064    vmulsd       xmm0, xmm0, QWORD PTR __real_1_over_2 ; xmm0 <-- r2^2/2
2065;   mulsd        xmm5, xmm7               ; xmm5 <-- r1*r2
2066;   addsd        xmm5, xmm0               ; xmm5 <-- r1*r2 + r2^2^2
2067    vfmadd213sd  xmm5, xmm7, xmm0         ; xmm5 <-- r1*r2 + r2^2^2
2068    vaddsd       xmm5, xmm5, xmm7         ; xmm5 <-- r1*r2 + r2^2/2 + r2
2069
2070    vmovapd      xmm0, xmm2               ; xmm0 <-- copy of r1
2071    vmovapd      xmm7, xmm2               ; xmm7 <-- copy of r1
2072    vmulsd       xmm0, xmm0, xmm0         ; xmm0 <-- r1^2
2073    vmulsd       xmm0, xmm0, QWORD PTR __real_1_over_2 ; xmm0 <-- r1^2/2
2074    vmovapd      xmm4, xmm0               ; xmm4 <-- copy of r1^2/2
2075    vaddsd       xmm2, xmm2, xmm0         ; xmm2 <--  r1 + r1^2/2
2076    vsubsd       xmm7, xmm7, xmm2         ; xmm7 <-- r1 - (r1 + r1^2/2)
2077    vaddsd       xmm7, xmm7, xmm4         ; xmm7 <-- r1 - (r1 + r1^2/2) + r1^2/2
2078    ; xmm3 <-- ((((r/7 + 1/6)*r) + 1/5)*r)*r^4 + r1 - (r1 + r1^2/2) + r1^2/2
2079    vaddsd       xmm3, xmm3, xmm7
2080    vmovsd       xmm4, QWORD PTR __real_log2_tail
2081    ; xmm1 <-- (((((r/7 + 1/6)*r) + 1/5)*r)*r^4) +
2082    ;   (r1 - (r1 + r1^2/2) + r1^2/2) + ((r/4 + 1/3)*r)*r^2)
2083    vaddsd       xmm1, xmm1, xmm3
2084    lea          rdx, __log_256_tail
2085    ; xmm1 <-- ((((((r/7 + 1/6)*r) + 1/5)*r)*r^4) +
2086    ;   (r1 - (r1 + r1^2/2) + r1^2/2) + ((r/4 + 1/3)*r)*r^2))
2087    ;   +(r1*r2 + r2^2/2 + r2)
2088    vaddsd       xmm1, xmm1, xmm5
2089    ; xmm4 <-- vt * log2_tail  + log256_tail
2090    vfmadd213sd  xmm4, xmm6, QWORD PTR [rdx+r8*8]
2091    ; xmm4 <-- vt * log2_tail  + log2_tail - corrected poly
2092    vsubsd       xmm4, xmm4, xmm1
2093
2094    vmovapd      xmm1, xmm4
2095    vsubsd       xmm3, xmm4, xmm2 ; xmm3 <-- xmm4 - more correction???
2096
2097    vmovsd       xmm0, QWORD PTR [r9+r8*8] ; xmm0 <-- log256_lead
2098    ; xmm0 <-- log256_lead + vt*log2_lead
2099    vfmadd231sd  xmm0, xmm6, QWORD PTR __real_log2_lead
2100
2101    ; at this point, xmm0, xmm1, xmm2, and xmm3 should matter
2102    jmp          Lpow_fma3_log_x_continue
2103
2104
2105ALIGN 16
2106Lpow_fma3_x_is_pos_one:
2107    jmp          Lpow_fma3_final_check
2108
2109ALIGN 16
2110Lpow_fma3_y_is_zero:
2111    vmovsd       xmm0, QWORD PTR __real_one
2112    jmp          Lpow_fma3_final_check
2113
2114ALIGN 16
2115Lpow_fma3_y_is_one:
2116    xor          rax, rax
2117    mov          r11, rdx
2118    mov          r9, QWORD PTR __exp_mask
2119    ;or          r11, QWORD PTR __qnan_set
2120    and          r9, rdx
2121    cmp          r9, QWORD PTR __exp_mask
2122    cmove        rax, rdx
2123    mov          r9, QWORD PTR __mant_mask
2124    and          r9, rax
2125    jnz          Lpow_fma3_x_is_nan
2126
2127    vmovq        xmm0, rdx
2128    jmp          Lpow_fma3_final_check
2129
2130ALIGN 16
2131Lpow_fma3_x_is_neg_one:
2132    mov          rdx, QWORD PTR __pos_one
2133    or           rdx, QWORD PTR [negate_result+rsp]
2134    xor          rax, rax
2135    mov          r11, r8
2136    mov          r10, QWORD PTR __exp_mask
2137    ;or          r11, QWORD PTR __qnan_set
2138    and          r10, r8
2139    cmp          r10, QWORD PTR __exp_mask
2140    cmove        rax, r8
2141    mov          r10, QWORD PTR __mant_mask
2142    and          r10, rax
2143    jnz          Lpow_fma3_y_is_nan
2144
2145    vmovq        xmm0, rdx
2146    jmp          Lpow_fma3_final_check
2147
2148ALIGN 16
2149Lpow_fma3_x_is_neg_y_is_not_int:
2150    mov          r9, QWORD PTR __exp_mask
2151    and          r9, rdx
2152    cmp          r9, QWORD PTR __exp_mask
2153    je           Lpow_fma3_x_is_inf_or_nan
2154
2155    cmp          rdx, QWORD PTR __neg_zero
2156    je           Lpow_fma3_x_is_zero
2157
2158    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2159    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2160    vmovsd       xmm2, QWORD PTR __neg_qnan
2161    mov          r9d, DWORD PTR __flag_x_neg_y_notint
2162
2163    call         fname_special
2164    jmp          Lpow_fma3_final_check
2165
2166ALIGN 16
2167Lpow_fma3_ay_is_very_large:
2168    mov          r9, QWORD PTR __exp_mask
2169    and          r9, rdx
2170    cmp          r9, QWORD PTR __exp_mask
2171    je           Lpow_fma3_x_is_inf_or_nan
2172
2173    mov          r9, QWORD PTR __exp_mant_mask
2174    and          r9, rdx
2175    jz           Lpow_fma3_x_is_zero
2176
2177    cmp          rdx, QWORD PTR __neg_one
2178    je           Lpow_fma3_x_is_neg_one
2179
2180    mov          r9, rdx
2181    and          r9, QWORD PTR __exp_mant_mask
2182    cmp          r9, QWORD PTR __pos_one
2183    jl           Lpow_fma3_ax_lt1_y_is_large_or_inf_or_nan
2184
2185    jmp          Lpow_fma3_ax_gt1_y_is_large_or_inf_or_nan
2186
2187ALIGN 16
2188Lpow_fma3_x_is_zero:
2189    mov          r10, QWORD PTR __exp_mask
2190    xor          rax, rax
2191    and          r10, r8
2192    cmp          r10, QWORD PTR __exp_mask
2193    je           Lpow_fma3_x_is_zero_y_is_inf_or_nan
2194
2195    mov          r10, QWORD PTR __sign_mask
2196    and          r10, r8
2197    cmovnz       rax, QWORD PTR __pos_inf
2198    jnz          Lpow_fma3_x_is_zero_z_is_inf
2199
2200    vmovq        xmm0, rax
2201    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
2202    jmp          Lpow_fma3_final_check
2203
2204ALIGN 16
2205Lpow_fma3_x_is_zero_z_is_inf:
2206
2207    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2208    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2209    vmovq        xmm2, rax
2210    vorpd        xmm2, xmm2, XMMWORD PTR [negate_result+rsp]
2211    mov          r9d, DWORD PTR __flag_x_zero_z_inf
2212
2213    call         fname_special
2214    jmp          Lpow_fma3_final_check
2215
2216ALIGN 16
2217Lpow_fma3_x_is_zero_y_is_inf_or_nan:
2218    mov          r11, r8
2219    cmp          r8, QWORD PTR __neg_inf
2220;   The next two lines do not correspond to IEEE754-2008.
2221;   +-0 ^ -Inf should be +Inf with no exception
2222;   +-0 ^ +Inf should be +0 with no exception
2223;   cmove        rax, QWORD PTR __pos_inf
2224;   je           Lpow_fma3_x_is_zero_z_is_inf
2225;  begin replacement
2226    je           Lpow_fma3_x_is_zero_y_is_neg_inf
2227    cmp          r8, QWORD PTR __neg_inf
2228    je           Lpow_fma3_x_is_zero_y_is_pos_inf
2229;  end replacement
2230
2231    ;or          r11, QWORD PTR __qnan_set
2232    mov          r10, QWORD PTR __mant_mask
2233    and          r10, r8
2234    jnz          Lpow_fma3_y_is_nan
2235
2236    vmovq        xmm0, rax
2237    jmp          Lpow_fma3_final_check
2238
2239ALIGN 16
2240Lpow_fma3_x_is_zero_y_is_neg_inf:
2241    ; quietly return +Inf
2242    vmovsd       xmm0, __pos_inf
2243    jmp          Lpow_fma3_final_check
2244
2245ALIGN 16
2246Lpow_fma3_x_is_zero_y_is_pos_inf:
2247    ; quietly return +0.
2248    vxorpd       xmm0, xmm0, xmm0
2249    jmp          Lpow_fma3_final_check
2250
2251ALIGN 16
2252Lpow_fma3_x_is_inf_or_nan:
2253    xor          r11, r11
2254    mov          r10, QWORD PTR __sign_mask
2255    and          r10, r8
2256    cmovz        r11, QWORD PTR __pos_inf
2257    mov          rax, rdx
2258    mov          r9, QWORD PTR __mant_mask
2259    ;or          rax, QWORD PTR __qnan_set
2260    and          r9, rdx
2261    cmovnz       r11, rax
2262    jnz          Lpow_fma3_x_is_nan
2263
2264    xor          rax, rax
2265    mov          r9, r8
2266    mov          r10, QWORD PTR __exp_mask
2267    ;or          r9, QWORD PTR __qnan_set
2268    and          r10, r8
2269    cmp          r10, QWORD PTR __exp_mask
2270    cmove        rax, r8
2271    mov          r10, QWORD PTR __mant_mask
2272    and          r10, rax
2273    cmovnz       r11, r9
2274    jnz          Lpow_fma3_y_is_nan
2275
2276    vmovq        xmm0, r11
2277    vorpd        xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
2278    jmp          Lpow_fma3_final_check
2279
2280ALIGN 16
2281Lpow_fma3_ay_is_very_small:
2282    vaddsd       xmm0, xmm1, QWORD PTR __pos_one
2283    jmp          Lpow_fma3_final_check
2284
2285
2286ALIGN 16
2287Lpow_fma3_ax_lt1_y_is_large_or_inf_or_nan:
2288    xor          r11, r11
2289    mov          r10, QWORD PTR __sign_mask
2290    and          r10, r8
2291    cmovnz       r11, QWORD PTR __pos_inf
2292    jmp          Lpow_fma3_adjust_for_nan
2293
2294ALIGN 16
2295Lpow_fma3_ax_gt1_y_is_large_or_inf_or_nan:
2296    xor          r11, r11
2297    mov          r10, QWORD PTR __sign_mask
2298    and          r10, r8
2299    cmovz        r11, QWORD PTR __pos_inf
2300
2301ALIGN 16
2302Lpow_fma3_adjust_for_nan:
2303
2304    xor          rax, rax
2305    mov          r9, r8
2306    mov          r10, QWORD PTR __exp_mask
2307    ;or          r9, QWORD PTR __qnan_set
2308    and          r10, r8
2309    cmp          r10, QWORD PTR __exp_mask
2310    cmove        rax, r8
2311    mov          r10, QWORD PTR __mant_mask
2312    and          r10, rax
2313    cmovnz       r11, r9
2314    jnz          Lpow_fma3_y_is_nan
2315
2316    test         rax, rax
2317    jnz          Lpow_fma3_y_is_inf
2318
2319ALIGN 16
2320Lpow_fma3_z_is_zero_or_inf:
2321
2322    mov          r9d, DWORD PTR __flag_z_zero
2323    test         r11, QWORD PTR __exp_mant_mask
2324    cmovnz       r9d, DWORD PTR __flag_z_inf
2325
2326    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2327    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2328    vmovq        xmm2, r11
2329
2330    call         fname_special
2331    jmp          Lpow_fma3_final_check
2332
2333ALIGN 16
2334Lpow_fma3_y_is_inf:
2335
2336    vmovq        xmm0, r11
2337    jmp          Lpow_fma3_final_check
2338
2339ALIGN 16
2340Lpow_fma3_x_is_nan:
2341
2342    xor          rax, rax
2343    mov          r10, QWORD PTR __exp_mask
2344    and          r10, r8
2345    cmp          r10, QWORD PTR __exp_mask
2346    cmove        rax, r8
2347    mov          r10, QWORD PTR __mant_mask
2348    and          r10, rax
2349    jnz          Lpow_fma3_x_is_nan_y_is_nan
2350
2351    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2352    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2353    vmovq        xmm2, r11
2354    mov          r9d, DWORD PTR __flag_x_nan
2355
2356    call         fname_special
2357    jmp          Lpow_fma3_final_check
2358
2359ALIGN 16
2360Lpow_fma3_y_is_nan:
2361
2362    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2363    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2364    vmovq        xmm2, r11
2365    mov          r9d, DWORD PTR __flag_y_nan
2366
2367    call         fname_special
2368    jmp          Lpow_fma3_final_check
2369
2370ALIGN 16
2371Lpow_fma3_x_is_nan_y_is_nan:
2372
2373    mov          r9, r8
2374
2375    cmp          r11, QWORD PTR __ind_pattern
2376    cmove        r11, r9
2377    je           Lpow_fma3_continue_xy_nan
2378
2379    cmp          r9, QWORD PTR __ind_pattern
2380    cmove        r9, r11
2381
2382    mov          r10, r9
2383    and          r10, QWORD PTR __sign_mask
2384    cmovnz       r9, r11
2385
2386    mov          r10, r11
2387    and          r10, QWORD PTR __sign_mask
2388    cmovnz       r11, r9
2389
2390Lpow_fma3_continue_xy_nan:
2391    ;or          r11, QWORD PTR __qnan_set
2392    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2393    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2394    vmovq        xmm2, r11
2395    mov          r9d, DWORD PTR __flag_x_nan_y_nan
2396
2397    call         fname_special
2398    jmp          Lpow_fma3_final_check
2399
2400ALIGN 16
2401Lpow_fma3_z_denormal:
2402    vmovapd      xmm2, xmm0
2403    vmovsd       xmm0, QWORD PTR [save_x+rsp]
2404    vmovsd       xmm1, QWORD PTR [save_y+rsp]
2405    mov          r9d, DWORD PTR __flag_z_denormal
2406
2407    call         fname_special
2408    jmp          Lpow_fma3_final_check
2409
2410fname endp
2411END
2412