mirror of
https://github.com/golang/go.git
synced 2025-10-19 19:13:18 +00:00
Revert "cmd/compile: make 386 float-to-int conversions match amd64"
This reverts commit 78d75b3799
.
Reason for revert: we need to do this more carefully, at minimum gated by a module version
(This should follow the softfloat FP conversion revert)
Change-Id: I736bec6cd860285dcc3b11fac85b377a149435c3
Reviewed-on: https://go-review.googlesource.com/c/go/+/711842
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
bb2a14252b
commit
6d5b13793f
9 changed files with 23 additions and 182 deletions
|
@ -88,10 +88,8 @@
|
||||||
(Cvt32to32F ...) => (CVTSL2SS ...)
|
(Cvt32to32F ...) => (CVTSL2SS ...)
|
||||||
(Cvt32to64F ...) => (CVTSL2SD ...)
|
(Cvt32to64F ...) => (CVTSL2SD ...)
|
||||||
|
|
||||||
(Cvt32Fto32 <t> x) && base.ConvertHash.MatchPos(v.Pos, nil) => (XORL <t> y (SARLconst <t> [31] (ANDL <t> y:(CVTTSS2SL <t> x) (NOTL <typ.Int32> (MOVLf2i x)))))
|
(Cvt32Fto32 ...) => (CVTTSS2SL ...)
|
||||||
(Cvt64Fto32 <t> x) && base.ConvertHash.MatchPos(v.Pos, nil) => (XORL <t> y (SARLconst <t> [31] (ANDL <t> y:(CVTTSD2SL <t> x) (NOTL <typ.Int32> (MOVLf2i (CVTSD2SS <typ.Float32> x))))))
|
(Cvt64Fto32 ...) => (CVTTSD2SL ...)
|
||||||
(Cvt32Fto32 <t> x) && !base.ConvertHash.MatchPos(v.Pos, nil) => (CVTTSS2SL <t> x)
|
|
||||||
(Cvt64Fto32 <t> x) && !base.ConvertHash.MatchPos(v.Pos, nil) => (CVTTSD2SL <t> x)
|
|
||||||
|
|
||||||
(Cvt32Fto64F ...) => (CVTSS2SD ...)
|
(Cvt32Fto64F ...) => (CVTSS2SD ...)
|
||||||
(Cvt64Fto32F ...) => (CVTSD2SS ...)
|
(Cvt64Fto32F ...) => (CVTSD2SS ...)
|
||||||
|
|
|
@ -342,8 +342,6 @@ func init() {
|
||||||
{name: "MOVWLSX", argLength: 1, reg: gp11, asm: "MOVWLSX"}, // sign extend arg0 from int16 to int32
|
{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: "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: "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
|
{name: "CVTTSD2SL", argLength: 1, reg: fpgp, asm: "CVTTSD2SL"}, // convert float64 to int32
|
||||||
|
|
|
@ -499,7 +499,6 @@ const (
|
||||||
Op386MOVBLZX
|
Op386MOVBLZX
|
||||||
Op386MOVWLSX
|
Op386MOVWLSX
|
||||||
Op386MOVWLZX
|
Op386MOVWLZX
|
||||||
Op386MOVLf2i
|
|
||||||
Op386MOVLconst
|
Op386MOVLconst
|
||||||
Op386CVTTSD2SL
|
Op386CVTTSD2SL
|
||||||
Op386CVTTSS2SL
|
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",
|
name: "MOVLconst",
|
||||||
auxType: auxInt32,
|
auxType: auxInt32,
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
package ssa
|
package ssa
|
||||||
|
|
||||||
import "math"
|
import "math"
|
||||||
import "cmd/compile/internal/base"
|
|
||||||
import "cmd/compile/internal/types"
|
import "cmd/compile/internal/types"
|
||||||
|
|
||||||
func rewriteValue386(v *Value) bool {
|
func rewriteValue386(v *Value) bool {
|
||||||
|
@ -341,7 +340,8 @@ func rewriteValue386(v *Value) bool {
|
||||||
v.Op = Op386BSFL
|
v.Op = Op386BSFL
|
||||||
return true
|
return true
|
||||||
case OpCvt32Fto32:
|
case OpCvt32Fto32:
|
||||||
return rewriteValue386_OpCvt32Fto32(v)
|
v.Op = Op386CVTTSS2SL
|
||||||
|
return true
|
||||||
case OpCvt32Fto64F:
|
case OpCvt32Fto64F:
|
||||||
v.Op = Op386CVTSS2SD
|
v.Op = Op386CVTSS2SD
|
||||||
return true
|
return true
|
||||||
|
@ -352,7 +352,8 @@ func rewriteValue386(v *Value) bool {
|
||||||
v.Op = Op386CVTSL2SD
|
v.Op = Op386CVTSL2SD
|
||||||
return true
|
return true
|
||||||
case OpCvt64Fto32:
|
case OpCvt64Fto32:
|
||||||
return rewriteValue386_OpCvt64Fto32(v)
|
v.Op = Op386CVTTSD2SL
|
||||||
|
return true
|
||||||
case OpCvt64Fto32F:
|
case OpCvt64Fto32F:
|
||||||
v.Op = Op386CVTSD2SS
|
v.Op = Op386CVTSD2SS
|
||||||
return true
|
return true
|
||||||
|
@ -7963,98 +7964,6 @@ func rewriteValue386_OpCtz8(v *Value) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func rewriteValue386_OpCvt32Fto32(v *Value) bool {
|
|
||||||
v_0 := v.Args[0]
|
|
||||||
b := v.Block
|
|
||||||
typ := &b.Func.Config.Types
|
|
||||||
// match: (Cvt32Fto32 <t> x)
|
|
||||||
// cond: base.ConvertHash.MatchPos(v.Pos, nil)
|
|
||||||
// result: (XORL <t> y (SARLconst <t> [31] (ANDL <t> y:(CVTTSS2SL <t> x) (NOTL <typ.Int32> (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 <t> x)
|
|
||||||
// cond: !base.ConvertHash.MatchPos(v.Pos, nil)
|
|
||||||
// result: (CVTTSS2SL <t> 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 <t> x)
|
|
||||||
// cond: base.ConvertHash.MatchPos(v.Pos, nil)
|
|
||||||
// result: (XORL <t> y (SARLconst <t> [31] (ANDL <t> y:(CVTTSD2SL <t> x) (NOTL <typ.Int32> (MOVLf2i (CVTSD2SS <typ.Float32> 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 <t> x)
|
|
||||||
// cond: !base.ConvertHash.MatchPos(v.Pos, nil)
|
|
||||||
// result: (CVTTSD2SL <t> 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 {
|
func rewriteValue386_OpDiv8(v *Value) bool {
|
||||||
v_1 := v.Args[1]
|
v_1 := v.Args[1]
|
||||||
v_0 := v.Args[0]
|
v_0 := v.Args[0]
|
||||||
|
|
|
@ -538,13 +538,6 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
p.To.Reg = v.Args[0].Reg()
|
p.To.Reg = v.Args[0].Reg()
|
||||||
ssagen.AddAux(&p.To, v)
|
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:
|
case ssa.Op386ADDLconstmodify:
|
||||||
sc := v.AuxValAndOff()
|
sc := v.AuxValAndOff()
|
||||||
val := sc.Val()
|
val := sc.Val()
|
||||||
|
|
|
@ -1407,6 +1407,16 @@ TEXT runtime·uint32tofloat64(SB),NOSPLIT,$8-12
|
||||||
FMOVDP F0, ret+4(FP)
|
FMOVDP F0, ret+4(FP)
|
||||||
RET
|
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 informs the GC about heap pointer writes.
|
||||||
//
|
//
|
||||||
// gcWriteBarrier returns space in a write barrier buffer which
|
// gcWriteBarrier returns space in a write barrier buffer which
|
||||||
|
|
|
@ -6,6 +6,7 @@ package runtime
|
||||||
|
|
||||||
import "unsafe"
|
import "unsafe"
|
||||||
|
|
||||||
|
func float64touint32(a float64) uint32
|
||||||
func uint32tofloat64(a uint32) float64
|
func uint32tofloat64(a uint32) float64
|
||||||
|
|
||||||
// stackcheck checks that SP is in range [g->stack.lo, g->stack.hi).
|
// stackcheck checks that SP is in range [g->stack.lo, g->stack.hi).
|
||||||
|
|
|
@ -40,17 +40,10 @@ func float64toint64(d float64) (y uint64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func float64touint64(d float64) (y uint64) {
|
func float64touint64(d float64) (y uint64) {
|
||||||
_d2vu(&y, d)
|
_d2v(&y, d)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func float64touint32(a float64) uint32 {
|
|
||||||
if a >= 0xffffffff {
|
|
||||||
return 0xffffffff
|
|
||||||
}
|
|
||||||
return uint32(float64touint64(a))
|
|
||||||
}
|
|
||||||
|
|
||||||
func int64tofloat64(y int64) float64 {
|
func int64tofloat64(y int64) float64 {
|
||||||
if y < 0 {
|
if y < 0 {
|
||||||
return -uint64tofloat64(-uint64(y))
|
return -uint64tofloat64(-uint64(y))
|
||||||
|
@ -124,16 +117,12 @@ func _d2v(y *uint64, d float64) {
|
||||||
} else {
|
} else {
|
||||||
/* v = (hi||lo) << -sh */
|
/* v = (hi||lo) << -sh */
|
||||||
sh := uint32(-sh)
|
sh := uint32(-sh)
|
||||||
if sh <= 10 {
|
if sh <= 11 {
|
||||||
ylo = xlo << sh
|
ylo = xlo << sh
|
||||||
yhi = xhi<<sh | xlo>>(32-sh)
|
yhi = xhi<<sh | xlo>>(32-sh)
|
||||||
} else {
|
} else {
|
||||||
if x&sign64 != 0 {
|
/* overflow */
|
||||||
*y = 0x8000000000000000
|
yhi = uint32(d) /* causes something awful */
|
||||||
} else {
|
|
||||||
*y = 0x7fffffffffffffff
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if x&sign64 != 0 {
|
if x&sign64 != 0 {
|
||||||
|
@ -147,50 +136,6 @@ func _d2v(y *uint64, d float64) {
|
||||||
|
|
||||||
*y = uint64(yhi)<<32 | uint64(ylo)
|
*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<<sh | xlo>>(32-sh)
|
|
||||||
} else {
|
|
||||||
/* overflow */
|
|
||||||
*y = 0xffffffffffffffff
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*y = uint64(yhi)<<32 | uint64(ylo)
|
|
||||||
}
|
|
||||||
func uint64div(n, d uint64) uint64 {
|
func uint64div(n, d uint64) uint64 {
|
||||||
// Check for 32 bit operands
|
// Check for 32 bit operands
|
||||||
if uint32(n>>32) == 0 && uint32(d>>32) == 0 {
|
if uint32(n>>32) == 0 && uint32(d>>32) == 0 {
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// 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.
|
// Doing more than this, however, expands the change.
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue