runtime: add support for math package

The math package uses routines written in Go assembly language which
LLVM/Clang cannot parse. Additionally, not all instruction sets are
supported.

Redirect all math functions written in assembly to their Go equivalent.
This is not the fastest option, but it gets packages requiring math
functions to work.
Этот коммит содержится в:
Ayke van Laethem 2019-02-01 17:22:09 +01:00 коммит произвёл Ron Evans
родитель 0757eb5919
коммит 6360e318a7
4 изменённых файлов: 488 добавлений и 1 удалений

Просмотреть файл

@ -68,10 +68,11 @@ func (p *Program) SimpleDCE() {
// functions.
main := p.mainPkg.Members["main"].(*ssa.Function)
runtimePkg := p.Program.ImportedPackage("runtime")
mathPkg := p.Program.ImportedPackage("math")
p.GetFunction(main).flag = true
worklist := []*ssa.Function{main}
for _, f := range p.Functions {
if f.exported || f.Synthetic == "package initializer" || f.Pkg == runtimePkg {
if f.exported || f.Synthetic == "package initializer" || f.Pkg == runtimePkg || (f.Pkg == mathPkg && f.Pkg != nil) {
if f.flag || isCGoInternal(f.Name()) {
continue
}

224
src/runtime/math.go Обычный файл
Просмотреть файл

@ -0,0 +1,224 @@
package runtime
// This file redirects math stubs to their fallback implementation.
// TODO: use optimized versions if possible.
import (
_ "unsafe"
)
//go:linkname math_Asin math.Asin
func math_Asin(x float64) float64 { return math_asin(x) }
//go:linkname math_asin math.asin
func math_asin(x float64) float64
//go:linkname math_Asinh math.Asinh
func math_Asinh(x float64) float64 { return math_asinh(x) }
//go:linkname math_asinh math.asinh
func math_asinh(x float64) float64
//go:linkname math_Acos math.Acos
func math_Acos(x float64) float64 { return math_acos(x) }
//go:linkname math_acos math.acos
func math_acos(x float64) float64
//go:linkname math_Acosh math.Acosh
func math_Acosh(x float64) float64 { return math_acosh(x) }
//go:linkname math_acosh math.acosh
func math_acosh(x float64) float64
//go:linkname math_Atan math.Atan
func math_Atan(x float64) float64 { return math_atan(x) }
//go:linkname math_atan math.atan
func math_atan(x float64) float64
//go:linkname math_Atanh math.Atanh
func math_Atanh(x float64) float64 { return math_atanh(x) }
//go:linkname math_atanh math.atanh
func math_atanh(x float64) float64
//go:linkname math_Atan2 math.Atan2
func math_Atan2(y, x float64) float64 { return math_atan2(y, x) }
//go:linkname math_atan2 math.atan2
func math_atan2(y, x float64) float64
//go:linkname math_Cbrt math.Cbrt
func math_Cbrt(x float64) float64 { return math_cbrt(x) }
//go:linkname math_cbrt math.cbrt
func math_cbrt(x float64) float64
//go:linkname math_Ceil math.Ceil
func math_Ceil(x float64) float64 { return math_ceil(x) }
//go:linkname math_ceil math.ceil
func math_ceil(x float64) float64
//go:linkname math_Cos math.Cos
func math_Cos(x float64) float64 { return math_cos(x) }
//go:linkname math_cos math.cos
func math_cos(x float64) float64
//go:linkname math_Cosh math.Cosh
func math_Cosh(x float64) float64 { return math_cosh(x) }
//go:linkname math_cosh math.cosh
func math_cosh(x float64) float64
//go:linkname math_Erf math.Erf
func math_Erf(x float64) float64 { return math_erf(x) }
//go:linkname math_erf math.erf
func math_erf(x float64) float64
//go:linkname math_Erfc math.Erfc
func math_Erfc(x float64) float64 { return math_erfc(x) }
//go:linkname math_erfc math.erfc
func math_erfc(x float64) float64
//go:linkname math_Exp math.Exp
func math_Exp(x float64) float64 { return math_exp(x) }
//go:linkname math_exp math.exp
func math_exp(x float64) float64
//go:linkname math_Expm1 math.Expm1
func math_Expm1(x float64) float64 { return math_expm1(x) }
//go:linkname math_expm1 math.expm1
func math_expm1(x float64) float64
//go:linkname math_Exp2 math.Exp2
func math_Exp2(x float64) float64 { return math_exp2(x) }
//go:linkname math_exp2 math.exp2
func math_exp2(x float64) float64
//go:linkname math_Floor math.Floor
func math_Floor(x float64) float64 { return math_floor(x) }
//go:linkname math_floor math.floor
func math_floor(x float64) float64
//go:linkname math_Frexp math.Frexp
func math_Frexp(x float64) (float64, int) { return math_frexp(x) }
//go:linkname math_frexp math.frexp
func math_frexp(x float64) (float64, int)
//go:linkname math_Hypot math.Hypot
func math_Hypot(p, q float64) float64 { return math_hypot(p, q) }
//go:linkname math_hypot math.hypot
func math_hypot(p, q float64) float64
//go:linkname math_Ldexp math.Ldexp
func math_Ldexp(frac float64, exp int) float64 { return math_ldexp(frac, exp) }
//go:linkname math_ldexp math.ldexp
func math_ldexp(frac float64, exp int) float64
//go:linkname math_Log math.Log
func math_Log(x float64) float64 { return math_log(x) }
//go:linkname math_log math.log
func math_log(x float64) float64
//go:linkname math_Log1p math.Log1p
func math_Log1p(x float64) float64 { return math_log1p(x) }
//go:linkname math_log1p math.log1p
func math_log1p(x float64) float64
//go:linkname math_Log10 math.Log10
func math_Log10(x float64) float64 { return math_log10(x) }
//go:linkname math_log10 math.log10
func math_log10(x float64) float64
//go:linkname math_Log2 math.Log2
func math_Log2(x float64) float64 { return math_log2(x) }
//go:linkname math_log2 math.log2
func math_log2(x float64) float64
//go:linkname math_Max math.Max
func math_Max(x, y float64) float64 { return math_max(x, y) }
//go:linkname math_max math.max
func math_max(x, y float64) float64
//go:linkname math_Min math.Min
func math_Min(x, y float64) float64 { return math_min(x, y) }
//go:linkname math_min math.min
func math_min(x, y float64) float64
//go:linkname math_Mod math.Mod
func math_Mod(x, y float64) float64 { return math_mod(x, y) }
//go:linkname math_mod math.mod
func math_mod(x, y float64) float64
//go:linkname math_Modf math.Modf
func math_Modf(x float64) (float64, float64) { return math_modf(x) }
//go:linkname math_modf math.modf
func math_modf(x float64) (float64, float64)
//go:linkname math_Pow math.Pow
func math_Pow(x, y float64) float64 { return math_pow(x, y) }
//go:linkname math_pow math.pow
func math_pow(x, y float64) float64
//go:linkname math_Remainder math.Remainder
func math_Remainder(x, y float64) float64 { return math_remainder(x, y) }
//go:linkname math_remainder math.remainder
func math_remainder(x, y float64) float64
//go:linkname math_Sin math.Sin
func math_Sin(x float64) float64 { return math_sin(x) }
//go:linkname math_sin math.sin
func math_sin(x float64) float64
//go:linkname math_Sinh math.Sinh
func math_Sinh(x float64) float64 { return math_sinh(x) }
//go:linkname math_sinh math.sinh
func math_sinh(x float64) float64
//go:linkname math_Sqrt math.Sqrt
func math_Sqrt(x float64) float64 { return math_sqrt(x) }
//go:linkname math_sqrt math.sqrt
func math_sqrt(x float64) float64
//go:linkname math_Tan math.Tan
func math_Tan(x float64) float64 { return math_tan(x) }
//go:linkname math_tan math.tan
func math_tan(x float64) float64
//go:linkname math_Tanh math.Tanh
func math_Tanh(x float64) float64 { return math_tanh(x) }
//go:linkname math_tanh math.tanh
func math_tanh(x float64) float64
//go:linkname math_Trunc math.Trunc
func math_Trunc(x float64) float64 { return math_trunc(x) }
//go:linkname math_trunc math.trunc
func math_trunc(x float64) float64

46
testdata/math.go предоставленный Обычный файл
Просмотреть файл

@ -0,0 +1,46 @@
package main
import "math"
func main() {
for _, n := range []float64{0.3, 1.5, 2.6, -1.1, -3.1, -3.8} {
println("n:", n)
println(" asin: ", math.Asin(n))
println(" asinh: ", math.Asinh(n))
println(" acos: ", math.Acos(n))
println(" acosh: ", math.Acosh(n))
println(" atan: ", math.Atan(n))
println(" atanh: ", math.Atanh(n))
println(" atan2: ", math.Atan2(n, 0.2))
println(" cbrt: ", math.Cbrt(n))
println(" ceil: ", math.Ceil(n))
println(" cos: ", math.Cos(n))
println(" cosh: ", math.Cosh(n))
println(" erf: ", math.Erf(n))
println(" erfc: ", math.Erfc(n))
println(" exp: ", math.Exp(n))
println(" expm1: ", math.Expm1(n))
println(" exp2: ", math.Exp2(n))
println(" floor: ", math.Floor(n))
f, e := math.Frexp(n)
println(" frexp: ", f, e)
println(" hypot: ", math.Hypot(n, n*2))
println(" ldexp: ", math.Ldexp(n, 2))
println(" log: ", math.Log(n))
println(" log1p: ", math.Log1p(n))
println(" log10: ", math.Log10(n))
println(" log2: ", math.Log2(n))
println(" max: ", math.Max(n, n+1))
println(" min: ", math.Min(n, n+1))
println(" mod: ", math.Mod(n, n+1))
i, f := math.Modf(n)
println(" modf: ", i, f)
println(" pow: ", math.Pow(n, n))
println(" remainder:", math.Remainder(n, n+0.2))
println(" sin: ", math.Sin(n))
println(" sinh: ", math.Sinh(n))
println(" tan: ", math.Tan(n))
println(" tanh: ", math.Tanh(n))
println(" trunc: ", math.Trunc(n))
}
}

216
testdata/math.txt предоставленный Обычный файл
Просмотреть файл

@ -0,0 +1,216 @@
n: +3.000000e-001
asin: +3.046927e-001
asinh: +2.956730e-001
acos: +1.266104e+000
acosh: NaN
atan: +2.914568e-001
atanh: +3.095196e-001
atan2: +9.827937e-001
cbrt: +6.694330e-001
ceil: +1.000000e+000
cos: +9.553365e-001
cosh: +1.045339e+000
erf: +3.286268e-001
erfc: +6.713732e-001
exp: +1.349859e+000
expm1: +3.498588e-001
exp2: +1.231144e+000
floor: +0.000000e+000
frexp: +6.000000e-001 -1
hypot: +6.708204e-001
ldexp: +1.200000e+000
log: -1.203973e+000
log1p: +2.623643e-001
log10: -5.228787e-001
log2: -1.736966e+000
max: +1.300000e+000
min: +3.000000e-001
mod: +3.000000e-001
modf: +0.000000e+000 +3.000000e-001
pow: +6.968453e-001
remainder: -2.000000e-001
sin: +2.955202e-001
sinh: +3.045203e-001
tan: +3.093362e-001
tanh: +2.913126e-001
trunc: +0.000000e+000
n: +1.500000e+000
asin: NaN
asinh: +1.194763e+000
acos: NaN
acosh: +9.624237e-001
atan: +9.827937e-001
atanh: NaN
atan2: +1.438245e+000
cbrt: +1.144714e+000
ceil: +2.000000e+000
cos: +7.073720e-002
cosh: +2.352410e+000
erf: +9.661051e-001
erfc: +3.389485e-002
exp: +4.481689e+000
expm1: +3.481689e+000
exp2: +2.828427e+000
floor: +1.000000e+000
frexp: +7.500000e-001 1
hypot: +3.354102e+000
ldexp: +6.000000e+000
log: +4.054651e-001
log1p: +9.162907e-001
log10: +1.760913e-001
log2: +5.849625e-001
max: +2.500000e+000
min: +1.500000e+000
mod: +1.500000e+000
modf: +1.000000e+000 +5.000000e-001
pow: +1.837117e+000
remainder: -2.000000e-001
sin: +9.974950e-001
sinh: +2.129279e+000
tan: +1.410142e+001
tanh: +9.051483e-001
trunc: +1.000000e+000
n: +2.600000e+000
asin: NaN
asinh: +1.683743e+000
acos: NaN
acosh: +1.609438e+000
atan: +1.203622e+000
atanh: NaN
atan2: +1.494024e+000
cbrt: +1.375069e+000
ceil: +3.000000e+000
cos: -8.568888e-001
cosh: +6.769006e+000
erf: +9.997640e-001
erfc: +2.360344e-004
exp: +1.346374e+001
expm1: +1.246374e+001
exp2: +6.062866e+000
floor: +2.000000e+000
frexp: +6.500000e-001 2
hypot: +5.813777e+000
ldexp: +1.040000e+001
log: +9.555114e-001
log1p: +1.280934e+000
log10: +4.149733e-001
log2: +1.378512e+000
max: +3.600000e+000
min: +2.600000e+000
mod: +2.600000e+000
modf: +2.000000e+000 +6.000000e-001
pow: +1.199308e+001
remainder: -2.000000e-001
sin: +5.155014e-001
sinh: +6.694732e+000
tan: -6.015966e-001
tanh: +9.890274e-001
trunc: +2.000000e+000
n: -1.100000e+000
asin: NaN
asinh: -9.503469e-001
acos: NaN
acosh: NaN
atan: -8.329813e-001
atanh: NaN
atan2: -1.390943e+000
cbrt: -1.032280e+000
ceil: -1.000000e+000
cos: +4.535961e-001
cosh: +1.668519e+000
erf: -8.802051e-001
erfc: +1.880205e+000
exp: +3.328711e-001
expm1: -6.671289e-001
exp2: +4.665165e-001
floor: -2.000000e+000
frexp: -5.500000e-001 1
hypot: +2.459675e+000
ldexp: -4.400000e+000
log: NaN
log1p: NaN
log10: NaN
log2: NaN
max: -1.000000e-001
min: -1.100000e+000
mod: -1.000000e-001
modf: -1.000000e+000 -1.000000e-001
pow: NaN
remainder: -2.000000e-001
sin: -8.912074e-001
sinh: -1.335647e+000
tan: -1.964760e+000
tanh: -8.004990e-001
trunc: -1.000000e+000
n: -3.100000e+000
asin: NaN
asinh: -1.849604e+000
acos: NaN
acosh: NaN
atan: -1.258754e+000
atanh: NaN
atan2: -1.506369e+000
cbrt: -1.458100e+000
ceil: -3.000000e+000
cos: -9.991352e-001
cosh: +1.112150e+001
erf: -9.999884e-001
erfc: +1.999988e+000
exp: +4.504920e-002
expm1: -9.549508e-001
exp2: +1.166291e-001
floor: -4.000000e+000
frexp: -7.750000e-001 2
hypot: +6.931811e+000
ldexp: -1.240000e+001
log: NaN
log1p: NaN
log10: NaN
log2: NaN
max: -2.100000e+000
min: -3.100000e+000
mod: -1.000000e+000
modf: -3.000000e+000 -1.000000e-001
pow: NaN
remainder: -2.000000e-001
sin: -4.158066e-002
sinh: -1.107645e+001
tan: +4.161665e-002
tanh: -9.959494e-001
trunc: -3.000000e+000
n: -3.800000e+000
asin: NaN
asinh: -2.045028e+000
acos: NaN
acosh: NaN
atan: -1.313473e+000
atanh: NaN
atan2: -1.518213e+000
cbrt: -1.560491e+000
ceil: -3.000000e+000
cos: -7.909677e-001
cosh: +2.236178e+001
erf: -9.999999e-001
erfc: +2.000000e+000
exp: +2.237077e-002
expm1: -9.776292e-001
exp2: +7.179365e-002
floor: -4.000000e+000
frexp: -9.500000e-001 2
hypot: +8.497058e+000
ldexp: -1.520000e+001
log: NaN
log1p: NaN
log10: NaN
log2: NaN
max: -2.800000e+000
min: -3.800000e+000
mod: -1.000000e+000
modf: -3.000000e+000 -8.000000e-001
pow: NaN
remainder: -2.000000e-001
sin: +6.118579e-001
sinh: -2.233941e+001
tan: -7.735561e-001
tanh: -9.989996e-001
trunc: -3.000000e+000