mirror of https://github.com/golang/go.git
cmd/internal/obj/ppc64: cleanup and remove usage of getimpliedreg
getimpliedreg was used to set a default register in cases where one was implied but not set by the assembler or compiler. In most cases with constant values, R0 is implied, and is the value 0 by architectural design. In those cases, R0 is always used, so treat 0 and REG_R0 as interchangeable in those encodings. Similarly, the pseudo-register SP or FP is used to in place of the stack pointer, always R1 on PPC64. Unconditionally set this during classification of NAME_AUTO and NAME_PARAM as it may be 0. The case where REGSB might be returned from getimpliedreg is never used. REGSB is aliased to R2, but in practice it is either R0 or R2 depending on buildmode. See symbolAccess in asm9.go for an example. Change-Id: I7283e66d5351f56a7fe04cee38714910eaa73cb3 Reviewed-on: https://go-review.googlesource.com/c/go/+/434775 Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Paul Murphy <murp@ibm.com> Reviewed-by: Than McIntosh <thanm@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
a9722bf918
commit
3ff5632d63
|
|
@ -607,32 +607,6 @@ func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Get the implied register of an operand which doesn't specify one. These show up
|
||||
// in handwritten asm like "MOVD R5, foosymbol" where a base register is not supplied,
|
||||
// or "MOVD R5, foo+10(SP) or pseudo-register is used. The other common case is when
|
||||
// generating constants in register like "MOVD $constant, Rx".
|
||||
func (c *ctxt9) getimpliedreg(a *obj.Addr, p *obj.Prog) int {
|
||||
class := oclass(a)
|
||||
if class >= C_ZCON && class <= C_64CON {
|
||||
return REGZERO
|
||||
}
|
||||
switch class {
|
||||
case C_SACON, C_LACON:
|
||||
return REGSP
|
||||
case C_LOREG, C_SOREG, C_ZOREG, C_XOREG:
|
||||
switch a.Name {
|
||||
case obj.NAME_EXTERN, obj.NAME_STATIC:
|
||||
return REGSB
|
||||
case obj.NAME_AUTO, obj.NAME_PARAM:
|
||||
return REGSP
|
||||
case obj.NAME_NONE:
|
||||
return REGZERO
|
||||
}
|
||||
}
|
||||
c.ctxt.Diag("failed to determine implied reg for class %v (%v)", DRconv(oclass(a)), p)
|
||||
return 0
|
||||
}
|
||||
|
||||
func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||
p := cursym.Func().Text
|
||||
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
|
||||
|
|
@ -944,14 +918,15 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
|
|||
}
|
||||
|
||||
case obj.NAME_AUTO:
|
||||
a.Reg = REGSP
|
||||
c.instoffset = int64(c.autosize) + a.Offset
|
||||
|
||||
if c.instoffset >= -BIG && c.instoffset < BIG {
|
||||
return C_SOREG
|
||||
}
|
||||
return C_LOREG
|
||||
|
||||
case obj.NAME_PARAM:
|
||||
a.Reg = REGSP
|
||||
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
|
||||
if c.instoffset >= -BIG && c.instoffset < BIG {
|
||||
return C_SOREG
|
||||
|
|
@ -1011,6 +986,7 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
|
|||
return C_LACON
|
||||
|
||||
case obj.NAME_AUTO:
|
||||
a.Reg = REGSP
|
||||
c.instoffset = int64(c.autosize) + a.Offset
|
||||
if c.instoffset >= -BIG && c.instoffset < BIG {
|
||||
return C_SACON
|
||||
|
|
@ -1018,6 +994,7 @@ func (c *ctxt9) aclass(a *obj.Addr) int {
|
|||
return C_LACON
|
||||
|
||||
case obj.NAME_PARAM:
|
||||
a.Reg = REGSP
|
||||
c.instoffset = int64(c.autosize) + a.Offset + c.ctxt.Arch.FixedFrameSize
|
||||
if c.instoffset >= -BIG && c.instoffset < BIG {
|
||||
return C_SACON
|
||||
|
|
@ -2569,9 +2546,9 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
|
||||
v := int32(d)
|
||||
r := int(p.From.Reg)
|
||||
if r == 0 {
|
||||
r = c.getimpliedreg(&p.From, p)
|
||||
}
|
||||
// p.From may be a constant value or an offset(reg) type argument.
|
||||
isZeroOrR0 := r&0x1f == 0
|
||||
|
||||
if r0iszero != 0 /*TypeKind(100016)*/ && p.To.Reg == 0 && (r != 0 || v != 0) {
|
||||
c.ctxt.Diag("literal operation on R0\n%v", p)
|
||||
}
|
||||
|
|
@ -2580,7 +2557,7 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
// Operand is 16 bit value with sign bit set
|
||||
if o.a1 == C_ANDCON {
|
||||
// Needs unsigned 16 bit so use ORI
|
||||
if r == 0 || r == REGZERO {
|
||||
if isZeroOrR0 {
|
||||
o1 = LOP_IRR(uint32(OP_ORI), uint32(p.To.Reg), uint32(0), uint32(v))
|
||||
break
|
||||
}
|
||||
|
|
@ -2634,10 +2611,6 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
|
||||
case 7: /* mov r, soreg ==> stw o(r) */
|
||||
r := int(p.To.Reg)
|
||||
|
||||
if r == 0 {
|
||||
r = c.getimpliedreg(&p.To, p)
|
||||
}
|
||||
v := c.regoff(&p.To)
|
||||
if int32(int16(v)) != v {
|
||||
log.Fatalf("mishandled instruction %v", p)
|
||||
|
|
@ -2651,10 +2624,6 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
|
||||
case 8: /* mov soreg, r ==> lbz/lhz/lwz o(r), lbz o(r) + extsb r,r */
|
||||
r := int(p.From.Reg)
|
||||
|
||||
if r == 0 {
|
||||
r = c.getimpliedreg(&p.From, p)
|
||||
}
|
||||
v := c.regoff(&p.From)
|
||||
if int32(int16(v)) != v {
|
||||
log.Fatalf("mishandled instruction %v", p)
|
||||
|
|
@ -3028,9 +2997,6 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
// Load a 32 bit constant, or relocation depending on if a symbol is attached
|
||||
o1, o2, rel = c.symbolAccess(p.From.Sym, v, p.To.Reg, OP_ADDI, true)
|
||||
default:
|
||||
if r == 0 {
|
||||
r = c.getimpliedreg(&p.From, p)
|
||||
}
|
||||
// Add a 32 bit offset to a register.
|
||||
o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(int32(v))))
|
||||
o2 = AOP_IRR(OP_ADDI, uint32(p.To.Reg), uint32(p.To.Reg), uint32(v))
|
||||
|
|
@ -3154,11 +3120,7 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
|
||||
case 35: /* mov r,lext/lauto/loreg ==> cau $(v>>16),sb,r'; store o(r') */
|
||||
v := c.regoff(&p.To)
|
||||
|
||||
r := int(p.To.Reg)
|
||||
if r == 0 {
|
||||
r = c.getimpliedreg(&p.To, p)
|
||||
}
|
||||
// Offsets in DS form stores must be a multiple of 4
|
||||
if o.ispfx {
|
||||
o1, o2 = pfxstore(p.As, p.From.Reg, int16(r), PFX_R_ABS)
|
||||
|
|
@ -3175,11 +3137,7 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
|
|||
|
||||
case 36: /* mov b/bz/h/hz lext/lauto/lreg,r ==> lbz+extsb/lbz/lha/lhz etc */
|
||||
v := c.regoff(&p.From)
|
||||
|
||||
r := int(p.From.Reg)
|
||||
if r == 0 {
|
||||
r = c.getimpliedreg(&p.From, p)
|
||||
}
|
||||
|
||||
if o.ispfx {
|
||||
o1, o2 = pfxload(p.As, p.To.Reg, int16(r), PFX_R_ABS)
|
||||
|
|
|
|||
Loading…
Reference in New Issue