1
0
mirror of https://github.com/golang/go synced 2024-11-26 04:58:00 -07:00

cmd/internal/obj: refactor ppc64 address relocation code generation

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>
This commit is contained in:
Paul E. Murphy 2021-03-09 16:55:13 -06:00 committed by Lynn Boger
parent e0815d041c
commit 1eca6aa747
2 changed files with 25 additions and 25 deletions

View 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

View 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_SACON, a6: C_REG, type_: 3, size: 4},
{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_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_GOTADDR, a6: C_REG, type_: 81, 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_SACON, a6: C_REG, type_: 3, size: 4},
{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_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_CREG, a6: C_REG, type_: 68, size: 4},
{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())