mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile, runtime: always enable Wasm signext and satconv features
These features have been standardized since at least Wasm 2.0. Always enable them. The corresponding GOWASM settings are now no-op. Change-Id: I0e59f21696a69a4e289127988aad629a720b002b Reviewed-on: https://go-review.googlesource.com/c/go/+/707855 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
db10db6be3
commit
742f92063e
6 changed files with 38 additions and 229 deletions
|
|
@ -55,12 +55,9 @@
|
||||||
(ZeroExt32to64 x:(I64Load32U _ _)) => x
|
(ZeroExt32to64 x:(I64Load32U _ _)) => x
|
||||||
(ZeroExt16to(64|32) x:(I64Load16U _ _)) => x
|
(ZeroExt16to(64|32) x:(I64Load16U _ _)) => x
|
||||||
(ZeroExt8to(64|32|16) x:(I64Load8U _ _)) => x
|
(ZeroExt8to(64|32|16) x:(I64Load8U _ _)) => x
|
||||||
(SignExt32to64 x) && buildcfg.GOWASM.SignExt => (I64Extend32S x)
|
(SignExt32to64 x) => (I64Extend32S x)
|
||||||
(SignExt8to(64|32|16) x) && buildcfg.GOWASM.SignExt => (I64Extend8S x)
|
(SignExt8to(64|32|16) x) => (I64Extend8S x)
|
||||||
(SignExt16to(64|32) x) && buildcfg.GOWASM.SignExt => (I64Extend16S x)
|
(SignExt16to(64|32) x) => (I64Extend16S x)
|
||||||
(SignExt32to64 x) => (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
|
|
||||||
(SignExt16to(64|32) x) => (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
|
|
||||||
(SignExt8to(64|32|16) x) => (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
|
||||||
(ZeroExt32to64 x) => (I64And x (I64Const [0xffffffff]))
|
(ZeroExt32to64 x) => (I64And x (I64Const [0xffffffff]))
|
||||||
(ZeroExt16to(64|32) x) => (I64And x (I64Const [0xffff]))
|
(ZeroExt16to(64|32) x) => (I64And x (I64Const [0xffff]))
|
||||||
(ZeroExt8to(64|32|16) x) => (I64And x (I64Const [0xff]))
|
(ZeroExt8to(64|32|16) x) => (I64And x (I64Const [0xff]))
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
package ssa
|
package ssa
|
||||||
|
|
||||||
import "internal/buildcfg"
|
|
||||||
import "math"
|
import "math"
|
||||||
import "cmd/compile/internal/types"
|
import "cmd/compile/internal/types"
|
||||||
|
|
||||||
|
|
@ -3202,8 +3201,6 @@ func rewriteValueWasm_OpRsh8x8(v *Value) bool {
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSignExt16to32(v *Value) bool {
|
func rewriteValueWasm_OpSignExt16to32(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (SignExt16to32 x:(I64Load16S _ _))
|
// match: (SignExt16to32 x:(I64Load16S _ _))
|
||||||
// result: x
|
// result: x
|
||||||
for {
|
for {
|
||||||
|
|
@ -3215,34 +3212,16 @@ func rewriteValueWasm_OpSignExt16to32(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt16to32 x)
|
// match: (SignExt16to32 x)
|
||||||
// cond: buildcfg.GOWASM.SignExt
|
|
||||||
// result: (I64Extend16S x)
|
// result: (I64Extend16S x)
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if !(buildcfg.GOWASM.SignExt) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpWasmI64Extend16S)
|
v.reset(OpWasmI64Extend16S)
|
||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt16to32 x)
|
|
||||||
// result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
|
|
||||||
for {
|
|
||||||
x := v_0
|
|
||||||
v.reset(OpWasmI64ShrS)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
|
|
||||||
v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
|
|
||||||
v1.AuxInt = int64ToAuxInt(48)
|
|
||||||
v0.AddArg2(x, v1)
|
|
||||||
v.AddArg2(v0, v1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSignExt16to64(v *Value) bool {
|
func rewriteValueWasm_OpSignExt16to64(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (SignExt16to64 x:(I64Load16S _ _))
|
// match: (SignExt16to64 x:(I64Load16S _ _))
|
||||||
// result: x
|
// result: x
|
||||||
for {
|
for {
|
||||||
|
|
@ -3254,34 +3233,16 @@ func rewriteValueWasm_OpSignExt16to64(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt16to64 x)
|
// match: (SignExt16to64 x)
|
||||||
// cond: buildcfg.GOWASM.SignExt
|
|
||||||
// result: (I64Extend16S x)
|
// result: (I64Extend16S x)
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if !(buildcfg.GOWASM.SignExt) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpWasmI64Extend16S)
|
v.reset(OpWasmI64Extend16S)
|
||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt16to64 x)
|
|
||||||
// result: (I64ShrS (I64Shl x (I64Const [48])) (I64Const [48]))
|
|
||||||
for {
|
|
||||||
x := v_0
|
|
||||||
v.reset(OpWasmI64ShrS)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
|
|
||||||
v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
|
|
||||||
v1.AuxInt = int64ToAuxInt(48)
|
|
||||||
v0.AddArg2(x, v1)
|
|
||||||
v.AddArg2(v0, v1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSignExt32to64(v *Value) bool {
|
func rewriteValueWasm_OpSignExt32to64(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (SignExt32to64 x:(I64Load32S _ _))
|
// match: (SignExt32to64 x:(I64Load32S _ _))
|
||||||
// result: x
|
// result: x
|
||||||
for {
|
for {
|
||||||
|
|
@ -3293,34 +3254,16 @@ func rewriteValueWasm_OpSignExt32to64(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt32to64 x)
|
// match: (SignExt32to64 x)
|
||||||
// cond: buildcfg.GOWASM.SignExt
|
|
||||||
// result: (I64Extend32S x)
|
// result: (I64Extend32S x)
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if !(buildcfg.GOWASM.SignExt) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpWasmI64Extend32S)
|
v.reset(OpWasmI64Extend32S)
|
||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt32to64 x)
|
|
||||||
// result: (I64ShrS (I64Shl x (I64Const [32])) (I64Const [32]))
|
|
||||||
for {
|
|
||||||
x := v_0
|
|
||||||
v.reset(OpWasmI64ShrS)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
|
|
||||||
v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
|
|
||||||
v1.AuxInt = int64ToAuxInt(32)
|
|
||||||
v0.AddArg2(x, v1)
|
|
||||||
v.AddArg2(v0, v1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSignExt8to16(v *Value) bool {
|
func rewriteValueWasm_OpSignExt8to16(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (SignExt8to16 x:(I64Load8S _ _))
|
// match: (SignExt8to16 x:(I64Load8S _ _))
|
||||||
// result: x
|
// result: x
|
||||||
for {
|
for {
|
||||||
|
|
@ -3332,34 +3275,16 @@ func rewriteValueWasm_OpSignExt8to16(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt8to16 x)
|
// match: (SignExt8to16 x)
|
||||||
// cond: buildcfg.GOWASM.SignExt
|
|
||||||
// result: (I64Extend8S x)
|
// result: (I64Extend8S x)
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if !(buildcfg.GOWASM.SignExt) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpWasmI64Extend8S)
|
v.reset(OpWasmI64Extend8S)
|
||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt8to16 x)
|
|
||||||
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
|
||||||
for {
|
|
||||||
x := v_0
|
|
||||||
v.reset(OpWasmI64ShrS)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
|
|
||||||
v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
|
|
||||||
v1.AuxInt = int64ToAuxInt(56)
|
|
||||||
v0.AddArg2(x, v1)
|
|
||||||
v.AddArg2(v0, v1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSignExt8to32(v *Value) bool {
|
func rewriteValueWasm_OpSignExt8to32(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (SignExt8to32 x:(I64Load8S _ _))
|
// match: (SignExt8to32 x:(I64Load8S _ _))
|
||||||
// result: x
|
// result: x
|
||||||
for {
|
for {
|
||||||
|
|
@ -3371,34 +3296,16 @@ func rewriteValueWasm_OpSignExt8to32(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt8to32 x)
|
// match: (SignExt8to32 x)
|
||||||
// cond: buildcfg.GOWASM.SignExt
|
|
||||||
// result: (I64Extend8S x)
|
// result: (I64Extend8S x)
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if !(buildcfg.GOWASM.SignExt) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpWasmI64Extend8S)
|
v.reset(OpWasmI64Extend8S)
|
||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt8to32 x)
|
|
||||||
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
|
||||||
for {
|
|
||||||
x := v_0
|
|
||||||
v.reset(OpWasmI64ShrS)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
|
|
||||||
v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
|
|
||||||
v1.AuxInt = int64ToAuxInt(56)
|
|
||||||
v0.AddArg2(x, v1)
|
|
||||||
v.AddArg2(v0, v1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSignExt8to64(v *Value) bool {
|
func rewriteValueWasm_OpSignExt8to64(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (SignExt8to64 x:(I64Load8S _ _))
|
// match: (SignExt8to64 x:(I64Load8S _ _))
|
||||||
// result: x
|
// result: x
|
||||||
for {
|
for {
|
||||||
|
|
@ -3410,29 +3317,13 @@ func rewriteValueWasm_OpSignExt8to64(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt8to64 x)
|
// match: (SignExt8to64 x)
|
||||||
// cond: buildcfg.GOWASM.SignExt
|
|
||||||
// result: (I64Extend8S x)
|
// result: (I64Extend8S x)
|
||||||
for {
|
for {
|
||||||
x := v_0
|
x := v_0
|
||||||
if !(buildcfg.GOWASM.SignExt) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
v.reset(OpWasmI64Extend8S)
|
v.reset(OpWasmI64Extend8S)
|
||||||
v.AddArg(x)
|
v.AddArg(x)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// match: (SignExt8to64 x)
|
|
||||||
// result: (I64ShrS (I64Shl x (I64Const [56])) (I64Const [56]))
|
|
||||||
for {
|
|
||||||
x := v_0
|
|
||||||
v.reset(OpWasmI64ShrS)
|
|
||||||
v0 := b.NewValue0(v.Pos, OpWasmI64Shl, typ.Int64)
|
|
||||||
v1 := b.NewValue0(v.Pos, OpWasmI64Const, typ.Int64)
|
|
||||||
v1.AuxInt = int64ToAuxInt(56)
|
|
||||||
v0.AddArg2(x, v1)
|
|
||||||
v.AddArg2(v0, v1)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
func rewriteValueWasm_OpSlicemask(v *Value) bool {
|
func rewriteValueWasm_OpSlicemask(v *Value) bool {
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/obj/wasm"
|
"cmd/internal/obj/wasm"
|
||||||
"internal/buildcfg"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -425,27 +424,11 @@ func ssaGenValueOnStack(s *ssagen.State, v *ssa.Value, extend bool) {
|
||||||
|
|
||||||
case ssa.OpWasmI64TruncSatF32S, ssa.OpWasmI64TruncSatF64S:
|
case ssa.OpWasmI64TruncSatF32S, ssa.OpWasmI64TruncSatF64S:
|
||||||
getValue64(s, v.Args[0])
|
getValue64(s, v.Args[0])
|
||||||
if buildcfg.GOWASM.SatConv {
|
s.Prog(v.Op.Asm())
|
||||||
s.Prog(v.Op.Asm())
|
|
||||||
} else {
|
|
||||||
if v.Op == ssa.OpWasmI64TruncSatF32S {
|
|
||||||
s.Prog(wasm.AF64PromoteF32)
|
|
||||||
}
|
|
||||||
p := s.Prog(wasm.ACall)
|
|
||||||
p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmTruncS}
|
|
||||||
}
|
|
||||||
|
|
||||||
case ssa.OpWasmI64TruncSatF32U, ssa.OpWasmI64TruncSatF64U:
|
case ssa.OpWasmI64TruncSatF32U, ssa.OpWasmI64TruncSatF64U:
|
||||||
getValue64(s, v.Args[0])
|
getValue64(s, v.Args[0])
|
||||||
if buildcfg.GOWASM.SatConv {
|
s.Prog(v.Op.Asm())
|
||||||
s.Prog(v.Op.Asm())
|
|
||||||
} else {
|
|
||||||
if v.Op == ssa.OpWasmI64TruncSatF32U {
|
|
||||||
s.Prog(wasm.AF64PromoteF32)
|
|
||||||
}
|
|
||||||
p := s.Prog(wasm.ACall)
|
|
||||||
p.To = obj.Addr{Type: obj.TYPE_MEM, Name: obj.NAME_EXTERN, Sym: ir.Syms.WasmTruncU}
|
|
||||||
}
|
|
||||||
|
|
||||||
case ssa.OpWasmF32DemoteF64:
|
case ssa.OpWasmF32DemoteF64:
|
||||||
getValue64(s, v.Args[0])
|
getValue64(s, v.Args[0])
|
||||||
|
|
|
||||||
|
|
@ -321,18 +321,13 @@ func goriscv64() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
type gowasmFeatures struct {
|
type gowasmFeatures struct {
|
||||||
SatConv bool
|
// Legacy features, now always enabled
|
||||||
SignExt bool
|
//SatConv bool
|
||||||
|
//SignExt bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f gowasmFeatures) String() string {
|
func (f gowasmFeatures) String() string {
|
||||||
var flags []string
|
var flags []string
|
||||||
if f.SatConv {
|
|
||||||
flags = append(flags, "satconv")
|
|
||||||
}
|
|
||||||
if f.SignExt {
|
|
||||||
flags = append(flags, "signext")
|
|
||||||
}
|
|
||||||
return strings.Join(flags, ",")
|
return strings.Join(flags, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,9 +335,9 @@ func gowasm() (f gowasmFeatures) {
|
||||||
for opt := range strings.SplitSeq(envOr("GOWASM", ""), ",") {
|
for opt := range strings.SplitSeq(envOr("GOWASM", ""), ",") {
|
||||||
switch opt {
|
switch opt {
|
||||||
case "satconv":
|
case "satconv":
|
||||||
f.SatConv = true
|
// ignore, always enabled
|
||||||
case "signext":
|
case "signext":
|
||||||
f.SignExt = true
|
// ignore, always enabled
|
||||||
case "":
|
case "":
|
||||||
// ignore
|
// ignore
|
||||||
default:
|
default:
|
||||||
|
|
@ -452,12 +447,10 @@ func gogoarchTags() []string {
|
||||||
return list
|
return list
|
||||||
case "wasm":
|
case "wasm":
|
||||||
var list []string
|
var list []string
|
||||||
if GOWASM.SatConv {
|
// SatConv is always enabled
|
||||||
list = append(list, GOARCH+".satconv")
|
list = append(list, GOARCH+".satconv")
|
||||||
}
|
// SignExt is always enabled
|
||||||
if GOWASM.SignExt {
|
list = append(list, GOARCH+".signext")
|
||||||
list = append(list, GOARCH+".signext")
|
|
||||||
}
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import (
|
||||||
var res int64
|
var res int64
|
||||||
var ures uint64
|
var ures uint64
|
||||||
|
|
||||||
|
// TODO: This test probably should be in a different place.
|
||||||
|
|
||||||
func TestFloatTruncation(t *testing.T) {
|
func TestFloatTruncation(t *testing.T) {
|
||||||
testdata := []struct {
|
testdata := []struct {
|
||||||
input float64
|
input float64
|
||||||
|
|
@ -21,36 +23,37 @@ func TestFloatTruncation(t *testing.T) {
|
||||||
// max +- 1
|
// max +- 1
|
||||||
{
|
{
|
||||||
input: 0x7fffffffffffffff,
|
input: 0x7fffffffffffffff,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0x8000000000000000,
|
||||||
},
|
},
|
||||||
// For out-of-bounds conversion, the result is implementation-dependent.
|
// For out-of-bounds conversion, the result is implementation-dependent.
|
||||||
// This test verifies the implementation of wasm architecture.
|
// This test verifies the implementation of wasm architecture, which is,
|
||||||
|
// saturating to the min/max value.
|
||||||
{
|
{
|
||||||
input: 0x8000000000000000,
|
input: 0x8000000000000000,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0x8000000000000000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 0x7ffffffffffffffe,
|
input: 0x7ffffffffffffffe,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0x8000000000000000,
|
||||||
},
|
},
|
||||||
// neg max +- 1
|
// neg max +- 1
|
||||||
{
|
{
|
||||||
input: -0x8000000000000000,
|
input: -0x8000000000000000,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: -0x8000000000000000,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: -0x8000000000000001,
|
input: -0x8000000000000001,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: -0x8000000000000000,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: -0x7fffffffffffffff,
|
input: -0x7fffffffffffffff,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: -0x8000000000000000,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0,
|
||||||
},
|
},
|
||||||
// trunc point +- 1
|
// trunc point +- 1
|
||||||
{
|
{
|
||||||
|
|
@ -60,7 +63,7 @@ func TestFloatTruncation(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 0x7ffffffffffffe00,
|
input: 0x7ffffffffffffe00,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0x8000000000000000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -72,48 +75,48 @@ func TestFloatTruncation(t *testing.T) {
|
||||||
{
|
{
|
||||||
input: -0x7ffffffffffffdff,
|
input: -0x7ffffffffffffdff,
|
||||||
convInt64: -0x7ffffffffffffc00,
|
convInt64: -0x7ffffffffffffc00,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: -0x7ffffffffffffe00,
|
input: -0x7ffffffffffffe00,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: -0x8000000000000000,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: -0x7ffffffffffffdfe,
|
input: -0x7ffffffffffffdfe,
|
||||||
convInt64: -0x7ffffffffffffc00,
|
convInt64: -0x7ffffffffffffc00,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0,
|
||||||
},
|
},
|
||||||
// umax +- 1
|
// umax +- 1
|
||||||
{
|
{
|
||||||
input: 0xffffffffffffffff,
|
input: 0xffffffffffffffff,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0xffffffffffffffff,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 0x10000000000000000,
|
input: 0x10000000000000000,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0xffffffffffffffff,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 0xfffffffffffffffe,
|
input: 0xfffffffffffffffe,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0xffffffffffffffff,
|
||||||
},
|
},
|
||||||
// umax trunc +- 1
|
// umax trunc +- 1
|
||||||
{
|
{
|
||||||
input: 0xfffffffffffffbff,
|
input: 0xfffffffffffffbff,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0xfffffffffffff800,
|
convUInt64: 0xfffffffffffff800,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 0xfffffffffffffc00,
|
input: 0xfffffffffffffc00,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0x8000000000000000,
|
convUInt64: 0xffffffffffffffff,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: 0xfffffffffffffbfe,
|
input: 0xfffffffffffffbfe,
|
||||||
convInt64: -0x8000000000000000,
|
convInt64: 0x7fffffffffffffff,
|
||||||
convUInt64: 0xfffffffffffff800,
|
convUInt64: 0xfffffffffffff800,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,64 +22,6 @@ TEXT runtime·wasmDiv(SB), NOSPLIT, $0-0
|
||||||
I64DivS
|
I64DivS
|
||||||
Return
|
Return
|
||||||
|
|
||||||
TEXT runtime·wasmTruncS(SB), NOSPLIT, $0-0
|
|
||||||
Get R0
|
|
||||||
Get R0
|
|
||||||
F64Ne // NaN
|
|
||||||
If
|
|
||||||
I64Const $0x8000000000000000
|
|
||||||
Return
|
|
||||||
End
|
|
||||||
|
|
||||||
Get R0
|
|
||||||
F64Const $0x7ffffffffffffc00p0 // Maximum truncated representation of 0x7fffffffffffffff
|
|
||||||
F64Gt
|
|
||||||
If
|
|
||||||
I64Const $0x8000000000000000
|
|
||||||
Return
|
|
||||||
End
|
|
||||||
|
|
||||||
Get R0
|
|
||||||
F64Const $-0x7ffffffffffffc00p0 // Minimum truncated representation of -0x8000000000000000
|
|
||||||
F64Lt
|
|
||||||
If
|
|
||||||
I64Const $0x8000000000000000
|
|
||||||
Return
|
|
||||||
End
|
|
||||||
|
|
||||||
Get R0
|
|
||||||
I64TruncF64S
|
|
||||||
Return
|
|
||||||
|
|
||||||
TEXT runtime·wasmTruncU(SB), NOSPLIT, $0-0
|
|
||||||
Get R0
|
|
||||||
Get R0
|
|
||||||
F64Ne // NaN
|
|
||||||
If
|
|
||||||
I64Const $0x8000000000000000
|
|
||||||
Return
|
|
||||||
End
|
|
||||||
|
|
||||||
Get R0
|
|
||||||
F64Const $0xfffffffffffff800p0 // Maximum truncated representation of 0xffffffffffffffff
|
|
||||||
F64Gt
|
|
||||||
If
|
|
||||||
I64Const $0x8000000000000000
|
|
||||||
Return
|
|
||||||
End
|
|
||||||
|
|
||||||
Get R0
|
|
||||||
F64Const $0.
|
|
||||||
F64Lt
|
|
||||||
If
|
|
||||||
I64Const $0x8000000000000000
|
|
||||||
Return
|
|
||||||
End
|
|
||||||
|
|
||||||
Get R0
|
|
||||||
I64TruncF64U
|
|
||||||
Return
|
|
||||||
|
|
||||||
TEXT runtime·exitThread(SB), NOSPLIT, $0-0
|
TEXT runtime·exitThread(SB), NOSPLIT, $0-0
|
||||||
UNDEF
|
UNDEF
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue