]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: set/unset base register for better assembly print
authorCherry Zhang <cherryyz@google.com>
Tue, 18 Jul 2017 12:35:00 +0000 (08:35 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 2 Aug 2017 12:24:02 +0000 (12:24 +0000)
For address of an auto or arg, on all non-x86 architectures
the assembler backend encodes the actual SP offset in the
instruction but leaves the offset in Prog unchanged. When the
assembly is printed in compile -S, it shows an offset
relative to pseudo FP/SP with an actual hardware SP base
register (e.g. R13 on ARM). This is confusing. Unset the
base register if it is indeed SP, so the assembly output is
consistent. If the base register isn't SP, it should be an
error and the error output contains the actual base register.

For address loading instructions, the base register isn't set
in the compiler on non-x86 architectures. Set it. Normally it
is SP and will be unset in the change mentioned above for
printing. If it is not, it will be an error and the error
output contains the actual base register.

No change in generated binary, only printed assembly. Passes
"go build -a -toolexec 'toolstash -cmp' std cmd" on all
architectures.

Fixes #21064.

Change-Id: Ifafe8d5f9b437efbe824b63b3cbc2f5f6cdc1fd5
Reviewed-on: https://go-review.googlesource.com/49432
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/asm_test.go
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/internal/obj/arm/asm5.go
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/mips/asm0.go
src/cmd/internal/obj/ppc64/asm9.go
src/cmd/internal/obj/s390x/asmz.go

index 343f2d3aec7daa1784288f446ed13e2fc7a0d7fd..93abee3da0f09b2aadb4a88bd42a8482f92864dc 100644 (file)
@@ -464,6 +464,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpARMMOVWaddr:
                p := s.Prog(arm.AMOVW)
                p.From.Type = obj.TYPE_ADDR
+               p.From.Reg = v.Args[0].Reg()
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
 
@@ -485,7 +486,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case nil:
                        // No sym, just MOVW $off(SP), R
                        wantreg = "SP"
-                       p.From.Reg = arm.REGSP
                        p.From.Offset = v.AuxInt
                }
                if reg := v.Args[0].RegName(); reg != wantreg {
index dec6a4e93ede54eaa22a4048f80fa55b53abdb4b..0f9e82c727db3b15d88cae8477908f821e9f4457 100644 (file)
@@ -260,6 +260,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpARM64MOVDaddr:
                p := s.Prog(arm64.AMOVD)
                p.From.Type = obj.TYPE_ADDR
+               p.From.Reg = v.Args[0].Reg()
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
 
@@ -281,7 +282,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case nil:
                        // No sym, just MOVD $off(SP), R
                        wantreg = "SP"
-                       p.From.Reg = arm64.REGSP
                        p.From.Offset = v.AuxInt
                }
                if reg := v.Args[0].RegName(); reg != wantreg {
index 221b8497f15984d834118d81045eb2a3bd1d73dd..08ec638f44ef7105d2dad1db5631c17fff5a2f79 100644 (file)
@@ -898,6 +898,17 @@ var linuxAMD64Tests = []*asmTest{
                }`,
                []string{"\tCMPL\t[A-Z]"},
        },
+       {
+               // make sure assembly output has matching offset and base register.
+               `
+               func f72(a, b int) int {
+                       var x [16]byte // use some frame
+                       _ = x
+                       return b
+               }
+               `,
+               []string{"b\\+40\\(SP\\)"},
+       },
 }
 
 var linux386Tests = []*asmTest{
@@ -1302,6 +1313,17 @@ var linuxARMTests = []*asmTest{
                `,
                []string{"\tCLZ\t"},
        },
+       {
+               // make sure assembly output has matching offset and base register.
+               `
+               func f13(a, b int) int {
+                       var x [16]byte // use some frame
+                       _ = x
+                       return b
+               }
+               `,
+               []string{"b\\+4\\(FP\\)"},
+       },
 }
 
 var linuxARM64Tests = []*asmTest{
@@ -1473,7 +1495,7 @@ var linuxARM64Tests = []*asmTest{
                        return
                }
                `,
-               []string{"\tMOVD\t\"\"\\.a\\+[0-9]+\\(RSP\\), R[0-9]+", "\tMOVD\tR[0-9]+, \"\"\\.b\\+[0-9]+\\(RSP\\)"},
+               []string{"\tMOVD\t\"\"\\.a\\+[0-9]+\\(FP\\), R[0-9]+", "\tMOVD\tR[0-9]+, \"\"\\.b\\+[0-9]+\\(FP\\)"},
        },
 }
 
index d2b4885eaad9c5bec0d8730852ec93a1ceeaadf3..e65515a85b0102876c4b6dd72952d34f8d02f43b 100644 (file)
@@ -273,6 +273,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpMIPSMOVWaddr:
                p := s.Prog(mips.AMOVW)
                p.From.Type = obj.TYPE_ADDR
+               p.From.Reg = v.Args[0].Reg()
                var wantreg string
                // MOVW $sym+off(base), R
                // the assembler expands it as the following:
@@ -291,7 +292,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case nil:
                        // No sym, just MOVW $off(SP), R
                        wantreg = "SP"
-                       p.From.Reg = mips.REGSP
                        p.From.Offset = v.AuxInt
                }
                if reg := v.Args[0].RegName(); reg != wantreg {
index 5a7a6019422b112b514018f579baacbbc8179cdb..db163f3e9d0776650062df3f4887b89fca2722b6 100644 (file)
@@ -247,6 +247,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpMIPS64MOVVaddr:
                p := s.Prog(mips.AMOVV)
                p.From.Type = obj.TYPE_ADDR
+               p.From.Reg = v.Args[0].Reg()
                var wantreg string
                // MOVV $sym+off(base), R
                // the assembler expands it as the following:
@@ -265,7 +266,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case nil:
                        // No sym, just MOVV $off(SP), R
                        wantreg = "SP"
-                       p.From.Reg = mips.REGSP
                        p.From.Offset = v.AuxInt
                }
                if reg := v.Args[0].RegName(); reg != wantreg {
index a95dabccf0be1215e2dab583930287d76a18ede4..5fe140fdcf16e47041f250375cfe0512d307f066 100644 (file)
@@ -638,6 +638,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
        case ssa.OpPPC64MOVDaddr:
                p := s.Prog(ppc64.AMOVD)
                p.From.Type = obj.TYPE_ADDR
+               p.From.Reg = v.Args[0].Reg()
                p.To.Type = obj.TYPE_REG
                p.To.Reg = v.Reg()
 
@@ -660,7 +661,6 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case nil:
                        // No sym, just MOVD $off(SP), R
                        wantreg = "SP"
-                       p.From.Reg = ppc64.REGSP
                        p.From.Offset = v.AuxInt
                }
                if reg := v.Args[0].RegName(); reg != wantreg {
index cfda99f60289b33921823e4ec5d9043d48acd8bc..8abf732b2caf70df140040d12b47b86932530966 100644 (file)
@@ -1167,6 +1167,11 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
                        return C_ADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = c.autosize + a.Offset
                        if t := immaddr(int32(c.instoffset)); t != 0 {
                                if immhalf(int32(c.instoffset)) {
@@ -1185,6 +1190,11 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
                        return C_LAUTO
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = c.autosize + a.Offset + 4
                        if t := immaddr(int32(c.instoffset)); t != 0 {
                                if immhalf(int32(c.instoffset)) {
@@ -1285,10 +1295,20 @@ func (c *ctxt5) aclass(a *obj.Addr) int {
                        return C_LCONADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = c.autosize + a.Offset
                        return c.aconsize()
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = c.autosize + a.Offset + 4
                        return c.aconsize()
                }
index 04a481863ad6f96600a7dcd93503fe17241e7924..4419909f69149e4c2c2f51644eefda4cd1663deb 100644 (file)
@@ -1149,10 +1149,20 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
                        return C_GOTADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        return autoclass(c.instoffset)
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + 8
                        return autoclass(c.instoffset)
 
@@ -1228,10 +1238,20 @@ func (c *ctxt7) aclass(a *obj.Addr) int {
                        return C_VCONADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        goto aconsize
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + 8
                        goto aconsize
                }
index 3cfb260d60398700e1377d45e3a40c86c1dfefd6..6257e5b83d2a084022c7c92f1f11e99348dd16b8 100644 (file)
@@ -556,6 +556,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
                        return C_LEXT
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SAUTO
@@ -563,6 +568,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
                        return C_LAUTO
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SAUTO
@@ -616,6 +626,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
                        return C_LECON
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SACON
@@ -623,6 +638,11 @@ func (c *ctxt0) aclass(a *obj.Addr) int {
                        return C_LACON
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SACON
index bdbac03f9c043324547bdf0ba9e369dea4a6f4b8..4d787b1c352eea3734210003ad54d8ece2efd7ed 100644 (file)
@@ -758,6 +758,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
                        return C_GOTADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SAUTO
@@ -765,6 +770,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
                        return C_LAUTO
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SAUTO
@@ -817,6 +827,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
                        return C_LCON
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SACON
@@ -824,6 +839,11 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
                        return C_LACON
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SACON
index 3bba7b2a5ce905f4d4c6b34e1c95c7a3bce2bc24..6d2b870f0aca95a5cf8e4714a787bb752edd3036 100644 (file)
@@ -505,6 +505,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
                        return C_GOTADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SAUTO
@@ -512,6 +517,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
                        return C_LAUTO
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SAUTO
@@ -567,6 +577,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
                        return C_SYMADDR
 
                case obj.NAME_AUTO:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-SP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SACON
@@ -574,6 +589,11 @@ func (c *ctxtz) aclass(a *obj.Addr) int {
                        return C_LACON
 
                case obj.NAME_PARAM:
+                       if a.Reg == REGSP {
+                               // unset base register for better printing, since
+                               // a.Offset is still relative to pseudo-FP.
+                               a.Reg = obj.REG_NONE
+                       }
                        c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.FixedFrameSize()
                        if c.instoffset >= -BIG && c.instoffset < BIG {
                                return C_SACON