Commit 2200b182 authored by Daniel Martí's avatar Daniel Martí Committed by Robert Griesemer

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: default avatarRobert Griesemer <gri@golang.org>
parent 60f83621
......@@ -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()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment