diff options
author | Cherry Zhang <cherryyz@google.com> | 2016-05-18 18:14:36 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2016-06-02 13:01:09 +0000 |
commit | 8756d9253f56f28167543fbd41c15e5695e654b2 (patch) | |
tree | bae261d966f74e115a7775d9cd69e697156e7c37 /src/cmd/compile/internal/ssa/decompose.go | |
parent | 31e13c83c26c5addad6c9a15a8f06a11edc7c519 (diff) | |
download | go-8756d9253f56f28167543fbd41c15e5695e654b2.tar.gz go-8756d9253f56f28167543fbd41c15e5695e654b2.zip |
[dev.ssa] cmd/compile: decompose 64-bit integer on ARM
Introduce dec64 rules to (generically) decompose 64-bit integer on
32-bit architectures. 64-bit integer is composed/decomposed with
Int64Make/Hi/Lo ops, as for complex types.
The idea of dealing with Add64 is the following:
(Add64 (Int64Make xh xl) (Int64Make yh yl))
->
(Int64Make
(Add32withcarry xh yh (Select0 (Add32carry xl yl)))
(Select1 (Add32carry xl yl)))
where Add32carry returns a tuple (flags,uint32). Select0 and Select1
read the first and the second component of the tuple, respectively.
The two Add32carry will be CSE'd.
Similarly for multiplication, Mul32uhilo returns a tuple (hi, lo).
Also add support of KeepAlive, to fix build after merge.
Tests addressed_ssa.go, array_ssa.go, break_ssa.go, chan_ssa.go,
cmp_ssa.go, ctl_ssa.go, map_ssa.go, and string_ssa.go in
cmd/compile/internal/gc/testdata passed.
Progress on SSA for ARM. Still not complete.
Updates #15365.
Change-Id: I7867c76785a456312de5d8398a6b3f7ca5a4f7ec
Reviewed-on: https://go-review.googlesource.com/23213
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/decompose.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/decompose.go | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go index 53116ba593..0ee5f53291 100644 --- a/src/cmd/compile/internal/ssa/decompose.go +++ b/src/cmd/compile/internal/ssa/decompose.go @@ -25,6 +25,22 @@ func decomposeBuiltIn(f *Func) { for _, name := range f.Names { t := name.Type switch { + case t.IsInteger() && t.Size() == 8 && f.Config.IntSize == 4: + var elemType Type + if t.IsSigned() { + elemType = f.Config.fe.TypeInt32() + } else { + elemType = f.Config.fe.TypeUInt32() + } + hiName, loName := f.Config.fe.SplitInt64(name) + newNames = append(newNames, hiName, loName) + for _, v := range f.NamedValues[name] { + hi := v.Block.NewValue1(v.Line, OpInt64Hi, elemType, v) + lo := v.Block.NewValue1(v.Line, OpInt64Lo, f.Config.fe.TypeUInt32(), v) + f.NamedValues[hiName] = append(f.NamedValues[hiName], hi) + f.NamedValues[loName] = append(f.NamedValues[loName], lo) + } + delete(f.NamedValues, name) case t.IsComplex(): var elemType Type if t.Size() == 16 { @@ -88,8 +104,9 @@ func decomposeBuiltIn(f *Func) { } func decomposeBuiltInPhi(v *Value) { - // TODO: decompose 64-bit ops on 32-bit archs? switch { + case v.Type.IsInteger() && v.Type.Size() == 8 && v.Block.Func.Config.IntSize == 4: + decomposeInt64Phi(v) case v.Type.IsComplex(): decomposeComplexPhi(v) case v.Type.IsString(): @@ -138,6 +155,26 @@ func decomposeSlicePhi(v *Value) { v.AddArg(cap) } +func decomposeInt64Phi(v *Value) { + fe := v.Block.Func.Config.fe + var partType Type + if v.Type.IsSigned() { + partType = fe.TypeInt32() + } else { + partType = fe.TypeUInt32() + } + + hi := v.Block.NewValue0(v.Line, OpPhi, partType) + lo := v.Block.NewValue0(v.Line, OpPhi, fe.TypeUInt32()) + for _, a := range v.Args { + hi.AddArg(a.Block.NewValue1(v.Line, OpInt64Hi, partType, a)) + lo.AddArg(a.Block.NewValue1(v.Line, OpInt64Lo, fe.TypeUInt32(), a)) + } + v.reset(OpInt64Make) + v.AddArg(hi) + v.AddArg(lo) +} + func decomposeComplexPhi(v *Value) { fe := v.Block.Func.Config.fe var partType Type |