From b3e8a00060030a8c60db3dbc0d2cf389c65c8a56 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Thu, 23 Apr 2020 13:11:00 -0700 Subject: [PATCH] cmd/compile: move duffcopy auxint calculation out of rewrite rules Package amd64 is a more natural home for it. It also makes it easier to see how many bytes are being copied in ssa.html. Passes toolstash-check. Change-Id: I5ecf0f0f18e8db2faa2caf7a05028c310952bd94 Reviewed-on: https://go-review.googlesource.com/c/go/+/229703 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/amd64/ssa.go | 11 ++++++++++- src/cmd/compile/internal/ssa/gen/AMD64.rules | 8 +------- src/cmd/compile/internal/ssa/gen/AMD64Ops.go | 2 +- src/cmd/compile/internal/ssa/rewriteAMD64.go | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/cmd/compile/internal/amd64/ssa.go b/src/cmd/compile/internal/amd64/ssa.go index 71b42b09a7..2b75bd6549 100644 --- a/src/cmd/compile/internal/amd64/ssa.go +++ b/src/cmd/compile/internal/amd64/ssa.go @@ -872,7 +872,16 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) { p := s.Prog(obj.ADUFFCOPY) p.To.Type = obj.TYPE_ADDR p.To.Sym = gc.Duffcopy - p.To.Offset = v.AuxInt + if v.AuxInt%16 != 0 { + v.Fatalf("bad DUFFCOPY AuxInt %v", v.AuxInt) + } + p.To.Offset = 14 * (64 - v.AuxInt/16) + // 14 and 64 are magic constants. 14 is the number of bytes to encode: + // MOVUPS (SI), X0 + // ADDQ $16, SI + // MOVUPS X0, (DI) + // ADDQ $16, DI + // and 64 is the number of such blocks. See src/runtime/duff_amd64.s:duffcopy. case ssa.OpCopy: // TODO: use MOVQreg for reg->reg copies instead of OpCopy? if v.Type.IsMemory() { diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 0b02301c7d..7538ce9f72 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -309,13 +309,7 @@ (Move [s] dst src mem) && s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s) => - (DUFFCOPY [14*(64-s/16)] dst src mem) -// 14 and 64 are magic constants. 14 is the number of bytes to encode: -// MOVUPS (SI), X0 -// ADDQ $16, SI -// MOVUPS X0, (DI) -// ADDQ $16, DI -// and 64 is the number of such blocks. See src/runtime/duff_amd64.s:duffcopy. + (DUFFCOPY [s] dst src mem) // Large copying uses REP MOVSQ. (Move [s] dst src mem) && (s > 16*64 || config.noDuffDevice) && s%8 == 0 && logLargeCopy(v, s) => diff --git a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go index be4a0bf805..144e76fea7 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/AMD64Ops.go @@ -681,7 +681,7 @@ func init() { // arg0 = destination pointer // arg1 = source pointer // arg2 = mem - // auxint = offset from duffcopy symbol to call + // auxint = # of bytes to copy, must be multiple of 16 // returns memory { name: "DUFFCOPY", diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 9f48609111..5f3d4e5b90 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -31641,7 +31641,7 @@ func rewriteValueAMD64_OpMove(v *Value) bool { } // match: (Move [s] dst src mem) // cond: s > 64 && s <= 16*64 && s%16 == 0 && !config.noDuffDevice && logLargeCopy(v, s) - // result: (DUFFCOPY [14*(64-s/16)] dst src mem) + // result: (DUFFCOPY [s] dst src mem) for { s := auxIntToInt64(v.AuxInt) dst := v_0 @@ -31651,7 +31651,7 @@ func rewriteValueAMD64_OpMove(v *Value) bool { break } v.reset(OpAMD64DUFFCOPY) - v.AuxInt = int64ToAuxInt(14 * (64 - s/16)) + v.AuxInt = int64ToAuxInt(s) v.AddArg3(dst, src, mem) return true } -- 2.50.0