{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},
{as: AMOVD, a1: C_TLS_IE, a6: C_REG, type_: 80, size: 12},
- {as: AMOVD, a1: C_TOCADDR, a6: C_REG, type_: 95, size: 8},
{as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
{as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
case obj.TYPE_MEM:
switch a.Name {
+ case obj.NAME_GOTREF, obj.NAME_TOCREF:
+ return C_ADDR
+
case obj.NAME_EXTERN,
obj.NAME_STATIC:
+ c.instoffset = a.Offset
if a.Sym == nil {
break
- }
- c.instoffset = a.Offset
- if a.Sym != nil { // use relocation
- if a.Sym.Type == objabi.STLSBSS {
- if c.ctxt.Flag_shared {
- return C_TLS_IE
- } else {
- return C_TLS_LE
- }
+ } else if a.Sym.Type == objabi.STLSBSS {
+ // For PIC builds, use 12 byte got initial-exec TLS accesses.
+ if c.ctxt.Flag_shared {
+ return C_TLS_IE
}
+ // Otherwise, use 8 byte local-exec TLS accesses.
+ return C_TLS_LE
+ } else {
return C_ADDR
}
- return C_LOREG
-
- case obj.NAME_GOTREF:
- return C_GOTADDR
-
- case obj.NAME_TOCREF:
- return C_TOCADDR
case obj.NAME_AUTO:
c.instoffset = int64(c.autosize) + a.Offset
}
o1, o2 = c.symbolAccess(p.To.Sym, v, p.From.Reg, inst)
- //if(dlm) reloc(&p->to, p->pc, 1);
+ case 75: // 32 bit offset symbol loads (got/toc/addr)
+ v := p.From.Offset
- case 75:
- v := c.vregoff(&p.From)
// Offsets in DS form loads must be a multiple of 4
inst := c.opload(p.As)
if c.opform(inst) == DS_FORM && v&0x3 != 0 {
log.Fatalf("invalid offset for DS form load/store %v", p)
}
- o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
-
- //if(dlm) reloc(&p->from, p->pc, 1);
+ switch p.From.Name {
+ case obj.NAME_GOTREF, obj.NAME_TOCREF:
+ if v != 0 {
+ c.ctxt.Diag("invalid offset for GOT/TOC access %v", p)
+ }
+ o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
+ o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
+ rel := obj.Addrel(c.cursym)
+ rel.Off = int32(c.pc)
+ rel.Siz = 8
+ rel.Sym = p.From.Sym
+ switch p.From.Name {
+ case obj.NAME_GOTREF:
+ rel.Type = objabi.R_ADDRPOWER_GOT
+ case obj.NAME_TOCREF:
+ rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
+ }
+ default:
+ o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
+ }
case 76:
v := c.vregoff(&p.From)
o1, o2 = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst)
o3 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
- //if(dlm) reloc(&p->from, p->pc, 1);
-
case 79:
if p.From.Offset != 0 {
c.ctxt.Diag("invalid offset against tls var %v", p)
rel.Sym = p.From.Sym
rel.Type = objabi.R_POWER_TLS
- case 81:
- v := c.vregoff(&p.To)
- if v != 0 {
- c.ctxt.Diag("invalid offset against GOT slot %v", p)
- }
-
- o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
- o2 = AOP_IRR(c.opload(AMOVD), uint32(p.To.Reg), uint32(p.To.Reg), 0)
- rel := obj.Addrel(c.cursym)
- rel.Off = int32(c.pc)
- rel.Siz = 8
- rel.Sym = p.From.Sym
- rel.Type = objabi.R_ADDRPOWER_GOT
case 82: /* vector instructions, VX-form and VC-form */
if p.From.Type == obj.TYPE_REG {
/* reg reg none OR reg reg reg */
cy := int(c.regoff(p.GetFrom3()))
o1 = AOP_Z23I(c.oprrr(p.As), uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), uint32(cy))
- case 95: /* Retrieve TOC relative symbol */
- /* This code is for AIX only */
- v := c.vregoff(&p.From)
- if v != 0 {
- c.ctxt.Diag("invalid offset against TOC slot %v", p)
- }
-
- inst := c.opload(p.As)
- if c.opform(inst) != DS_FORM {
- c.ctxt.Diag("invalid form for a TOC access in %v", p)
- }
-
- o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), REG_R2, 0)
- o2 = AOP_IRR(inst, uint32(p.To.Reg), uint32(p.To.Reg), 0)
- rel := obj.Addrel(c.cursym)
- rel.Off = int32(c.pc)
- rel.Siz = 8
- rel.Sym = p.From.Sym
- rel.Type = objabi.R_ADDRPOWER_TOCREL_DS
-
case 96: /* VSX load, DQ-form */
/* reg imm reg */
/* operand order: (RA)(DQ), XT */