aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/rewritePPC64.go
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2016-08-10 11:44:57 -0700
committerDavid Chase <drchase@google.com>2016-08-15 14:47:49 +0000
commitd08010f94e06e5d5b6d01c248ba2a976b75d95a2 (patch)
treedf74490d9fecdccb5f75f7786ffa19f892cdb5ed /src/cmd/compile/internal/ssa/rewritePPC64.go
parentd99cee79b98dfb6c1cd8e64c96845ee29aa28b4c (diff)
downloadgo-d08010f94e06e5d5b6d01c248ba2a976b75d95a2.tar.gz
go-d08010f94e06e5d5b6d01c248ba2a976b75d95a2.zip
[dev.ssa] cmd/compile: PPC64, FP to/from int conversions.dev.ssa
Passes ssa_test. Requires a few new instructions and some scratchpad memory to move data between G and F registers. Also fixed comparisons to be correct in case of NaN. Added missing instructions for run.bash. Removed some FP registers that are apparently "reserved" (but that are also apparently also unused except for a gratuitous multiplication by two when y = x+x would work just as well). Currently failing stack splits. Updates #16010. Change-Id: I73b161bfff54445d72bd7b813b1479f89fc72602 Reviewed-on: https://go-review.googlesource.com/26813 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/rewritePPC64.go')
-rw-r--r--src/cmd/compile/internal/ssa/rewritePPC64.go426
1 files changed, 410 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 7ba0a9cb9c..9675d2f731 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -34,6 +34,8 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
return rewriteValuePPC64_OpAnd8(v, config)
case OpAndB:
return rewriteValuePPC64_OpAndB(v, config)
+ case OpAvg64u:
+ return rewriteValuePPC64_OpAvg64u(v, config)
case OpClosureCall:
return rewriteValuePPC64_OpClosureCall(v, config)
case OpCom16:
@@ -62,6 +64,26 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
return rewriteValuePPC64_OpConstNil(v, config)
case OpConvert:
return rewriteValuePPC64_OpConvert(v, config)
+ case OpCvt32Fto32:
+ return rewriteValuePPC64_OpCvt32Fto32(v, config)
+ case OpCvt32Fto64:
+ return rewriteValuePPC64_OpCvt32Fto64(v, config)
+ case OpCvt32Fto64F:
+ return rewriteValuePPC64_OpCvt32Fto64F(v, config)
+ case OpCvt32to32F:
+ return rewriteValuePPC64_OpCvt32to32F(v, config)
+ case OpCvt32to64F:
+ return rewriteValuePPC64_OpCvt32to64F(v, config)
+ case OpCvt64Fto32:
+ return rewriteValuePPC64_OpCvt64Fto32(v, config)
+ case OpCvt64Fto32F:
+ return rewriteValuePPC64_OpCvt64Fto32F(v, config)
+ case OpCvt64Fto64:
+ return rewriteValuePPC64_OpCvt64Fto64(v, config)
+ case OpCvt64to32F:
+ return rewriteValuePPC64_OpCvt64to32F(v, config)
+ case OpCvt64to64F:
+ return rewriteValuePPC64_OpCvt64to64F(v, config)
case OpDeferCall:
return rewriteValuePPC64_OpDeferCall(v, config)
case OpDiv16:
@@ -328,6 +350,14 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
return rewriteValuePPC64_OpPPC64CMPconst(v, config)
case OpPPC64Equal:
return rewriteValuePPC64_OpPPC64Equal(v, config)
+ case OpPPC64FGreaterEqual:
+ return rewriteValuePPC64_OpPPC64FGreaterEqual(v, config)
+ case OpPPC64FGreaterThan:
+ return rewriteValuePPC64_OpPPC64FGreaterThan(v, config)
+ case OpPPC64FLessEqual:
+ return rewriteValuePPC64_OpPPC64FLessEqual(v, config)
+ case OpPPC64FLessThan:
+ return rewriteValuePPC64_OpPPC64FLessThan(v, config)
case OpPPC64GreaterEqual:
return rewriteValuePPC64_OpPPC64GreaterEqual(v, config)
case OpPPC64GreaterThan:
@@ -430,6 +460,8 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
return rewriteValuePPC64_OpSignExt8to32(v, config)
case OpSignExt8to64:
return rewriteValuePPC64_OpSignExt8to64(v, config)
+ case OpSqrt:
+ return rewriteValuePPC64_OpSqrt(v, config)
case OpStaticCall:
return rewriteValuePPC64_OpStaticCall(v, config)
case OpStore:
@@ -680,6 +712,41 @@ func rewriteValuePPC64_OpAndB(v *Value, config *Config) bool {
return true
}
}
+func rewriteValuePPC64_OpAvg64u(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Avg64u <t> x y)
+ // cond:
+ // result: (ADD (ADD <t> (SRD <t> x (MOVDconst <t> [1])) (SRD <t> y (MOVDconst <t> [1]))) (ANDconst <t> (AND <t> x y) [1]))
+ for {
+ t := v.Type
+ x := v.Args[0]
+ y := v.Args[1]
+ v.reset(OpPPC64ADD)
+ v0 := b.NewValue0(v.Line, OpPPC64ADD, t)
+ v1 := b.NewValue0(v.Line, OpPPC64SRD, t)
+ v1.AddArg(x)
+ v2 := b.NewValue0(v.Line, OpPPC64MOVDconst, t)
+ v2.AuxInt = 1
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v3 := b.NewValue0(v.Line, OpPPC64SRD, t)
+ v3.AddArg(y)
+ v4 := b.NewValue0(v.Line, OpPPC64MOVDconst, t)
+ v4.AuxInt = 1
+ v3.AddArg(v4)
+ v0.AddArg(v3)
+ v.AddArg(v0)
+ v5 := b.NewValue0(v.Line, OpPPC64ANDconst, t)
+ v5.AuxInt = 1
+ v6 := b.NewValue0(v.Line, OpPPC64AND, t)
+ v6.AddArg(x)
+ v6.AddArg(y)
+ v5.AddArg(v6)
+ v.AddArg(v5)
+ return true
+ }
+}
func rewriteValuePPC64_OpClosureCall(v *Value, config *Config) bool {
b := v.Block
_ = b
@@ -875,6 +942,161 @@ func rewriteValuePPC64_OpConvert(v *Value, config *Config) bool {
return true
}
}
+func rewriteValuePPC64_OpCvt32Fto32(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt32Fto32 x)
+ // cond:
+ // result: (Xf2i64 (FCTIWZ x))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64Xf2i64)
+ v0 := b.NewValue0(v.Line, OpPPC64FCTIWZ, config.fe.TypeFloat64())
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt32Fto64(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt32Fto64 x)
+ // cond:
+ // result: (Xf2i64 (FCTIDZ x))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64Xf2i64)
+ v0 := b.NewValue0(v.Line, OpPPC64FCTIDZ, config.fe.TypeFloat64())
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt32Fto64F(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt32Fto64F x)
+ // cond:
+ // result: x
+ for {
+ x := v.Args[0]
+ v.reset(OpCopy)
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt32to32F(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt32to32F x)
+ // cond:
+ // result: (FRSP (FCFID (Xi2f64 (SignExt32to64 x))))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64FRSP)
+ v0 := b.NewValue0(v.Line, OpPPC64FCFID, config.fe.TypeFloat64())
+ v1 := b.NewValue0(v.Line, OpPPC64Xi2f64, config.fe.TypeFloat64())
+ v2 := b.NewValue0(v.Line, OpSignExt32to64, config.fe.TypeInt64())
+ v2.AddArg(x)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt32to64F(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt32to64F x)
+ // cond:
+ // result: (FCFID (Xi2f64 (SignExt32to64 x)))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64FCFID)
+ v0 := b.NewValue0(v.Line, OpPPC64Xi2f64, config.fe.TypeFloat64())
+ v1 := b.NewValue0(v.Line, OpSignExt32to64, config.fe.TypeInt64())
+ v1.AddArg(x)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt64Fto32(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt64Fto32 x)
+ // cond:
+ // result: (Xf2i64 (FCTIWZ x))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64Xf2i64)
+ v0 := b.NewValue0(v.Line, OpPPC64FCTIWZ, config.fe.TypeFloat64())
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt64Fto32F(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt64Fto32F x)
+ // cond:
+ // result: (FRSP x)
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64FRSP)
+ v.AddArg(x)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt64Fto64(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt64Fto64 x)
+ // cond:
+ // result: (Xf2i64 (FCTIDZ x))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64Xf2i64)
+ v0 := b.NewValue0(v.Line, OpPPC64FCTIDZ, config.fe.TypeFloat64())
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt64to32F(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt64to32F x)
+ // cond:
+ // result: (FRSP (FCFID (Xi2f64 x)))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64FRSP)
+ v0 := b.NewValue0(v.Line, OpPPC64FCFID, config.fe.TypeFloat64())
+ v1 := b.NewValue0(v.Line, OpPPC64Xi2f64, config.fe.TypeFloat64())
+ v1.AddArg(x)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+}
+func rewriteValuePPC64_OpCvt64to64F(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Cvt64to64F x)
+ // cond:
+ // result: (FCFID (Xi2f64 x))
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64FCFID)
+ v0 := b.NewValue0(v.Line, OpPPC64Xi2f64, config.fe.TypeFloat64())
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
+}
func rewriteValuePPC64_OpDeferCall(v *Value, config *Config) bool {
b := v.Block
_ = b
@@ -1265,11 +1487,11 @@ func rewriteValuePPC64_OpGeq32F(v *Value, config *Config) bool {
_ = b
// match: (Geq32F x y)
// cond:
- // result: (GreaterEqual (FCMPU x y))
+ // result: (FGreaterEqual (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64GreaterEqual)
+ v.reset(OpPPC64FGreaterEqual)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -1316,11 +1538,11 @@ func rewriteValuePPC64_OpGeq64F(v *Value, config *Config) bool {
_ = b
// match: (Geq64F x y)
// cond:
- // result: (GreaterEqual (FCMPU x y))
+ // result: (FGreaterEqual (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64GreaterEqual)
+ v.reset(OpPPC64FGreaterEqual)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -1477,11 +1699,11 @@ func rewriteValuePPC64_OpGreater32F(v *Value, config *Config) bool {
_ = b
// match: (Greater32F x y)
// cond:
- // result: (GreaterThan (FCMPU x y))
+ // result: (FGreaterThan (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64GreaterThan)
+ v.reset(OpPPC64FGreaterThan)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -1528,11 +1750,11 @@ func rewriteValuePPC64_OpGreater64F(v *Value, config *Config) bool {
_ = b
// match: (Greater64F x y)
// cond:
- // result: (GreaterThan (FCMPU x y))
+ // result: (FGreaterThan (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64GreaterThan)
+ v.reset(OpPPC64FGreaterThan)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -1878,11 +2100,11 @@ func rewriteValuePPC64_OpLeq32F(v *Value, config *Config) bool {
_ = b
// match: (Leq32F x y)
// cond:
- // result: (LessEqual (FCMPU x y))
+ // result: (FLessEqual (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64LessEqual)
+ v.reset(OpPPC64FLessEqual)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -1929,11 +2151,11 @@ func rewriteValuePPC64_OpLeq64F(v *Value, config *Config) bool {
_ = b
// match: (Leq64F x y)
// cond:
- // result: (LessEqual (FCMPU x y))
+ // result: (FLessEqual (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64LessEqual)
+ v.reset(OpPPC64FLessEqual)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -2064,11 +2286,11 @@ func rewriteValuePPC64_OpLess32F(v *Value, config *Config) bool {
_ = b
// match: (Less32F x y)
// cond:
- // result: (LessThan (FCMPU x y))
+ // result: (FLessThan (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64LessThan)
+ v.reset(OpPPC64FLessThan)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -2115,11 +2337,11 @@ func rewriteValuePPC64_OpLess64F(v *Value, config *Config) bool {
_ = b
// match: (Less64F x y)
// cond:
- // result: (LessThan (FCMPU x y))
+ // result: (FLessThan (FCMPU x y))
for {
x := v.Args[0]
y := v.Args[1]
- v.reset(OpPPC64LessThan)
+ v.reset(OpPPC64FLessThan)
v0 := b.NewValue0(v.Line, OpPPC64FCMPU, TypeFlags)
v0.AddArg(x)
v0.AddArg(y)
@@ -3956,6 +4178,78 @@ func rewriteValuePPC64_OpPPC64Equal(v *Value, config *Config) bool {
}
return false
}
+func rewriteValuePPC64_OpPPC64FGreaterEqual(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (FGreaterEqual (InvertFlags x))
+ // cond:
+ // result: (FLessEqual x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpPPC64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpPPC64FLessEqual)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpPPC64FGreaterThan(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (FGreaterThan (InvertFlags x))
+ // cond:
+ // result: (FLessThan x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpPPC64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpPPC64FLessThan)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpPPC64FLessEqual(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (FLessEqual (InvertFlags x))
+ // cond:
+ // result: (FGreaterEqual x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpPPC64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpPPC64FGreaterEqual)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpPPC64FLessThan(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (FLessThan (InvertFlags x))
+ // cond:
+ // result: (FGreaterThan x)
+ for {
+ v_0 := v.Args[0]
+ if v_0.Op != OpPPC64InvertFlags {
+ break
+ }
+ x := v_0.Args[0]
+ v.reset(OpPPC64FGreaterThan)
+ v.AddArg(x)
+ return true
+ }
+ return false
+}
func rewriteValuePPC64_OpPPC64GreaterEqual(v *Value, config *Config) bool {
b := v.Block
_ = b
@@ -5444,6 +5738,19 @@ func rewriteValuePPC64_OpSignExt8to64(v *Value, config *Config) bool {
return true
}
}
+func rewriteValuePPC64_OpSqrt(v *Value, config *Config) bool {
+ b := v.Block
+ _ = b
+ // match: (Sqrt x)
+ // cond:
+ // result: (FSQRT x)
+ for {
+ x := v.Args[0]
+ v.reset(OpPPC64FSQRT)
+ v.AddArg(x)
+ return true
+ }
+}
func rewriteValuePPC64_OpStaticCall(v *Value, config *Config) bool {
b := v.Block
_ = b
@@ -5483,6 +5790,25 @@ func rewriteValuePPC64_OpStore(v *Value, config *Config) bool {
v.AddArg(mem)
return true
}
+ // match: (Store [8] ptr val mem)
+ // cond: is32BitFloat(val.Type)
+ // result: (FMOVDstore ptr val mem)
+ for {
+ if v.AuxInt != 8 {
+ break
+ }
+ ptr := v.Args[0]
+ val := v.Args[1]
+ mem := v.Args[2]
+ if !(is32BitFloat(val.Type)) {
+ break
+ }
+ v.reset(OpPPC64FMOVDstore)
+ v.AddArg(ptr)
+ v.AddArg(val)
+ v.AddArg(mem)
+ return true
+ }
// match: (Store [4] ptr val mem)
// cond: is32BitFloat(val.Type)
// result: (FMOVSstore ptr val mem)
@@ -6515,6 +6841,74 @@ func rewriteBlockPPC64(b *Block) bool {
_ = no
return true
}
+ // match: (If (FLessThan cc) yes no)
+ // cond:
+ // result: (FLT cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpPPC64FLessThan {
+ break
+ }
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockPPC64FLT
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (If (FLessEqual cc) yes no)
+ // cond:
+ // result: (FLE cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpPPC64FLessEqual {
+ break
+ }
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockPPC64FLE
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (If (FGreaterThan cc) yes no)
+ // cond:
+ // result: (FGT cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpPPC64FGreaterThan {
+ break
+ }
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockPPC64FGT
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (If (FGreaterEqual cc) yes no)
+ // cond:
+ // result: (FGE cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpPPC64FGreaterEqual {
+ break
+ }
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockPPC64FGE
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
// match: (If cond yes no)
// cond:
// result: (NE (CMPWconst [0] cond) yes no)