Skip to content

Commit

Permalink
feat(gnovm): add software floating point package (#3185)
Browse files Browse the repository at this point in the history
Closes: #312 

The idea to use softfloat and work originates from this PR:
#2863
<!-- please provide a detailed description of the changes made in this
pull request. -->

<details><summary>Contributors' checklist...</summary>

- [ ] Added new tests, or not needed, or not feasible
- [ ] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [ ] Updated the official documentation or not needed
- [ ] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [ ] Added references to related issues and PRs
- [ ] Provided any useful hints for running manual tests
</details>

---------

Co-authored-by: Morgan Bazalgette <[email protected]>
Co-authored-by: Miloš Živković <[email protected]>
  • Loading branch information
3 people authored Jan 13, 2025
1 parent ddfff60 commit 663edac
Show file tree
Hide file tree
Showing 15 changed files with 1,360 additions and 187 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(float32(value))
tv.SetFloat32(math.Float32bits(float32(value)))
return
case gno.Float64Type:
value := convertFloat(arg, 64)
tv.SetFloat64(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(float32(rv.Float()))
tv.SetFloat32(softfloat.F64to32(math.Float64bits(rv.Float())))
case reflect.Float64:
tv.SetFloat64(rv.Float())
tv.SetFloat64(math.Float64bits(rv.Float()))
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(float32(rv.Float()))
tv.SetFloat32(softfloat.F64to32(math.Float64bits(rv.Float())))
}
case Float64Kind:
if lvl != 0 {
tv.SetFloat64(rv.Float())
tv.SetFloat64(math.Float64bits(rv.Float()))
}
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(float32(rv.Float()))
tv.SetFloat32(softfloat.F64to32(math.Float64bits(rv.Float())))
case reflect.Float64:
tv.SetFloat64(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(float64(tv.GetFloat32()))
rv.SetFloat(math.Float64frombits(softfloat.F32to64(tv.GetFloat32())))
case Float64Type:
rv.SetFloat(tv.GetFloat64())
rv.SetFloat(math.Float64frombits(tv.GetFloat64()))
default:
panic(fmt.Sprintf(
"unexpected type %s",
Expand Down
32 changes: 32 additions & 0 deletions gnovm/pkg/gnolang/internal/softfloat/copy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/sh

# softfloat64.go:
# - add header
# - change package name
cat > runtime_softfloat64.go << EOF
// Code generated by copy.sh. DO NOT EDIT.
// This file is copied from \$GOROOT/src/runtime/softfloat64.go.
// It is the software floating point implementation used by the Go runtime.
EOF
cat "$GOROOT/src/runtime/softfloat64.go" >> ./runtime_softfloat64.go
sed -i 's/^package runtime$/package softfloat/' runtime_softfloat64.go

# softfloat64_test.go:
# - add header
# - change package name
# - change import to right package
# - change GOARCH to runtime.GOARCH, and import the "runtime" package
cat > runtime_softfloat64_test.go << EOF
// Code generated by copy.sh. DO NOT EDIT.
// This file is copied from \$GOROOT/src/runtime/softfloat64_test.go.
// It is the tests for the software floating point implementation
// used by the Go runtime.
EOF
cat "$GOROOT/src/runtime/softfloat64_test.go" >> ./runtime_softfloat64_test.go
sed -i 's/^package runtime_test$/package softfloat_test/
s#^\t\. "runtime"$#\t. "github.com/gnolang/gno/gnovm/pkg/gnolang/internal/softfloat"#
s/GOARCH/runtime.GOARCH/g
16a\
"runtime"' runtime_softfloat64_test.go
Loading

0 comments on commit 663edac

Please sign in to comment.