reactos/sdk/lib/crt/math/libm_sse2/pow.asm
2022-12-01 15:21:59 +02:00

2412 lines
76 KiB
NASM

;
; MIT License
; -----------
;
; Copyright (c) 2002-2019 Advanced Micro Devices, Inc.
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this Software and associated documentaon files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
; THE SOFTWARE.
;
; pow.asm
;
; An implementation of the pow libm function.
;
; Prototype:
;
; double pow(double x, double y);
;
;
; Algorithm:
; x^y = e^(y*ln(x))
;
; Look in exp, log for the respective algorithms
;
.const
ALIGN 16
; these codes and the ones in the corresponding .c file have to match
__flag_x_one_y_snan DD 00000001
__flag_x_zero_z_inf DD 00000002
__flag_x_nan DD 00000003
__flag_y_nan DD 00000004
__flag_x_nan_y_nan DD 00000005
__flag_x_neg_y_notint DD 00000006
__flag_z_zero DD 00000007
__flag_z_denormal DD 00000008
__flag_z_inf DD 00000009
ALIGN 16
__ay_max_bound DQ 43e0000000000000h
__ay_min_bound DQ 3c00000000000000h
__sign_mask DQ 8000000000000000h
__sign_and_exp_mask DQ 0fff0000000000000h
__exp_mask DQ 7ff0000000000000h
__neg_inf DQ 0fff0000000000000h
__pos_inf DQ 7ff0000000000000h
__pos_one DQ 3ff0000000000000h
__pos_zero DQ 0000000000000000h
__exp_mant_mask DQ 7fffffffffffffffh
__mant_mask DQ 000fffffffffffffh
__ind_pattern DQ 0fff8000000000000h
__neg_qnan DQ 0fff8000000000000h
__qnan DQ 7ff8000000000000h
__qnan_set DQ 0008000000000000h
__neg_one DQ 0bff0000000000000h
__neg_zero DQ 8000000000000000h
__exp_shift DQ 0000000000000034h ; 52
__exp_bias DQ 00000000000003ffh ; 1023
__exp_bias_m1 DQ 00000000000003feh ; 1022
__yexp_53 DQ 0000000000000035h ; 53
__mant_full DQ 000fffffffffffffh
__1_before_mant DQ 0010000000000000h
__mask_mant_all8 DQ 000ff00000000000h
__mask_mant9 DQ 0000080000000000h
ALIGN 16
__real_fffffffff8000000 DQ 0fffffffff8000000h
DQ 0fffffffff8000000h
__mask_8000000000000000 DQ 8000000000000000h
DQ 8000000000000000h
__real_4090040000000000 DQ 4090040000000000h
DQ 4090040000000000h
__real_C090C80000000000 DQ 0C090C80000000000h
DQ 0C090C80000000000h
;---------------------
; log data
;---------------------
ALIGN 16
__real_ninf DQ 0fff0000000000000h ; -inf
DQ 0000000000000000h
__real_inf DQ 7ff0000000000000h ; +inf
DQ 0000000000000000h
__real_nan DQ 7ff8000000000000h ; NaN
DQ 0000000000000000h
__real_mant DQ 000FFFFFFFFFFFFFh ; mantissa bits
DQ 0000000000000000h
__mask_1023 DQ 00000000000003ffh
DQ 0000000000000000h
__mask_001 DQ 0000000000000001h
DQ 0000000000000000h
__real_log2_lead DQ 3fe62e42e0000000h ; log2_lead 6.93147122859954833984e-01
DQ 0000000000000000h
__real_log2_tail DQ 3e6efa39ef35793ch ; log2_tail 5.76999904754328540596e-08
DQ 0000000000000000h
__real_two DQ 4000000000000000h ; 2
DQ 0000000000000000h
__real_one DQ 3ff0000000000000h ; 1
DQ 0000000000000000h
__real_half DQ 3fe0000000000000h ; 1/2
DQ 0000000000000000h
__mask_100 DQ 0000000000000100h
DQ 0000000000000000h
__real_1_over_2 DQ 3fe0000000000000h
DQ 0000000000000000h
__real_1_over_3 DQ 3fd5555555555555h
DQ 0000000000000000h
__real_1_over_4 DQ 3fd0000000000000h
DQ 0000000000000000h
__real_1_over_5 DQ 3fc999999999999ah
DQ 0000000000000000h
__real_1_over_6 DQ 3fc5555555555555h
DQ 0000000000000000h
__real_1_over_7 DQ 3fc2492492492494h
DQ 0000000000000000h
__mask_1023_f DQ 0c08ff80000000000h
DQ 0000000000000000h
__mask_2045 DQ 00000000000007fdh
DQ 0000000000000000h
__real_threshold DQ 3fc0000000000000h ; 0.125
DQ 3fc0000000000000h
__real_notsign DQ 7ffFFFFFFFFFFFFFh ; ^sign bit
DQ 0000000000000000h
EXTRN __log_256_lead:QWORD
EXTRN __log_256_tail:QWORD
EXTRN __use_fma3_lib:DWORD
; This table differs from the tables in log_256_lead_tail_table.asm:
; the heads have fewer significant bits (hence the tails also differ).
ALIGN 16
__log_F_inv_head DQ 4000000000000000h
DQ 3fffe00000000000h
DQ 3fffc00000000000h
DQ 3fffa00000000000h
DQ 3fff800000000000h
DQ 3fff600000000000h
DQ 3fff400000000000h
DQ 3fff200000000000h
DQ 3fff000000000000h
DQ 3ffee00000000000h
DQ 3ffec00000000000h
DQ 3ffea00000000000h
DQ 3ffe900000000000h
DQ 3ffe700000000000h
DQ 3ffe500000000000h
DQ 3ffe300000000000h
DQ 3ffe100000000000h
DQ 3ffe000000000000h
DQ 3ffde00000000000h
DQ 3ffdc00000000000h
DQ 3ffda00000000000h
DQ 3ffd900000000000h
DQ 3ffd700000000000h
DQ 3ffd500000000000h
DQ 3ffd400000000000h
DQ 3ffd200000000000h
DQ 3ffd000000000000h
DQ 3ffcf00000000000h
DQ 3ffcd00000000000h
DQ 3ffcb00000000000h
DQ 3ffca00000000000h
DQ 3ffc800000000000h
DQ 3ffc700000000000h
DQ 3ffc500000000000h
DQ 3ffc300000000000h
DQ 3ffc200000000000h
DQ 3ffc000000000000h
DQ 3ffbf00000000000h
DQ 3ffbd00000000000h
DQ 3ffbc00000000000h
DQ 3ffba00000000000h
DQ 3ffb900000000000h
DQ 3ffb700000000000h
DQ 3ffb600000000000h
DQ 3ffb400000000000h
DQ 3ffb300000000000h
DQ 3ffb200000000000h
DQ 3ffb000000000000h
DQ 3ffaf00000000000h
DQ 3ffad00000000000h
DQ 3ffac00000000000h
DQ 3ffaa00000000000h
DQ 3ffa900000000000h
DQ 3ffa800000000000h
DQ 3ffa600000000000h
DQ 3ffa500000000000h
DQ 3ffa400000000000h
DQ 3ffa200000000000h
DQ 3ffa100000000000h
DQ 3ffa000000000000h
DQ 3ff9e00000000000h
DQ 3ff9d00000000000h
DQ 3ff9c00000000000h
DQ 3ff9a00000000000h
DQ 3ff9900000000000h
DQ 3ff9800000000000h
DQ 3ff9700000000000h
DQ 3ff9500000000000h
DQ 3ff9400000000000h
DQ 3ff9300000000000h
DQ 3ff9200000000000h
DQ 3ff9000000000000h
DQ 3ff8f00000000000h
DQ 3ff8e00000000000h
DQ 3ff8d00000000000h
DQ 3ff8b00000000000h
DQ 3ff8a00000000000h
DQ 3ff8900000000000h
DQ 3ff8800000000000h
DQ 3ff8700000000000h
DQ 3ff8600000000000h
DQ 3ff8400000000000h
DQ 3ff8300000000000h
DQ 3ff8200000000000h
DQ 3ff8100000000000h
DQ 3ff8000000000000h
DQ 3ff7f00000000000h
DQ 3ff7e00000000000h
DQ 3ff7d00000000000h
DQ 3ff7b00000000000h
DQ 3ff7a00000000000h
DQ 3ff7900000000000h
DQ 3ff7800000000000h
DQ 3ff7700000000000h
DQ 3ff7600000000000h
DQ 3ff7500000000000h
DQ 3ff7400000000000h
DQ 3ff7300000000000h
DQ 3ff7200000000000h
DQ 3ff7100000000000h
DQ 3ff7000000000000h
DQ 3ff6f00000000000h
DQ 3ff6e00000000000h
DQ 3ff6d00000000000h
DQ 3ff6c00000000000h
DQ 3ff6b00000000000h
DQ 3ff6a00000000000h
DQ 3ff6900000000000h
DQ 3ff6800000000000h
DQ 3ff6700000000000h
DQ 3ff6600000000000h
DQ 3ff6500000000000h
DQ 3ff6400000000000h
DQ 3ff6300000000000h
DQ 3ff6200000000000h
DQ 3ff6100000000000h
DQ 3ff6000000000000h
DQ 3ff5f00000000000h
DQ 3ff5e00000000000h
DQ 3ff5d00000000000h
DQ 3ff5c00000000000h
DQ 3ff5b00000000000h
DQ 3ff5a00000000000h
DQ 3ff5900000000000h
DQ 3ff5800000000000h
DQ 3ff5800000000000h
DQ 3ff5700000000000h
DQ 3ff5600000000000h
DQ 3ff5500000000000h
DQ 3ff5400000000000h
DQ 3ff5300000000000h
DQ 3ff5200000000000h
DQ 3ff5100000000000h
DQ 3ff5000000000000h
DQ 3ff5000000000000h
DQ 3ff4f00000000000h
DQ 3ff4e00000000000h
DQ 3ff4d00000000000h
DQ 3ff4c00000000000h
DQ 3ff4b00000000000h
DQ 3ff4a00000000000h
DQ 3ff4a00000000000h
DQ 3ff4900000000000h
DQ 3ff4800000000000h
DQ 3ff4700000000000h
DQ 3ff4600000000000h
DQ 3ff4600000000000h
DQ 3ff4500000000000h
DQ 3ff4400000000000h
DQ 3ff4300000000000h
DQ 3ff4200000000000h
DQ 3ff4200000000000h
DQ 3ff4100000000000h
DQ 3ff4000000000000h
DQ 3ff3f00000000000h
DQ 3ff3e00000000000h
DQ 3ff3e00000000000h
DQ 3ff3d00000000000h
DQ 3ff3c00000000000h
DQ 3ff3b00000000000h
DQ 3ff3b00000000000h
DQ 3ff3a00000000000h
DQ 3ff3900000000000h
DQ 3ff3800000000000h
DQ 3ff3800000000000h
DQ 3ff3700000000000h
DQ 3ff3600000000000h
DQ 3ff3500000000000h
DQ 3ff3500000000000h
DQ 3ff3400000000000h
DQ 3ff3300000000000h
DQ 3ff3200000000000h
DQ 3ff3200000000000h
DQ 3ff3100000000000h
DQ 3ff3000000000000h
DQ 3ff3000000000000h
DQ 3ff2f00000000000h
DQ 3ff2e00000000000h
DQ 3ff2e00000000000h
DQ 3ff2d00000000000h
DQ 3ff2c00000000000h
DQ 3ff2b00000000000h
DQ 3ff2b00000000000h
DQ 3ff2a00000000000h
DQ 3ff2900000000000h
DQ 3ff2900000000000h
DQ 3ff2800000000000h
DQ 3ff2700000000000h
DQ 3ff2700000000000h
DQ 3ff2600000000000h
DQ 3ff2500000000000h
DQ 3ff2500000000000h
DQ 3ff2400000000000h
DQ 3ff2300000000000h
DQ 3ff2300000000000h
DQ 3ff2200000000000h
DQ 3ff2100000000000h
DQ 3ff2100000000000h
DQ 3ff2000000000000h
DQ 3ff2000000000000h
DQ 3ff1f00000000000h
DQ 3ff1e00000000000h
DQ 3ff1e00000000000h
DQ 3ff1d00000000000h
DQ 3ff1c00000000000h
DQ 3ff1c00000000000h
DQ 3ff1b00000000000h
DQ 3ff1b00000000000h
DQ 3ff1a00000000000h
DQ 3ff1900000000000h
DQ 3ff1900000000000h
DQ 3ff1800000000000h
DQ 3ff1800000000000h
DQ 3ff1700000000000h
DQ 3ff1600000000000h
DQ 3ff1600000000000h
DQ 3ff1500000000000h
DQ 3ff1500000000000h
DQ 3ff1400000000000h
DQ 3ff1300000000000h
DQ 3ff1300000000000h
DQ 3ff1200000000000h
DQ 3ff1200000000000h
DQ 3ff1100000000000h
DQ 3ff1100000000000h
DQ 3ff1000000000000h
DQ 3ff0f00000000000h
DQ 3ff0f00000000000h
DQ 3ff0e00000000000h
DQ 3ff0e00000000000h
DQ 3ff0d00000000000h
DQ 3ff0d00000000000h
DQ 3ff0c00000000000h
DQ 3ff0c00000000000h
DQ 3ff0b00000000000h
DQ 3ff0a00000000000h
DQ 3ff0a00000000000h
DQ 3ff0900000000000h
DQ 3ff0900000000000h
DQ 3ff0800000000000h
DQ 3ff0800000000000h
DQ 3ff0700000000000h
DQ 3ff0700000000000h
DQ 3ff0600000000000h
DQ 3ff0600000000000h
DQ 3ff0500000000000h
DQ 3ff0500000000000h
DQ 3ff0400000000000h
DQ 3ff0400000000000h
DQ 3ff0300000000000h
DQ 3ff0300000000000h
DQ 3ff0200000000000h
DQ 3ff0200000000000h
DQ 3ff0100000000000h
DQ 3ff0100000000000h
DQ 3ff0000000000000h
DQ 3ff0000000000000h
ALIGN 16
__log_F_inv_tail DQ 0000000000000000h
DQ 3effe01fe01fe020h
DQ 3f1fc07f01fc07f0h
DQ 3f31caa01fa11caah
DQ 3f3f81f81f81f820h
DQ 3f48856506ddaba6h
DQ 3f5196792909c560h
DQ 3f57d9108c2ad433h
DQ 3f5f07c1f07c1f08h
DQ 3f638ff08b1c03ddh
DQ 3f680f6603d980f6h
DQ 3f6d00f57403d5d0h
DQ 3f331abf0b7672a0h
DQ 3f506a965d43919bh
DQ 3f5ceb240795ceb2h
DQ 3f6522f3b834e67fh
DQ 3f6c3c3c3c3c3c3ch
DQ 3f3e01e01e01e01eh
DQ 3f575b8fe21a291ch
DQ 3f6403b9403b9404h
DQ 3f6cc0ed7303b5cch
DQ 3f479118f3fc4da2h
DQ 3f5ed952e0b0ce46h
DQ 3f695900eae56404h
DQ 3f3d41d41d41d41dh
DQ 3f5cb28ff16c69aeh
DQ 3f696b1edd80e866h
DQ 3f4372e225fe30d9h
DQ 3f60ad12073615a2h
DQ 3f6cdb2c0397cdb3h
DQ 3f52cc157b864407h
DQ 3f664cb5f7148404h
DQ 3f3c71c71c71c71ch
DQ 3f6129a21a930b84h
DQ 3f6f1e0387f1e038h
DQ 3f5ad4e4ba80709bh
DQ 3f6c0e070381c0e0h
DQ 3f560fba1a362bb0h
DQ 3f6a5713280dee96h
DQ 3f53f59620f9ece9h
DQ 3f69f22983759f23h
DQ 3f5478ac63fc8d5ch
DQ 3f6ad87bb4671656h
DQ 3f578b8efbb8148ch
DQ 3f6d0369d0369d03h
DQ 3f5d212b601b3748h
DQ 3f0b2036406c80d9h
DQ 3f629663b24547d1h
DQ 3f4435e50d79435eh
DQ 3f67d0ff2920bc03h
DQ 3f55c06b15c06b16h
DQ 3f6e3a5f0fd7f954h
DQ 3f61dec0d4c77b03h
DQ 3f473289870ac52eh
DQ 3f6a034da034da03h
DQ 3f5d041da2292856h
DQ 3f3a41a41a41a41ah
DQ 3f68550f8a39409dh
DQ 3f5b4fe5e92c0686h
DQ 3f3a01a01a01a01ah
DQ 3f691d2a2067b23ah
DQ 3f5e7c5dada0b4e5h
DQ 3f468a7725080ce1h
DQ 3f6c49d4aa21b490h
DQ 3f63333333333333h
DQ 3f54bc363b03fccfh
DQ 3f2c9f01970e4f81h
DQ 3f697617c6ef5b25h
DQ 3f6161f9add3c0cah
DQ 3f5319fe6cb39806h
DQ 3f2f693a1c451ab3h
DQ 3f6a9e240321a9e2h
DQ 3f63831f3831f383h
DQ 3f5949ebc4dcfc1ch
DQ 3f480c6980c6980ch
DQ 3f6f9d00c5fe7403h
DQ 3f69721ed7e75347h
DQ 3f6381ec0313381fh
DQ 3f5b97c2aec12653h
DQ 3f509ef3024ae3bah
DQ 3f38618618618618h
DQ 3f6e0184f00c2780h
DQ 3f692ef5657dba52h
DQ 3f64940305494030h
DQ 3f60303030303030h
DQ 3f58060180601806h
DQ 3f5017f405fd017fh
DQ 3f412a8ad278e8ddh
DQ 3f17d05f417d05f4h
DQ 3f6d67245c02f7d6h
DQ 3f6a4411c1d986a9h
DQ 3f6754d76c7316dfh
DQ 3f649902f149902fh
DQ 3f621023358c1a68h
DQ 3f5f7390d2a6c406h
DQ 3f5b2b0805d5b2b1h
DQ 3f5745d1745d1746h
DQ 3f53c31507fa32c4h
DQ 3f50a1fd1b7af017h
DQ 3f4bc36ce3e0453ah
DQ 3f4702e05c0b8170h
DQ 3f4300b79300b793h
DQ 3f3f76b4337c6cb1h
DQ 3f3a62681c860fb0h
DQ 3f36c16c16c16c17h
DQ 3f3490aa31a3cfc7h
DQ 3f33cd153729043eh
DQ 3f3473a88d0bfd2eh
DQ 3f36816816816817h
DQ 3f39f36016719f36h
DQ 3f3ec6a5122f9016h
DQ 3f427c29da5519cfh
DQ 3f4642c8590b2164h
DQ 3f4ab5c45606f00bh
DQ 3f4fd3b80b11fd3ch
DQ 3f52cda0c6ba4eaah
DQ 3f56058160581606h
DQ 3f5990d0a4b7ef87h
DQ 3f5d6ee340579d6fh
DQ 3f60cf87d9c54a69h
DQ 3f6310572620ae4ch
DQ 3f65798c8ff522a2h
DQ 3f680ad602b580adh
DQ 3f6ac3e24799546fh
DQ 3f6da46102b1da46h
DQ 3f15805601580560h
DQ 3f3ed3c506b39a23h
DQ 3f4cbdd3e2970f60h
DQ 3f55555555555555h
DQ 3f5c979aee0bf805h
DQ 3f621291e81fd58eh
DQ 3f65fead500a9580h
DQ 3f6a0fd5c5f02a3ah
DQ 3f6e45c223898adch
DQ 3f35015015015015h
DQ 3f4c7b16ea64d422h
DQ 3f57829cbc14e5e1h
DQ 3f60877db8589720h
DQ 3f65710e4b5edceah
DQ 3f6a7dbb4d1fc1c8h
DQ 3f6fad40a57eb503h
DQ 3f43fd6bb00a5140h
DQ 3f54e78ecb419ba9h
DQ 3f600a44029100a4h
DQ 3f65c28f5c28f5c3h
DQ 3f6b9c68b2c0cc4ah
DQ 3f2978feb9f34381h
DQ 3f4ecf163bb6500ah
DQ 3f5be1958b67ebb9h
DQ 3f644e6157dc9a3bh
DQ 3f6acc4baa3f0ddfh
DQ 3f26a4cbcb2a247bh
DQ 3f50505050505050h
DQ 3f5e0b4439959819h
DQ 3f66027f6027f602h
DQ 3f6d1e854b5e0db4h
DQ 3f4165e7254813e2h
DQ 3f576646a9d716efh
DQ 3f632b48f757ce88h
DQ 3f6ac1b24652a906h
DQ 3f33b13b13b13b14h
DQ 3f5490e1eb208984h
DQ 3f62385830fec66eh
DQ 3f6a45a6cc111b7eh
DQ 3f33813813813814h
DQ 3f556f472517b708h
DQ 3f631be7bc0e8f2ah
DQ 3f6b9cbf3e55f044h
DQ 3f40e7d95bc609a9h
DQ 3f59e6b3804d19e7h
DQ 3f65c8b6af7963c2h
DQ 3f6eb9dad43bf402h
DQ 3f4f1a515885fb37h
DQ 3f60eeb1d3d76c02h
DQ 3f6a320261a32026h
DQ 3f3c82ac40260390h
DQ 3f5a12f684bda12fh
DQ 3f669d43fda2962ch
DQ 3f02e025c04b8097h
DQ 3f542804b542804bh
DQ 3f63f69b02593f6ah
DQ 3f6df31cb46e21fah
DQ 3f5012b404ad012bh
DQ 3f623925e7820a7fh
DQ 3f6c8253c8253c82h
DQ 3f4b92ddc02526e5h
DQ 3f61602511602511h
DQ 3f6bf471439c9adfh
DQ 3f4a85c40939a85ch
DQ 3f6166f9ac024d16h
DQ 3f6c44e10125e227h
DQ 3f4cebf48bbd90e5h
DQ 3f62492492492492h
DQ 3f6d6f2e2ec0b673h
DQ 3f5159e26af37c05h
DQ 3f64024540245402h
DQ 3f6f6f0243f6f024h
DQ 3f55e60121579805h
DQ 3f668e18cf81b10fh
DQ 3f32012012012012h
DQ 3f5c11f7047dc11fh
DQ 3f69e878ff70985eh
DQ 3f4779d9fdc3a219h
DQ 3f61eace5c957907h
DQ 3f6e0d5b450239e1h
DQ 3f548bf073816367h
DQ 3f6694808dda5202h
DQ 3f37c67f2bae2b21h
DQ 3f5ee58469ee5847h
DQ 3f6c0233c0233c02h
DQ 3f514e02328a7012h
DQ 3f6561072057b573h
DQ 3f31811811811812h
DQ 3f5e28646f5a1060h
DQ 3f6c0d1284e6f1d7h
DQ 3f523543f0c80459h
DQ 3f663cbeea4e1a09h
DQ 3f3b9a3fdd5c8cb8h
DQ 3f60be1c159a76d2h
DQ 3f6e1d1a688e4838h
DQ 3f572044d72044d7h
DQ 3f691713db81577bh
DQ 3f4ac73ae9819b50h
DQ 3f6460334e904cf6h
DQ 3f31111111111111h
DQ 3f5feef80441fef0h
DQ 3f6de021fde021feh
DQ 3f57b7eacc9686a0h
DQ 3f69ead7cd391fbch
DQ 3f50195609804390h
DQ 3f6641511e8d2b32h
DQ 3f4222b1acf1ce96h
DQ 3f62e29f79b47582h
DQ 3f24f0d1682e11cdh
DQ 3f5f9bb096771e4dh
DQ 3f6e5ee45dd96ae2h
DQ 3f5a0429a0429a04h
DQ 3f6bb74d5f06c021h
DQ 3f54fce404254fceh
DQ 3f695766eacbc402h
DQ 3f50842108421084h
DQ 3f673e5371d5c338h
DQ 3f4930523fbe3368h
DQ 3f656b38f225f6c4h
DQ 3f426e978d4fdf3bh
DQ 3f63dd40e4eb0cc6h
DQ 3f397f7d73404146h
DQ 3f6293982cc98af1h
DQ 3f30410410410410h
DQ 3f618d6f048ff7e4h
DQ 3f2236a3ebc349deh
DQ 3f60c9f8ee53d18ch
DQ 3f10204081020408h
DQ 3f60486ca2f46ea6h
DQ 3ef0101010101010h
DQ 3f60080402010080h
DQ 0000000000000000h
;---------------------
; exp data
;---------------------
ALIGN 16
__denormal_threshold DD 0fffffc02h ; -1022
DD 0
DQ 0
__enable_almost_inf DQ 7fe0000000000000h
DQ 0
__real_zero DQ 0000000000000000h
DQ 0
__real_smallest_denormal DQ 0000000000000001h
DQ 0
__denormal_tiny_threshold DQ 0c0874046dfefd9d0h
DQ 0
__real_p65536 DQ 40f0000000000000h ; 65536
DQ 0
__real_m68800 DQ 0c0f0cc0000000000h ; -68800
DQ 0
__real_64_by_log2 DQ 40571547652b82feh ; 64/ln(2)
DQ 0
__real_log2_by_64_head DQ 3f862e42f0000000h ; log2_by_64_head
DQ 0
__real_log2_by_64_tail DQ 0bdfdf473de6af278h ; -log2_by_64_tail
DQ 0
__real_1_by_720 DQ 3f56c16c16c16c17h ; 1/720
DQ 0
__real_1_by_120 DQ 3f81111111111111h ; 1/120
DQ 0
__real_1_by_24 DQ 3fa5555555555555h ; 1/24
DQ 0
__real_1_by_6 DQ 3fc5555555555555h ; 1/6
DQ 0
__real_1_by_2 DQ 3fe0000000000000h ; 1/2
DQ 0
EXTRN __two_to_jby64_head_table:QWORD
EXTRN __two_to_jby64_tail_table:QWORD
EXTRN __use_fma3_lib:DWORD
fname TEXTEQU <pow>
fname_special TEXTEQU <_pow_special>
; define local variable storage offsets
save_x EQU 10h
save_y EQU 20h
p_temp_exp EQU 30h
negate_result EQU 40h
save_ax EQU 50h
y_head EQU 60h
p_temp_log EQU 70h
save_xmm6 EQU 080h
save_xmm7 EQU 090h
dummy_space EQU 0a0h
stack_size EQU 0c8h
include fm.inc
; external function
EXTERN fname_special:PROC
.code
ALIGN 16
PUBLIC fname
fname PROC FRAME
StackAllocate stack_size
SaveXmm xmm6, save_xmm6
SaveXmm xmm7, save_xmm7
.ENDPROLOG
cmp DWORD PTR __use_fma3_lib, 0
jne Lpow_fma3
ALIGN 16
Lpow_sse2:
movsd QWORD PTR [save_x+rsp], xmm0
movsd QWORD PTR [save_y+rsp], xmm1
mov rdx, QWORD PTR [save_x+rsp]
mov r8, QWORD PTR [save_y+rsp]
mov r10, QWORD PTR __exp_mant_mask
and r10, r8
jz Lpow_sse2_y_is_zero
cmp r8, QWORD PTR __pos_one
je Lpow_sse2_y_is_one
mov r9, QWORD PTR __sign_mask
and r9, rdx
mov rax, QWORD PTR __pos_zero
mov QWORD PTR [negate_result+rsp], rax
cmp r9, QWORD PTR __sign_mask
je Lpow_sse2_x_is_neg
cmp rdx, QWORD PTR __pos_one
je Lpow_sse2_x_is_pos_one
cmp rdx, QWORD PTR __pos_zero
je Lpow_sse2_x_is_zero
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_sse2_x_is_inf_or_nan
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __ay_max_bound
jg Lpow_sse2_ay_is_very_large
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __ay_min_bound
jl Lpow_sse2_ay_is_very_small
; -----------------------------
; compute log(x) here
; -----------------------------
Lpow_sse2_log_x:
; compute exponent part
xor r8, r8
movdqa xmm3, xmm0
psrlq xmm3, 52
movd r8, xmm0
psubq xmm3, XMMWORD PTR __mask_1023
movdqa xmm2, xmm0
cvtdq2pd xmm6, xmm3 ; xexp
pand xmm2, XMMWORD PTR __real_mant
comisd xmm6, QWORD PTR __mask_1023_f
je Lpow_sse2_denormal_adjust
Lpow_sse2_continue_common:
; compute index into the log tables
movsd xmm7, xmm0
mov r9, r8
and r8, QWORD PTR __mask_mant_all8
and r9, QWORD PTR __mask_mant9
subsd xmm7, __real_one
shl r9, 1
add r8, r9
mov QWORD PTR [p_temp_log+rsp], r8
andpd xmm7, __real_notsign
; F, Y, switch to near-one codepath
movsd xmm1, QWORD PTR [p_temp_log+rsp]
shr r8, 44
por xmm2, XMMWORD PTR __real_half
por xmm1, XMMWORD PTR __real_half
lea r9, QWORD PTR __log_F_inv_head
lea rdx, QWORD PTR __log_F_inv_tail
comisd xmm7, __real_threshold
jb Lpow_sse2_near_one
; f = F - Y, r = f * inv
subsd xmm1, xmm2
movsd xmm4, xmm1
mulsd xmm1, QWORD PTR [r9+r8*8]
movsd xmm5, xmm1
mulsd xmm4, QWORD PTR [rdx+r8*8]
movsd xmm7, xmm4
addsd xmm1, xmm4
movsd xmm2, xmm1
movsd xmm0, xmm1
lea r9, __log_256_lead
; poly
movsd xmm3, QWORD PTR __real_1_over_6
movsd xmm1, QWORD PTR __real_1_over_3
mulsd xmm3, xmm2
mulsd xmm1, xmm2
mulsd xmm0, xmm2
subsd xmm5, xmm2
movsd xmm4, xmm0
addsd xmm3, QWORD PTR __real_1_over_5
addsd xmm1, QWORD PTR __real_1_over_2
mulsd xmm4, xmm0
mulsd xmm3, xmm2
mulsd xmm1, xmm0
addsd xmm3, QWORD PTR __real_1_over_4
addsd xmm7, xmm5
mulsd xmm3, xmm4
addsd xmm1, xmm3
addsd xmm1, xmm7
movsd xmm5, QWORD PTR __real_log2_tail
lea rdx, __log_256_tail
mulsd xmm5, xmm6
movsd xmm0, QWORD PTR [r9+r8*8]
subsd xmm5, xmm1
movsd xmm3, QWORD PTR [rdx+r8*8]
addsd xmm3, xmm5
movsd xmm1, xmm3
subsd xmm3, xmm2
movsd xmm7, QWORD PTR __real_log2_lead
mulsd xmm7, xmm6
addsd xmm0, xmm7
; result of ln(x) is computed from head and tail parts, resH and resT
; res = ln(x) = resH + resT
; resH and resT are in full precision
; resT is computed from head and tail parts, resT_h and resT_t
; resT = resT_h + resT_t
; now
; xmm3 - resT
; xmm0 - resH
; xmm1 - (resT_t)
; xmm2 - (-resT_h)
Lpow_sse2_log_x_continue:
movsd xmm7, xmm0
addsd xmm0, xmm3
movsd xmm5, xmm0
andpd xmm0, XMMWORD PTR __real_fffffffff8000000
; xmm0 - H
; xmm7 - resH
; xmm5 - res
mov rax, QWORD PTR [save_y+rsp]
and rax, QWORD PTR __real_fffffffff8000000
addsd xmm2, xmm3
subsd xmm7, xmm5
subsd xmm1, xmm2
addsd xmm7, xmm3
subsd xmm5, xmm0
mov QWORD PTR [y_head+rsp], rax
movsd xmm4, QWORD PTR [save_y+rsp]
addsd xmm7, xmm1
addsd xmm7, xmm5
; res = H + T
; H has leading 26 bits of precision
; T has full precision
; xmm0 - H
; xmm7 - T
movsd xmm2, QWORD PTR [y_head+rsp]
subsd xmm4, xmm2
; y is split into head and tail
; for y * ln(x) computation
; xmm4 - Yt
; xmm2 - Yh
; xmm0 - H
; xmm7 - T
movsd xmm3, xmm4
movsd xmm5, xmm7
movsd xmm6, xmm0
mulsd xmm3, xmm7 ; YtRt
mulsd xmm4, xmm0 ; YtRh
mulsd xmm5, xmm2 ; YhRt
mulsd xmm6, xmm2 ; YhRh
movsd xmm1, xmm6
addsd xmm3, xmm4
addsd xmm3, xmm5
addsd xmm1, xmm3
movsd xmm0, xmm1
subsd xmm6, xmm1
addsd xmm6, xmm3
; y * ln(x) = v + vt
; v and vt are in full precision
; xmm0 - v
; xmm6 - vt
; -----------------------------
; compute exp( y * ln(x) ) here
; -----------------------------
; v * (64/ln(2))
movsd xmm7, QWORD PTR __real_64_by_log2
movsd QWORD PTR [p_temp_exp+rsp], xmm0
mulsd xmm7, xmm0
mov rdx, QWORD PTR [p_temp_exp+rsp]
; v < 1024*ln(2), ( v * (64/ln(2)) ) < 64*1024
; v >= -1075*ln(2), ( v * (64/ln(2)) ) >= 64*(-1075)
comisd xmm7, QWORD PTR __real_p65536
ja Lpow_sse2_process_result_inf
comisd xmm7, QWORD PTR __real_m68800
jb Lpow_sse2_process_result_zero
; n = int( v * (64/ln(2)) )
cvtpd2dq xmm4, xmm7
lea r10, __two_to_jby64_head_table
lea r11, __two_to_jby64_tail_table
cvtdq2pd xmm1, xmm4
; r1 = x - n * ln(2)/64 head
movsd xmm2, QWORD PTR __real_log2_by_64_head
mulsd xmm2, xmm1
movd ecx, xmm4
mov rax, 3fh
and eax, ecx
subsd xmm0, xmm2
; r2 = - n * ln(2)/64 tail
mulsd xmm1, QWORD PTR __real_log2_by_64_tail
movsd xmm2, xmm0
; m = (n - j) / 64
sub ecx, eax
sar ecx, 6
; r1+r2
addsd xmm2, xmm1
addsd xmm2, xmm6 ; add vt here
movsd xmm1, xmm2
; q
movsd xmm0, QWORD PTR __real_1_by_2
movsd xmm3, QWORD PTR __real_1_by_24
movsd xmm4, QWORD PTR __real_1_by_720
mulsd xmm1, xmm2
mulsd xmm0, xmm2
mulsd xmm3, xmm2
mulsd xmm4, xmm2
movsd xmm5, xmm1
mulsd xmm1, xmm2
addsd xmm0, QWORD PTR __real_one
addsd xmm3, QWORD PTR __real_1_by_6
mulsd xmm5, xmm1
addsd xmm4, QWORD PTR __real_1_by_120
mulsd xmm0, xmm2
mulsd xmm3, xmm1
mulsd xmm4, xmm5
; deal with denormal results
xor r9d, r9d
addsd xmm3, xmm4
addsd xmm0, xmm3
cmp ecx, DWORD PTR __denormal_threshold
cmovle r9d, ecx
add rcx, 1023
shl rcx, 52
; f1, f2
movsd xmm5, QWORD PTR [r11+rax*8]
movsd xmm1, QWORD PTR [r10+rax*8]
mulsd xmm5, xmm0
mulsd xmm1, xmm0
; (f1+f2)*(1+q)
addsd xmm5, QWORD PTR [r11+rax*8]
addsd xmm1, xmm5
addsd xmm1, QWORD PTR [r10+rax*8]
movsd xmm0, xmm1
cmp rcx, QWORD PTR __real_inf
je Lpow_sse2_process_almost_inf
mov QWORD PTR [p_temp_exp+rsp], rcx
test r9d, r9d
jnz Lpow_sse2_process_denormal
mulsd xmm0, QWORD PTR [p_temp_exp+rsp]
orpd xmm0, XMMWORD PTR [negate_result+rsp]
Lpow_sse2_final_check:
RestoreXmm xmm7, save_xmm7
RestoreXmm xmm6, save_xmm6
StackDeallocate stack_size
ret
ALIGN 16
Lpow_sse2_process_almost_inf:
comisd xmm0, QWORD PTR __real_one
jae Lpow_sse2_process_result_inf
orpd xmm0, XMMWORD PTR __enable_almost_inf
orpd xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_process_denormal:
mov ecx, r9d
xor r11d, r11d
comisd xmm0, QWORD PTR __real_one
cmovae r11d, ecx
cmp r11d, DWORD PTR __denormal_threshold
jne Lpow_sse2_process_true_denormal
mulsd xmm0, QWORD PTR [p_temp_exp+rsp]
orpd xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_process_true_denormal:
xor r8, r8
mov r9, 1
cmp rdx, QWORD PTR __denormal_tiny_threshold
jg Lpow_sse2_process_denormal_tiny
add ecx, 1074
cmovs rcx, r8
shl r9, cl
mov rcx, r9
mov QWORD PTR [p_temp_exp+rsp], rcx
mulsd xmm0, QWORD PTR [p_temp_exp+rsp]
orpd xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_sse2_z_denormal
ALIGN 16
Lpow_sse2_process_denormal_tiny:
movsd xmm0, QWORD PTR __real_smallest_denormal
orpd xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_sse2_z_denormal
ALIGN 16
Lpow_sse2_process_result_zero:
mov r11, QWORD PTR __real_zero
or r11, QWORD PTR [negate_result+rsp]
jmp Lpow_sse2_z_is_zero_or_inf
ALIGN 16
Lpow_sse2_process_result_inf:
mov r11, QWORD PTR __real_inf
or r11, QWORD PTR [negate_result+rsp]
jmp Lpow_sse2_z_is_zero_or_inf
ALIGN 16
Lpow_sse2_denormal_adjust:
por xmm2, XMMWORD PTR __real_one
subsd xmm2, QWORD PTR __real_one
movsd xmm5, xmm2
pand xmm2, XMMWORD PTR __real_mant
movd r8, xmm2
psrlq xmm5, 52
psubd xmm5, XMMWORD PTR __mask_2045
cvtdq2pd xmm6, xmm5
jmp Lpow_sse2_continue_common
ALIGN 16
Lpow_sse2_x_is_neg:
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __ay_max_bound
jg Lpow_sse2_ay_is_very_large
; determine if y is an integer
mov r10, QWORD PTR __exp_mant_mask
and r10, r8
mov r11, r10
mov rcx, QWORD PTR __exp_shift
shr r10, cl
sub r10, QWORD PTR __exp_bias
js Lpow_sse2_x_is_neg_y_is_not_int
mov rax, QWORD PTR __exp_mant_mask
and rax, rdx
mov QWORD PTR [save_ax+rsp], rax
mov rcx, r10
cmp r10, QWORD PTR __yexp_53
jg Lpow_sse2_continue_after_y_int_check
mov r9, QWORD PTR __mant_full
shr r9, cl
and r9, r11
jnz Lpow_sse2_x_is_neg_y_is_not_int
mov r9, QWORD PTR __1_before_mant
shr r9, cl
and r9, r11
jz Lpow_sse2_continue_after_y_int_check
mov rax, QWORD PTR __sign_mask
mov QWORD PTR [negate_result+rsp], rax
Lpow_sse2_continue_after_y_int_check:
cmp rdx, QWORD PTR __neg_zero
je Lpow_sse2_x_is_zero
cmp rdx, QWORD PTR __neg_one
je Lpow_sse2_x_is_neg_one
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_sse2_x_is_inf_or_nan
movsd xmm0, QWORD PTR [save_ax+rsp]
jmp Lpow_sse2_log_x
ALIGN 16
Lpow_sse2_near_one:
; f = F - Y, r = f * inv
movsd xmm0, xmm1
subsd xmm1, xmm2
movsd xmm4, xmm1
movsd xmm3, QWORD PTR [r9+r8*8]
addsd xmm3, QWORD PTR [rdx+r8*8]
mulsd xmm4, xmm3
andpd xmm4, QWORD PTR __real_fffffffff8000000
movsd xmm5, xmm4 ; r1
mulsd xmm4, xmm0
subsd xmm1, xmm4
mulsd xmm1, xmm3
movsd xmm7, xmm1 ; r2
addsd xmm1, xmm5
movsd xmm2, xmm1
movsd xmm0, xmm1
lea r9, __log_256_lead
; poly
movsd xmm3, QWORD PTR __real_1_over_7
movsd xmm1, QWORD PTR __real_1_over_4
mulsd xmm3, xmm2
mulsd xmm1, xmm2
mulsd xmm0, xmm2
movsd xmm4, xmm0
addsd xmm3, QWORD PTR __real_1_over_6
addsd xmm1, QWORD PTR __real_1_over_3
mulsd xmm4, xmm0
mulsd xmm3, xmm2
mulsd xmm1, xmm2
addsd xmm3, QWORD PTR __real_1_over_5
mulsd xmm3, xmm2
mulsd xmm1, xmm0
mulsd xmm3, xmm4
movsd xmm2, xmm5
movsd xmm0, xmm7
mulsd xmm0, xmm0
mulsd xmm0, QWORD PTR __real_1_over_2
mulsd xmm5, xmm7
addsd xmm5, xmm0
addsd xmm5, xmm7
movsd xmm0, xmm2
movsd xmm7, xmm2
mulsd xmm0, xmm0
mulsd xmm0, QWORD PTR __real_1_over_2
movsd xmm4, xmm0
addsd xmm2, xmm0 ; r1 + r1^2/2
subsd xmm7, xmm2
addsd xmm7, xmm4
addsd xmm3, xmm7
movsd xmm4, QWORD PTR __real_log2_tail
addsd xmm1, xmm3
mulsd xmm4, xmm6
lea rdx, __log_256_tail
addsd xmm1, xmm5
addsd xmm4, QWORD PTR [rdx+r8*8]
subsd xmm4, xmm1
movsd xmm3, xmm4
movsd xmm1, xmm4
subsd xmm3, xmm2
movsd xmm0, QWORD PTR [r9+r8*8]
movsd xmm7, QWORD PTR __real_log2_lead
mulsd xmm7, xmm6
addsd xmm0, xmm7
jmp Lpow_sse2_log_x_continue
ALIGN 16
Lpow_sse2_x_is_pos_one:
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_y_is_zero:
movsd xmm0, QWORD PTR __real_one
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_y_is_one:
xor rax, rax
mov r11, rdx
mov r9, QWORD PTR __exp_mask
;or r11, QWORD PTR __qnan_set
and r9, rdx
cmp r9, QWORD PTR __exp_mask
cmove rax, rdx
mov r9, QWORD PTR __mant_mask
and r9, rax
jnz Lpow_sse2_x_is_nan
movd xmm0, rdx
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_neg_one:
mov rdx, QWORD PTR __pos_one
or rdx, QWORD PTR [negate_result+rsp]
xor rax, rax
mov r11, r8
mov r10, QWORD PTR __exp_mask
;or r11, QWORD PTR __qnan_set
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
jnz Lpow_sse2_y_is_nan
movd xmm0, rdx
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_neg_y_is_not_int:
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_sse2_x_is_inf_or_nan
cmp rdx, QWORD PTR __neg_zero
je Lpow_sse2_x_is_zero
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
movsd xmm2, QWORD PTR __neg_qnan
mov r9d, DWORD PTR __flag_x_neg_y_notint
call fname_special
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_ay_is_very_large:
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_sse2_x_is_inf_or_nan
mov r9, QWORD PTR __exp_mant_mask
and r9, rdx
jz Lpow_sse2_x_is_zero
cmp rdx, QWORD PTR __neg_one
je Lpow_sse2_x_is_neg_one
mov r9, rdx
and r9, QWORD PTR __exp_mant_mask
cmp r9, QWORD PTR __pos_one
jl Lpow_sse2_ax_lt1_y_is_large_or_inf_or_nan
jmp Lpow_sse2_ax_gt1_y_is_large_or_inf_or_nan
ALIGN 16
Lpow_sse2_x_is_zero:
mov r10, QWORD PTR __exp_mask
xor rax, rax
and r10, r8
cmp r10, QWORD PTR __exp_mask
je Lpow_sse2_x_is_zero_y_is_inf_or_nan
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovnz rax, QWORD PTR __pos_inf
jnz Lpow_sse2_x_is_zero_z_is_inf
movd xmm0, rax
orpd xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_zero_z_is_inf:
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
movd xmm2, rax
orpd xmm2, XMMWORD PTR [negate_result+rsp]
mov r9d, DWORD PTR __flag_x_zero_z_inf
call fname_special
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_zero_y_is_inf_or_nan:
mov r11, r8
cmp r8, QWORD PTR __neg_inf
cmove rax, QWORD PTR __pos_inf
je Lpow_sse2_x_is_zero_z_is_inf
;or r11, QWORD PTR __qnan_set
mov r10, QWORD PTR __mant_mask
and r10, r8
jnz Lpow_sse2_y_is_nan
movd xmm0, rax
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_inf_or_nan:
xor r11, r11
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovz r11, QWORD PTR __pos_inf
mov rax, rdx
mov r9, QWORD PTR __mant_mask
;or rax, QWORD PTR __qnan_set
and r9, rdx
cmovnz r11, rax
jnz Lpow_sse2_x_is_nan
xor rax, rax
mov r9, r8
mov r10, QWORD PTR __exp_mask
;or r9, QWORD PTR __qnan_set
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
cmovnz r11, r9
jnz Lpow_sse2_y_is_nan
movd xmm0, r11
orpd xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_ay_is_very_small:
movsd xmm0, QWORD PTR __pos_one
addsd xmm0, xmm1
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_ax_lt1_y_is_large_or_inf_or_nan:
xor r11, r11
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovnz r11, QWORD PTR __pos_inf
jmp Lpow_sse2_adjust_for_nan
ALIGN 16
Lpow_sse2_ax_gt1_y_is_large_or_inf_or_nan:
xor r11, r11
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovz r11, QWORD PTR __pos_inf
ALIGN 16
Lpow_sse2_adjust_for_nan:
xor rax, rax
mov r9, r8
mov r10, QWORD PTR __exp_mask
;or r9, QWORD PTR __qnan_set
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
cmovnz r11, r9
jnz Lpow_sse2_y_is_nan
test rax, rax
jnz Lpow_sse2_y_is_inf
ALIGN 16
Lpow_sse2_z_is_zero_or_inf:
mov r9d, DWORD PTR __flag_z_zero
test r11, QWORD PTR __exp_mant_mask
cmovnz r9d, DWORD PTR __flag_z_inf
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
movd xmm2, r11
call fname_special
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_y_is_inf:
movd xmm0, r11
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_nan:
xor rax, rax
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
jnz Lpow_sse2_x_is_nan_y_is_nan
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
movd xmm2, r11
mov r9d, DWORD PTR __flag_x_nan
call fname_special
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_y_is_nan:
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
movd xmm2, r11
mov r9d, DWORD PTR __flag_y_nan
call fname_special
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_x_is_nan_y_is_nan:
mov r9, r8
cmp r11, QWORD PTR __ind_pattern
cmove r11, r9
je Lpow_sse2_continue_xy_nan
cmp r9, QWORD PTR __ind_pattern
cmove r9, r11
mov r10, r9
and r10, QWORD PTR __sign_mask
cmovnz r9, r11
mov r10, r11
and r10, QWORD PTR __sign_mask
cmovnz r11, r9
Lpow_sse2_continue_xy_nan:
;or r11, QWORD PTR __qnan_set
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
movd xmm2, r11
mov r9d, DWORD PTR __flag_x_nan_y_nan
call fname_special
jmp Lpow_sse2_final_check
ALIGN 16
Lpow_sse2_z_denormal:
movsd xmm2, xmm0
movsd xmm0, QWORD PTR [save_x+rsp]
movsd xmm1, QWORD PTR [save_y+rsp]
mov r9d, DWORD PTR __flag_z_denormal
call fname_special
jmp Lpow_sse2_final_check
Lpow_fma3:
vmovsd QWORD PTR [save_x+rsp], xmm0
vmovsd QWORD PTR [save_y+rsp], xmm1
mov rdx, QWORD PTR [save_x+rsp]
mov r8, QWORD PTR [save_y+rsp]
mov r10, QWORD PTR __exp_mant_mask
and r10, r8
jz Lpow_fma3_y_is_zero
cmp r8, QWORD PTR __pos_one
je Lpow_fma3_y_is_one
mov r9, QWORD PTR __sign_mask
and r9, rdx
cmp r9, QWORD PTR __sign_mask
mov rax, QWORD PTR __pos_zero
mov QWORD PTR [negate_result+rsp], rax
je Lpow_fma3_x_is_neg
cmp rdx, QWORD PTR __pos_one
je Lpow_fma3_x_is_pos_one
cmp rdx, QWORD PTR __pos_zero
je Lpow_fma3_x_is_zero
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_fma3_x_is_inf_or_nan
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __ay_max_bound
jg Lpow_fma3_ay_is_very_large
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __ay_min_bound
jl Lpow_fma3_ay_is_very_small
; -----------------------------
; compute log(x) here
; -----------------------------
Lpow_fma3_log_x:
; compute exponent part
vpsrlq xmm3, xmm0, 52
vmovq r8, xmm0
vpsubq xmm3, xmm3, XMMWORD PTR __mask_1023
vcvtdq2pd xmm6, xmm3 ; xexp
vpand xmm2, xmm0, XMMWORD PTR __real_mant
vcomisd xmm6, QWORD PTR __mask_1023_f
je Lpow_fma3_denormal_adjust
Lpow_fma3_continue_common:
; compute index into the log tables
mov r9, r8
and r8, QWORD PTR __mask_mant_all8
and r9, QWORD PTR __mask_mant9
vsubsd xmm7, xmm0, __real_one
shl r9, 1
add r8, r9
vmovq xmm1, r8
vandpd xmm7, xmm7, __real_notsign
; F, Y, switch to near-one codepath
shr r8, 44
vpor xmm2, xmm2, XMMWORD PTR __real_half
vpor xmm1, xmm1, XMMWORD PTR __real_half
vcomisd xmm7, __real_threshold
lea r9, QWORD PTR __log_F_inv_head
lea rdx, QWORD PTR __log_F_inv_tail
jb Lpow_fma3_near_one
; f = F - Y, r = f * inv
vsubsd xmm4, xmm1, xmm2 ; xmm4 <-- f = F - Y
vmulsd xmm1, xmm4, QWORD PTR [r9+r8*8] ; xmm1 <-- rhead = f*inv_head
vmovapd xmm5, xmm1 ; xmm5 <-- copy of rhead
vmulsd xmm4, xmm4, QWORD PTR [rdx+r8*8] ; xmm4 <-- rtail = f*inv_tail
vmovapd xmm7, xmm4 ; xmm7 <-- copy of rtail
vaddsd xmm1, xmm1, xmm4 ; xmm1 <-- r = rhead + rtail
vmovapd xmm2, xmm1 ; xmm2 <-- copy of r
vmovapd xmm0, xmm1 ; xmm1 <-- copy of r
lea r9, __log_256_lead
; poly
; movsd xmm3, QWORD PTR __real_1_over_6
; movsd xmm1, QWORD PTR __real_1_over_3
; mulsd xmm3, xmm2 ; r*1/6
; mulsd xmm1, xmm2 ; r*1/3
; mulsd xmm0, xmm2 ; r^2
; subsd xmm5, xmm2 ; xmm5 <-- rhead - r
; movsd xmm4, xmm0 ; xmm4 <-- copy of r^2
; addsd xmm3, QWORD PTR __real_1_over_5 ; xmm3 <-- r*1/6 + 1/5
; addsd xmm1, QWORD PTR __real_1_over_2 ; xmm1 <-- r*1/3 + 1/2
; mulsd xmm4, xmm0 ; xmm4 <-- r^4
; mulsd xmm3, xmm2 ; xmm3 <-- (r*1/6 + 1/5)*r
; mulsd xmm1, xmm0 ; xmm1 <-- (r*1/3 + 1/2)*r^2
; addsd xmm3, QWORD PTR __real_1_over_4 ; xmm3 <-- (r*1/6+1/5)*r + 1/4
; addsd xmm7, xmm5 ; xmm7 <-- rtail + (rhead - r)
; mulsd xmm3, xmm4 ; xmm3 <-- (r*1/6 + 1/5)*r^5 + r^4*1/4
; addsd xmm1, xmm3 ; xmm1 <-- poly down to r^2
; addsd xmm1, xmm7 ; xmm1 <-- poly + correction
vsubsd xmm3, xmm5, xmm2
vmovsd xmm1, QWORD PTR __real_1_over_6
vmulsd xmm0,xmm0,xmm0
vaddsd xmm3, xmm3, xmm7
vfmadd213sd xmm1, xmm2, QWORD PTR __real_1_over_5
vfmadd213sd xmm1, xmm2, QWORD PTR __real_1_over_4
vfmadd213sd xmm1, xmm2, QWORD PTR __real_1_over_3
vfmadd213sd xmm1, xmm2, QWORD PTR __real_1_over_2
vfmadd213sd xmm1, xmm0, xmm3
vmovsd xmm5, QWORD PTR __real_log2_tail
lea rdx, __log_256_tail
vfmsub213sd xmm5, xmm6, xmm1
vmovsd xmm0, QWORD PTR [r9+r8*8]
vaddsd xmm3, xmm5, QWORD PTR [rdx+r8*8]
vmovapd xmm1, xmm3
vsubsd xmm3, xmm3, xmm2
vfmadd231sd xmm0, xmm6, QWORD PTR __real_log2_lead
; result of ln(x) is computed from head and tail parts, resH and resT
; res = ln(x) = resH + resT
; resH and resT are in full precision
; resT is computed from head and tail parts, resT_h and resT_t
; resT = resT_h + resT_t
; now
; xmm3 - resT
; xmm0 - resH
; xmm1 - (resT_t)
; xmm2 - (-resT_h)
Lpow_fma3_log_x_continue:
vmovapd xmm7, xmm0
vaddsd xmm0, xmm0, xmm3
vmovapd xmm5, xmm0
vandpd xmm0, xmm0, XMMWORD PTR __real_fffffffff8000000
; xmm0 - H
; xmm7 - resH
; xmm5 - res
mov rax, QWORD PTR [save_y+rsp]
and rax, QWORD PTR __real_fffffffff8000000
vaddsd xmm2, xmm2, xmm3
vsubsd xmm7, xmm7, xmm5
vsubsd xmm1, xmm1, xmm2
vaddsd xmm7, xmm7, xmm3
vsubsd xmm5, xmm5, xmm0
mov QWORD PTR [y_head+rsp], rax
vmovsd xmm4, QWORD PTR [save_y+rsp]
vaddsd xmm7, xmm7, xmm1
vaddsd xmm7, xmm7, xmm5
; res = H + T
; H has leading 26 bits of precision
; T has full precision
; xmm0 - H
; xmm7 - T
vmovsd xmm2, QWORD PTR [y_head+rsp]
vsubsd xmm4, xmm4, xmm2
; y is split into head and tail
; for y * ln(x) computation
; xmm4 - Yt
; xmm2 - Yh
; xmm0 - H
; xmm7 - T
vmulsd xmm3, xmm4, xmm7 ; YtRt
vmulsd xmm4, xmm4, xmm0 ; YtRh
vmulsd xmm5, xmm7, xmm2 ; YhRt
vmulsd xmm6, xmm0, xmm2 ; YhRh
vmovapd xmm1, xmm6
vaddsd xmm3, xmm3, xmm4
vaddsd xmm3, xmm3, xmm5
vaddsd xmm1, xmm1, xmm3
vmovapd xmm0, xmm1
vsubsd xmm6, xmm6, xmm1
vaddsd xmm6, xmm6, xmm3
; y * ln(x) = v + vt
; v and vt are in full precision
; xmm0 - v
; xmm6 - vt
; -----------------------------
; compute exp( y * ln(x) ) here
; -----------------------------
; v * (64/ln(2))
vmovsd QWORD PTR [p_temp_exp+rsp], xmm0
vmulsd xmm7, xmm0, QWORD PTR __real_64_by_log2
mov rdx, QWORD PTR [p_temp_exp+rsp]
; v < 1024*ln(2), ( v * (64/ln(2)) ) < 64*1024
; v >= -1075*ln(2), ( v * (64/ln(2)) ) >= 64*(-1075)
vcomisd xmm7, QWORD PTR __real_p65536
ja Lpow_fma3_process_result_inf
vcomisd xmm7, QWORD PTR __real_m68800
jb Lpow_fma3_process_result_zero
; n = int( v * (64/ln(2)) )
vcvtpd2dq xmm4, xmm7
lea r10, __two_to_jby64_head_table
lea r11, __two_to_jby64_tail_table
vcvtdq2pd xmm1, xmm4
; r1 = x - n * ln(2)/64 head
vfnmadd231sd xmm0, xmm1, QWORD PTR __real_log2_by_64_head
vmovd ecx, xmm4
mov rax, 3fh
and eax, ecx
; r2 = - n * ln(2)/64 tail
vmulsd xmm1, xmm1, QWORD PTR __real_log2_by_64_tail
vmovapd xmm2, xmm0
; m = (n - j) / 64
sub ecx, eax
sar ecx, 6
; r1+r2
vaddsd xmm2, xmm2, xmm1
vaddsd xmm2, xmm2, xmm6 ; add vt here
vmovapd xmm1, xmm2
; q
vmovsd xmm0, QWORD PTR __real_1_by_720
xor r9d, r9d
vfmadd213sd xmm0, xmm2, QWORD PTR __real_1_by_120
cmp ecx, DWORD PTR __denormal_threshold
vfmadd213sd xmm0, xmm2, QWORD PTR __real_1_by_24
cmovle r9d, ecx
vfmadd213sd xmm0, xmm2, QWORD PTR __real_1_by_6
add rcx, 1023
vfmadd213sd xmm0, xmm2, QWORD PTR __real_1_by_2
shl rcx, 52
vfmadd213sd xmm0, xmm2, QWORD PTR __real_one
vmulsd xmm0, xmm0, xmm2 ; xmm0 <-- q
; movsd xmm0, QWORD PTR __real_1_by_2
; movsd xmm3, QWORD PTR __real_1_by_24
; movsd xmm4, QWORD PTR __real_1_by_720
; mulsd xmm1, xmm2 ; xmm1 <-- r^2
; mulsd xmm0, xmm2 ; xmm0 <-- r/2
; mulsd xmm3, xmm2 ; xmm3 <-- r/24
; mulsd xmm4, xmm2 ; xmm4 <-- r/720
; movsd xmm5, xmm1 ; xmm5 <-- copy of r^2
; mulsd xmm1, xmm2 ; xmm1 <-- r^3
; addsd xmm0, QWORD PTR __real_one ; xmm0 <-- r/2 + 1
; addsd xmm3, QWORD PTR __real_1_by_6 ; xmm3 <-- r/24 + 1/6
; mulsd xmm5, xmm1 ; xmm5 <-- r^5
; addsd xmm4, QWORD PTR __real_1_by_120 ; xmm4 <-- r/720 + 1/120
; mulsd xmm0, xmm2 ; xmm0 <-- (r/2 + 1)*r
; mulsd xmm3, xmm1 ; xmm3 <-- (r/24 + 1/6)*r^3
; mulsd xmm4, xmm5 ; xmm4 <-- (r/720 + 1/120)*r^5
; ; deal with denormal results
; xor r9d, r9d
; cmp ecx, DWORD PTR __denormal_threshold
; addsd xmm3, xmm4 ; xmm3 <-- (r/720 + 1/120)*r^5 + (r/24 + 1/6)*r^3
; addsd xmm0, xmm3 ; xmm0 <-- poly
; cmovle r9d, ecx
; add rcx, 1023
; shl rcx, 52
; f1, f2
vmulsd xmm5, xmm0, QWORD PTR [r11+rax*8]
vmulsd xmm1, xmm0, QWORD PTR [r10+rax*8]
cmp rcx, QWORD PTR __real_inf
; (f1+f2)*(1+q)
vaddsd xmm5, xmm5, QWORD PTR [r11+rax*8]
vaddsd xmm1, xmm1, xmm5
vaddsd xmm1, xmm1, QWORD PTR [r10+rax*8]
vmovapd xmm0, xmm1
je Lpow_fma3_process_almost_inf
test r9d, r9d
mov QWORD PTR [p_temp_exp+rsp], rcx
jnz Lpow_fma3_process_denormal
vmulsd xmm0, xmm0, QWORD PTR [p_temp_exp+rsp]
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
Lpow_fma3_final_check:
AVXRestoreXmm xmm7, save_xmm7
AVXRestoreXmm xmm6, save_xmm6
StackDeallocate stack_size
ret
ALIGN 16
Lpow_fma3_process_almost_inf:
vcomisd xmm0, QWORD PTR __real_one
jae Lpow_fma3_process_result_inf
vorpd xmm0, xmm0, XMMWORD PTR __enable_almost_inf
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_process_denormal:
mov ecx, r9d
xor r11d, r11d
vcomisd xmm0, QWORD PTR __real_one
cmovae r11d, ecx
cmp r11d, DWORD PTR __denormal_threshold
jne Lpow_fma3_process_true_denormal
vmulsd xmm0, xmm0, QWORD PTR [p_temp_exp+rsp]
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_process_true_denormal:
xor r8, r8
cmp rdx, QWORD PTR __denormal_tiny_threshold
mov r9, 1
jg Lpow_fma3_process_denormal_tiny
add ecx, 1074
cmovs rcx, r8
shl r9, cl
mov rcx, r9
mov QWORD PTR [p_temp_exp+rsp], rcx
vmulsd xmm0, xmm0, QWORD PTR [p_temp_exp+rsp]
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_fma3_z_denormal
ALIGN 16
Lpow_fma3_process_denormal_tiny:
vmovsd xmm0, QWORD PTR __real_smallest_denormal
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_fma3_z_denormal
ALIGN 16
Lpow_fma3_process_result_zero:
mov r11, QWORD PTR __real_zero
or r11, QWORD PTR [negate_result+rsp]
jmp Lpow_fma3_z_is_zero_or_inf
ALIGN 16
Lpow_fma3_process_result_inf:
mov r11, QWORD PTR __real_inf
or r11, QWORD PTR [negate_result+rsp]
jmp Lpow_fma3_z_is_zero_or_inf
ALIGN 16
Lpow_fma3_denormal_adjust:
vpor xmm2, xmm2, XMMWORD PTR __real_one
vsubsd xmm2, xmm2, QWORD PTR __real_one
vmovapd xmm5, xmm2
vpand xmm2, xmm2, XMMWORD PTR __real_mant
vmovq r8, xmm2
vpsrlq xmm5, xmm5, 52
vpsubd xmm5, xmm5, XMMWORD PTR __mask_2045
vcvtdq2pd xmm6, xmm5
jmp Lpow_fma3_continue_common
ALIGN 16
Lpow_fma3_x_is_neg:
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __ay_max_bound
jg Lpow_fma3_ay_is_very_large
; determine if y is an integer
mov r10, QWORD PTR __exp_mant_mask
and r10, r8
mov r11, r10
mov rcx, QWORD PTR __exp_shift
shr r10, cl
sub r10, QWORD PTR __exp_bias
js Lpow_fma3_x_is_neg_y_is_not_int
mov rax, QWORD PTR __exp_mant_mask
and rax, rdx
mov QWORD PTR [save_ax+rsp], rax
cmp r10, QWORD PTR __yexp_53
mov rcx, r10
jg Lpow_fma3_continue_after_y_int_check
mov r9, QWORD PTR __mant_full
shr r9, cl
and r9, r11
jnz Lpow_fma3_x_is_neg_y_is_not_int
mov r9, QWORD PTR __1_before_mant
shr r9, cl
and r9, r11
jz Lpow_fma3_continue_after_y_int_check
mov rax, QWORD PTR __sign_mask
mov QWORD PTR [negate_result+rsp], rax
Lpow_fma3_continue_after_y_int_check:
cmp rdx, QWORD PTR __neg_zero
je Lpow_fma3_x_is_zero
cmp rdx, QWORD PTR __neg_one
je Lpow_fma3_x_is_neg_one
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_fma3_x_is_inf_or_nan
vmovsd xmm0, QWORD PTR [save_ax+rsp]
jmp Lpow_fma3_log_x
ALIGN 16
Lpow_fma3_near_one:
; f = F - Y, r = f * inv
vmovapd xmm0, xmm1
vsubsd xmm1, xmm1, xmm2 ; xmm1 <-- f
vmovapd xmm4, xmm1 ; xmm4 <-- copy of f
vmovsd xmm3, QWORD PTR [r9+r8*8]
vaddsd xmm3, xmm3, QWORD PTR [rdx+r8*8]
vmulsd xmm4, xmm4, xmm3 ; xmm4 <-- r = f*inv
vandpd xmm4, xmm4, QWORD PTR __real_fffffffff8000000 ; r1
vmovapd xmm5, xmm4 ; xmm5 <-- copy of r1
; mulsd xmm4, xmm0 ; xmm4 <-- F*r1
; subsd xmm1, xmm4 ; xmm1 <-- f - F*r1
vfnmadd231sd xmm1, xmm4, xmm0 ; xmm1 <-- f - F*r1
vmulsd xmm1, xmm1, xmm3 ; xmm1 <-- r2 = (f - F*r1)*inv
vmovapd xmm7, xmm1 ; xmm7 <-- copy of r2
vaddsd xmm1, xmm1, xmm5 ; xmm1 <-- r = r1 + r2
vmovapd xmm2, xmm1 ; xmm2 <-- copy of r
vmovapd xmm0, xmm1 ; xmm0 <-- copy of r
lea r9, __log_256_lead
; poly
; NOTE: Given the complicated corrections here,
; I'm afraid to mess with it too much - WAT
vmovsd xmm3, QWORD PTR __real_1_over_7
vmovsd xmm1, QWORD PTR __real_1_over_4
vmulsd xmm0, xmm0, xmm2 ; xmm0 <-- r^2
vmovapd xmm4, xmm0 ; xmm4 <-- copy of r^2
vfmadd213sd xmm3, xmm2, QWORD PTR __real_1_over_6 ; xmm3 <-- r/7 + 1/6
vfmadd213sd xmm1, xmm2, QWORD PTR __real_1_over_3 ; xmm1 <-- r/4 + 1/3
vmulsd xmm4, xmm4, xmm0 ; xmm4 <-- r^4
vmulsd xmm1, xmm1, xmm2 ; xmm1 <-- (r/4 + 1/3)*r
vfmadd213sd xmm3, xmm2, QWORD PTR __real_1_over_5 ; xmm3 <-- ((r/7 + 1/6)*r) + 1/5
vmulsd xmm3, xmm3, xmm2 ; xmm3 <-- (((r/7 + 1/6)*r) + 1/5)*r
vmulsd xmm1, xmm1, xmm0 ; xmm1 <-- ((r/4 + 1/3)*r)*r^2
vmulsd xmm3, xmm3, xmm4 ; xmm3 <-- ((((r/7 + 1/6)*r) + 1/5)*r)*r^4
vmovapd xmm2, xmm5 ; xmm2 <-- copy of r1
vmovapd xmm0, xmm7 ; xmm0 <-- copy of r2
vmulsd xmm0, xmm0, xmm0 ; xmm0 <-- r2^2
vmulsd xmm0, xmm0, QWORD PTR __real_1_over_2 ; xmm0 <-- r2^2/2
; mulsd xmm5, xmm7 ; xmm5 <-- r1*r2
; addsd xmm5, xmm0 ; xmm5 <-- r1*r2 + r2^2^2
vfmadd213sd xmm5, xmm7, xmm0 ; xmm5 <-- r1*r2 + r2^2^2
vaddsd xmm5, xmm5, xmm7 ; xmm5 <-- r1*r2 + r2^2/2 + r2
vmovapd xmm0, xmm2 ; xmm0 <-- copy of r1
vmovapd xmm7, xmm2 ; xmm7 <-- copy of r1
vmulsd xmm0, xmm0, xmm0 ; xmm0 <-- r1^2
vmulsd xmm0, xmm0, QWORD PTR __real_1_over_2 ; xmm0 <-- r1^2/2
vmovapd xmm4, xmm0 ; xmm4 <-- copy of r1^2/2
vaddsd xmm2, xmm2, xmm0 ; xmm2 <-- r1 + r1^2/2
vsubsd xmm7, xmm7, xmm2 ; xmm7 <-- r1 - (r1 + r1^2/2)
vaddsd xmm7, xmm7, xmm4 ; xmm7 <-- r1 - (r1 + r1^2/2) + r1^2/2
; xmm3 <-- ((((r/7 + 1/6)*r) + 1/5)*r)*r^4 + r1 - (r1 + r1^2/2) + r1^2/2
vaddsd xmm3, xmm3, xmm7
vmovsd xmm4, QWORD PTR __real_log2_tail
; xmm1 <-- (((((r/7 + 1/6)*r) + 1/5)*r)*r^4) +
; (r1 - (r1 + r1^2/2) + r1^2/2) + ((r/4 + 1/3)*r)*r^2)
vaddsd xmm1, xmm1, xmm3
lea rdx, __log_256_tail
; xmm1 <-- ((((((r/7 + 1/6)*r) + 1/5)*r)*r^4) +
; (r1 - (r1 + r1^2/2) + r1^2/2) + ((r/4 + 1/3)*r)*r^2))
; +(r1*r2 + r2^2/2 + r2)
vaddsd xmm1, xmm1, xmm5
; xmm4 <-- vt * log2_tail + log256_tail
vfmadd213sd xmm4, xmm6, QWORD PTR [rdx+r8*8]
; xmm4 <-- vt * log2_tail + log2_tail - corrected poly
vsubsd xmm4, xmm4, xmm1
vmovapd xmm1, xmm4
vsubsd xmm3, xmm4, xmm2 ; xmm3 <-- xmm4 - more correction???
vmovsd xmm0, QWORD PTR [r9+r8*8] ; xmm0 <-- log256_lead
; xmm0 <-- log256_lead + vt*log2_lead
vfmadd231sd xmm0, xmm6, QWORD PTR __real_log2_lead
; at this point, xmm0, xmm1, xmm2, and xmm3 should matter
jmp Lpow_fma3_log_x_continue
ALIGN 16
Lpow_fma3_x_is_pos_one:
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_y_is_zero:
vmovsd xmm0, QWORD PTR __real_one
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_y_is_one:
xor rax, rax
mov r11, rdx
mov r9, QWORD PTR __exp_mask
;or r11, QWORD PTR __qnan_set
and r9, rdx
cmp r9, QWORD PTR __exp_mask
cmove rax, rdx
mov r9, QWORD PTR __mant_mask
and r9, rax
jnz Lpow_fma3_x_is_nan
vmovq xmm0, rdx
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_neg_one:
mov rdx, QWORD PTR __pos_one
or rdx, QWORD PTR [negate_result+rsp]
xor rax, rax
mov r11, r8
mov r10, QWORD PTR __exp_mask
;or r11, QWORD PTR __qnan_set
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
jnz Lpow_fma3_y_is_nan
vmovq xmm0, rdx
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_neg_y_is_not_int:
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_fma3_x_is_inf_or_nan
cmp rdx, QWORD PTR __neg_zero
je Lpow_fma3_x_is_zero
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
vmovsd xmm2, QWORD PTR __neg_qnan
mov r9d, DWORD PTR __flag_x_neg_y_notint
call fname_special
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_ay_is_very_large:
mov r9, QWORD PTR __exp_mask
and r9, rdx
cmp r9, QWORD PTR __exp_mask
je Lpow_fma3_x_is_inf_or_nan
mov r9, QWORD PTR __exp_mant_mask
and r9, rdx
jz Lpow_fma3_x_is_zero
cmp rdx, QWORD PTR __neg_one
je Lpow_fma3_x_is_neg_one
mov r9, rdx
and r9, QWORD PTR __exp_mant_mask
cmp r9, QWORD PTR __pos_one
jl Lpow_fma3_ax_lt1_y_is_large_or_inf_or_nan
jmp Lpow_fma3_ax_gt1_y_is_large_or_inf_or_nan
ALIGN 16
Lpow_fma3_x_is_zero:
mov r10, QWORD PTR __exp_mask
xor rax, rax
and r10, r8
cmp r10, QWORD PTR __exp_mask
je Lpow_fma3_x_is_zero_y_is_inf_or_nan
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovnz rax, QWORD PTR __pos_inf
jnz Lpow_fma3_x_is_zero_z_is_inf
vmovq xmm0, rax
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_zero_z_is_inf:
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
vmovq xmm2, rax
vorpd xmm2, xmm2, XMMWORD PTR [negate_result+rsp]
mov r9d, DWORD PTR __flag_x_zero_z_inf
call fname_special
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_zero_y_is_inf_or_nan:
mov r11, r8
cmp r8, QWORD PTR __neg_inf
; The next two lines do not correspond to IEEE754-2008.
; +-0 ^ -Inf should be +Inf with no exception
; +-0 ^ +Inf should be +0 with no exception
; cmove rax, QWORD PTR __pos_inf
; je Lpow_fma3_x_is_zero_z_is_inf
; begin replacement
je Lpow_fma3_x_is_zero_y_is_neg_inf
cmp r8, QWORD PTR __neg_inf
je Lpow_fma3_x_is_zero_y_is_pos_inf
; end replacement
;or r11, QWORD PTR __qnan_set
mov r10, QWORD PTR __mant_mask
and r10, r8
jnz Lpow_fma3_y_is_nan
vmovq xmm0, rax
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_zero_y_is_neg_inf:
; quietly return +Inf
vmovsd xmm0, __pos_inf
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_zero_y_is_pos_inf:
; quietly return +0.
vxorpd xmm0, xmm0, xmm0
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_inf_or_nan:
xor r11, r11
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovz r11, QWORD PTR __pos_inf
mov rax, rdx
mov r9, QWORD PTR __mant_mask
;or rax, QWORD PTR __qnan_set
and r9, rdx
cmovnz r11, rax
jnz Lpow_fma3_x_is_nan
xor rax, rax
mov r9, r8
mov r10, QWORD PTR __exp_mask
;or r9, QWORD PTR __qnan_set
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
cmovnz r11, r9
jnz Lpow_fma3_y_is_nan
vmovq xmm0, r11
vorpd xmm0, xmm0, XMMWORD PTR [negate_result+rsp]
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_ay_is_very_small:
vaddsd xmm0, xmm1, QWORD PTR __pos_one
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_ax_lt1_y_is_large_or_inf_or_nan:
xor r11, r11
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovnz r11, QWORD PTR __pos_inf
jmp Lpow_fma3_adjust_for_nan
ALIGN 16
Lpow_fma3_ax_gt1_y_is_large_or_inf_or_nan:
xor r11, r11
mov r10, QWORD PTR __sign_mask
and r10, r8
cmovz r11, QWORD PTR __pos_inf
ALIGN 16
Lpow_fma3_adjust_for_nan:
xor rax, rax
mov r9, r8
mov r10, QWORD PTR __exp_mask
;or r9, QWORD PTR __qnan_set
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
cmovnz r11, r9
jnz Lpow_fma3_y_is_nan
test rax, rax
jnz Lpow_fma3_y_is_inf
ALIGN 16
Lpow_fma3_z_is_zero_or_inf:
mov r9d, DWORD PTR __flag_z_zero
test r11, QWORD PTR __exp_mant_mask
cmovnz r9d, DWORD PTR __flag_z_inf
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
vmovq xmm2, r11
call fname_special
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_y_is_inf:
vmovq xmm0, r11
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_nan:
xor rax, rax
mov r10, QWORD PTR __exp_mask
and r10, r8
cmp r10, QWORD PTR __exp_mask
cmove rax, r8
mov r10, QWORD PTR __mant_mask
and r10, rax
jnz Lpow_fma3_x_is_nan_y_is_nan
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
vmovq xmm2, r11
mov r9d, DWORD PTR __flag_x_nan
call fname_special
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_y_is_nan:
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
vmovq xmm2, r11
mov r9d, DWORD PTR __flag_y_nan
call fname_special
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_x_is_nan_y_is_nan:
mov r9, r8
cmp r11, QWORD PTR __ind_pattern
cmove r11, r9
je Lpow_fma3_continue_xy_nan
cmp r9, QWORD PTR __ind_pattern
cmove r9, r11
mov r10, r9
and r10, QWORD PTR __sign_mask
cmovnz r9, r11
mov r10, r11
and r10, QWORD PTR __sign_mask
cmovnz r11, r9
Lpow_fma3_continue_xy_nan:
;or r11, QWORD PTR __qnan_set
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
vmovq xmm2, r11
mov r9d, DWORD PTR __flag_x_nan_y_nan
call fname_special
jmp Lpow_fma3_final_check
ALIGN 16
Lpow_fma3_z_denormal:
vmovapd xmm2, xmm0
vmovsd xmm0, QWORD PTR [save_x+rsp]
vmovsd xmm1, QWORD PTR [save_y+rsp]
mov r9d, DWORD PTR __flag_z_denormal
call fname_special
jmp Lpow_fma3_final_check
fname endp
END