Text file
src/math/log_loong64.s
1 // Copyright 2026 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 HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
8 #define Ln2Hi 6.93147180369123816490e-01
9 #define Ln2Lo 1.90821492927058770002e-10
10 #define L1 6.666666666666735130e-01
11 #define L2 3.999999999940941908e-01
12 #define L3 2.857142874366239149e-01
13 #define L4 2.222219843214978396e-01
14 #define L5 1.818357216161805012e-01
15 #define L6 1.531383769920937332e-01
16 #define L7 1.479819860511658591e-01
17 #define NaN 0x7FF8000000000001
18 #define NegInf 0xFFF0000000000000
19 #define PosInf 0x7FF0000000000000
20 #define FracMask 0x000FFFFFFFFFFFFF
21 #define HalfExp 0x3FE0000000000000 // bit pattern of 0.5, used to force f1 into [0.5,1)
22
23 DATA logrodata<>+0(SB)/8, $0.5
24 DATA logrodata<>+8(SB)/8, $1.0
25 DATA logrodata<>+16(SB)/8, $2.0
26 DATA logrodata<>+24(SB)/8, $HSqrt2
27 DATA logrodata<>+32(SB)/8, $Ln2Hi
28 DATA logrodata<>+40(SB)/8, $Ln2Lo
29 DATA logrodata<>+48(SB)/8, $L1
30 DATA logrodata<>+56(SB)/8, $L2
31 DATA logrodata<>+64(SB)/8, $L3
32 DATA logrodata<>+72(SB)/8, $L4
33 DATA logrodata<>+80(SB)/8, $L5
34 DATA logrodata<>+88(SB)/8, $L6
35 DATA logrodata<>+96(SB)/8, $L7
36 GLOBL logrodata<>+0(SB), NOPTR|RODATA, $104
37
38 // func archLog(x float64) float64
39 TEXT ·archLog(SB),NOSPLIT,$0
40 MOVD x+0(FP), F0
41 MOVV F0, R4 // R4 = raw bits of x
42
43 MOVV $~(1<<63), R5
44 AND R4, R5, R6 // R6 = |bits(x)|
45 BEQ R6, R0, isZero
46
47 BLT R4, R0, isNegative // sign bit set -> x < 0
48
49 MOVV $PosInf, R8
50 BGE R4, R8, isInfOrNaN // bits(x) >= PosInf pattern -> +Inf or NaN
51
52 MOVV $logrodata<>+0(SB), R13
53
54 // f1, ki := Frexp(x)
55 MOVV $FracMask, R9
56 AND R4, R9, R10 // fraction bits
57 MOVV $HalfExp, R11
58 OR R11, R10, R10 // f1 bits, f1 in [0.5, 1)
59 MOVV R10, F1 // F1 = f1
60
61 SRLV $52, R4, R12
62 AND $0x7FF, R12, R12 // biased exponent
63 ADDV $-0x3FE, R12, R12 // R12 = ki
64 MOVV R12, F2
65 FFINTDV F2, F2 // F2 = k (float64)
66
67 // if f1 < Sqrt2/2 { k -= 1; f1 *= 2 }
68 MOVD 24(R13), F3 // HSqrt2
69 CMPGTD F3, F1, FCC0 // FCC0 = (HSqrt2 > f1)
70
71 MOVD 8(R13), F4 // 1.0
72 SUBD F4, F2, F17
73 MOVD 16(R13), F18 // 2.0
74 MULD F18, F1, F19
75 FSEL FCC0, F17, F2, F2
76 FSEL FCC0, F19, F1, F1
77
78 SUBD F4, F1, F3 // f := f1 - 1
79
80 // s := f / (2 + f)
81 MOVD 16(R13), F5
82 ADDD F3, F5, F5 // 2 + f
83 MOVD F3, F6
84 DIVD F5, F6, F6 // s
85
86 MULD F6, F6, F7 // s2
87 MULD F7, F7, F8 // s4
88
89 // t1 := s2 * (L1 + s4*(L3 + s4*(L5 + s4*L7)))
90 MOVD 96(R13), F9 // L7
91 MOVD 80(R13), F10 // L5
92 FMADDD F10, F8, F9, F9 // F9 = L7*s4 + L5
93 MOVD 64(R13), F10 // L3
94 FMADDD F10, F8, F9, F9 // F9 = F9*s4 + L3
95 MOVD 48(R13), F10 // L1
96 FMADDD F10, F8, F9, F9 // F9 = F9*s4 + L1
97 MULD F7, F9, F9 // t1 = F9 * s2
98
99 // t2 := s4 * (L2 + s4*(L4 + s4*L6))
100 MOVD 88(R13), F11 // L6
101 MOVD 72(R13), F12 // L4
102 FMADDD F12, F8, F11, F11 // F11 = L6*s4 + L4
103 MOVD 56(R13), F12 // L2
104 FMADDD F12, F8, F11, F11 // F11 = F11*s4 + L2
105 MULD F8, F11, F11 // t2 = F11 * s4
106
107 ADDD F11, F9, F9 // R = t1 + t2
108
109 // hfsq := 0.5 * f * f
110 MOVD 0(R13), F14 // 0.5
111 MULD F3, F14, F14
112 MULD F3, F14, F14 // hfsq
113
114 // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
115 ADDD F14, F9, F9 // hfsq + R
116 MOVD 40(R13), F15 // Ln2Lo
117 MULD F2, F15, F15 // k*Ln2Lo
118 FMADDD F15, F6, F9, F9 // F9 = s*(hfsq+R) + k*Ln2Lo
119 SUBD F9, F14, F14
120 SUBD F3, F14, F14
121 MOVD 32(R13), F16 // Ln2Hi
122 FMSUBD F14, F2, F16, F16
123
124 MOVD F16, ret+8(FP)
125 RET
126 isInfOrNaN:
127 MOVD F0, ret+8(FP) // +Inf or NaN, return x
128 RET
129 isNegative:
130 MOVV $NaN, R6
131 MOVV R6, ret+8(FP)
132 RET
133 isZero:
134 MOVV $NegInf, R6
135 MOVV R6, ret+8(FP)
136 RET
137
View as plain text