Skip to content

Commit

Permalink
feat: use soft float
Browse files Browse the repository at this point in the history
  • Loading branch information
omarsy committed Nov 23, 2024
1 parent 9a55489 commit beab1fb
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 60 deletions.
2 changes: 2 additions & 0 deletions gnovm/pkg/gnolang/internal/softfloat/softfloat.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ func Fint32to32(x int32) uint32 { return fint32to32(x) }
func Fint32to64(x int32) uint64 { return fint32to64(x) }
func Fint64to32(x int64) uint32 { return fint64to32(x) }
func Fint64to64(x int64) uint64 { return fint64to64(x) }
func Fuint64to32(x uint64) uint32 { return fuint64to32(x) }
func Fuint64to64(x uint64) uint64 { return fuint64to64(x) }
68 changes: 52 additions & 16 deletions gnovm/pkg/gnolang/op_binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package gnolang

import (
"fmt"
"math"
"math/big"

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

// ----------------------------------------
Expand Down Expand Up @@ -329,6 +331,18 @@ func (m *Machine) doOpBandn() {
bandnAssign(lv, rv)
}

func compFloat32(lv, rv *TypedValue) (int32, bool) {
lvf := softfloat.F32to64(math.Float32bits(lv.GetFloat32()))
rvf := softfloat.F32to64(math.Float32bits(rv.GetFloat32()))
return softfloat.Fcmp64(lvf, rvf)
}

func compFloat64(lv, rv *TypedValue) (int32, bool) {
lvf := math.Float64bits(lv.GetFloat64())
rvf := math.Float64bits(rv.GetFloat64())
return softfloat.Fcmp64(lvf, rvf)
}

// ----------------------------------------
// logic functions

Expand Down Expand Up @@ -384,9 +398,11 @@ func isEql(store Store, lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() == rv.GetUint64())
case Float32Kind:
return (lv.GetFloat32() == rv.GetFloat32()) // XXX determinism?
cmp, nan := compFloat32(lv, rv)
return cmp == 0 && !nan
case Float64Kind:
return (lv.GetFloat64() == rv.GetFloat64()) // XXX determinism?
cmp, nan := compFloat64(lv, rv)
return cmp == 0 && !nan
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -525,9 +541,11 @@ func isLss(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() < rv.GetUint64())
case Float32Kind:
return (lv.GetFloat32() < rv.GetFloat32()) // XXX determinism?
cmp, nan := compFloat32(lv, rv)
return (cmp < 0) && !nan
case Float64Kind:
return (lv.GetFloat64() < rv.GetFloat64()) // XXX determinism?
cmp, nan := compFloat64(lv, rv)
return (cmp < 0) && !nan
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -569,9 +587,11 @@ func isLeq(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() <= rv.GetUint64())
case Float32Kind:
return (lv.GetFloat32() <= rv.GetFloat32()) // XXX determinism?
cmp, nan := compFloat32(lv, rv)
return (cmp <= 0) && !nan
case Float64Kind:
return (lv.GetFloat64() <= rv.GetFloat64()) // XXX determinism?
cmp, nan := compFloat64(lv, rv)
return (cmp <= 0) && !nan
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -613,9 +633,11 @@ func isGtr(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() > rv.GetUint64())
case Float32Kind:
return (lv.GetFloat32() > rv.GetFloat32()) // XXX determinism?
cmp, nan := compFloat32(lv, rv)
return (cmp > 0) && !nan
case Float64Kind:
return (lv.GetFloat64() > rv.GetFloat64()) // XXX determinism?
cmp, nan := compFloat64(lv, rv)
return (cmp > 0) && !nan
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -657,9 +679,11 @@ func isGeq(lv, rv *TypedValue) bool {
case Uint64Kind:
return (lv.GetUint64() >= rv.GetUint64())
case Float32Kind:
return (lv.GetFloat32() >= rv.GetFloat32()) // XXX determinism?
cmp, nan := compFloat32(lv, rv)
return (cmp >= 0) && !nan
case Float64Kind:
return (lv.GetFloat64() >= rv.GetFloat64()) // XXX determinism?
cmp, nan := compFloat64(lv, rv)
return (cmp >= 0) && !nan
case BigintKind:
lb := lv.V.(BigintValue).V
rb := rv.V.(BigintValue).V
Expand Down Expand Up @@ -707,10 +731,14 @@ func addAssign(alloc *Allocator, lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() + rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(lv.GetFloat32() + rv.GetFloat32()) // XXX determinism?
lvf := math.Float32bits(lv.GetFloat32())
rvf := math.Float32bits(rv.GetFloat32())
lv.SetFloat32(math.Float32frombits(softfloat.Fadd32(lvf, rvf)))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(lv.GetFloat64() + rv.GetFloat64()) // XXX determinism?
lvf := math.Float64bits(lv.GetFloat64())
rvf := math.Float64bits(rv.GetFloat64())
lv.SetFloat64(math.Float64frombits(softfloat.Fadd64(lvf, rvf)))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Add(lb, rv.GetBigInt())
Expand Down Expand Up @@ -763,10 +791,14 @@ func subAssign(lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() - rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(lv.GetFloat32() - rv.GetFloat32()) // XXX determinism?
lvf := math.Float32bits(lv.GetFloat32())
rvf := math.Float32bits(rv.GetFloat32())
lv.SetFloat32(math.Float32frombits(softfloat.Fsub32(lvf, rvf)))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(lv.GetFloat64() - rv.GetFloat64()) // XXX determinism?
lvf := math.Float64bits(lv.GetFloat64())
rvf := math.Float64bits(rv.GetFloat64())
lv.SetFloat64(math.Float64frombits(softfloat.Fsub64(lvf, rvf)))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Sub(lb, rv.GetBigInt())
Expand Down Expand Up @@ -819,10 +851,14 @@ func mulAssign(lv, rv *TypedValue) {
lv.SetUint64(lv.GetUint64() * rv.GetUint64())
case Float32Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat32(lv.GetFloat32() * rv.GetFloat32()) // XXX determinism?
lvf := math.Float32bits(lv.GetFloat32())
rvf := math.Float32bits(rv.GetFloat32())
lv.SetFloat32(math.Float32frombits(softfloat.Fmul32(lvf, rvf)))
case Float64Type:
// NOTE: gno doesn't fuse *+.
lv.SetFloat64(lv.GetFloat64() * rv.GetFloat64()) // XXX determinism?
lvf := math.Float64bits(lv.GetFloat64())
rvf := math.Float64bits(rv.GetFloat64())
lv.SetFloat64(math.Float64frombits(softfloat.Fmul64(lvf, rvf)))
case BigintType, UntypedBigintType:
lb := lv.GetBigInt()
lb = big.NewInt(0).Mul(lb, rv.GetBigInt())
Expand Down
Loading

0 comments on commit beab1fb

Please sign in to comment.