diff --git a/src/cmd/internal/obj/ppc64/a.out.go b/src/cmd/internal/obj/ppc64/a.out.go index 477bc9acd9..556ea37608 100644 --- a/src/cmd/internal/obj/ppc64/a.out.go +++ b/src/cmd/internal/obj/ppc64/a.out.go @@ -213,6 +213,43 @@ const ( NOSCHED = 1 << 9 ) +// Values for use in branch instruction BC +// BC B0,BI,label +// BO is type of branch + likely bits described below +// BI is CR value + branch type +// ex: BEQ CR2,label is BC 12,10,label +// 12 = BO_BCR +// 10 = BI_CR2 + BI_EQ + +const ( + BI_CR0 = 0 + BI_CR1 = 4 + BI_CR2 = 8 + BI_CR3 = 12 + BI_CR4 = 16 + BI_CR5 = 20 + BI_CR6 = 24 + BI_CR7 = 28 + BI_LT = 0 + BI_GT = 1 + BI_EQ = 2 + BI_OVF = 3 +) + +// Values for the BO field. Add the branch type to +// 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 ( + BO_BCTR = 16 // branch on ctr value + BO_BCR = 12 // branch on cr value + BO_BCRBCTR = 8 // branch on ctr and 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 const ( diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 2a6f1bc577..d36e32ff0d 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -2137,12 +2137,35 @@ func asmout(ctxt *obj.Link, p *obj.Prog, o *Optab, out []uint32) { 16: /* bc bo,bi,sbra */ a := 0 + r := int(p.Reg) + if p.From.Type == obj.TYPE_CONST { a = int(regoff(ctxt, &p.From)) - } - r := int(p.Reg) - if r == 0 { - r = 0 + } else if p.From.Type == obj.TYPE_REG { + if r != 0 { + ctxt.Diag("unexpected register setting for branch with CR: %d\n", r) + } + // BI values for the CR + switch p.From.Reg { + case REG_CR0: + r = BI_CR0 + case REG_CR1: + r = BI_CR1 + case REG_CR2: + r = BI_CR2 + case REG_CR3: + r = BI_CR3 + case REG_CR4: + r = BI_CR4 + case REG_CR5: + r = BI_CR5 + case REG_CR6: + r = BI_CR6 + case REG_CR7: + r = BI_CR7 + default: + ctxt.Diag("unrecognized register: expecting CR\n") + } } v := int32(0) if p.Pcond != nil {