mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj/ppc64: improve long conditional branch fixup
Improve the code which fixes up conditional branches which exceed the range of a single instruction by inserting one extra jump when possible instead of two. Change-Id: Ib0eb5b0f47f7d0e0ccd55471307a5f73fbda88a9 Reviewed-on: https://go-review.googlesource.com/c/go/+/342930 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: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
5670ff4ae5
commit
8f397bc118
2 changed files with 73 additions and 26 deletions
|
|
@ -329,18 +329,13 @@ const (
|
||||||
BI_OVF = 3
|
BI_OVF = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// Values for the BO field. Add the branch type to
|
// Common values for the BO field.
|
||||||
// the likely bits, if a likely setting is known.
|
|
||||||
// If branch likely or unlikely is not known, don't set it.
|
|
||||||
// e.g. branch on cr+likely = 15
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BO_BCTR = 16 // branch on ctr value
|
BO_BCTR = 16 // decrement ctr, branch on ctr != 0
|
||||||
BO_BCR = 12 // branch on cr value
|
BO_BCR = 12 // branch on cr value
|
||||||
BO_BCRBCTR = 8 // branch on ctr and cr value
|
BO_BCRBCTR = 8 // decrement ctr, branch on ctr != 0 and cr value
|
||||||
BO_NOTBCR = 4 // branch on not cr value
|
BO_NOTBCR = 4 // branch on not cr value
|
||||||
BO_UNLIKELY = 2 // value for unlikely
|
|
||||||
BO_LIKELY = 3 // value for likely
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Bit settings from the CR
|
// Bit settings from the CR
|
||||||
|
|
|
||||||
|
|
@ -642,6 +642,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
|
|
||||||
var otxt int64
|
var otxt int64
|
||||||
var q *obj.Prog
|
var q *obj.Prog
|
||||||
|
var out [6]uint32
|
||||||
for bflag != 0 {
|
for bflag != 0 {
|
||||||
bflag = 0
|
bflag = 0
|
||||||
pc = 0
|
pc = 0
|
||||||
|
|
@ -653,22 +654,74 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
|
if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
|
||||||
otxt = p.To.Target().Pc - pc
|
otxt = p.To.Target().Pc - pc
|
||||||
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
|
if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
|
||||||
q = c.newprog()
|
// Assemble the instruction with a target not too far to figure out BI and BO fields.
|
||||||
q.Link = p.Link
|
// If only the CTR or BI (the CR bit) are tested, the conditional branch can be inverted,
|
||||||
p.Link = q
|
// and only one extra branch is needed to reach the target.
|
||||||
q.As = ABR
|
tgt := p.To.Target()
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
p.To.SetTarget(p.Link)
|
||||||
q.To.SetTarget(p.To.Target())
|
c.asmout(p, o, out[:])
|
||||||
p.To.SetTarget(q)
|
p.To.SetTarget(tgt)
|
||||||
q = c.newprog()
|
|
||||||
q.Link = p.Link
|
|
||||||
p.Link = q
|
|
||||||
q.As = ABR
|
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
|
||||||
q.To.SetTarget(q.Link.Link)
|
|
||||||
|
|
||||||
//addnop(p->link);
|
bo := int64(out[0]>>21) & 31
|
||||||
//addnop(p);
|
bi := int16((out[0] >> 16) & 31)
|
||||||
|
invertible := false
|
||||||
|
|
||||||
|
if bo&0x14 == 0x14 {
|
||||||
|
// A conditional branch that is unconditionally taken. This cannot be inverted.
|
||||||
|
} else if bo&0x10 == 0x10 {
|
||||||
|
// A branch based on the value of CTR. Invert the CTR comparison against zero bit.
|
||||||
|
bo ^= 0x2
|
||||||
|
invertible = true
|
||||||
|
} else if bo&0x04 == 0x04 {
|
||||||
|
// A branch based on CR bit. Invert the BI comparison bit.
|
||||||
|
bo ^= 0x8
|
||||||
|
invertible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if invertible {
|
||||||
|
// Rewrite
|
||||||
|
// BC bo,...,far_away_target
|
||||||
|
// NEXT_INSN
|
||||||
|
// to:
|
||||||
|
// BC invert(bo),next_insn
|
||||||
|
// JMP far_away_target
|
||||||
|
// next_insn:
|
||||||
|
// NEXT_INSN
|
||||||
|
p.As = ABC
|
||||||
|
p.From = obj.Addr{Type: obj.TYPE_CONST, Name: obj.NAME_NONE, Offset: bo}
|
||||||
|
q = c.newprog()
|
||||||
|
q.As = ABR
|
||||||
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
|
q.To.SetTarget(p.To.Target())
|
||||||
|
q.Link = p.Link
|
||||||
|
p.To.SetTarget(p.Link)
|
||||||
|
p.Link = q
|
||||||
|
p.Reg = bi // TODO: This is a hack since BI bits are not enumerated as registers
|
||||||
|
} else {
|
||||||
|
// Rewrite
|
||||||
|
// BC ...,far_away_target
|
||||||
|
// NEXT_INSN
|
||||||
|
// to
|
||||||
|
// BC ...,tmp
|
||||||
|
// JMP next_insn
|
||||||
|
// tmp:
|
||||||
|
// JMP far_away_target
|
||||||
|
// next_insn:
|
||||||
|
// NEXT_INSN
|
||||||
|
q = c.newprog()
|
||||||
|
q.Link = p.Link
|
||||||
|
p.Link = q
|
||||||
|
q.As = ABR
|
||||||
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
|
q.To.SetTarget(p.To.Target())
|
||||||
|
p.To.SetTarget(q)
|
||||||
|
q = c.newprog()
|
||||||
|
q.Link = p.Link
|
||||||
|
p.Link = q
|
||||||
|
q.As = ABR
|
||||||
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
|
q.To.SetTarget(q.Link.Link)
|
||||||
|
}
|
||||||
bflag = 1
|
bflag = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -706,7 +759,6 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
|
|
||||||
bp := c.cursym.P
|
bp := c.cursym.P
|
||||||
var i int32
|
var i int32
|
||||||
var out [6]uint32
|
|
||||||
for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
|
for p := c.cursym.Func().Text.Link; p != nil; p = p.Link {
|
||||||
c.pc = p.Pc
|
c.pc = p.Pc
|
||||||
o = c.oplook(p)
|
o = c.oplook(p)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue