1
0
mirror of https://github.com/golang/go synced 2024-11-12 08:50:22 -07:00

cmd/compile: cleanup walking OCONV/OCONVNOP

Use a separate func, which needs less indentation and can use returns
instead of labelled breaks. We can also give the types better names, and
we don't have to repeat the calls to conv and mkcall.

Passes toolstash -cmp on std cmd.

Change-Id: I1071c170fa729562d70093a09b7dea003c5fe26e
Reviewed-on: https://go-review.googlesource.com/130075
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Daniel Martí 2018-08-20 21:31:49 +01:00 committed by Robert Griesemer
parent 60f83621fc
commit 2200b18258

View File

@ -1022,64 +1022,13 @@ opswitch:
n = walkexpr(n, init)
case OCONV, OCONVNOP:
if thearch.SoftFloat {
// For the soft-float case, ssa.go handles these conversions.
n.Left = walkexpr(n.Left, init)
n.Left = walkexpr(n.Left, init)
param, result := rtconvfn(n.Left.Type, n.Type)
if param == Txxx {
break
}
switch thearch.LinkArch.Family {
case sys.ARM, sys.MIPS:
if n.Left.Type.IsFloat() {
switch n.Type.Etype {
case TINT64:
n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break opswitch
case TUINT64:
n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break opswitch
}
}
if n.Type.IsFloat() {
switch n.Left.Type.Etype {
case TINT64:
n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
break opswitch
case TUINT64:
n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
break opswitch
}
}
case sys.I386:
if n.Left.Type.IsFloat() {
switch n.Type.Etype {
case TINT64:
n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break opswitch
case TUINT64:
n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break opswitch
case TUINT32, TUINT, TUINTPTR:
n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break opswitch
}
}
if n.Type.IsFloat() {
switch n.Left.Type.Etype {
case TINT64:
n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
break opswitch
case TUINT64:
n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
break opswitch
case TUINT32, TUINT, TUINTPTR:
n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type)
break opswitch
}
}
}
n.Left = walkexpr(n.Left, init)
fn := basicnames[param] + "to" + basicnames[result]
n = conv(mkcall(fn, types.Types[result], init, conv(n.Left, types.Types[param])), n.Type)
case OANDNOT:
n.Left = walkexpr(n.Left, init)
@ -1771,6 +1720,52 @@ opswitch:
return n
}
// rtconvfn returns the parameter and result types that will be used by a
// runtime function to convert from type src to type dst. The runtime function
// name can be derived from the names of the returned types.
//
// If no such function is necessary, it returns (Txxx, Txxx).
func rtconvfn(src, dst *types.Type) (param, result types.EType) {
if thearch.SoftFloat {
return Txxx, Txxx
}
switch thearch.LinkArch.Family {
case sys.ARM, sys.MIPS:
if src.IsFloat() {
switch dst.Etype {
case TINT64, TUINT64:
return TFLOAT64, dst.Etype
}
}
if dst.IsFloat() {
switch src.Etype {
case TINT64, TUINT64:
return src.Etype, TFLOAT64
}
}
case sys.I386:
if src.IsFloat() {
switch dst.Etype {
case TINT64, TUINT64:
return TFLOAT64, dst.Etype
case TUINT32, TUINT, TUINTPTR:
return TFLOAT64, TUINT32
}
}
if dst.IsFloat() {
switch src.Etype {
case TINT64, TUINT64:
return src.Etype, TFLOAT64
case TUINT32, TUINT, TUINTPTR:
return TUINT32, TFLOAT64
}
}
}
return Txxx, Txxx
}
// TODO(josharian): combine this with its caller and simplify
func reduceSlice(n *Node) *Node {
low, high, max := n.SliceBounds()