| // Copyright 2017 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| #include "textflag.h" | |
| #define PosInf 0x7FF0000000000000 | |
| #define NegInf 0xFFF0000000000000 | |
| #define NegZero 0x8000000000000000 | |
| #define Pi 0x400921FB54442D18 | |
| #define NegPi 0xC00921FB54442D18 | |
| #define Pi3Div4 0x4002D97C7F3321D2 // 3Pi/4 | |
| #define NegPi3Div4 0xC002D97C7F3321D2 // -3Pi/4 | |
| #define PiDiv4 0x3FE921FB54442D18 // Pi/4 | |
| #define NegPiDiv4 0xBFE921FB54442D18 // -Pi/4 | |
| // Minimax polynomial coefficients and other constants | |
| DATA ·atan2rodataL25<> + 0(SB)/8, $0.199999999999554423E+00 | |
| DATA ·atan2rodataL25<> + 8(SB)/8, $-.333333333333330928E+00 | |
| DATA ·atan2rodataL25<> + 16(SB)/8, $0.111111110136634272E+00 | |
| DATA ·atan2rodataL25<> + 24(SB)/8, $-.142857142828026806E+00 | |
| DATA ·atan2rodataL25<> + 32(SB)/8, $0.769228118888682505E-01 | |
| DATA ·atan2rodataL25<> + 40(SB)/8, $0.588059263575587687E-01 | |
| DATA ·atan2rodataL25<> + 48(SB)/8, $-.909090711945939878E-01 | |
| DATA ·atan2rodataL25<> + 56(SB)/8, $-.666641501287528609E-01 | |
| DATA ·atan2rodataL25<> + 64(SB)/8, $0.472329433805024762E-01 | |
| DATA ·atan2rodataL25<> + 72(SB)/8, $-.525380587584426406E-01 | |
| DATA ·atan2rodataL25<> + 80(SB)/8, $-.422172007412067035E-01 | |
| DATA ·atan2rodataL25<> + 88(SB)/8, $0.366935664549587481E-01 | |
| DATA ·atan2rodataL25<> + 96(SB)/8, $0.220852012160300086E-01 | |
| DATA ·atan2rodataL25<> + 104(SB)/8, $-.299856214685512712E-01 | |
| DATA ·atan2rodataL25<> + 112(SB)/8, $0.726338160757602439E-02 | |
| DATA ·atan2rodataL25<> + 120(SB)/8, $0.134893651284712515E-04 | |
| DATA ·atan2rodataL25<> + 128(SB)/8, $-.291935324869629616E-02 | |
| DATA ·atan2rodataL25<> + 136(SB)/8, $-.154797890856877418E-03 | |
| DATA ·atan2rodataL25<> + 144(SB)/8, $0.843488472994227321E-03 | |
| DATA ·atan2rodataL25<> + 152(SB)/8, $-.139950258898989925E-01 | |
| GLOBL ·atan2rodataL25<> + 0(SB), RODATA, $160 | |
| DATA ·atan2xpi2h<> + 0(SB)/8, $0x3ff330e4e4fa7b1b | |
| DATA ·atan2xpi2h<> + 8(SB)/8, $0xbff330e4e4fa7b1b | |
| DATA ·atan2xpi2h<> + 16(SB)/8, $0x400330e4e4fa7b1b | |
| DATA ·atan2xpi2h<> + 24(SB)/8, $0xc00330e4e4fa7b1b | |
| GLOBL ·atan2xpi2h<> + 0(SB), RODATA, $32 | |
| DATA ·atan2xpim<> + 0(SB)/8, $0x3ff4f42b00000000 | |
| GLOBL ·atan2xpim<> + 0(SB), RODATA, $8 | |
| // Atan2 returns the arc tangent of y/x, using | |
| // the signs of the two to determine the quadrant | |
| // of the return value. | |
| // | |
| // Special cases are (in order): | |
| // Atan2(y, NaN) = NaN | |
| // Atan2(NaN, x) = NaN | |
| // Atan2(+0, x>=0) = +0 | |
| // Atan2(-0, x>=0) = -0 | |
| // Atan2(+0, x<=-0) = +Pi | |
| // Atan2(-0, x<=-0) = -Pi | |
| // Atan2(y>0, 0) = +Pi/2 | |
| // Atan2(y<0, 0) = -Pi/2 | |
| // Atan2(+Inf, +Inf) = +Pi/4 | |
| // Atan2(-Inf, +Inf) = -Pi/4 | |
| // Atan2(+Inf, -Inf) = 3Pi/4 | |
| // Atan2(-Inf, -Inf) = -3Pi/4 | |
| // Atan2(y, +Inf) = 0 | |
| // Atan2(y>0, -Inf) = +Pi | |
| // Atan2(y<0, -Inf) = -Pi | |
| // Atan2(+Inf, x) = +Pi/2 | |
| // Atan2(-Inf, x) = -Pi/2 | |
| // The algorithm used is minimax polynomial approximation | |
| // with coefficients determined with a Remez exchange algorithm. | |
| TEXT ·atan2Asm(SB), NOSPLIT, $0-24 | |
| // special case | |
| MOVD x+0(FP), R1 | |
| MOVD y+8(FP), R2 | |
| // special case Atan2(NaN, y) = NaN | |
| MOVD $~(1<<63), R5 | |
| AND R1, R5 // x = |x| | |
| MOVD $PosInf, R3 | |
| CMPUBLT R3, R5, returnX | |
| // special case Atan2(x, NaN) = NaN | |
| MOVD $~(1<<63), R5 | |
| AND R2, R5 | |
| CMPUBLT R3, R5, returnY | |
| MOVD $NegZero, R3 | |
| CMPUBEQ R3, R1, xIsNegZero | |
| MOVD $0, R3 | |
| CMPUBEQ R3, R1, xIsPosZero | |
| MOVD $PosInf, R4 | |
| CMPUBEQ R4, R2, yIsPosInf | |
| MOVD $NegInf, R4 | |
| CMPUBEQ R4, R2, yIsNegInf | |
| BR Normal | |
| xIsNegZero: | |
| // special case Atan(-0, y>=0) = -0 | |
| MOVD $0, R4 | |
| CMPBLE R4, R2, returnX | |
| //special case Atan2(-0, y<=-0) = -Pi | |
| MOVD $NegZero, R4 | |
| CMPBGE R4, R2, returnNegPi | |
| BR Normal | |
| xIsPosZero: | |
| //special case Atan2(0, 0) = 0 | |
| MOVD $0, R4 | |
| CMPUBEQ R4, R2, returnX | |
| //special case Atan2(0, y<=-0) = Pi | |
| MOVD $NegZero, R4 | |
| CMPBGE R4, R2, returnPi | |
| BR Normal | |
| yIsNegInf: | |
| //special case Atan2(+Inf, -Inf) = 3Pi/4 | |
| MOVD $PosInf, R3 | |
| CMPUBEQ R3, R1, posInfNegInf | |
| //special case Atan2(-Inf, -Inf) = -3Pi/4 | |
| MOVD $NegInf, R3 | |
| CMPUBEQ R3, R1, negInfNegInf | |
| BR Normal | |
| yIsPosInf: | |
| //special case Atan2(+Inf, +Inf) = Pi/4 | |
| MOVD $PosInf, R3 | |
| CMPUBEQ R3, R1, posInfPosInf | |
| //special case Atan2(-Inf, +Inf) = -Pi/4 | |
| MOVD $NegInf, R3 | |
| CMPUBEQ R3, R1, negInfPosInf | |
| //special case Atan2(x, +Inf) = Copysign(0, x) | |
| CMPBLT R1, $0, returnNegZero | |
| BR returnPosZero | |
| Normal: | |
| FMOVD x+0(FP), F0 | |
| FMOVD y+8(FP), F2 | |
| MOVD $·atan2rodataL25<>+0(SB), R9 | |
| LGDR F0, R2 | |
| LGDR F2, R1 | |
| RISBGNZ $32, $63, $32, R2, R2 | |
| RISBGNZ $32, $63, $32, R1, R1 | |
| WORD $0xB9170032 //llgtr %r3,%r2 | |
| RISBGZ $63, $63, $33, R2, R5 | |
| WORD $0xB9170041 //llgtr %r4,%r1 | |
| WFLCDB V0, V20 | |
| MOVW R4, R6 | |
| MOVW R3, R7 | |
| CMPUBLT R6, R7, L17 | |
| WFDDB V2, V0, V3 | |
| ADDW $2, R5, R2 | |
| MOVW R4, R6 | |
| MOVW R3, R7 | |
| CMPUBLE R6, R7, L20 | |
| L3: | |
| WFMDB V3, V3, V4 | |
| VLEG $0, 152(R9), V18 | |
| VLEG $0, 144(R9), V16 | |
| FMOVD 136(R9), F1 | |
| FMOVD 128(R9), F5 | |
| FMOVD 120(R9), F6 | |
| WFMADB V4, V16, V5, V16 | |
| WFMADB V4, V6, V1, V6 | |
| FMOVD 112(R9), F7 | |
| WFMDB V4, V4, V1 | |
| WFMADB V4, V7, V18, V7 | |
| VLEG $0, 104(R9), V18 | |
| WFMADB V1, V6, V16, V6 | |
| CMPWU R4, R3 | |
| FMOVD 96(R9), F5 | |
| VLEG $0, 88(R9), V16 | |
| WFMADB V4, V5, V18, V5 | |
| VLEG $0, 80(R9), V18 | |
| VLEG $0, 72(R9), V22 | |
| WFMADB V4, V16, V18, V16 | |
| VLEG $0, 64(R9), V18 | |
| WFMADB V1, V7, V5, V7 | |
| WFMADB V4, V18, V22, V18 | |
| WFMDB V1, V1, V5 | |
| WFMADB V1, V16, V18, V16 | |
| VLEG $0, 56(R9), V18 | |
| WFMADB V5, V6, V7, V6 | |
| VLEG $0, 48(R9), V22 | |
| FMOVD 40(R9), F7 | |
| WFMADB V4, V7, V18, V7 | |
| VLEG $0, 32(R9), V18 | |
| WFMADB V5, V6, V16, V6 | |
| WFMADB V4, V18, V22, V18 | |
| VLEG $0, 24(R9), V16 | |
| WFMADB V1, V7, V18, V7 | |
| VLEG $0, 16(R9), V18 | |
| VLEG $0, 8(R9), V22 | |
| WFMADB V4, V18, V16, V18 | |
| VLEG $0, 0(R9), V16 | |
| WFMADB V5, V6, V7, V6 | |
| WFMADB V4, V16, V22, V16 | |
| FMUL F3, F4 | |
| WFMADB V1, V18, V16, V1 | |
| FMADD F6, F5, F1 | |
| WFMADB V4, V1, V3, V4 | |
| BLT L18 | |
| BGT L7 | |
| LTDBR F2, F2 | |
| BLTU L21 | |
| L8: | |
| LTDBR F0, F0 | |
| BLTU L22 | |
| L9: | |
| WFCHDBS V2, V0, V0 | |
| BNE L18 | |
| L7: | |
| MOVW R1, R6 | |
| CMPBGE R6, $0, L1 | |
| L18: | |
| RISBGZ $58, $60, $3, R2, R2 | |
| MOVD $·atan2xpi2h<>+0(SB), R1 | |
| MOVD ·atan2xpim<>+0(SB), R3 | |
| LDGR R3, F0 | |
| WORD $0xED021000 //madb %f4,%f0,0(%r2,%r1) | |
| BYTE $0x40 | |
| BYTE $0x1E | |
| L1: | |
| FMOVD F4, ret+16(FP) | |
| RET | |
| L20: | |
| LTDBR F2, F2 | |
| BLTU L23 | |
| FMOVD F2, F6 | |
| L4: | |
| LTDBR F0, F0 | |
| BLTU L24 | |
| FMOVD F0, F4 | |
| L5: | |
| WFCHDBS V6, V4, V4 | |
| BEQ L3 | |
| L17: | |
| WFDDB V0, V2, V4 | |
| BYTE $0x18 //lr %r2,%r5 | |
| BYTE $0x25 | |
| LCDBR F4, F3 | |
| BR L3 | |
| L23: | |
| LCDBR F2, F6 | |
| BR L4 | |
| L22: | |
| VLR V20, V0 | |
| BR L9 | |
| L21: | |
| LCDBR F2, F2 | |
| BR L8 | |
| L24: | |
| VLR V20, V4 | |
| BR L5 | |
| returnX: //the result is same as the first argument | |
| MOVD R1, ret+16(FP) | |
| RET | |
| returnY: //the result is same as the second argument | |
| MOVD R2, ret+16(FP) | |
| RET | |
| returnPi: | |
| MOVD $Pi, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| returnNegPi: | |
| MOVD $NegPi, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| posInfNegInf: | |
| MOVD $Pi3Div4, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| negInfNegInf: | |
| MOVD $NegPi3Div4, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| posInfPosInf: | |
| MOVD $PiDiv4, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| negInfPosInf: | |
| MOVD $NegPiDiv4, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| returnNegZero: | |
| MOVD $NegZero, R1 | |
| MOVD R1, ret+16(FP) | |
| RET | |
| returnPosZero: | |
| MOVD $0, ret+16(FP) | |
| RET |