Copy printfloat() from original runtime
I've tried writing my own, but I couldn't make it correct in all cases. So just copy the one from upstream for now, hopefully to be replaced at some point. TODO: add a printfloat32() implementation, now it just casts to float64. This will be useful for embedded systems that sometimes have float32 but not float64.
Этот коммит содержится в:
родитель
46d2d2e777
коммит
94ce893ab4
2 изменённых файлов: 90 добавлений и 0 удалений
|
@ -1303,6 +1303,10 @@ func (c *Compiler) parseBuiltin(frame *Frame, args []ssa.Value, callName string)
|
||||||
c.builder.CreateCall(fn, []llvm.Value{value}, "")
|
c.builder.CreateCall(fn, []llvm.Value{value}, "")
|
||||||
} else if typ.Kind() == types.Bool {
|
} else if typ.Kind() == types.Bool {
|
||||||
c.builder.CreateCall(c.mod.NamedFunction("runtime.printbool"), []llvm.Value{value}, "")
|
c.builder.CreateCall(c.mod.NamedFunction("runtime.printbool"), []llvm.Value{value}, "")
|
||||||
|
} else if typ.Kind() == types.Float32 {
|
||||||
|
c.builder.CreateCall(c.mod.NamedFunction("runtime.printfloat32"), []llvm.Value{value}, "")
|
||||||
|
} else if typ.Kind() == types.Float64 {
|
||||||
|
c.builder.CreateCall(c.mod.NamedFunction("runtime.printfloat64"), []llvm.Value{value}, "")
|
||||||
} else {
|
} else {
|
||||||
return llvm.Value{}, errors.New("unknown basic arg type: " + typ.String())
|
return llvm.Value{}, errors.New("unknown basic arg type: " + typ.String())
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,92 @@ func printint64(n int64) {
|
||||||
printuint64(uint64(n))
|
printuint64(uint64(n))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func printfloat32(v float32) {
|
||||||
|
// TODO: write an implementation like printfloat64, as some systems have
|
||||||
|
// 32-bit floats but only software emulation for 64-bit floats.
|
||||||
|
printfloat64(float64(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// printfloat64() was copied from the relevant source in the original Go
|
||||||
|
// implementation. It is copyright by the Go authors, licensed under the same
|
||||||
|
// BSD 3-clause license. See https://golang.org/LICENSE for details.
|
||||||
|
//
|
||||||
|
// Source:
|
||||||
|
// https://github.com/golang/go/blob/master/src/runtime/print.go
|
||||||
|
func printfloat64(v float64) {
|
||||||
|
switch {
|
||||||
|
case v != v:
|
||||||
|
printstring("NaN")
|
||||||
|
return
|
||||||
|
case v+v == v && v > 0:
|
||||||
|
printstring("+Inf")
|
||||||
|
return
|
||||||
|
case v+v == v && v < 0:
|
||||||
|
printstring("-Inf")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const n = 7 // digits printed
|
||||||
|
var buf [n + 7]byte
|
||||||
|
buf[0] = '+'
|
||||||
|
e := 0 // exp
|
||||||
|
if v == 0 {
|
||||||
|
if 1/v < 0 {
|
||||||
|
buf[0] = '-'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if v < 0 {
|
||||||
|
v = -v
|
||||||
|
buf[0] = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize
|
||||||
|
for v >= 10 {
|
||||||
|
e++
|
||||||
|
v /= 10
|
||||||
|
}
|
||||||
|
for v < 1 {
|
||||||
|
e--
|
||||||
|
v *= 10
|
||||||
|
}
|
||||||
|
|
||||||
|
// round
|
||||||
|
h := 5.0
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
h /= 10
|
||||||
|
}
|
||||||
|
v += h
|
||||||
|
if v >= 10 {
|
||||||
|
e++
|
||||||
|
v /= 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// format +d.dddd+edd
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
s := int(v)
|
||||||
|
buf[i+2] = byte(s + '0')
|
||||||
|
v -= float64(s)
|
||||||
|
v *= 10
|
||||||
|
}
|
||||||
|
buf[1] = buf[2]
|
||||||
|
buf[2] = '.'
|
||||||
|
|
||||||
|
buf[n+2] = 'e'
|
||||||
|
buf[n+3] = '+'
|
||||||
|
if e < 0 {
|
||||||
|
e = -e
|
||||||
|
buf[n+3] = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[n+4] = byte(e/100) + '0'
|
||||||
|
buf[n+5] = byte(e/10)%10 + '0'
|
||||||
|
buf[n+6] = byte(e%10) + '0'
|
||||||
|
for _, c := range buf {
|
||||||
|
putchar(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func printspace() {
|
func printspace() {
|
||||||
putchar(' ')
|
putchar(' ')
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче