diff --git a/src/cmd/compile/internal/ssa/_gen/386.rules b/src/cmd/compile/internal/ssa/_gen/386.rules index 4e3d3203c7..5f11502419 100644 --- a/src/cmd/compile/internal/ssa/_gen/386.rules +++ b/src/cmd/compile/internal/ssa/_gen/386.rules @@ -88,10 +88,8 @@ (Cvt32to32F ...) => (CVTSL2SS ...) (Cvt32to64F ...) => (CVTSL2SD ...) -(Cvt32Fto32 x) && base.ConvertHash.MatchPos(v.Pos, nil) => (XORL y (SARLconst [31] (ANDL y:(CVTTSS2SL x) (NOTL (MOVLf2i x))))) -(Cvt64Fto32 x) && base.ConvertHash.MatchPos(v.Pos, nil) => (XORL y (SARLconst [31] (ANDL y:(CVTTSD2SL x) (NOTL (MOVLf2i (CVTSD2SS x)))))) -(Cvt32Fto32 x) && !base.ConvertHash.MatchPos(v.Pos, nil) => (CVTTSS2SL x) -(Cvt64Fto32 x) && !base.ConvertHash.MatchPos(v.Pos, nil) => (CVTTSD2SL x) +(Cvt32Fto32 ...) => (CVTTSS2SL ...) +(Cvt64Fto32 ...) => (CVTTSD2SL ...) (Cvt32Fto64F ...) => (CVTSS2SD ...) (Cvt64Fto32F ...) => (CVTSD2SS ...) diff --git a/src/cmd/compile/internal/ssa/_gen/386Ops.go b/src/cmd/compile/internal/ssa/_gen/386Ops.go index 86c2f9c8f0..60599a33ab 100644 --- a/src/cmd/compile/internal/ssa/_gen/386Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/386Ops.go @@ -342,8 +342,6 @@ func init() { {name: "MOVWLSX", argLength: 1, reg: gp11, asm: "MOVWLSX"}, // sign extend arg0 from int16 to int32 {name: "MOVWLZX", argLength: 1, reg: gp11, asm: "MOVWLZX"}, // zero extend arg0 from int16 to int32 - {name: "MOVLf2i", argLength: 1, reg: fpgp, typ: "UInt32"}, // move 32 bits from float to int reg, zero extend - {name: "MOVLconst", reg: gp01, asm: "MOVL", typ: "UInt32", aux: "Int32", rematerializeable: true}, // 32 low bits of auxint {name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32 diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index ee0eb657dc..9b38e66a23 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -499,7 +499,6 @@ const ( Op386MOVBLZX Op386MOVWLSX Op386MOVWLZX - Op386MOVLf2i Op386MOVLconst Op386CVTTSD2SL Op386CVTTSS2SL @@ -5602,18 +5601,6 @@ var opcodeTable = [...]opInfo{ }, }, }, - { - name: "MOVLf2i", - argLen: 1, - reg: regInfo{ - inputs: []inputInfo{ - {0, 65280}, // X0 X1 X2 X3 X4 X5 X6 X7 - }, - outputs: []outputInfo{ - {0, 239}, // AX CX DX BX BP SI DI - }, - }, - }, { name: "MOVLconst", auxType: auxInt32, diff --git a/src/cmd/compile/internal/ssa/rewrite386.go b/src/cmd/compile/internal/ssa/rewrite386.go index 4845f1e025..0495438710 100644 --- a/src/cmd/compile/internal/ssa/rewrite386.go +++ b/src/cmd/compile/internal/ssa/rewrite386.go @@ -3,7 +3,6 @@ package ssa import "math" -import "cmd/compile/internal/base" import "cmd/compile/internal/types" func rewriteValue386(v *Value) bool { @@ -341,7 +340,8 @@ func rewriteValue386(v *Value) bool { v.Op = Op386BSFL return true case OpCvt32Fto32: - return rewriteValue386_OpCvt32Fto32(v) + v.Op = Op386CVTTSS2SL + return true case OpCvt32Fto64F: v.Op = Op386CVTSS2SD return true @@ -352,7 +352,8 @@ func rewriteValue386(v *Value) bool { v.Op = Op386CVTSL2SD return true case OpCvt64Fto32: - return rewriteValue386_OpCvt64Fto32(v) + v.Op = Op386CVTTSD2SL + return true case OpCvt64Fto32F: v.Op = Op386CVTSD2SS return true @@ -7963,98 +7964,6 @@ func rewriteValue386_OpCtz8(v *Value) bool { return true } } -func rewriteValue386_OpCvt32Fto32(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Cvt32Fto32 x) - // cond: base.ConvertHash.MatchPos(v.Pos, nil) - // result: (XORL y (SARLconst [31] (ANDL y:(CVTTSS2SL x) (NOTL (MOVLf2i x))))) - for { - t := v.Type - x := v_0 - if !(base.ConvertHash.MatchPos(v.Pos, nil)) { - break - } - v.reset(Op386XORL) - v.Type = t - v0 := b.NewValue0(v.Pos, Op386SARLconst, t) - v0.AuxInt = int32ToAuxInt(31) - v1 := b.NewValue0(v.Pos, Op386ANDL, t) - y := b.NewValue0(v.Pos, Op386CVTTSS2SL, t) - y.AddArg(x) - v3 := b.NewValue0(v.Pos, Op386NOTL, typ.Int32) - v4 := b.NewValue0(v.Pos, Op386MOVLf2i, typ.UInt32) - v4.AddArg(x) - v3.AddArg(v4) - v1.AddArg2(y, v3) - v0.AddArg(v1) - v.AddArg2(y, v0) - return true - } - // match: (Cvt32Fto32 x) - // cond: !base.ConvertHash.MatchPos(v.Pos, nil) - // result: (CVTTSS2SL x) - for { - t := v.Type - x := v_0 - if !(!base.ConvertHash.MatchPos(v.Pos, nil)) { - break - } - v.reset(Op386CVTTSS2SL) - v.Type = t - v.AddArg(x) - return true - } - return false -} -func rewriteValue386_OpCvt64Fto32(v *Value) bool { - v_0 := v.Args[0] - b := v.Block - typ := &b.Func.Config.Types - // match: (Cvt64Fto32 x) - // cond: base.ConvertHash.MatchPos(v.Pos, nil) - // result: (XORL y (SARLconst [31] (ANDL y:(CVTTSD2SL x) (NOTL (MOVLf2i (CVTSD2SS x)))))) - for { - t := v.Type - x := v_0 - if !(base.ConvertHash.MatchPos(v.Pos, nil)) { - break - } - v.reset(Op386XORL) - v.Type = t - v0 := b.NewValue0(v.Pos, Op386SARLconst, t) - v0.AuxInt = int32ToAuxInt(31) - v1 := b.NewValue0(v.Pos, Op386ANDL, t) - y := b.NewValue0(v.Pos, Op386CVTTSD2SL, t) - y.AddArg(x) - v3 := b.NewValue0(v.Pos, Op386NOTL, typ.Int32) - v4 := b.NewValue0(v.Pos, Op386MOVLf2i, typ.UInt32) - v5 := b.NewValue0(v.Pos, Op386CVTSD2SS, typ.Float32) - v5.AddArg(x) - v4.AddArg(v5) - v3.AddArg(v4) - v1.AddArg2(y, v3) - v0.AddArg(v1) - v.AddArg2(y, v0) - return true - } - // match: (Cvt64Fto32 x) - // cond: !base.ConvertHash.MatchPos(v.Pos, nil) - // result: (CVTTSD2SL x) - for { - t := v.Type - x := v_0 - if !(!base.ConvertHash.MatchPos(v.Pos, nil)) { - break - } - v.reset(Op386CVTTSD2SL) - v.Type = t - v.AddArg(x) - return true - } - return false -} func rewriteValue386_OpDiv8(v *Value) bool { v_1 := v.Args[1] v_0 := v.Args[0] diff --git a/src/cmd/compile/internal/x86/ssa.go b/src/cmd/compile/internal/x86/ssa.go index 2858a81b4b..d0aad08849 100644 --- a/src/cmd/compile/internal/x86/ssa.go +++ b/src/cmd/compile/internal/x86/ssa.go @@ -538,13 +538,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.To.Type = obj.TYPE_MEM p.To.Reg = v.Args[0].Reg() ssagen.AddAux(&p.To, v) - case ssa.Op386MOVLf2i: - var p *obj.Prog - p = s.Prog(x86.AMOVL) - p.From.Type = obj.TYPE_REG - p.From.Reg = v.Args[0].Reg() - p.To.Type = obj.TYPE_REG - p.To.Reg = v.Reg() case ssa.Op386ADDLconstmodify: sc := v.AuxValAndOff() val := sc.Val() diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index 2a6de64f9f..df32e90fda 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -1407,6 +1407,16 @@ TEXT runtime·uint32tofloat64(SB),NOSPLIT,$8-12 FMOVDP F0, ret+4(FP) RET +TEXT runtime·float64touint32(SB),NOSPLIT,$12-12 + FMOVD a+0(FP), F0 + FSTCW 0(SP) + FLDCW runtime·controlWord64trunc(SB) + FMOVVP F0, 4(SP) + FLDCW 0(SP) + MOVL 4(SP), AX + MOVL AX, ret+8(FP) + RET + // gcWriteBarrier informs the GC about heap pointer writes. // // gcWriteBarrier returns space in a write barrier buffer which diff --git a/src/runtime/stubs_386.go b/src/runtime/stubs_386.go index 4f3dcd4fd9..a1dd023974 100644 --- a/src/runtime/stubs_386.go +++ b/src/runtime/stubs_386.go @@ -6,6 +6,7 @@ package runtime import "unsafe" +func float64touint32(a float64) uint32 func uint32tofloat64(a uint32) float64 // stackcheck checks that SP is in range [g->stack.lo, g->stack.hi). diff --git a/src/runtime/vlrt.go b/src/runtime/vlrt.go index 511eb0dd4e..4b12f593c8 100644 --- a/src/runtime/vlrt.go +++ b/src/runtime/vlrt.go @@ -40,17 +40,10 @@ func float64toint64(d float64) (y uint64) { } func float64touint64(d float64) (y uint64) { - _d2vu(&y, d) + _d2v(&y, d) return } -func float64touint32(a float64) uint32 { - if a >= 0xffffffff { - return 0xffffffff - } - return uint32(float64touint64(a)) -} - func int64tofloat64(y int64) float64 { if y < 0 { return -uint64tofloat64(-uint64(y)) @@ -124,16 +117,12 @@ func _d2v(y *uint64, d float64) { } else { /* v = (hi||lo) << -sh */ sh := uint32(-sh) - if sh <= 10 { + if sh <= 11 { ylo = xlo << sh yhi = xhi<>(32-sh) } else { - if x&sign64 != 0 { - *y = 0x8000000000000000 - } else { - *y = 0x7fffffffffffffff - } - return + /* overflow */ + yhi = uint32(d) /* causes something awful */ } } if x&sign64 != 0 { @@ -147,50 +136,6 @@ func _d2v(y *uint64, d float64) { *y = uint64(yhi)<<32 | uint64(ylo) } -func _d2vu(y *uint64, d float64) { - x := *(*uint64)(unsafe.Pointer(&d)) - if x&sign64 != 0 { - *y = 0 - return - } - - xhi := uint32(x>>32)&0xfffff | 0x100000 - xlo := uint32(x) - sh := 1075 - int32(uint32(x>>52)&0x7ff) - - var ylo, yhi uint32 - if sh >= 0 { - sh := uint32(sh) - /* v = (hi||lo) >> sh */ - if sh < 32 { - if sh == 0 { - ylo = xlo - yhi = xhi - } else { - ylo = xlo>>sh | xhi<<(32-sh) - yhi = xhi >> sh - } - } else { - if sh == 32 { - ylo = xhi - } else if sh < 64 { - ylo = xhi >> (sh - 32) - } - } - } else { - /* v = (hi||lo) << -sh */ - sh := uint32(-sh) - if sh <= 11 { - ylo = xlo << sh - yhi = xhi<>(32-sh) - } else { - /* overflow */ - *y = 0xffffffffffffffff - return - } - } - *y = uint64(yhi)<<32 | uint64(ylo) -} func uint64div(n, d uint64) uint64 { // Check for 32 bit operands if uint32(n>>32) == 0 && uint32(d>>32) == 0 { diff --git a/test/convert5.go b/test/convert5.go index 57585ef76e..1bd74abdad 100644 --- a/test/convert5.go +++ b/test/convert5.go @@ -4,9 +4,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build !wasm +//go:build !wasm && !386 && !arm && !mips -// TODO fix this to work for wasm +// TODO fix this to work for wasm and 32-bit architectures. // Doing more than this, however, expands the change. package main