Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 1 | // Copyright 2017 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | #include "textflag.h" |
| 6 | |
| 7 | #define PosInf 0x7FF0000000000000 |
| 8 | #define NaN 0x7FF8000000000001 |
| 9 | #define NegInf 0xFFF0000000000000 |
| 10 | #define PosOne 0x3FF0000000000000 |
| 11 | #define NegOne 0xBFF0000000000000 |
| 12 | #define NegZero 0x8000000000000000 |
| 13 | |
| 14 | // Minimax polynomial approximation |
| 15 | DATA ·powrodataL51<> + 0(SB)/8, $-1.0 |
| 16 | DATA ·powrodataL51<> + 8(SB)/8, $1.0 |
| 17 | DATA ·powrodataL51<> + 16(SB)/8, $0.24022650695910110361E+00 |
| 18 | DATA ·powrodataL51<> + 24(SB)/8, $0.69314718055994686185E+00 |
| 19 | DATA ·powrodataL51<> + 32(SB)/8, $0.96181291057109484809E-02 |
| 20 | DATA ·powrodataL51<> + 40(SB)/8, $0.15403814778342868389E-03 |
| 21 | DATA ·powrodataL51<> + 48(SB)/8, $0.55504108652095235601E-01 |
| 22 | DATA ·powrodataL51<> + 56(SB)/8, $0.13333818813168698658E-02 |
| 23 | DATA ·powrodataL51<> + 64(SB)/8, $0.68205322933914439200E-12 |
| 24 | DATA ·powrodataL51<> + 72(SB)/8, $-.18466496523378731640E-01 |
| 25 | DATA ·powrodataL51<> + 80(SB)/8, $0.19697596291603973706E-02 |
| 26 | DATA ·powrodataL51<> + 88(SB)/8, $0.23083120654155209200E+00 |
| 27 | DATA ·powrodataL51<> + 96(SB)/8, $0.55324356012093416771E-06 |
| 28 | DATA ·powrodataL51<> + 104(SB)/8, $-.40340677224649339048E-05 |
| 29 | DATA ·powrodataL51<> + 112(SB)/8, $0.30255507904062541562E-04 |
| 30 | DATA ·powrodataL51<> + 120(SB)/8, $-.77453979912413008787E-07 |
| 31 | DATA ·powrodataL51<> + 128(SB)/8, $-.23637115549923464737E-03 |
| 32 | DATA ·powrodataL51<> + 136(SB)/8, $0.11016119077267717198E-07 |
| 33 | DATA ·powrodataL51<> + 144(SB)/8, $0.22608272174486123035E-09 |
| 34 | DATA ·powrodataL51<> + 152(SB)/8, $-.15895808101370190382E-08 |
| 35 | DATA ·powrodataL51<> + 160(SB)/8, $0x4540190000000000 |
| 36 | GLOBL ·powrodataL51<> + 0(SB), RODATA, $168 |
| 37 | |
| 38 | // Constants |
| 39 | DATA ·pow_x001a<> + 0(SB)/8, $0x1a000000000000 |
| 40 | GLOBL ·pow_x001a<> + 0(SB), RODATA, $8 |
| 41 | DATA ·pow_xinf<> + 0(SB)/8, $0x7ff0000000000000 //+Inf |
| 42 | GLOBL ·pow_xinf<> + 0(SB), RODATA, $8 |
| 43 | DATA ·pow_xnan<> + 0(SB)/8, $0x7ff8000000000000 //NaN |
| 44 | GLOBL ·pow_xnan<> + 0(SB), RODATA, $8 |
| 45 | DATA ·pow_x434<> + 0(SB)/8, $0x4340000000000000 |
| 46 | GLOBL ·pow_x434<> + 0(SB), RODATA, $8 |
| 47 | DATA ·pow_x433<> + 0(SB)/8, $0x4330000000000000 |
| 48 | GLOBL ·pow_x433<> + 0(SB), RODATA, $8 |
| 49 | DATA ·pow_x43f<> + 0(SB)/8, $0x43f0000000000000 |
| 50 | GLOBL ·pow_x43f<> + 0(SB), RODATA, $8 |
| 51 | DATA ·pow_xadd<> + 0(SB)/8, $0xc2f0000100003fef |
| 52 | GLOBL ·pow_xadd<> + 0(SB), RODATA, $8 |
| 53 | DATA ·pow_xa<> + 0(SB)/8, $0x4019000000000000 |
| 54 | GLOBL ·pow_xa<> + 0(SB), RODATA, $8 |
| 55 | |
| 56 | // Scale correction tables |
| 57 | DATA powiadd<> + 0(SB)/8, $0xf000000000000000 |
| 58 | DATA powiadd<> + 8(SB)/8, $0x1000000000000000 |
| 59 | GLOBL powiadd<> + 0(SB), RODATA, $16 |
| 60 | DATA powxscale<> + 0(SB)/8, $0x4ff0000000000000 |
| 61 | DATA powxscale<> + 8(SB)/8, $0x2ff0000000000000 |
| 62 | GLOBL powxscale<> + 0(SB), RODATA, $16 |
| 63 | |
| 64 | // Fractional powers of 2 table |
| 65 | DATA ·powtexp<> + 0(SB)/8, $0.442737824274138381E-01 |
| 66 | DATA ·powtexp<> + 8(SB)/8, $0.263602189790660309E-01 |
| 67 | DATA ·powtexp<> + 16(SB)/8, $0.122565642281703586E-01 |
| 68 | DATA ·powtexp<> + 24(SB)/8, $0.143757052860721398E-02 |
| 69 | DATA ·powtexp<> + 32(SB)/8, $-.651375034121276075E-02 |
| 70 | DATA ·powtexp<> + 40(SB)/8, $-.119317678849450159E-01 |
| 71 | DATA ·powtexp<> + 48(SB)/8, $-.150868749549871069E-01 |
| 72 | DATA ·powtexp<> + 56(SB)/8, $-.161992609578469234E-01 |
| 73 | DATA ·powtexp<> + 64(SB)/8, $-.154492360403337917E-01 |
| 74 | DATA ·powtexp<> + 72(SB)/8, $-.129850717389178721E-01 |
| 75 | DATA ·powtexp<> + 80(SB)/8, $-.892902649276657891E-02 |
| 76 | DATA ·powtexp<> + 88(SB)/8, $-.338202636596794887E-02 |
| 77 | DATA ·powtexp<> + 96(SB)/8, $0.357266307045684762E-02 |
| 78 | DATA ·powtexp<> + 104(SB)/8, $0.118665304327406698E-01 |
| 79 | DATA ·powtexp<> + 112(SB)/8, $0.214434994118118914E-01 |
| 80 | DATA ·powtexp<> + 120(SB)/8, $0.322580645161290314E-01 |
| 81 | GLOBL ·powtexp<> + 0(SB), RODATA, $128 |
| 82 | |
| 83 | // Log multiplier tables |
| 84 | DATA ·powtl<> + 0(SB)/8, $0xbdf9723a80db6a05 |
| 85 | DATA ·powtl<> + 8(SB)/8, $0x3e0cfe4a0babe862 |
| 86 | DATA ·powtl<> + 16(SB)/8, $0xbe163b42dd33dada |
| 87 | DATA ·powtl<> + 24(SB)/8, $0xbe0cdf9de2a8429c |
| 88 | DATA ·powtl<> + 32(SB)/8, $0xbde9723a80db6a05 |
| 89 | DATA ·powtl<> + 40(SB)/8, $0xbdb37fcae081745e |
| 90 | DATA ·powtl<> + 48(SB)/8, $0xbdd8b2f901ac662c |
| 91 | DATA ·powtl<> + 56(SB)/8, $0xbde867dc68c36cc9 |
| 92 | DATA ·powtl<> + 64(SB)/8, $0xbdd23e36b47256b7 |
| 93 | DATA ·powtl<> + 72(SB)/8, $0xbde4c9b89fcc7933 |
| 94 | DATA ·powtl<> + 80(SB)/8, $0xbdd16905cad7cf66 |
| 95 | DATA ·powtl<> + 88(SB)/8, $0x3ddb417414aa5529 |
| 96 | DATA ·powtl<> + 96(SB)/8, $0xbdce046f2889983c |
| 97 | DATA ·powtl<> + 104(SB)/8, $0x3dc2c3865d072897 |
| 98 | DATA ·powtl<> + 112(SB)/8, $0x8000000000000000 |
| 99 | DATA ·powtl<> + 120(SB)/8, $0x3dc1ca48817f8afe |
| 100 | DATA ·powtl<> + 128(SB)/8, $0xbdd703518a88bfb7 |
| 101 | DATA ·powtl<> + 136(SB)/8, $0x3dc64afcc46942ce |
| 102 | DATA ·powtl<> + 144(SB)/8, $0xbd9d79191389891a |
| 103 | DATA ·powtl<> + 152(SB)/8, $0x3ddd563044da4fa0 |
| 104 | DATA ·powtl<> + 160(SB)/8, $0x3e0f42b5e5f8f4b6 |
| 105 | DATA ·powtl<> + 168(SB)/8, $0x3e0dfa2c2cbf6ead |
| 106 | DATA ·powtl<> + 176(SB)/8, $0x3e14e25e91661293 |
| 107 | DATA ·powtl<> + 184(SB)/8, $0x3e0aac461509e20c |
| 108 | GLOBL ·powtl<> + 0(SB), RODATA, $192 |
| 109 | |
| 110 | DATA ·powtm<> + 0(SB)/8, $0x3da69e13 |
| 111 | DATA ·powtm<> + 8(SB)/8, $0x100003d66fcb6 |
| 112 | DATA ·powtm<> + 16(SB)/8, $0x200003d1538df |
| 113 | DATA ·powtm<> + 24(SB)/8, $0x300003cab729e |
| 114 | DATA ·powtm<> + 32(SB)/8, $0x400003c1a784c |
| 115 | DATA ·powtm<> + 40(SB)/8, $0x500003ac9b074 |
| 116 | DATA ·powtm<> + 48(SB)/8, $0x60000bb498d22 |
| 117 | DATA ·powtm<> + 56(SB)/8, $0x68000bb8b29a2 |
| 118 | DATA ·powtm<> + 64(SB)/8, $0x70000bb9a32d4 |
| 119 | DATA ·powtm<> + 72(SB)/8, $0x74000bb9946bb |
| 120 | DATA ·powtm<> + 80(SB)/8, $0x78000bb92e34b |
| 121 | DATA ·powtm<> + 88(SB)/8, $0x80000bb6c57dc |
| 122 | DATA ·powtm<> + 96(SB)/8, $0x84000bb4020f7 |
| 123 | DATA ·powtm<> + 104(SB)/8, $0x8c000ba93832d |
| 124 | DATA ·powtm<> + 112(SB)/8, $0x9000080000000 |
| 125 | DATA ·powtm<> + 120(SB)/8, $0x940003aa66c4c |
| 126 | DATA ·powtm<> + 128(SB)/8, $0x980003b2fb12a |
| 127 | DATA ·powtm<> + 136(SB)/8, $0xa00003bc1def6 |
| 128 | DATA ·powtm<> + 144(SB)/8, $0xa80003c1eb0eb |
| 129 | DATA ·powtm<> + 152(SB)/8, $0xb00003c64dcec |
| 130 | DATA ·powtm<> + 160(SB)/8, $0xc00003cc49e4e |
| 131 | DATA ·powtm<> + 168(SB)/8, $0xd00003d12f1de |
| 132 | DATA ·powtm<> + 176(SB)/8, $0xe00003d4a9c6f |
| 133 | DATA ·powtm<> + 184(SB)/8, $0xf00003d846c66 |
| 134 | GLOBL ·powtm<> + 0(SB), RODATA, $192 |
| 135 | |
| 136 | // Table of indeces into multiplier tables |
| 137 | // Adjusted from asm to remove offset and convert |
| 138 | DATA ·powtabi<> + 0(SB)/8, $0x1010101 |
| 139 | DATA ·powtabi<> + 8(SB)/8, $0x101020202020203 |
| 140 | DATA ·powtabi<> + 16(SB)/8, $0x303030404040405 |
| 141 | DATA ·powtabi<> + 24(SB)/8, $0x505050606060708 |
| 142 | DATA ·powtabi<> + 32(SB)/8, $0x90a0b0c0d0e0f10 |
| 143 | DATA ·powtabi<> + 40(SB)/8, $0x1011111212121313 |
| 144 | DATA ·powtabi<> + 48(SB)/8, $0x1314141414151515 |
| 145 | DATA ·powtabi<> + 56(SB)/8, $0x1516161617171717 |
| 146 | GLOBL ·powtabi<> + 0(SB), RODATA, $64 |
| 147 | |
| 148 | // Pow returns x**y, the base-x exponential of y. |
| 149 | // |
| 150 | // Special cases are (in order): |
| 151 | // Pow(x, ±0) = 1 for any x |
| 152 | // Pow(1, y) = 1 for any y |
| 153 | // Pow(x, 1) = x for any x |
| 154 | // Pow(NaN, y) = NaN |
| 155 | // Pow(x, NaN) = NaN |
| 156 | // Pow(±0, y) = ±Inf for y an odd integer < 0 |
| 157 | // Pow(±0, -Inf) = +Inf |
| 158 | // Pow(±0, +Inf) = +0 |
| 159 | // Pow(±0, y) = +Inf for finite y < 0 and not an odd integer |
| 160 | // Pow(±0, y) = ±0 for y an odd integer > 0 |
| 161 | // Pow(±0, y) = +0 for finite y > 0 and not an odd integer |
| 162 | // Pow(-1, ±Inf) = 1 |
| 163 | // Pow(x, +Inf) = +Inf for |x| > 1 |
| 164 | // Pow(x, -Inf) = +0 for |x| > 1 |
| 165 | // Pow(x, +Inf) = +0 for |x| < 1 |
| 166 | // Pow(x, -Inf) = +Inf for |x| < 1 |
| 167 | // Pow(+Inf, y) = +Inf for y > 0 |
| 168 | // Pow(+Inf, y) = +0 for y < 0 |
| 169 | // Pow(-Inf, y) = Pow(-0, -y) |
| 170 | // Pow(x, y) = NaN for finite x < 0 and finite non-integer y |
| 171 | |
| 172 | TEXT ·powAsm(SB), NOSPLIT, $0-24 |
| 173 | // special case |
| 174 | MOVD x+0(FP), R1 |
| 175 | MOVD y+8(FP), R2 |
| 176 | |
| 177 | // special case Pow(1, y) = 1 for any y |
| 178 | MOVD $PosOne, R3 |
| 179 | CMPUBEQ R1, R3, xIsOne |
| 180 | |
| 181 | // special case Pow(x, 1) = x for any x |
| 182 | MOVD $PosOne, R4 |
| 183 | CMPUBEQ R2, R4, yIsOne |
| 184 | |
| 185 | // special case Pow(x, NaN) = NaN for any x |
| 186 | MOVD $~(1<<63), R5 |
| 187 | AND R2, R5 // y = |y| |
| 188 | MOVD $PosInf, R4 |
| 189 | CMPUBLT R4, R5, yIsNan |
| 190 | |
| 191 | MOVD $NegInf, R3 |
| 192 | CMPUBEQ R1, R3, xIsNegInf |
| 193 | |
| 194 | MOVD $NegOne, R3 |
| 195 | CMPUBEQ R1, R3, xIsNegOne |
| 196 | |
| 197 | MOVD $PosInf, R3 |
| 198 | CMPUBEQ R1, R3, xIsPosInf |
| 199 | |
| 200 | MOVD $NegZero, R3 |
| 201 | CMPUBEQ R1, R3, xIsNegZero |
| 202 | |
| 203 | MOVD $PosInf, R4 |
| 204 | CMPUBEQ R2, R4, yIsPosInf |
| 205 | |
| 206 | MOVD $0x0, R3 |
| 207 | CMPUBEQ R1, R3, xIsPosZero |
| 208 | CMPBLT R1, R3, xLtZero |
| 209 | BR Normal |
| 210 | xIsPosInf: |
| 211 | // special case Pow(+Inf, y) = +Inf for y > 0 |
| 212 | MOVD $0x0, R4 |
| 213 | CMPBGT R2, R4, posInfGeZero |
| 214 | BR Normal |
| 215 | xIsNegInf: |
| 216 | //Pow(-Inf, y) = Pow(-0, -y) |
| 217 | FMOVD y+8(FP), F2 |
| 218 | FNEG F2, F2 // y = -y |
| 219 | BR negZeroNegY // call Pow(-0, -y) |
| 220 | xIsNegOne: |
| 221 | // special case Pow(-1, ±Inf) = 1 |
| 222 | MOVD $PosInf, R4 |
| 223 | CMPUBEQ R2, R4, negOnePosInf |
| 224 | MOVD $NegInf, R4 |
| 225 | CMPUBEQ R2, R4, negOneNegInf |
| 226 | BR Normal |
| 227 | xIsPosZero: |
| 228 | // special case Pow(+0, -Inf) = +Inf |
| 229 | MOVD $NegInf, R4 |
| 230 | CMPUBEQ R2, R4, zeroNegInf |
| 231 | |
| 232 | // special case Pow(+0, y < 0) = +Inf |
| 233 | FMOVD y+8(FP), F2 |
| 234 | FMOVD $(0.0), F4 |
| 235 | FCMPU F2, F4 |
| 236 | BLT posZeroLtZero //y < 0.0 |
| 237 | BR Normal |
| 238 | xIsNegZero: |
| 239 | // special case Pow(-0, -Inf) = +Inf |
| 240 | MOVD $NegInf, R4 |
| 241 | CMPUBEQ R2, R4, zeroNegInf |
| 242 | FMOVD y+8(FP), F2 |
| 243 | negZeroNegY: |
| 244 | // special case Pow(x, ±0) = 1 for any x |
| 245 | FMOVD $(0.0), F4 |
| 246 | FCMPU F4, F2 |
| 247 | BLT negZeroGtZero // y > 0.0 |
| 248 | BEQ yIsZero // y = 0.0 |
| 249 | |
| 250 | FMOVD $(-0.0), F4 |
| 251 | FCMPU F4, F2 |
| 252 | BLT negZeroGtZero // y > -0.0 |
| 253 | BEQ yIsZero // y = -0.0 |
| 254 | |
| 255 | // special case Pow(-0, y) = -Inf for y an odd integer < 0 |
| 256 | // special case Pow(-0, y) = +Inf for finite y < 0 and not an odd integer |
| 257 | FIDBR $5, F2, F4 //F2 translate to integer F4 |
| 258 | FCMPU F2, F4 |
| 259 | BNE zeroNotOdd // y is not an (odd) integer and y < 0 |
| 260 | FMOVD $(2.0), F4 |
| 261 | FDIV F4, F2 // F2 = F2 / 2.0 |
| 262 | FIDBR $5, F2, F4 //F2 translate to integer F4 |
| 263 | FCMPU F2, F4 |
| 264 | BNE negZeroOddInt // y is an odd integer and y < 0 |
| 265 | BR zeroNotOdd // y is not an (odd) integer and y < 0 |
| 266 | |
| 267 | negZeroGtZero: |
| 268 | // special case Pow(-0, y) = -0 for y an odd integer > 0 |
| 269 | // special case Pow(±0, y) = +0 for finite y > 0 and not an odd integer |
| 270 | FIDBR $5, F2, F4 //F2 translate to integer F4 |
| 271 | FCMPU F2, F4 |
| 272 | BNE zeroNotOddGtZero // y is not an (odd) integer and y > 0 |
| 273 | FMOVD $(2.0), F4 |
| 274 | FDIV F4, F2 // F2 = F2 / 2.0 |
| 275 | FIDBR $5, F2, F4 //F2 translate to integer F4 |
| 276 | FCMPU F2, F4 |
| 277 | BNE negZeroOddIntGtZero // y is an odd integer and y > 0 |
| 278 | BR zeroNotOddGtZero // y is not an (odd) integer |
| 279 | |
| 280 | xLtZero: |
| 281 | // special case Pow(x, y) = NaN for finite x < 0 and finite non-integer y |
| 282 | FMOVD y+8(FP), F2 |
| 283 | FIDBR $5, F2, F4 |
| 284 | FCMPU F2, F4 |
| 285 | BNE ltZeroInt |
| 286 | BR Normal |
| 287 | yIsPosInf: |
| 288 | // special case Pow(x, +Inf) = +Inf for |x| > 1 |
| 289 | FMOVD x+0(FP), F1 |
| 290 | FMOVD $(1.0), F3 |
| 291 | FCMPU F1, F3 |
| 292 | BGT gtOnePosInf |
| 293 | FMOVD $(-1.0), F3 |
| 294 | FCMPU F1, F3 |
| 295 | BLT ltNegOnePosInf |
| 296 | Normal: |
| 297 | FMOVD x+0(FP), F0 |
| 298 | FMOVD y+8(FP), F2 |
| 299 | MOVD $·powrodataL51<>+0(SB), R9 |
| 300 | WORD $0xB3CD0030 //lgdr %r3,%f0 |
| 301 | WORD $0xC0298009 //iilf %r2,2148095317 |
| 302 | BYTE $0x55 |
| 303 | BYTE $0x55 |
| 304 | WORD $0xEC1320BF //risbgn %r1,%r3,64-32,128+63,64+0+32 |
| 305 | BYTE $0x60 |
| 306 | BYTE $0x59 |
| 307 | SUBW R1, R2 |
| 308 | WORD $0xEC323ABF //risbgn %r3,%r2,64-6,128+63,64+44+6 |
| 309 | BYTE $0x72 |
| 310 | BYTE $0x59 |
| 311 | BYTE $0x18 //lr %r5,%r1 |
| 312 | BYTE $0x51 |
| 313 | MOVD $·powtabi<>+0(SB), R12 |
| 314 | WORD $0xE303C000 //llgc %r0,0(%r3,%r12) |
| 315 | BYTE $0x00 |
| 316 | BYTE $0x90 |
| 317 | SUBW $0x1A0000, R5 |
| 318 | SLD $3, R0, R3 |
| 319 | MOVD $·powtm<>+0(SB), R4 |
| 320 | MOVH $0x0, R8 |
| 321 | ANDW $0x7FF00000, R2 |
| 322 | ORW R5, R1 |
| 323 | WORD $0x5A234000 //a %r2,0(%r3,%r4) |
| 324 | MOVD $0x3FF0000000000000, R5 |
| 325 | WORD $0xEC3228BF //risbg %r3,%r2,64-24,128+63,64+32+24 |
| 326 | BYTE $0x78 |
| 327 | BYTE $0x55 |
| 328 | WORD $0xEC82001F //risbgn %r8,%r2,64-64+0,64-64+0+32-1,64-0-32 |
| 329 | BYTE $0x20 |
| 330 | BYTE $0x59 |
| 331 | ORW $0x45000000, R3 |
| 332 | MOVW R1, R6 |
| 333 | CMPBLT R6, $0, L42 |
| 334 | FMOVD F0, F4 |
| 335 | L2: |
| 336 | VLVGF $0, R3, V1 |
| 337 | MOVD $·pow_xa<>+0(SB), R2 |
| 338 | WORD $0xED3090A0 //lde %f3,.L52-.L51(%r9) |
| 339 | BYTE $0x00 |
| 340 | BYTE $0x24 |
| 341 | FMOVD 0(R2), F6 |
| 342 | FSUBS F1, F3 |
| 343 | WORD $0xB3C10018 //ldgr %f1,%r8 |
| 344 | WFMSDB V4, V1, V6, V4 |
| 345 | FMOVD 152(R9), F6 |
| 346 | WFMDB V4, V4, V7 |
| 347 | FMOVD 144(R9), F1 |
| 348 | FMOVD 136(R9), F5 |
| 349 | WFMADB V4, V1, V6, V1 |
| 350 | VLEG $0, 128(R9), V16 |
| 351 | FMOVD 120(R9), F6 |
| 352 | WFMADB V4, V5, V6, V5 |
| 353 | FMOVD 112(R9), F6 |
| 354 | WFMADB V1, V7, V5, V1 |
| 355 | WFMADB V4, V6, V16, V16 |
| 356 | SLD $3, R0, R2 |
| 357 | FMOVD 104(R9), F5 |
| 358 | WORD $0xED824004 //ldeb %f8,4(%r2,%r4) |
| 359 | BYTE $0x00 |
| 360 | BYTE $0x04 |
| 361 | LDEBR F3, F3 |
| 362 | FMOVD 96(R9), F6 |
| 363 | WFMADB V4, V6, V5, V6 |
| 364 | FADD F8, F3 |
| 365 | WFMADB V7, V6, V16, V6 |
| 366 | FMUL F7, F7 |
| 367 | FMOVD 88(R9), F5 |
| 368 | FMADD F7, F1, F6 |
| 369 | WFMADB V4, V5, V3, V16 |
| 370 | FMOVD 80(R9), F1 |
| 371 | WFSDB V16, V3, V3 |
| 372 | MOVD $·powtl<>+0(SB), R3 |
| 373 | WFMADB V4, V6, V1, V6 |
| 374 | FMADD F5, F4, F3 |
| 375 | FMOVD 72(R9), F1 |
| 376 | WFMADB V4, V6, V1, V6 |
| 377 | WORD $0xED323000 //adb %f3,0(%r2,%r3) |
| 378 | BYTE $0x00 |
| 379 | BYTE $0x1A |
| 380 | FMOVD 64(R9), F1 |
| 381 | WFMADB V4, V6, V1, V6 |
| 382 | MOVD $·pow_xadd<>+0(SB), R2 |
| 383 | WFMADB V4, V6, V3, V4 |
| 384 | FMOVD 0(R2), F5 |
| 385 | WFADB V4, V16, V3 |
| 386 | VLEG $0, 56(R9), V20 |
| 387 | WFMSDB V2, V3, V5, V3 |
| 388 | VLEG $0, 48(R9), V18 |
| 389 | WFADB V3, V5, V6 |
| 390 | WORD $0xB3CD0023 //lgdr %r2,%f3 |
| 391 | WFMSDB V2, V16, V6, V16 |
| 392 | FMOVD 40(R9), F1 |
| 393 | WFMADB V2, V4, V16, V4 |
| 394 | FMOVD 32(R9), F7 |
| 395 | WFMDB V4, V4, V3 |
| 396 | WFMADB V4, V1, V20, V1 |
| 397 | WFMADB V4, V7, V18, V7 |
| 398 | VLEG $0, 24(R9), V16 |
| 399 | WFMADB V1, V3, V7, V1 |
| 400 | FMOVD 16(R9), F5 |
| 401 | WFMADB V4, V5, V16, V5 |
| 402 | WORD $0xEC4239BC //risbg %r4,%r2,57,128+60,3 |
| 403 | BYTE $0x03 |
| 404 | BYTE $0x55 |
| 405 | WFMADB V3, V1, V5, V1 |
| 406 | MOVD $·powtexp<>+0(SB), R3 |
| 407 | WORD $0x68343000 //ld %f3,0(%r4,%r3) |
| 408 | FMADD F3, F4, F4 |
| 409 | WORD $0xEC52000F //risbgn %r5,%r2,64-64+0,64-64+0+16-1,64-0-16 |
| 410 | BYTE $0x30 |
| 411 | BYTE $0x59 |
| 412 | WFMADB V4, V1, V3, V4 |
| 413 | WORD $0xB3CD0026 //lgdr %r2,%f6 |
| 414 | WORD $0xB3C10015 //ldgr %f1,%r5 |
| 415 | SRAD $48, R2, R2 |
| 416 | FMADD F1, F4, F1 |
| 417 | RLL $16, R2, R2 |
| 418 | ANDW $0x7FFF0000, R2 |
| 419 | WORD $0xC22B3F71 //alfi %r2,1064370176 |
| 420 | BYTE $0x00 |
| 421 | BYTE $0x00 |
| 422 | ORW R2, R1, R3 |
| 423 | MOVW R3, R6 |
| 424 | CMPBLT R6, $0, L43 |
| 425 | L1: |
| 426 | FMOVD F1, ret+16(FP) |
| 427 | RET |
| 428 | L43: |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 429 | LTDBR F0, F0 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 430 | BLTU L44 |
| 431 | FMOVD F0, F3 |
| 432 | L7: |
| 433 | MOVD $·pow_xinf<>+0(SB), R3 |
| 434 | FMOVD 0(R3), F5 |
| 435 | WFCEDBS V3, V5, V7 |
| 436 | BVS L8 |
| 437 | WFMDB V3, V2, V6 |
| 438 | L8: |
| 439 | WFCEDBS V2, V2, V3 |
| 440 | BVS L9 |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 441 | LTDBR F2, F2 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 442 | BEQ L26 |
| 443 | MOVW R1, R6 |
| 444 | CMPBLT R6, $0, L45 |
| 445 | L11: |
| 446 | WORD $0xC0190003 //iilf %r1,262143 |
| 447 | BYTE $0xFF |
| 448 | BYTE $0xFF |
| 449 | MOVW R2, R7 |
| 450 | MOVW R1, R6 |
| 451 | CMPBLE R7, R6, L34 |
| 452 | WORD $0xEC1520BF //risbgn %r1,%r5,64-32,128+63,64+0+32 |
| 453 | BYTE $0x60 |
| 454 | BYTE $0x59 |
| 455 | WORD $0xB3CD0026 //lgdr %r2,%f6 |
| 456 | MOVD $powiadd<>+0(SB), R3 |
| 457 | WORD $0xEC223CBC //risbg %r2,%r2,60,128+60,64-60 |
| 458 | BYTE $0x04 |
| 459 | BYTE $0x55 |
| 460 | WORD $0x5A123000 //a %r1,0(%r2,%r3) |
| 461 | WORD $0xEC51001F //risbgn %r5,%r1,64-64+0,64-64+0+32-1,64-0-32 |
| 462 | BYTE $0x20 |
| 463 | BYTE $0x59 |
| 464 | WORD $0xB3C10015 //ldgr %f1,%r5 |
| 465 | FMADD F1, F4, F1 |
| 466 | MOVD $powxscale<>+0(SB), R1 |
| 467 | WORD $0xED121000 //mdb %f1,0(%r2,%r1) |
| 468 | BYTE $0x00 |
| 469 | BYTE $0x1C |
| 470 | BR L1 |
| 471 | L42: |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 472 | LTDBR F0, F0 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 473 | BLTU L46 |
| 474 | FMOVD F0, F4 |
| 475 | L3: |
| 476 | MOVD $·pow_x001a<>+0(SB), R2 |
| 477 | WORD $0xED402000 //cdb %f4,0(%r2) |
| 478 | BYTE $0x00 |
| 479 | BYTE $0x19 |
| 480 | BGE L2 |
| 481 | BVS L2 |
| 482 | MOVD $·pow_x43f<>+0(SB), R2 |
| 483 | WORD $0xED402000 //mdb %f4,0(%r2) |
| 484 | BYTE $0x00 |
| 485 | BYTE $0x1C |
| 486 | WORD $0xC0298009 //iilf %r2,2148095317 |
| 487 | BYTE $0x55 |
| 488 | BYTE $0x55 |
| 489 | WORD $0xB3CD0034 //lgdr %r3,%f4 |
| 490 | WORD $0xEC3320BF //risbgn %r3,%r3,64-32,128+63,64+0+32 |
| 491 | BYTE $0x60 |
| 492 | BYTE $0x59 |
| 493 | SUBW R3, R2, R3 |
| 494 | WORD $0xEC2321AB //risbg %r2,%r3,33,128+43,0 |
| 495 | BYTE $0x00 |
| 496 | BYTE $0x55 |
| 497 | WORD $0xEC333ABF //risbgn %r3,%r3,64-6,128+63,64+44+6 |
| 498 | BYTE $0x72 |
| 499 | BYTE $0x59 |
| 500 | WORD $0xE303C000 //llgc %r0,0(%r3,%r12) |
| 501 | BYTE $0x00 |
| 502 | BYTE $0x90 |
| 503 | SLD $3, R0, R3 |
| 504 | WORD $0x5A234000 //a %r2,0(%r3,%r4) |
| 505 | BYTE $0x18 //lr %r3,%r2 |
| 506 | BYTE $0x32 |
| 507 | WORD $0xEC83001F //risbgn %r8,%r3,64-64+0,64-64+0+32-1,64-0-32 |
| 508 | BYTE $0x20 |
| 509 | BYTE $0x59 |
| 510 | ADDW $0x4000000, R3 |
| 511 | BLEU L5 |
| 512 | WORD $0xEC3328BF //risbg %r3,%r3,64-24,128+63,64+32+24 |
| 513 | BYTE $0x78 |
| 514 | BYTE $0x55 |
| 515 | ORW $0x45000000, R3 |
| 516 | BR L2 |
| 517 | L9: |
| 518 | WFCEDBS V0, V0, V4 |
| 519 | BVS L35 |
| 520 | FMOVD F2, F1 |
| 521 | BR L1 |
| 522 | L46: |
| 523 | WORD $0xB3130040 //lcdbr %f4,%f0 |
| 524 | BR L3 |
| 525 | L44: |
| 526 | WORD $0xB3130030 //lcdbr %f3,%f0 |
| 527 | BR L7 |
| 528 | L35: |
| 529 | FMOVD F0, F1 |
| 530 | BR L1 |
| 531 | L26: |
| 532 | FMOVD 8(R9), F1 |
| 533 | BR L1 |
| 534 | L34: |
| 535 | FMOVD 8(R9), F4 |
| 536 | L19: |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 537 | LTDBR F6, F6 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 538 | BLEU L47 |
| 539 | L18: |
| 540 | WFMDB V4, V5, V1 |
| 541 | BR L1 |
| 542 | L5: |
| 543 | WORD $0xEC3321B2 //risbg %r3,%r3,33,128+50,64-1 |
| 544 | BYTE $0x3F |
| 545 | BYTE $0x55 |
| 546 | WORD $0xC23B4000 //alfi %r3,1073741824 |
| 547 | BYTE $0x00 |
| 548 | BYTE $0x00 |
| 549 | RLL $24, R3, R3 |
| 550 | ORW $0x45000000, R3 |
| 551 | BR L2 |
| 552 | L45: |
| 553 | WFCEDBS V0, V0, V4 |
| 554 | BVS L35 |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 555 | LTDBR F0, F0 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 556 | BLEU L48 |
| 557 | FMOVD 8(R9), F4 |
| 558 | L12: |
| 559 | MOVW R2, R6 |
| 560 | CMPBLT R6, $0, L19 |
| 561 | FMUL F4, F1 |
| 562 | BR L1 |
| 563 | L47: |
| 564 | BLT L40 |
| 565 | WFCEDBS V0, V0, V2 |
| 566 | BVS L49 |
| 567 | L16: |
| 568 | MOVD ·pow_xnan<>+0(SB), R1 |
| 569 | WORD $0xB3C10001 //ldgr %f0,%r1 |
| 570 | WFMDB V4, V0, V1 |
| 571 | BR L1 |
| 572 | L48: |
| 573 | WORD $0xB3CD0030 //lgdr %r3,%f0 |
| 574 | WORD $0xEC1320BF //risbgn %r1,%r3,64-32,128+63,64+0+32 |
| 575 | BYTE $0x60 |
| 576 | BYTE $0x59 |
| 577 | MOVW R1, R6 |
| 578 | CMPBEQ R6, $0, L29 |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 579 | LTDBR F2, F2 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 580 | BLTU L50 |
| 581 | FMOVD F2, F4 |
| 582 | L14: |
| 583 | MOVD $·pow_x433<>+0(SB), R1 |
| 584 | FMOVD 0(R1), F7 |
| 585 | WFCHDBS V4, V7, V3 |
| 586 | BEQ L15 |
| 587 | WFADB V7, V4, V3 |
| 588 | FSUB F7, F3 |
| 589 | WFCEDBS V4, V3, V3 |
| 590 | BEQ L15 |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 591 | LTDBR F0, F0 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 592 | FMOVD 8(R9), F4 |
| 593 | BNE L16 |
| 594 | L13: |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 595 | LTDBR F2, F2 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 596 | BLT L18 |
| 597 | L40: |
| 598 | FMOVD $0, F0 |
| 599 | WFMDB V4, V0, V1 |
| 600 | BR L1 |
| 601 | L49: |
| 602 | WFMDB V0, V4, V1 |
| 603 | BR L1 |
| 604 | L29: |
| 605 | FMOVD 8(R9), F4 |
| 606 | BR L13 |
| 607 | L15: |
| 608 | MOVD $·pow_x434<>+0(SB), R1 |
| 609 | FMOVD 0(R1), F7 |
| 610 | WFCHDBS V4, V7, V3 |
| 611 | BEQ L32 |
| 612 | WFADB V7, V4, V3 |
| 613 | FSUB F7, F3 |
| 614 | WFCEDBS V4, V3, V4 |
| 615 | BEQ L32 |
| 616 | FMOVD 0(R9), F4 |
| 617 | L17: |
Dan Willemsen | c741332 | 2018-08-27 23:21:26 -0700 | [diff] [blame^] | 618 | LTDBR F0, F0 |
Dan Willemsen | d279748 | 2017-07-26 13:13:13 -0700 | [diff] [blame] | 619 | BNE L12 |
| 620 | BR L13 |
| 621 | L32: |
| 622 | FMOVD 8(R9), F4 |
| 623 | BR L17 |
| 624 | L50: |
| 625 | WORD $0xB3130042 //lcdbr %f4,%f2 |
| 626 | BR L14 |
| 627 | xIsOne: // Pow(1, y) = 1 for any y |
| 628 | yIsOne: // Pow(x, 1) = x for any x |
| 629 | posInfGeZero: // Pow(+Inf, y) = +Inf for y > 0 |
| 630 | MOVD R1, ret+16(FP) |
| 631 | RET |
| 632 | yIsNan: // Pow(NaN, y) = NaN |
| 633 | ltZeroInt: // Pow(x, y) = NaN for finite x < 0 and finite non-integer y |
| 634 | MOVD $NaN, R2 |
| 635 | MOVD R2, ret+16(FP) |
| 636 | RET |
| 637 | negOnePosInf: // Pow(-1, ±Inf) = 1 |
| 638 | negOneNegInf: |
| 639 | MOVD $PosOne, R3 |
| 640 | MOVD R3, ret+16(FP) |
| 641 | RET |
| 642 | negZeroOddInt: |
| 643 | MOVD $NegInf, R3 |
| 644 | MOVD R3, ret+16(FP) |
| 645 | RET |
| 646 | zeroNotOdd: // Pow(±0, y) = +Inf for finite y < 0 and not an odd integer |
| 647 | posZeroLtZero: // special case Pow(+0, y < 0) = +Inf |
| 648 | zeroNegInf: // Pow(±0, -Inf) = +Inf |
| 649 | MOVD $PosInf, R3 |
| 650 | MOVD R3, ret+16(FP) |
| 651 | RET |
| 652 | gtOnePosInf: //Pow(x, +Inf) = +Inf for |x| > 1 |
| 653 | ltNegOnePosInf: |
| 654 | MOVD R2, ret+16(FP) |
| 655 | RET |
| 656 | yIsZero: //Pow(x, ±0) = 1 for any x |
| 657 | MOVD $PosOne, R4 |
| 658 | MOVD R4, ret+16(FP) |
| 659 | RET |
| 660 | negZeroOddIntGtZero: // Pow(-0, y) = -0 for y an odd integer > 0 |
| 661 | MOVD $NegZero, R3 |
| 662 | MOVD R3, ret+16(FP) |
| 663 | RET |
| 664 | zeroNotOddGtZero: // Pow(±0, y) = +0 for finite y > 0 and not an odd integer |
| 665 | MOVD $0, ret+16(FP) |
| 666 | RET |