Skip to content

Commit

Permalink
feat: use softfloat as is it
Browse files Browse the repository at this point in the history
  • Loading branch information
omarsy committed Dec 20, 2024
1 parent 08dba29 commit 7f7b888
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 498 deletions.
5 changes: 3 additions & 2 deletions gno.land/pkg/sdk/vm/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package vm
import (
"encoding/base64"
"fmt"
"math"
"strconv"
"strings"

Expand Down Expand Up @@ -143,11 +144,11 @@ func convertArgToGno(arg string, argT gno.Type) (tv gno.TypedValue) {
return
case gno.Float32Type:
value := convertFloat(arg, 32)
tv.SetFloat32(gno.ConvertToSoftFloat32(value))
tv.SetFloat32(math.Float32bits(float32(value)))
return
case gno.Float64Type:
value := convertFloat(arg, 64)
tv.SetFloat64(gno.ConvertToSoftFloat64(value))
tv.SetFloat64(math.Float64bits(value))
return
default:
panic(fmt.Sprintf("unexpected primitive type %s", bt.String()))
Expand Down
5 changes: 3 additions & 2 deletions gnovm/pkg/gnolang/frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gnolang

import (
"fmt"
"math"
"strings"
)

Expand Down Expand Up @@ -207,9 +208,9 @@ func toConstExpTrace(cte *ConstExpr) string {
case Uint64Type:
return fmt.Sprintf("%d", tv.GetUint64())
case Float32Type:
return fmt.Sprintf("%v", tv.GetFloat32())
return fmt.Sprintf("%v", math.Float32frombits(tv.GetFloat32()))
case Float64Type:
return fmt.Sprintf("%v", tv.GetFloat64())
return fmt.Sprintf("%v", math.Float64frombits(tv.GetFloat64()))
}
}

Expand Down
19 changes: 11 additions & 8 deletions gnovm/pkg/gnolang/gonative.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package gnolang

import (
"fmt"
"math"
"reflect"

"github.com/gnolang/gno/gnovm/pkg/gnolang/internal/softfloat"
)

// NOTE
Expand Down Expand Up @@ -329,9 +332,9 @@ func go2GnoValue(alloc *Allocator, rv reflect.Value) (tv TypedValue) {
case reflect.Uint64:
tv.SetUint64(rv.Uint())
case reflect.Float32:
tv.SetFloat32(ConvertToSoftFloat32(rv.Float()))
tv.SetFloat32(softfloat.F64to32(math.Float64bits(rv.Float())))

Check warning on line 335 in gnovm/pkg/gnolang/gonative.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/gonative.go#L335

Added line #L335 was not covered by tests
case reflect.Float64:
tv.SetFloat64(ConvertToSoftFloat64(rv.Float()))
tv.SetFloat64(math.Float64bits(rv.Float()))

Check warning on line 337 in gnovm/pkg/gnolang/gonative.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/gonative.go#L337

Added line #L337 was not covered by tests
case reflect.Array:
tv.V = alloc.NewNative(rv)
case reflect.Slice:
Expand Down Expand Up @@ -428,11 +431,11 @@ func go2GnoValueUpdate(alloc *Allocator, rlm *Realm, lvl int, tv *TypedValue, rv
}
case Float32Kind:
if lvl != 0 {
tv.SetFloat32(ConvertToSoftFloat32(rv.Float()))
tv.SetFloat32(softfloat.F64to32(math.Float64bits(rv.Float())))

Check warning on line 434 in gnovm/pkg/gnolang/gonative.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/gonative.go#L434

Added line #L434 was not covered by tests
}
case Float64Kind:
if lvl != 0 {
tv.SetFloat64(ConvertToSoftFloat64(rv.Float()))
tv.SetFloat64(math.Float64bits(rv.Float()))

Check warning on line 438 in gnovm/pkg/gnolang/gonative.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/gonative.go#L438

Added line #L438 was not covered by tests
}
case BigintKind:
panic("not yet implemented")
Expand Down Expand Up @@ -644,9 +647,9 @@ func go2GnoValue2(alloc *Allocator, store Store, rv reflect.Value, recursive boo
case reflect.Uint64:
tv.SetUint64(rv.Uint())
case reflect.Float32:
tv.SetFloat32(ConvertToSoftFloat32(rv.Float()))
tv.SetFloat32(softfloat.F64to32(math.Float64bits(rv.Float())))
case reflect.Float64:
tv.SetFloat64(ConvertToSoftFloat64(rv.Float()))
tv.SetFloat64(math.Float64bits(rv.Float()))
case reflect.Array:
rvl := rv.Len()
if rv.Type().Elem().Kind() == reflect.Uint8 {
Expand Down Expand Up @@ -1049,9 +1052,9 @@ func gno2GoValue(tv *TypedValue, rv reflect.Value) (ret reflect.Value) {
case Uint64Type:
rv.SetUint(tv.GetUint64())
case Float32Type:
rv.SetFloat(tv.GetFloat32().Float64())
rv.SetFloat(math.Float64frombits(softfloat.F32to64(tv.GetFloat32())))
case Float64Type:
rv.SetFloat(tv.GetFloat64().Float64())
rv.SetFloat(math.Float64frombits(tv.GetFloat64()))
default:
panic(fmt.Sprintf(
"unexpected type %s",
Expand Down
45 changes: 45 additions & 0 deletions gnovm/pkg/gnolang/internal/softfloat/softfloat.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ package softfloat

//go:generate sh copy.sh

const (
mask = 0x7FF
shift = 64 - 11 - 1
bias = 1023
)

func Fadd64(f, g uint64) uint64 { return fadd64(f, g) }
func Fsub64(f, g uint64) uint64 { return fsub64(f, g) }
func Fmul64(f, g uint64) uint64 { return fmul64(f, g) }
Expand Down Expand Up @@ -87,3 +93,42 @@ func Fuint64to64(x uint64) uint64 { return fuint64to64(x) }

func Funpack32(f uint32) (sign, mant uint32, exp int, inf, nan bool) { return funpack32(f) }

Check warning on line 94 in gnovm/pkg/gnolang/internal/softfloat/softfloat.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/internal/softfloat/softfloat.go#L94

Added line #L94 was not covered by tests
func Funpack64(f uint64) (sign, mant uint64, exp int, inf, nan bool) { return funpack64(f) }

// Trunc

func Ftrunc64(f uint64) uint64 { return trunc(f) }
func Ftrunc32(f uint32) uint32 { return f64to32(trunc(f32to64(f))) }

func trunc(x uint64) uint64 {
cmp, _ := Fcmp64(x, Fintto64(0))
if _, _, _, isInf, IsNaN := Funpack64(x); cmp == 0 || isInf || IsNaN {
return x
}

Check warning on line 106 in gnovm/pkg/gnolang/internal/softfloat/softfloat.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/internal/softfloat/softfloat.go#L105-L106

Added lines #L105 - L106 were not covered by tests

d, _ := modf(x)
return d
}

func modf(u uint64) (it uint64, frac uint64) {
if Flt64(u, fint64to64(1)) {
switch {
case Flt64(u, fint64to64(0)):
it, frac = modf(Fneg64(u))
return -it, -frac
case feq64(u, fint64to64(0)):
return u, u // Return -0, -0 when f == -0

Check warning on line 119 in gnovm/pkg/gnolang/internal/softfloat/softfloat.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/internal/softfloat/softfloat.go#L114-L119

Added lines #L114 - L119 were not covered by tests
}
return 0, u

Check warning on line 121 in gnovm/pkg/gnolang/internal/softfloat/softfloat.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/internal/softfloat/softfloat.go#L121

Added line #L121 was not covered by tests
}

it = u
e := uint(it>>shift)&mask - bias

// Keep the top 12+e bits, the integer part; clear the rest.
if e < 64-12 {
it &^= 1<<(64-12-e) - 1
}

frac = fsub64(u, it)
return
}
41 changes: 21 additions & 20 deletions gnovm/pkg/gnolang/op_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math/big"

"github.com/cockroachdb/apd/v3"
"github.com/gnolang/gno/gnovm/pkg/gnolang/internal/softfloat"
)

// ----------------------------------------
Expand Down Expand Up @@ -391,9 +392,9 @@ func isEql(store Store, lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() == rv.GetUint64())
case Float32Kind:
return lv.GetFloat32().Eq(rv.GetFloat32())
return softfloat.Feq32(lv.GetFloat32(), rv.GetFloat32())
case Float64Kind:
return lv.GetFloat64().Eq(rv.GetFloat64())
return softfloat.Feq64(lv.GetFloat64(), rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -532,9 +533,9 @@ func isLss(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() < rv.GetUint64())
case Float32Kind:
return lv.GetFloat32().Lt(rv.GetFloat32())
return softfloat.Flt32(lv.GetFloat32(), rv.GetFloat32())
case Float64Kind:
return lv.GetFloat64().Lt(rv.GetFloat64())
return softfloat.Flt64(lv.GetFloat64(), rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -576,9 +577,9 @@ func isLeq(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() <= rv.GetUint64())
case Float32Kind:
return lv.GetFloat32().Le(rv.GetFloat32())
return softfloat.Fle32(lv.GetFloat32(), rv.GetFloat32())

Check warning on line 580 in gnovm/pkg/gnolang/op_binary.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/op_binary.go#L580

Added line #L580 was not covered by tests
case Float64Kind:
return lv.GetFloat64().Le(rv.GetFloat64())
return softfloat.Fle64(lv.GetFloat64(), rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -620,9 +621,9 @@ func isGtr(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() > rv.GetUint64())
case Float32Kind:
return lv.GetFloat32().Gt(rv.GetFloat32())
return softfloat.Fgt32(lv.GetFloat32(), rv.GetFloat32())
case Float64Kind:
return lv.GetFloat64().Gt(rv.GetFloat64())
return softfloat.Fgt64(lv.GetFloat64(), rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -664,9 +665,9 @@ func isGeq(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() >= rv.GetUint64())
case Float32Kind:
return lv.GetFloat32().Ge(rv.GetFloat32())
return softfloat.Fge32(lv.GetFloat32(), rv.GetFloat32())
case Float64Kind:
return lv.GetFloat64().Ge(rv.GetFloat64())
return softfloat.Fge64(lv.GetFloat64(), rv.GetFloat64())
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -714,10 +715,10 @@ func addAssign(alloc *Allocator, lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() + rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(lv.GetFloat32().Add(rv.GetFloat32()))
lv.SetFloat32(softfloat.Fadd32(lv.GetFloat32(), rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(lv.GetFloat64().Add(rv.GetFloat64()))
lv.SetFloat64(softfloat.Fadd64(lv.GetFloat64(), rv.GetFloat64()))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Add(lb, rv.GetBigInt())
Expand Down Expand Up @@ -770,10 +771,10 @@ func subAssign(lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() - rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(lv.GetFloat32().Sub(rv.GetFloat32()))
lv.SetFloat32(softfloat.Fsub32(lv.GetFloat32(), rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(lv.GetFloat64().Sub(rv.GetFloat64()))
lv.SetFloat64(softfloat.Fsub64(lv.GetFloat64(), rv.GetFloat64()))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Sub(lb, rv.GetBigInt())
Expand Down Expand Up @@ -826,10 +827,10 @@ func mulAssign(lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() * rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(lv.GetFloat32().Mul(rv.GetFloat32()))
lv.SetFloat32(softfloat.Fmul32(lv.GetFloat32(), rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(lv.GetFloat64().Mul(rv.GetFloat64()))
lv.SetFloat64(softfloat.Fmul64(lv.GetFloat64(), rv.GetFloat64()))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Mul(lb, rv.GetBigInt())
Expand Down Expand Up @@ -917,16 +918,16 @@ func quoAssign(lv, rv *TypedValue) *Exception {
lv.SetUint64(lv.GetUint64() / rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
if rv.GetFloat32().Eq(0) {
if softfloat.Feq32(rv.GetFloat32(), softfloat.Fintto32(0)) {
return expt
}
lv.SetFloat32(lv.GetFloat32().Div(rv.GetFloat32()))
lv.SetFloat32(softfloat.Fdiv32(lv.GetFloat32(), rv.GetFloat32()))
case Float64Type:
// NOTE: gno doesn't fuse *+.
if rv.GetFloat64().Eq(0) {
if softfloat.Feq64(rv.GetFloat64(), softfloat.Fintto64(0)) {
return expt
}
lv.SetFloat64(lv.GetFloat64().Div(rv.GetFloat64()))
lv.SetFloat64(softfloat.Fdiv64(lv.GetFloat64(), rv.GetFloat64()))
case BigintType, UntypedBigintType:
if rv.GetBigInt().Sign() == 0 {
return expt
Expand Down
9 changes: 5 additions & 4 deletions gnovm/pkg/gnolang/op_inc_dec.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/big"

"github.com/cockroachdb/apd/v3"
"github.com/gnolang/gno/gnovm/pkg/gnolang/internal/softfloat"
)

func (m *Machine) doOpInc() {
Expand Down Expand Up @@ -54,9 +55,9 @@ func (m *Machine) doOpInc() {
case Uint64Type:
lv.SetUint64(lv.GetUint64() + 1)
case Float32Type:
lv.SetFloat32(lv.GetFloat32().Add(1))
lv.SetFloat32(softfloat.Fadd32(lv.GetFloat32(), softfloat.Fintto32(1)))

Check warning on line 58 in gnovm/pkg/gnolang/op_inc_dec.go

View check run for this annotation

Codecov / codecov/patch

gnovm/pkg/gnolang/op_inc_dec.go#L58

Added line #L58 was not covered by tests
case Float64Type:
lv.SetFloat64(lv.GetFloat64().Add(1))
lv.SetFloat64(softfloat.Fadd64(lv.GetFloat64(), softfloat.Fintto64(1)))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Add(lb, big.NewInt(1))
Expand Down Expand Up @@ -124,9 +125,9 @@ func (m *Machine) doOpDec() {
case Uint64Type:
lv.SetUint64(lv.GetUint64() - 1)
case Float32Type:
lv.SetFloat32(lv.GetFloat32().Sub(1))
lv.SetFloat32(softfloat.Fsub32(lv.GetFloat32(), softfloat.Fintto32(1)))
case Float64Type:
lv.SetFloat64(lv.GetFloat64().Sub(1))
lv.SetFloat64(softfloat.Fsub64(lv.GetFloat64(), softfloat.Fintto64(1)))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Sub(lb, big.NewInt(1))
Expand Down
5 changes: 3 additions & 2 deletions gnovm/pkg/gnolang/op_unary.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/big"

"github.com/cockroachdb/apd/v3"
"github.com/gnolang/gno/gnovm/pkg/gnolang/internal/softfloat"
)

func (m *Machine) doOpUpos() {
Expand Down Expand Up @@ -46,9 +47,9 @@ func (m *Machine) doOpUneg() {
case Uint64Type:
xv.SetUint64(-xv.GetUint64())
case Float32Type:
xv.SetFloat32(xv.GetFloat32().Neg())
xv.SetFloat32(softfloat.Fneg32(xv.GetFloat32()))
case Float64Type:
xv.SetFloat64(xv.GetFloat64().Neg())
xv.SetFloat64(softfloat.Fneg64(xv.GetFloat64()))
case UntypedBigintType, BigintType:
bv := xv.V.(BigintValue)
xv.V = BigintValue{V: new(big.Int).Neg(bv.V)}
Expand Down
Loading

0 comments on commit 7f7b888

Please sign in to comment.