obj.Flagcount("y", "debug declarations in canned imports (with -d)", &Debug['y'])
var flag_shared int
var flag_dynlink bool
- if Thearch.Thechar == '6' || Thearch.Thechar == '5' {
+ if Thearch.Thechar == '5' || Thearch.Thechar == '6' || Thearch.Thechar == '9' {
obj.Flagcount("shared", "generate code that can be linked into a shared library", &flag_shared)
}
if Thearch.Thechar == '6' {
obj.Flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel)
+ }
+ if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
flag.BoolVar(&flag_dynlink, "dynlink", false, "support references to Go symbols defined in other shared libraries")
}
obj.Flagstr("cpuprofile", "write cpu profile to `file`", &cpuprofile)
gc.Widthptr = 8
gc.Widthint = 8
gc.Widthreg = 8
+
+ if gc.Ctxt.Flag_shared != 0 {
+ gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, ppc64.REG_R2)
+ gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, ppc64.REG_R12)
+ }
}
func Main() {
case obj.ACALL:
if p.To.Type == obj.TYPE_REG && p.To.Reg != ppc64.REG_CTR {
// Allow front end to emit CALL REG, and rewrite into MOV REG, CTR; CALL CTR.
+ if gc.Ctxt.Flag_dynlink {
+ // Make sure function pointer is in R12 as well when
+ // dynamically linking Go.
+ // TODO(mwhudson): it would obviously be better to
+ // change the register allocation to put the value in
+ // R12 already, but I don't know how to do that.
+ q := gc.Prog(as)
+ q.As = ppc64.AMOVD
+ q.From = p.To
+ q.To.Type = obj.TYPE_REG
+ q.To.Reg = ppc64.REG_R12
+ }
pp := gc.Prog(as)
pp.From = p.From
pp.To.Type = obj.TYPE_REG
// Exclude registers with fixed functions
regbits := uint64(1<<0 | RtoB(ppc64.REGSP) | RtoB(ppc64.REGG) | RtoB(ppc64.REGTLS) | RtoB(ppc64.REGTMP))
+ if gc.Ctxt.Flag_dynlink {
+ // When dynamically linking Go, R2 is reserved to be the TOC pointer
+ // and R12 so that calls via function pointer can stomp on it.
+ regbits |= RtoB(ppc64.REG_R2)
+ regbits |= RtoB(ppc64.REG_R12)
+ }
// Also exclude floating point registers with fixed constants
regbits |= RtoB(ppc64.REG_F27) | RtoB(ppc64.REG_F28) | RtoB(ppc64.REG_F29) | RtoB(ppc64.REG_F30) | RtoB(ppc64.REG_F31)