diff --git a/src/cmd/asm/internal/asm/testdata/ppc64.s b/src/cmd/asm/internal/asm/testdata/ppc64.s index edaecaea49a..1bd4b1e1c89 100644 --- a/src/cmd/asm/internal/asm/testdata/ppc64.s +++ b/src/cmd/asm/internal/asm/testdata/ppc64.s @@ -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 diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 69c84b21d48..60ffc936c5c 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -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())