]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't use duffcopy and duffzero on Plan 9
authorDavid du Colombier <0intro@gmail.com>
Thu, 3 Mar 2016 18:45:24 +0000 (19:45 +0100)
committerDavid du Colombier <0intro@gmail.com>
Thu, 3 Mar 2016 21:36:11 +0000 (21:36 +0000)
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/20171
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: David du Colombier <0intro@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/config.go
src/cmd/compile/internal/ssa/gen/AMD64.rules
src/cmd/compile/internal/ssa/rewriteAMD64.go

index 7d345ae280296cff4a48375a6d21d9f1c1186722..5e54f4f96f3ff2945bf1b77ec62b2fa0abcc1ba1 100644 (file)
@@ -13,16 +13,17 @@ import (
 )
 
 type Config struct {
-       arch       string                     // "amd64", etc.
-       IntSize    int64                      // 4 or 8
-       PtrSize    int64                      // 4 or 8
-       lowerBlock func(*Block) bool          // lowering function
-       lowerValue func(*Value, *Config) bool // lowering function
-       fe         Frontend                   // callbacks into compiler frontend
-       HTML       *HTMLWriter                // html writer, for debugging
-       ctxt       *obj.Link                  // Generic arch information
-       optimize   bool                       // Do optimization
-       curFunc    *Func
+       arch         string                     // "amd64", etc.
+       IntSize      int64                      // 4 or 8
+       PtrSize      int64                      // 4 or 8
+       lowerBlock   func(*Block) bool          // lowering function
+       lowerValue   func(*Value, *Config) bool // lowering function
+       fe           Frontend                   // callbacks into compiler frontend
+       HTML         *HTMLWriter                // html writer, for debugging
+       ctxt         *obj.Link                  // Generic arch information
+       optimize     bool                       // Do optimization
+       noDuffDevice bool                       // Don't use Duff's device
+       curFunc      *Func
 
        // TODO: more stuff. Compiler flags of interest, ...
 
@@ -122,6 +123,12 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
        c.ctxt = ctxt
        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.
        for i := range c.values {
                c.values[i].ID = ID(i)
index 25a88611301d0c19594c9a7e6c631da6cafcef95..73fa700d93214108adde081bc05c24e7c6e735a9 100644 (file)
                (MOVOstore dst (MOVOload src mem) mem))
 
 // 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)
 // 14 and 64 are magic constants.  14 is the number of bytes to encode:
 //     MOVUPS  (SI), X0
 // and 64 is the number of such blocks. See src/runtime/duff_amd64.s:duffcopy.
 
 // 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)
 
 (Not x) -> (XORBconst [1] x)
                                (MOVQstoreconst [0] destptr mem))))
 
 // 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] 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)
 
 // 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)
 
 // Absorb InvertFlags into branches.
index 83fc437747d0f747769ea0da01382fd4a71a86b1..bed44ef103cc97e3ca12f41b4577a89b37397d4a 100644 (file)
@@ -8811,14 +8811,14 @@ func rewriteValueAMD64_OpMove(v *Value, config *Config) bool {
                return true
        }
        // 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)
        for {
                size := v.AuxInt
                dst := v.Args[0]
                src := v.Args[1]
                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
                }
                v.reset(OpAMD64DUFFCOPY)
@@ -8829,14 +8829,14 @@ func rewriteValueAMD64_OpMove(v *Value, config *Config) bool {
                return true
        }
        // 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)
        for {
                size := v.AuxInt
                dst := v.Args[0]
                src := v.Args[1]
                mem := v.Args[2]
-               if !(size > 16*64 && size%8 == 0) {
+               if !((size > 16*64 || config.noDuffDevice) && size%8 == 0) {
                        break
                }
                v.reset(OpAMD64REPMOVSQ)
@@ -13693,13 +13693,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool {
                return true
        }
        // 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))
        for {
                size := v.AuxInt
                destptr := v.Args[0]
                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
                }
                v.reset(OpZero)
@@ -13718,13 +13718,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool {
                return true
        }
        // 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)
        for {
                size := v.AuxInt
                destptr := v.Args[0]
                mem := v.Args[1]
-               if !(size <= 1024 && size%16 == 0) {
+               if !(size <= 1024 && size%16 == 0 && !config.noDuffDevice) {
                        break
                }
                v.reset(OpAMD64DUFFZERO)
@@ -13740,13 +13740,13 @@ func rewriteValueAMD64_OpZero(v *Value, config *Config) bool {
                return true
        }
        // 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)
        for {
                size := v.AuxInt
                destptr := v.Args[0]
                mem := v.Args[1]
-               if !(size > 1024 && size%8 == 0) {
+               if !((size > 1024 || (config.noDuffDevice && size > 32)) && size%8 == 0) {
                        break
                }
                v.reset(OpAMD64REPSTOSQ)