Commit d55a099e authored by David du Colombier's avatar David du Colombier

cmd/compile: don't use duffcopy and duffzero on Plan 9

The ssa compiler uses the duffcopy and duffzero functions,
which rely on the MOVUPS instructions.

However, this doesn't work on Plan 9, since floating point
operations are not allowed in the note handler.

This change disables the use of duffcopy and duffzero
on Plan 9 in the ssa compiler.

Updates #14605.

Change-Id: I017f8ff83de00eabaf7e146b4344a863db1dfddc
Reviewed-on: https://go-review.googlesource.com/20171Reviewed-by: default avatarKeith Randall <khr@golang.org>
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 466c948b
...@@ -22,6 +22,7 @@ type Config struct { ...@@ -22,6 +22,7 @@ type Config struct {
HTML *HTMLWriter // html writer, for debugging HTML *HTMLWriter // html writer, for debugging
ctxt *obj.Link // Generic arch information ctxt *obj.Link // Generic arch information
optimize bool // Do optimization optimize bool // Do optimization
noDuffDevice bool // Don't use Duff's device
curFunc *Func curFunc *Func
// TODO: more stuff. Compiler flags of interest, ... // TODO: more stuff. Compiler flags of interest, ...
...@@ -122,6 +123,12 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config ...@@ -122,6 +123,12 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
c.ctxt = ctxt c.ctxt = ctxt
c.optimize = optimize c.optimize = optimize
// Don't use Duff's device on Plan 9, because floating
// point operations are not allowed in note handler.
if obj.Getgoos() == "plan9" {
c.noDuffDevice = true
}
// Assign IDs to preallocated values/blocks. // Assign IDs to preallocated values/blocks.
for i := range c.values { for i := range c.values {
c.values[i].ID = ID(i) c.values[i].ID = ID(i)
......
...@@ -328,7 +328,7 @@ ...@@ -328,7 +328,7 @@
(MOVOstore dst (MOVOload src mem) mem)) (MOVOstore dst (MOVOload src mem) mem))
// Medium copying uses a duff device. // Medium copying uses a duff device.
(Move [size] dst src mem) && size >= 32 && size <= 16*64 && size%16 == 0 -> (Move [size] dst src mem) && size >= 32 && size <= 16*64 && size%16 == 0 && !config.noDuffDevice ->
(DUFFCOPY [14*(64-size/16)] dst src mem) (DUFFCOPY [14*(64-size/16)] dst src mem)
// 14 and 64 are magic constants. 14 is the number of bytes to encode: // 14 and 64 are magic constants. 14 is the number of bytes to encode:
// MOVUPS (SI), X0 // MOVUPS (SI), X0
...@@ -338,7 +338,7 @@ ...@@ -338,7 +338,7 @@
// and 64 is the number of such blocks. See src/runtime/duff_amd64.s:duffcopy. // and 64 is the number of such blocks. See src/runtime/duff_amd64.s:duffcopy.
// Large copying uses REP MOVSQ. // Large copying uses REP MOVSQ.
(Move [size] dst src mem) && size > 16*64 && size%8 == 0 -> (Move [size] dst src mem) && (size > 16*64 || config.noDuffDevice) && size%8 == 0 ->
(REPMOVSQ dst src (MOVQconst [size/8]) mem) (REPMOVSQ dst src (MOVQconst [size/8]) mem)
(Not x) -> (XORBconst [1] x) (Not x) -> (XORBconst [1] x)
...@@ -869,13 +869,13 @@ ...@@ -869,13 +869,13 @@
(MOVQstoreconst [0] destptr mem)))) (MOVQstoreconst [0] destptr mem))))
// Medium zeroing uses a duff device. // Medium zeroing uses a duff device.
(Zero [size] destptr mem) && size <= 1024 && size%8 == 0 && size%16 != 0 -> (Zero [size] destptr mem) && size <= 1024 && size%8 == 0 && size%16 != 0 && !config.noDuffDevice ->
(Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem)) (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
(Zero [size] destptr mem) && size <= 1024 && size%16 == 0 -> (Zero [size] destptr mem) && size <= 1024 && size%16 == 0 && !config.noDuffDevice ->
(DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem) (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem)
// Large zeroing uses REP STOSQ. // Large zeroing uses REP STOSQ.
(Zero [size] destptr mem) && size > 1024 && size%8 == 0 -> (Zero [size] destptr mem) && (size > 1024 || (config.noDuffDevice && size > 32)) && size%8 == 0 ->
(REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem) (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem)
// Absorb InvertFlags into branches. // Absorb InvertFlags into branches.
......
...@@ -8811,14 +8811,14 @@ func rewriteValueAMD64_OpMove(v *Value, config *Config) bool { ...@@ -8811,14 +8811,14 @@ func rewriteValueAMD64_OpMove(v *Value, config *Config) bool {
return true return true
} }
// match: (Move [size] dst src mem) // match: (Move [size] dst src mem)
// cond: size >= 32 && size <= 16*64 && size%16 == 0 // cond: size >= 32 && size <= 16*64 && size%16 == 0 && !config.noDuffDevice
// result: (DUFFCOPY [14*(64-size/16)] dst src mem) // result: (DUFFCOPY [14*(64-size/16)] dst src mem)
for { for {
size := v.AuxInt size := v.AuxInt
dst := v.Args[0] dst := v.Args[0]
src := v.Args[1] src := v.Args[1]
mem := v.Args[2] mem := v.Args[2]
if !(size >= 32 && size <= 16*64 && size%16 == 0) { if !(size >= 32 && size <= 16*64 && size%16 == 0 && !config.noDuffDevice) {
break break
} }
v.reset(OpAMD64DUFFCOPY) v.reset(OpAMD64DUFFCOPY)
...@@ -8829,14 +8829,14 @@ func rewriteValueAMD64_OpMove(v *Value, config *Config) bool { ...@@ -8829,14 +8829,14 @@ func rewriteValueAMD64_OpMove(v *Value, config *Config) bool {
return true return true
} }
// match: (Move [size] dst src mem) // match: (Move [size] dst src mem)
// cond: size > 16*64 && size%8 == 0 // cond: (size > 16*64 || config.noDuffDevice) && size%8 == 0
// result: (REPMOVSQ dst src (MOVQconst [size/8]) mem) // result: (REPMOVSQ dst src (MOVQconst [size/8]) mem)
for { for {
size := v.AuxInt size := v.AuxInt
dst := v.Args[0] dst := v.Args[0]
src := v.Args[1] src := v.Args[1]
mem := v.Args[2] mem := v.Args[2]
if !(size > 16*64 && size%8 == 0) { if !((size > 16*64 || config.noDuffDevice) && size%8 == 0) {
break break
} }
v.reset(OpAMD64REPMOVSQ) v.reset(OpAMD64REPMOVSQ)
...@@ -13693,13 +13693,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool { ...@@ -13693,13 +13693,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool {
return true return true
} }
// match: (Zero [size] destptr mem) // match: (Zero [size] destptr mem)
// cond: size <= 1024 && size%8 == 0 && size%16 != 0 // cond: size <= 1024 && size%8 == 0 && size%16 != 0 && !config.noDuffDevice
// result: (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem)) // result: (Zero [size-8] (ADDQconst [8] destptr) (MOVQstore destptr (MOVQconst [0]) mem))
for { for {
size := v.AuxInt size := v.AuxInt
destptr := v.Args[0] destptr := v.Args[0]
mem := v.Args[1] mem := v.Args[1]
if !(size <= 1024 && size%8 == 0 && size%16 != 0) { if !(size <= 1024 && size%8 == 0 && size%16 != 0 && !config.noDuffDevice) {
break break
} }
v.reset(OpZero) v.reset(OpZero)
...@@ -13718,13 +13718,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool { ...@@ -13718,13 +13718,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool {
return true return true
} }
// match: (Zero [size] destptr mem) // match: (Zero [size] destptr mem)
// cond: size <= 1024 && size%16 == 0 // cond: size <= 1024 && size%16 == 0 && !config.noDuffDevice
// result: (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem) // result: (DUFFZERO [duffStart(size)] (ADDQconst [duffAdj(size)] destptr) (MOVOconst [0]) mem)
for { for {
size := v.AuxInt size := v.AuxInt
destptr := v.Args[0] destptr := v.Args[0]
mem := v.Args[1] mem := v.Args[1]
if !(size <= 1024 && size%16 == 0) { if !(size <= 1024 && size%16 == 0 && !config.noDuffDevice) {
break break
} }
v.reset(OpAMD64DUFFZERO) v.reset(OpAMD64DUFFZERO)
...@@ -13740,13 +13740,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool { ...@@ -13740,13 +13740,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool {
return true return true
} }
// match: (Zero [size] destptr mem) // match: (Zero [size] destptr mem)
// cond: size > 1024 && size%8 == 0 // cond: (size > 1024 || (config.noDuffDevice && size > 32)) && size%8 == 0
// result: (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem) // result: (REPSTOSQ destptr (MOVQconst [size/8]) (MOVQconst [0]) mem)
for { for {
size := v.AuxInt size := v.AuxInt
destptr := v.Args[0] destptr := v.Args[0]
mem := v.Args[1] mem := v.Args[1]
if !(size > 1024 && size%8 == 0) { if !((size > 1024 || (config.noDuffDevice && size > 32)) && size%8 == 0) {
break break
} }
v.reset(OpAMD64REPSTOSQ) v.reset(OpAMD64REPSTOSQ)
......
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