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:
parent
e0815d041c
commit
1eca6aa747
2
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
2
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
@ -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
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user