| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- //go:build !tinygo && !noasm
- // Copyright 2010 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSS-style
- // license that can be found in the LICENSE file.
- #include "textflag.h"
- #define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
- #define Ln2Hi 6.9313812256e-01 // 0x3f317180
- #define Ln2Lo 9.0580006145e-06 // 0x3717f7d1
- #define L1 6.6666668653e-01 // 0x3f2aaaab
- #define L2 4.0000000596e-01 // 0x3ecccccd
- #define L3 2.8571429849e-01 // 0x3e924925
- #define L4 2.2222198546e-01 // 0x3e638e29
- #define L5 1.8183572590e-01 // 0x3e3a3325
- #define L6 1.5313838422e-01 // 0x3e1cd04f
- #define L7 1.4798198640e-01 // 0x3e178897
- #define NaN 0x7FE00000
- #define PosInf 0x7F800000
- #define NegInf 0xFF800000
- // func archLog(x float64) float64
- TEXT ·archLog(SB),NOSPLIT,$0
- // test bits for special cases
- MOVL x+0(FP), BX
- MOVQ $~(1<<31), AX // sign bit mask
- ANDQ BX, AX
- JEQ isZero
- MOVL $0, AX
- CMPL AX, BX
- JGT isNegative
- MOVL $PosInf, AX
- CMPQ AX, BX
- JLE isInfOrNaN
- // f1, ki := math.Frexp(x); k := float64(ki)
- MOVL BX, X0
- MOVL $0x007FFFFF, AX
- MOVL AX, X2
- ANDPS X0, X2
- MOVSS $0.5, X0 // 0x3FE0000000000000
- ORPS X0, X2 // X2= f1
- SHRQ $23, BX
- ANDL $0xFF, BX
- SUBL $0x7E, BX
- CVTSL2SS BX, X1 // x1= k, x2= f1
- // if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
- MOVSS $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1
- CMPSS X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1
- MOVSS $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1
- ANDPS X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
- SUBSS X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
- MOVSS $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1
- ADDSS X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2
- MULSS X3, X2 // x0= 1, x1= k, x2= f1
- // f := f1 - 1
- SUBSS X0, X2 // x1= k, x2= f
- // s := f / (2 + f)
- MOVSS $2.0, X0
- ADDSS X2, X0
- MOVUPS X2, X3
- DIVSS X0, X3 // x1=k, x2= f, x3= s
- // s2 := s * s
- MOVUPS X3, X4 // x1= k, x2= f, x3= s
- MULSS X4, X4 // x1= k, x2= f, x3= s, x4= s2
- // s4 := s2 * s2
- MOVUPS X4, X5 // x1= k, x2= f, x3= s, x4= s2
- MULSS X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4
- // t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7)))
- MOVSS $L7, X6
- MULSS X5, X6
- ADDSS $L5, X6
- MULSS X5, X6
- ADDSS $L3, X6
- MULSS X5, X6
- ADDSS $L1, X6
- MULSS X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4
- // t2 := s4 * (L2 + s4*(L4+s4*L6))
- MOVSS $L6, X6
- MULSS X5, X6
- ADDSS $L4, X6
- MULSS X5, X6
- ADDSS $L2, X6
- MULSS X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2
- // R := t1 + t2
- ADDSS X5, X4 // x1= k, x2= f, x3= s, x4= R
- // hfsq := 0.5 * f * f
- MOVSS $0.5, X0
- MULSS X2, X0
- MULSS X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R
- // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
- ADDSS X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R
- MULSS X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)
- MOVSS $Ln2Lo, X4
- MULSS X1, X4 // x4= k*Ln2Lo
- ADDSS X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo
- SUBSS X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f
- SUBSS X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k
- MULSS $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi
- SUBSS X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f)
- MOVSS X1, ret+8(FP)
- RET
- isInfOrNaN:
- MOVL BX, ret+8(FP) // +Inf or NaN, return x
- RET
- isNegative:
- MOVL $NaN, AX
- MOVL AX, ret+8(FP) // return NaN
- RET
- isZero:
- MOVL $NegInf, AX
- MOVL AX, ret+8(FP) // return -Inf
- RET
|