| // Copyright 2026 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 HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2 |
| #define Ln2Hi 6.93147180369123816490e-01 |
| #define Ln2Lo 1.90821492927058770002e-10 |
| #define L1 6.666666666666735130e-01 |
| #define L2 3.999999999940941908e-01 |
| #define L3 2.857142874366239149e-01 |
| #define L4 2.222219843214978396e-01 |
| #define L5 1.818357216161805012e-01 |
| #define L6 1.531383769920937332e-01 |
| #define L7 1.479819860511658591e-01 |
| #define NaN 0x7FF8000000000001 |
| #define NegInf 0xFFF0000000000000 |
| #define PosInf 0x7FF0000000000000 |
| #define FracMask 0x000FFFFFFFFFFFFF |
| #define HalfExp 0x3FE0000000000000 // bit pattern of 0.5, used to force f1 into [0.5,1) |
| |
| DATA logrodata<>+0(SB)/8, $0.5 |
| DATA logrodata<>+8(SB)/8, $1.0 |
| DATA logrodata<>+16(SB)/8, $2.0 |
| DATA logrodata<>+24(SB)/8, $HSqrt2 |
| DATA logrodata<>+32(SB)/8, $Ln2Hi |
| DATA logrodata<>+40(SB)/8, $Ln2Lo |
| DATA logrodata<>+48(SB)/8, $L1 |
| DATA logrodata<>+56(SB)/8, $L2 |
| DATA logrodata<>+64(SB)/8, $L3 |
| DATA logrodata<>+72(SB)/8, $L4 |
| DATA logrodata<>+80(SB)/8, $L5 |
| DATA logrodata<>+88(SB)/8, $L6 |
| DATA logrodata<>+96(SB)/8, $L7 |
| GLOBL logrodata<>+0(SB), NOPTR|RODATA, $104 |
| |
| // func archLog(x float64) float64 |
| TEXT ·archLog(SB),NOSPLIT,$0 |
| MOVD x+0(FP), F0 |
| MOVV F0, R4 // R4 = raw bits of x |
| |
| MOVV $~(1<<63), R5 |
| AND R4, R5, R6 // R6 = |bits(x)| |
| BEQ R6, R0, isZero |
| |
| BLT R4, R0, isNegative // sign bit set -> x < 0 |
| |
| MOVV $PosInf, R8 |
| BGE R4, R8, isInfOrNaN // bits(x) >= PosInf pattern -> +Inf or NaN |
| |
| MOVV $logrodata<>+0(SB), R13 |
| |
| // f1, ki := Frexp(x) |
| MOVV $FracMask, R9 |
| AND R4, R9, R10 // fraction bits |
| MOVV $HalfExp, R11 |
| OR R11, R10, R10 // f1 bits, f1 in [0.5, 1) |
| MOVV R10, F1 // F1 = f1 |
| |
| SRLV $52, R4, R12 |
| AND $0x7FF, R12, R12 // biased exponent |
| ADDV $-0x3FE, R12, R12 // R12 = ki |
| MOVV R12, F2 |
| FFINTDV F2, F2 // F2 = k (float64) |
| |
| // if f1 < Sqrt2/2 { k -= 1; f1 *= 2 } |
| MOVD 24(R13), F3 // HSqrt2 |
| CMPGTD F3, F1, FCC0 // FCC0 = (HSqrt2 > f1) |
| |
| MOVD 8(R13), F4 // 1.0 |
| SUBD F4, F2, F17 |
| MOVD 16(R13), F18 // 2.0 |
| MULD F18, F1, F19 |
| FSEL FCC0, F17, F2, F2 |
| FSEL FCC0, F19, F1, F1 |
| |
| SUBD F4, F1, F3 // f := f1 - 1 |
| |
| // s := f / (2 + f) |
| MOVD 16(R13), F5 |
| ADDD F3, F5, F5 // 2 + f |
| MOVD F3, F6 |
| DIVD F5, F6, F6 // s |
| |
| MULD F6, F6, F7 // s2 |
| MULD F7, F7, F8 // s4 |
| |
| // t1 := s2 * (L1 + s4*(L3 + s4*(L5 + s4*L7))) |
| MOVD 96(R13), F9 // L7 |
| MOVD 80(R13), F10 // L5 |
| FMADDD F10, F8, F9, F9 // F9 = L7*s4 + L5 |
| MOVD 64(R13), F10 // L3 |
| FMADDD F10, F8, F9, F9 // F9 = F9*s4 + L3 |
| MOVD 48(R13), F10 // L1 |
| FMADDD F10, F8, F9, F9 // F9 = F9*s4 + L1 |
| MULD F7, F9, F9 // t1 = F9 * s2 |
| |
| // t2 := s4 * (L2 + s4*(L4 + s4*L6)) |
| MOVD 88(R13), F11 // L6 |
| MOVD 72(R13), F12 // L4 |
| FMADDD F12, F8, F11, F11 // F11 = L6*s4 + L4 |
| MOVD 56(R13), F12 // L2 |
| FMADDD F12, F8, F11, F11 // F11 = F11*s4 + L2 |
| MULD F8, F11, F11 // t2 = F11 * s4 |
| |
| ADDD F11, F9, F9 // R = t1 + t2 |
| |
| // hfsq := 0.5 * f * f |
| MOVD 0(R13), F14 // 0.5 |
| MULD F3, F14, F14 |
| MULD F3, F14, F14 // hfsq |
| |
| // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f) |
| ADDD F14, F9, F9 // hfsq + R |
| MOVD 40(R13), F15 // Ln2Lo |
| MULD F2, F15, F15 // k*Ln2Lo |
| FMADDD F15, F6, F9, F9 // F9 = s*(hfsq+R) + k*Ln2Lo |
| SUBD F9, F14, F14 |
| SUBD F3, F14, F14 |
| MOVD 32(R13), F16 // Ln2Hi |
| FMSUBD F14, F2, F16, F16 |
| |
| MOVD F16, ret+8(FP) |
| RET |
| isInfOrNaN: |
| MOVD F0, ret+8(FP) // +Inf or NaN, return x |
| RET |
| isNegative: |
| MOVV $NaN, R6 |
| MOVV R6, ret+8(FP) |
| RET |
| isZero: |
| MOVV $NegInf, R6 |
| MOVV R6, ret+8(FP) |
| RET |