]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/internal/obj: refactor ppc64 address relocation code generation
authorPaul E. Murphy <murp@ibm.com>
Tue, 9 Mar 2021 22:55:13 +0000 (16:55 -0600)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Tue, 27 Apr 2021 11:50:41 +0000 (11:50 +0000)
The code for generating a long constant versus generating an address
(either via a relocation, or known offset) should be handled in the
same place.

Resolve this by classifying memory arguments as C_LACON (a long
address constant) instead of C_LCON (a long constant).

Likewise, reorder AMOVD/AMOVW optab entries to keep similar
classifications near each other. An extra optab entry for
DWORD is also added to continue handling C_LACON arguments
correctly.

Change-Id: I5ce28400492a071f615125a9b8d260826f1600d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/312296
Run-TryBot: Paul Murphy <murp@ibm.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Carlos Eduardo Seo <carlos.seo@linaro.org>
Trust: Carlos Eduardo Seo <carlos.seo@linaro.org>

src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/internal/obj/ppc64/asm9.go

index edaecaea49ae9b664b48c19d22690c911742f749..1bd4b1e1c89057783fd84b71c2339415bfd38ff0 100644 (file)
@@ -41,6 +41,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        MOVDBR (R3)(R4), R5             // 7ca41c28
        MOVWBR (R3)(R4), R5             // 7ca41c2c
        MOVHBR (R3)(R4), R5             // 7ca41e2c
+       MOVD $foo+4009806848(FP), R5    // 3fe1ef0138bfcc20
+       MOVD $foo(SB), R5               // 3fe0000038bf0000
 
        MOVDU 8(R3), R4                 // e8830009
        MOVDU (R3)(R4), R5              // 7ca4186a
index 69c84b21d48fc3f02059a94897fceeaa7ce629dc..60ffc936c5ccbf4e60c40b08fc885a1c220dee87 100644 (file)
@@ -222,11 +222,11 @@ var optab = []Optab{
        {as: AMOVD, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
        {as: AMOVD, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
        {as: AMOVD, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
+       {as: AMOVD, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
        {as: AMOVD, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
+       {as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
        {as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
-       {as: AMOVD, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
        {as: AMOVD, a1: C_GOTADDR, a6: C_REG, type_: 81, size: 8},
-       {as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
        {as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
        {as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
        {as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8},
@@ -242,11 +242,11 @@ var optab = []Optab{
        {as: AMOVW, a1: C_ADDCON, a6: C_REG, type_: 3, size: 4},
        {as: AMOVW, a1: C_ANDCON, a6: C_REG, type_: 3, size: 4},
        {as: AMOVW, a1: C_UCON, a6: C_REG, type_: 3, size: 4},
+       {as: AMOVW, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
        {as: AMOVW, a1: C_SACON, a6: C_REG, type_: 3, size: 4},
+       {as: AMOVW, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
        {as: AMOVW, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
-       {as: AMOVW, a1: C_LCON, a6: C_REG, type_: 19, size: 8},
        {as: AMOVW, a1: C_CREG, a6: C_REG, type_: 68, size: 4},
-       {as: AMOVW, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
        {as: AMOVW, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
        {as: AMOVW, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
        {as: AMOVW, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
@@ -304,6 +304,7 @@ var optab = []Optab{
        {as: AWORD, a1: C_LCON, type_: 40, size: 4},
        {as: ADWORD, a1: C_LCON, type_: 31, size: 8},
        {as: ADWORD, a1: C_DCON, type_: 31, size: 8},
+       {as: ADWORD, a1: C_LACON, type_: 31, size: 8},
        {as: AADDME, a1: C_REG, a6: C_REG, type_: 47, size: 4},
        {as: AEXTSB, a1: C_REG, a6: C_REG, type_: 48, size: 4},
        {as: AEXTSB, a6: C_REG, type_: 48, size: 4},
@@ -877,11 +878,8 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
                        if s == nil {
                                return C_GOK
                        }
-
                        c.instoffset = a.Offset
-
-                       /* not sure why this barfs */
-                       return C_LCON
+                       return C_LACON
 
                case obj.NAME_AUTO:
                        c.instoffset = int64(c.autosize) + a.Offset
@@ -2775,13 +2773,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
 
        case 19: /* mov $lcon,r ==> cau+or */
                d := c.vregoff(&p.From)
-
-               if p.From.Sym == nil {
-                       o1 = loadu32(int(p.To.Reg), d)
-                       o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
-               } else {
-                       o1, o2 = c.symbolAccess(p.From.Sym, d, p.To.Reg, OP_ADDI)
-               }
+               o1 = loadu32(int(p.To.Reg), d)
+               o2 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(int32(d)))
 
        case 20: /* add $ucon,,r | addis $addcon,r,r */
                v := c.regoff(&p.From)
@@ -2899,16 +2892,21 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
                }
 
        case 26: /* mov $lsext/auto/oreg,,r2 ==> addis+addi */
-               if p.To.Reg == REGTMP {
-                       c.ctxt.Diag("can't synthesize large constant\n%v", p)
-               }
-               v := c.regoff(&p.From)
+               v := c.vregoff(&p.From)
                r := int(p.From.Reg)
-               if r == 0 {
-                       r = c.getimpliedreg(&p.From, p)
+
+               switch p.From.Name {
+               case obj.NAME_EXTERN, obj.NAME_STATIC:
+                       // Load a 32 bit constant, or relocation depending on if a symbol is attached
+                       o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, OP_ADDI)
+               default:
+                       if r == 0 {
+                               r = c.getimpliedreg(&p.From, p)
+                       }
+                       // Add a 32 bit offset to a register.
+                       o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(int32(v))))
+                       o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
                }
-               o1 = AOP_IRR(OP_ADDIS, REGTMP, uint32(r), uint32(high16adjusted(v)))
-               o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), REGTMP, uint32(v))
 
        case 27: /* subc ra,$simm,rd => subfic rd,ra,$simm */
                v := c.regoff(p.GetFrom3())