]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile,cmd/asm: simplify recording of branch targets, take 2
authorKeith Randall <khr@golang.org>
Fri, 28 Aug 2020 17:10:32 +0000 (17:10 +0000)
committerKeith Randall <khr@golang.org>
Mon, 31 Aug 2020 17:36:08 +0000 (17:36 +0000)
We currently use two fields to store the targets of branches.
Some phases use p.To.Val, some use p.Pcond. Rewrite so that
every branch instruction uses p.To.Val.
p.From.Val is also used in rare instances.
Introduce a Pool link for use by arm/arm64, instead of
repurposing Pcond.

This is a cleanup CL in preparation for some stack frame CLs.

Change-Id: If8239177e4b1ea2bccd0608eb39553d23210d405
Reviewed-on: https://go-review.googlesource.com/c/go/+/251437
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
21 files changed:
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/s390x/ssa.go
src/cmd/compile/internal/x86/ssa.go
src/cmd/internal/obj/arm/asm5.go
src/cmd/internal/obj/arm/obj5.go
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/arm64/obj7.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/mips/asm0.go
src/cmd/internal/obj/mips/obj0.go
src/cmd/internal/obj/pass.go
src/cmd/internal/obj/ppc64/asm9.go
src/cmd/internal/obj/ppc64/obj9.go
src/cmd/internal/obj/riscv/obj.go
src/cmd/internal/obj/s390x/asmz.go
src/cmd/internal/obj/s390x/objz.go
src/cmd/internal/obj/util.go
src/cmd/internal/obj/x86/asm6.go
src/cmd/internal/obj/x86/obj6.go

index 9d8a0920b39ba78eceab1cceaf3cd4af7eb86418..4ac877986cd99425fae89265a7fae25352aff888 100644 (file)
@@ -319,8 +319,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                        // TODO(khr): issue only the -1 fixup code we need.
                        // For instance, if only the quotient is used, no point in zeroing the remainder.
 
-                       j1.To.Val = n1
-                       j2.To.Val = s.Pc()
+                       j1.To.SetTarget(n1)
+                       j2.To.SetTarget(s.Pc())
                }
 
        case ssa.OpAMD64HMULQ, ssa.OpAMD64HMULL, ssa.OpAMD64HMULQU, ssa.OpAMD64HMULLU:
index 15a84a8a43dca63dd92a79cc022645714c02c9f6..480d411f4959a0b204614549ff924c5959a30f09 100644 (file)
@@ -342,6 +342,6 @@ func Patch(p *obj.Prog, to *obj.Prog) {
        if p.To.Type != obj.TYPE_BRANCH {
                Fatalf("patch: not a branch")
        }
-       p.To.Val = to
+       p.To.SetTarget(to)
        p.To.Offset = to.Pc
 }
index 104dd403eab1b7cc19759e50eb15c96e384c704b..52083d999e544b9807a3581ea98ee84a00c1b112 100644 (file)
@@ -6182,7 +6182,7 @@ func genssa(f *ssa.Func, pp *Progs) {
 
        // Resolve branches, and relax DefaultStmt into NotStmt
        for _, br := range s.Branches {
-               br.P.To.Val = s.bstart[br.B.ID]
+               br.P.To.SetTarget(s.bstart[br.B.ID])
                if br.P.Pos.IsStmt() != src.PosIsStmt {
                        br.P.Pos = br.P.Pos.WithNotStmt()
                } else if v0 := br.B.FirstPossibleStmtValue(); v0 != nil && v0.Pos.Line() == br.P.Pos.Line() && v0.Pos.IsStmt() == src.PosIsStmt {
index 4cf4b70a323df97c9da9bdae7ced79ad992466c9..00d253c95a2e49191ae6ea6e2f18b52c735c32e9 100644 (file)
@@ -338,8 +338,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                                n.To.Reg = dividend
                        }
 
-                       j.To.Val = n
-                       j2.To.Val = s.Pc()
+                       j.To.SetTarget(n)
+                       j2.To.SetTarget(s.Pc())
                }
        case ssa.OpS390XADDconst, ssa.OpS390XADDWconst:
                opregregimm(s, v.Op.Asm(), v.Reg(), v.Args[0].Reg(), v.AuxInt)
index 2de978c28a2e90db85627515db2d62cce8c09a06..c21ac3229769aadf724dfeb1cc577ae6867342b9 100644 (file)
@@ -261,8 +261,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                                n.To.Reg = x86.REG_DX
                        }
 
-                       j.To.Val = n
-                       j2.To.Val = s.Pc()
+                       j.To.SetTarget(n)
+                       j2.To.SetTarget(s.Pc())
                }
 
        case ssa.Op386HMULL, ssa.Op386HMULLU:
index 7b7e42ee2e9c547c4b1335c7ab962007846fbbb2..269a4223d578ebd542d5634cb2e549ff39529556 100644 (file)
@@ -644,7 +644,7 @@ func (c *ctxt5) flushpool(p *obj.Prog, skip int, force int) bool {
                        q := c.newprog()
                        q.As = AB
                        q.To.Type = obj.TYPE_BRANCH
-                       q.Pcond = p.Link
+                       q.To.SetTarget(p.Link)
                        q.Link = c.blitrl
                        q.Pos = p.Pos
                        c.blitrl = q
@@ -705,7 +705,7 @@ func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
        if t.Rel == nil {
                for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
                        if q.Rel == nil && q.To == t.To {
-                               p.Pcond = q
+                               p.Pool = q
                                return
                        }
                }
@@ -724,8 +724,8 @@ func (c *ctxt5) addpool(p *obj.Prog, a *obj.Addr) {
        c.elitrl = q
        c.pool.size += 4
 
-       // Store the link to the pool entry in Pcond.
-       p.Pcond = q
+       // Store the link to the pool entry in Pool.
+       p.Pool = q
 }
 
 func (c *ctxt5) regoff(a *obj.Addr) int32 {
@@ -1584,8 +1584,8 @@ func (c *ctxt5) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        break
                }
 
-               if p.Pcond != nil {
-                       v = int32((p.Pcond.Pc - c.pc) - 8)
+               if p.To.Target() != nil {
+                       v = int32((p.To.Target().Pc - c.pc) - 8)
                }
                o1 |= (uint32(v) >> 2) & 0xffffff
 
@@ -3023,7 +3023,7 @@ func (c *ctxt5) omvr(p *obj.Prog, a *obj.Addr, dr int) uint32 {
 
 func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
        var o1 uint32
-       if p.Pcond == nil {
+       if p.Pool == nil {
                c.aclass(a)
                v := immrot(^uint32(c.instoffset))
                if v == 0 {
@@ -3035,7 +3035,7 @@ func (c *ctxt5) omvl(p *obj.Prog, a *obj.Addr, dr int) uint32 {
                o1 |= uint32(v)
                o1 |= (uint32(dr) & 15) << 12
        } else {
-               v := int32(p.Pcond.Pc - p.Pc - 8)
+               v := int32(p.Pool.Pc - p.Pc - 8)
                o1 = c.olr(v, REGPC, dr, int(p.Scond)&C_SCOND)
        }
 
index 86831f2b4414e7e3307a3e1874f88777d210065e..4d9187b530a8c1879360584079bdb10ebfcdde9d 100644 (file)
@@ -406,7 +406,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                mov.To.Reg = REG_R2
 
                                // B.NE branch target is MOVW above
-                               bne.Pcond = mov
+                               bne.To.SetTarget(mov)
 
                                // ADD $(autosize+4), R13, R3
                                p = obj.Appendp(mov, newprog)
@@ -428,7 +428,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                p = obj.Appendp(p, newprog)
                                p.As = ABNE
                                p.To.Type = obj.TYPE_BRANCH
-                               p.Pcond = end
+                               p.To.SetTarget(end)
 
                                // ADD $4, R13, R4
                                p = obj.Appendp(p, newprog)
@@ -452,7 +452,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                p = obj.Appendp(p, newprog)
                                p.As = AB
                                p.To.Type = obj.TYPE_BRANCH
-                               p.Pcond = end
+                               p.To.SetTarget(end)
 
                                // reset for subsequent passes
                                p = end
@@ -741,7 +741,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        movw.To.Type = obj.TYPE_REG
        movw.To.Reg = REG_R3
 
-       bls.Pcond = movw
+       bls.To.SetTarget(movw)
 
        // BL runtime.morestack
        call := obj.Appendp(movw, c.newprog)
@@ -762,7 +762,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        b := obj.Appendp(pcdata, c.newprog)
        b.As = obj.AJMP
        b.To.Type = obj.TYPE_BRANCH
-       b.Pcond = c.cursym.Func.Text.Link
+       b.To.SetTarget(c.cursym.Func.Text.Link)
        b.Spadj = +framesize
 
        return end
index bc277404693df2817e9faf045f80be24d6a70df9..65f789833290f8b3a4c22cc1104ea1e4f7a870a9 100644 (file)
@@ -977,8 +977,8 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        o = c.oplook(p)
 
                        /* very large branches */
-                       if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
-                               otxt := p.Pcond.Pc - pc
+                       if (o.type_ == 7 || o.type_ == 39 || o.type_ == 40) && p.To.Target() != nil { // 7: BEQ and like, 39: CBZ and like, 40: TBZ and like
+                               otxt := p.To.Target().Pc - pc
                                var toofar bool
                                switch o.type_ {
                                case 7, 39: // branch instruction encodes 19 bits
@@ -992,14 +992,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                        p.Link = q
                                        q.As = AB
                                        q.To.Type = obj.TYPE_BRANCH
-                                       q.Pcond = p.Pcond
-                                       p.Pcond = q
+                                       q.To.SetTarget(p.To.Target())
+                                       p.To.SetTarget(q)
                                        q = c.newprog()
                                        q.Link = p.Link
                                        p.Link = q
                                        q.As = AB
                                        q.To.Type = obj.TYPE_BRANCH
-                                       q.Pcond = q.Link.Link
+                                       q.To.SetTarget(q.Link.Link)
                                        bflag = 1
                                }
                        }
@@ -1123,7 +1123,7 @@ func (c *ctxt7) flushpool(p *obj.Prog, skip int) {
                        q := c.newprog()
                        q.As = AB
                        q.To.Type = obj.TYPE_BRANCH
-                       q.Pcond = p.Link
+                       q.To.SetTarget(p.Link)
                        q.Link = c.blitrl
                        q.Pos = p.Pos
                        c.blitrl = q
@@ -1249,7 +1249,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
 
        for q := c.blitrl; q != nil; q = q.Link { /* could hash on t.t0.offset */
                if q.To == t.To {
-                       p.Pcond = q
+                       p.Pool = q
                        return
                }
        }
@@ -1266,7 +1266,7 @@ func (c *ctxt7) addpool(p *obj.Prog, a *obj.Addr) {
        c.elitrl = q
        c.pool.size = -c.pool.size & (funcAlign - 1)
        c.pool.size += uint32(sz)
-       p.Pcond = q
+       p.Pool = q
 }
 
 func (c *ctxt7) regoff(a *obj.Addr) uint32 {
@@ -6042,15 +6042,21 @@ func (c *ctxt7) opimm(p *obj.Prog, a obj.As) uint32 {
 func (c *ctxt7) brdist(p *obj.Prog, preshift int, flen int, shift int) int64 {
        v := int64(0)
        t := int64(0)
-       if p.Pcond != nil {
-               v = (p.Pcond.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
+       q := p.To.Target()
+       if q == nil {
+               // TODO: don't use brdist for this case, as it isn't a branch.
+               // (Calls from omovlit, and maybe adr/adrp opcodes as well.)
+               q = p.Pool
+       }
+       if q != nil {
+               v = (q.Pc >> uint(preshift)) - (c.pc >> uint(preshift))
                if (v & ((1 << uint(shift)) - 1)) != 0 {
                        c.ctxt.Diag("misaligned label\n%v", p)
                }
                v >>= uint(shift)
                t = int64(1) << uint(flen-1)
                if v < -t || v >= t {
-                       c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, p.Pcond)
+                       c.ctxt.Diag("branch too far %#x vs %#x [%p]\n%v\n%v", v, t, c.blitrl, p, q)
                        panic("branch too far")
                }
        }
@@ -6526,7 +6532,7 @@ func (c *ctxt7) oaddi(p *obj.Prog, o1 int32, v int32, r int, rt int) uint32 {
  */
 func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
        var o1 int32
-       if p.Pcond == nil { /* not in literal pool */
+       if p.Pool == nil { /* not in literal pool */
                c.aclass(a)
                c.ctxt.Logf("omovlit add %d (%#x)\n", c.instoffset, uint64(c.instoffset))
 
@@ -6552,11 +6558,11 @@ func (c *ctxt7) omovlit(as obj.As, p *obj.Prog, a *obj.Addr, dr int) uint32 {
                        w = 1 /* 64-bit SIMD/FP */
 
                case AMOVD:
-                       if p.Pcond.As == ADWORD {
+                       if p.Pool.As == ADWORD {
                                w = 1 /* 64-bit */
-                       } else if p.Pcond.To.Offset < 0 {
+                       } else if p.Pool.To.Offset < 0 {
                                w = 2 /* 32-bit, sign-extended to 64-bit */
-                       } else if p.Pcond.To.Offset >= 0 {
+                       } else if p.Pool.To.Offset >= 0 {
                                w = 0 /* 32-bit, zero-extended to 64-bit */
                        } else {
                                c.ctxt.Diag("invalid operand %v in %v", a, p)
index f54429fabed1753a8f0c739ec97b20dc8a64da05..56da854f16ae32b1bd5feda299760e794a256239 100644 (file)
@@ -187,9 +187,9 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        movlr.To.Type = obj.TYPE_REG
        movlr.To.Reg = REG_R3
        if q != nil {
-               q.Pcond = movlr
+               q.To.SetTarget(movlr)
        }
-       bls.Pcond = movlr
+       bls.To.SetTarget(movlr)
 
        debug := movlr
        if false {
@@ -220,7 +220,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        jmp := obj.Appendp(pcdata, c.newprog)
        jmp.As = AB
        jmp.To.Type = obj.TYPE_BRANCH
-       jmp.Pcond = c.cursym.Func.Text.Link
+       jmp.To.SetTarget(c.cursym.Func.Text.Link)
        jmp.Spadj = +framesize
 
        return end
@@ -697,7 +697,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                mov.To.Reg = REG_R2
 
                                // CBNZ branches to the MOV above
-                               cbnz.Pcond = mov
+                               cbnz.To.SetTarget(mov)
 
                                // ADD $(autosize+8), SP, R3
                                q = obj.Appendp(mov, c.newprog)
@@ -719,7 +719,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = obj.Appendp(q, c.newprog)
                                q.As = ABNE
                                q.To.Type = obj.TYPE_BRANCH
-                               q.Pcond = end
+                               q.To.SetTarget(end)
 
                                // ADD $8, SP, R4
                                q = obj.Appendp(q, c.newprog)
@@ -743,7 +743,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = obj.Appendp(q, c.newprog)
                                q.As = AB
                                q.To.Type = obj.TYPE_BRANCH
-                               q.Pcond = end
+                               q.To.SetTarget(end)
                        }
 
                case obj.ARET:
@@ -913,7 +913,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q5.Reg = REGSP
                                q5.To.Type = obj.TYPE_REG
                                q5.To.Reg = REGFP
-                               q1.Pcond = q5
+                               q1.From.SetTarget(q5)
                                p = q5
                        }
 
@@ -966,7 +966,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q5.Reg = REGSP
                                q5.To.Type = obj.TYPE_REG
                                q5.To.Reg = REGFP
-                               q1.Pcond = q5
+                               q1.From.SetTarget(q5)
                                p = q5
                        }
                }
index 1fc90db86451533723f018e04936a5518227f7f5..1d4217b5f558a45648f2c180c748dc6e0d8c7e81 100644 (file)
@@ -237,6 +237,19 @@ const (
        TYPE_REGLIST
 )
 
+func (a *Addr) Target() *Prog {
+       if a.Type == TYPE_BRANCH && a.Val != nil {
+               return a.Val.(*Prog)
+       }
+       return nil
+}
+func (a *Addr) SetTarget(t *Prog) {
+       if a.Type != TYPE_BRANCH {
+               panic("setting branch target when type is not TYPE_BRANCH")
+       }
+       a.Val = t
+}
+
 // Prog describes a single machine instruction.
 //
 // The general instruction form is:
@@ -255,7 +268,7 @@ const (
 // to avoid too much changes in a single swing.
 // (1) scheme is enough to express any kind of operand combination.
 //
-// Jump instructions use the Pcond field to point to the target instruction,
+// Jump instructions use the To.Val field to point to the target *Prog,
 // which must be in the same linked list as the jump instruction.
 //
 // The Progs for a given function are arranged in a list linked through the Link field.
@@ -274,7 +287,7 @@ type Prog struct {
        From     Addr     // first source operand
        RestArgs []Addr   // can pack any operands that not fit into {Prog.From, Prog.To}
        To       Addr     // destination operand (second is RegTo2 below)
-       Pcond    *Prog    // target of conditional jump
+       Pool     *Prog    // constant pool entry, for arm,arm64 back ends
        Forwd    *Prog    // for x86 back end
        Rel      *Prog    // for x86, arm back ends
        Pc       int64    // for back ends or assembler: virtual or actual program counter, depending on phase
index faa827da9fd6b6612b6a2e7fa6e3ef41cede9212..6107974745939f074ebef01ecd60f74d2ae00a7e 100644 (file)
@@ -460,8 +460,8 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        o = c.oplook(p)
 
                        // very large conditional branches
-                       if o.type_ == 6 && p.Pcond != nil {
-                               otxt = p.Pcond.Pc - pc
+                       if o.type_ == 6 && p.To.Target() != nil {
+                               otxt = p.To.Target().Pc - pc
                                if otxt < -(1<<17)+10 || otxt >= (1<<17)-10 {
                                        q = c.newprog()
                                        q.Link = p.Link
@@ -469,15 +469,15 @@ func span0(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                        q.As = AJMP
                                        q.Pos = p.Pos
                                        q.To.Type = obj.TYPE_BRANCH
-                                       q.Pcond = p.Pcond
-                                       p.Pcond = q
+                                       q.To.SetTarget(p.To.Target())
+                                       p.To.SetTarget(q)
                                        q = c.newprog()
                                        q.Link = p.Link
                                        p.Link = q
                                        q.As = AJMP
                                        q.Pos = p.Pos
                                        q.To.Type = obj.TYPE_BRANCH
-                                       q.Pcond = q.Link.Link
+                                       q.To.SetTarget(q.Link.Link)
 
                                        c.addnop(p.Link)
                                        c.addnop(p)
@@ -1230,10 +1230,10 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
 
        case 6: /* beq r1,[r2],sbra */
                v := int32(0)
-               if p.Pcond == nil {
+               if p.To.Target() == nil {
                        v = int32(-4) >> 2
                } else {
-                       v = int32(p.Pcond.Pc-p.Pc-4) >> 2
+                       v = int32(p.To.Target().Pc-p.Pc-4) >> 2
                }
                if (v<<16)>>16 != v {
                        c.ctxt.Diag("short branch too far\n%v", p)
@@ -1285,25 +1285,25 @@ func (c *ctxt0) asmout(p *obj.Prog, o *Optab, out []uint32) {
                if c.aclass(&p.To) == C_SBRA && p.To.Sym == nil && p.As == AJMP {
                        // use PC-relative branch for short branches
                        // BEQ  R0, R0, sbra
-                       if p.Pcond == nil {
+                       if p.To.Target() == nil {
                                v = int32(-4) >> 2
                        } else {
-                               v = int32(p.Pcond.Pc-p.Pc-4) >> 2
+                               v = int32(p.To.Target().Pc-p.Pc-4) >> 2
                        }
                        if (v<<16)>>16 == v {
                                o1 = OP_IRR(c.opirr(ABEQ), uint32(v), uint32(REGZERO), uint32(REGZERO))
                                break
                        }
                }
-               if p.Pcond == nil {
+               if p.To.Target() == nil {
                        v = int32(p.Pc) >> 2
                } else {
-                       v = int32(p.Pcond.Pc) >> 2
+                       v = int32(p.To.Target().Pc) >> 2
                }
                o1 = OP_JMP(c.opirr(p.As), uint32(v))
                if p.To.Sym == nil {
                        p.To.Sym = c.cursym.Func.Text.From.Sym
-                       p.To.Offset = p.Pcond.Pc
+                       p.To.Offset = p.To.Target().Pc
                }
                rel := obj.Addrel(c.cursym)
                rel.Off = int32(c.pc)
index 77cad979a64dab4558b19035d9f524798a06c7f7..f19facc00c688333369a2d679882993e5c7ec39f 100644 (file)
@@ -227,11 +227,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        } else {
                                p.Mark |= BRANCH
                        }
-                       q1 := p.Pcond
+                       q1 := p.To.Target()
                        if q1 != nil {
                                for q1.As == obj.ANOP {
                                        q1 = q1.Link
-                                       p.Pcond = q1
+                                       p.To.SetTarget(q1)
                                }
 
                                if q1.Mark&LEAF == 0 {
@@ -424,8 +424,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = obj.Appendp(q, newprog)
 
                                q.As = obj.ANOP
-                               p1.Pcond = q
-                               p2.Pcond = q
+                               p1.To.SetTarget(q)
+                               p2.To.SetTarget(q)
                        }
 
                case ARET:
@@ -778,7 +778,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        p.To.Type = obj.TYPE_REG
        p.To.Reg = REG_R3
        if q != nil {
-               q.Pcond = p
+               q.To.SetTarget(p)
                p.Mark |= LABEL
        }
 
@@ -805,14 +805,14 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
 
        p.As = AJMP
        p.To.Type = obj.TYPE_BRANCH
-       p.Pcond = c.cursym.Func.Text.Link
+       p.To.SetTarget(c.cursym.Func.Text.Link)
        p.Mark |= BRANCH
 
        // placeholder for q1's jump target
        p = obj.Appendp(p, c.newprog)
 
        p.As = obj.ANOP // zero-width place holder
-       q1.Pcond = p
+       q1.To.SetTarget(p)
 
        return p
 }
index 4f156d969b767370e392b9b92b885119242b6051..09d520b4e9bec62ce9aba25cba47b6118034928c 100644 (file)
@@ -36,8 +36,8 @@ package obj
 // In the case of an infinite loop, brloop returns nil.
 func brloop(p *Prog) *Prog {
        c := 0
-       for q := p; q != nil; q = q.Pcond {
-               if q.As != AJMP || q.Pcond == nil {
+       for q := p; q != nil; q = q.To.Target() {
+               if q.As != AJMP || q.To.Target() == nil {
                        return q
                }
                c++
@@ -132,8 +132,6 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
                        continue
                }
                if p.To.Val != nil {
-                       // TODO: Remove To.Val.(*Prog) in favor of p->pcond.
-                       p.Pcond = p.To.Val.(*Prog)
                        continue
                }
 
@@ -158,8 +156,7 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
                        p.To.Type = TYPE_NONE
                }
 
-               p.To.Val = q
-               p.Pcond = q
+               p.To.SetTarget(q)
        }
 
        if !ctxt.Flag_optimize {
@@ -168,12 +165,12 @@ func linkpatch(ctxt *Link, sym *LSym, newprog ProgAlloc) {
 
        // Collapse series of jumps to jumps.
        for p := sym.Func.Text; p != nil; p = p.Link {
-               if p.Pcond == nil {
+               if p.To.Target() == nil {
                        continue
                }
-               p.Pcond = brloop(p.Pcond)
-               if p.Pcond != nil && p.To.Type == TYPE_BRANCH {
-                       p.To.Offset = p.Pcond.Pc
+               p.To.SetTarget(brloop(p.To.Target()))
+               if p.To.Target() != nil && p.To.Type == TYPE_BRANCH {
+                       p.To.Offset = p.To.Target().Pc
                }
        }
 }
index 3c82477fc4b0849bc7494677b3d047731f8fc7f7..98b453de6c911962da7e8b0b51a5357b23309b55 100644 (file)
@@ -725,22 +725,22 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        o = c.oplook(p)
 
                        // very large conditional branches
-                       if (o.type_ == 16 || o.type_ == 17) && p.Pcond != nil {
-                               otxt = p.Pcond.Pc - pc
+                       if (o.type_ == 16 || o.type_ == 17) && p.To.Target() != nil {
+                               otxt = p.To.Target().Pc - pc
                                if otxt < -(1<<15)+10 || otxt >= (1<<15)-10 {
                                        q = c.newprog()
                                        q.Link = p.Link
                                        p.Link = q
                                        q.As = ABR
                                        q.To.Type = obj.TYPE_BRANCH
-                                       q.Pcond = p.Pcond
-                                       p.Pcond = q
+                                       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.Pcond = q.Link.Link
+                                       q.To.SetTarget(q.Link.Link)
 
                                        //addnop(p->link);
                                        //addnop(p);
@@ -2630,8 +2630,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
        case 11: /* br/bl lbra */
                v := int32(0)
 
-               if p.Pcond != nil {
-                       v = int32(p.Pcond.Pc - p.Pc)
+               if p.To.Target() != nil {
+                       v = int32(p.To.Target().Pc - p.Pc)
                        if v&03 != 0 {
                                c.ctxt.Diag("odd branch target address\n%v", p)
                                v &^= 03
@@ -2781,8 +2781,8 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
                        }
                }
                v := int32(0)
-               if p.Pcond != nil {
-                       v = int32(p.Pcond.Pc - p.Pc)
+               if p.To.Target() != nil {
+                       v = int32(p.To.Target().Pc - p.Pc)
                }
                if v&03 != 0 {
                        c.ctxt.Diag("odd branch target address\n%v", p)
index 749f7066de7e36daa37f61bd668a74a30ac157ef..c012762a18d025c5350348a656e741a7db486741 100644 (file)
@@ -556,7 +556,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                        ABVS:
                        p.Mark |= BRANCH
                        q = p
-                       q1 = p.Pcond
+                       q1 = p.To.Target()
                        if q1 != nil {
                                // NOPs are not removed due to #40689.
 
@@ -841,8 +841,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = obj.Appendp(q, c.newprog)
 
                                q.As = obj.ANOP
-                               p1.Pcond = q
-                               p2.Pcond = q
+                               p1.To.SetTarget(q)
+                               p2.To.SetTarget(q)
                        }
 
                case obj.ARET:
@@ -1153,7 +1153,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        p.To.Type = obj.TYPE_REG
        p.To.Reg = REG_R5
        if q != nil {
-               q.Pcond = p
+               q.To.SetTarget(p)
        }
 
        p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog)
@@ -1248,13 +1248,13 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
        p = obj.Appendp(p, c.newprog)
        p.As = ABR
        p.To.Type = obj.TYPE_BRANCH
-       p.Pcond = p0.Link
+       p.To.SetTarget(p0.Link)
 
        // placeholder for q1's jump target
        p = obj.Appendp(p, c.newprog)
 
        p.As = obj.ANOP // zero-width place holder
-       q1.Pcond = p
+       q1.To.SetTarget(p)
 
        return p
 }
index 2eb2935b318edb92f0afd32e3050f8cb579a8b24..77d383b290aa148090cb2b4057a339a3e8a9b2c0 100644 (file)
@@ -634,7 +634,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                getargp.Reg = 0
                getargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12}
 
-               bneadj.Pcond = getargp
+               bneadj.To.SetTarget(getargp)
 
                calcargp := obj.Appendp(getargp, newprog)
                calcargp.As = AADDI
@@ -647,7 +647,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                testargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12}
                testargp.Reg = REG_X13
                testargp.To.Type = obj.TYPE_BRANCH
-               testargp.Pcond = endadj
+               testargp.To.SetTarget(endadj)
 
                adjargp := obj.Appendp(testargp, newprog)
                adjargp.As = AADDI
@@ -665,7 +665,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                godone.As = AJAL
                godone.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
                godone.To.Type = obj.TYPE_BRANCH
-               godone.Pcond = endadj
+               godone.To.SetTarget(endadj)
        }
 
        // Update stack-based offsets.
@@ -890,27 +890,27 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                if p.To.Type != obj.TYPE_BRANCH {
                                        panic("assemble: instruction with branch-like opcode lacks destination")
                                }
-                               offset := p.Pcond.Pc - p.Pc
+                               offset := p.To.Target().Pc - p.Pc
                                if offset < -4096 || 4096 <= offset {
                                        // Branch is long.  Replace it with a jump.
                                        jmp := obj.Appendp(p, newprog)
                                        jmp.As = AJAL
                                        jmp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
                                        jmp.To = obj.Addr{Type: obj.TYPE_BRANCH}
-                                       jmp.Pcond = p.Pcond
+                                       jmp.To.SetTarget(p.To.Target())
 
                                        p.As = InvertBranch(p.As)
-                                       p.Pcond = jmp.Link
+                                       p.To.SetTarget(jmp.Link)
 
                                        // We may have made previous branches too long,
                                        // so recheck them.
                                        rescan = true
                                }
                        case AJAL:
-                               if p.Pcond == nil {
+                               if p.To.Target() == nil {
                                        panic("intersymbol jumps should be expressed as AUIPC+JALR")
                                }
-                               offset := p.Pcond.Pc - p.Pc
+                               offset := p.To.Target().Pc - p.Pc
                                if offset < -(1<<20) || (1<<20) <= offset {
                                        // Replace with 2-instruction sequence. This assumes
                                        // that TMP is not live across J instructions, since
@@ -925,6 +925,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                        // fixed up in the next loop.
                                        p.As = AAUIPC
                                        p.From = obj.Addr{Type: obj.TYPE_BRANCH, Sym: p.From.Sym}
+                                       p.From.SetTarget(p.To.Target())
                                        p.Reg = 0
                                        p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_TMP}
 
@@ -946,16 +947,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                case ABEQ, ABEQZ, ABGE, ABGEU, ABGEZ, ABGT, ABGTU, ABGTZ, ABLE, ABLEU, ABLEZ, ABLT, ABLTU, ABLTZ, ABNE, ABNEZ, AJAL:
                        switch p.To.Type {
                        case obj.TYPE_BRANCH:
-                               p.To.Type, p.To.Offset = obj.TYPE_CONST, p.Pcond.Pc-p.Pc
+                               p.To.Type, p.To.Offset = obj.TYPE_CONST, p.To.Target().Pc-p.Pc
                        case obj.TYPE_MEM:
                                panic("unhandled type")
                        }
 
                case AAUIPC:
                        if p.From.Type == obj.TYPE_BRANCH {
-                               low, high, err := Split32BitImmediate(p.Pcond.Pc - p.Pc)
+                               low, high, err := Split32BitImmediate(p.From.Target().Pc - p.Pc)
                                if err != nil {
-                                       ctxt.Diag("%v: jump displacement %d too large", p, p.Pcond.Pc-p.Pc)
+                                       ctxt.Diag("%v: jump displacement %d too large", p, p.To.Target().Pc-p.Pc)
                                }
                                p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: high, Sym: cursym}
                                p.Link.From.Offset = low
@@ -1098,7 +1099,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA
                p.To.Sym = ctxt.Lookup("runtime.morestack")
        }
        if to_more != nil {
-               to_more.Pcond = p
+               to_more.To.SetTarget(p)
        }
        p = jalrToSym(ctxt, p, newprog, REG_X5)
 
@@ -1107,12 +1108,12 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA
        p.As = AJAL
        p.To = obj.Addr{Type: obj.TYPE_BRANCH}
        p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
-       p.Pcond = cursym.Func.Text.Link
+       p.To.SetTarget(cursym.Func.Text.Link)
 
        // placeholder for to_done's jump target
        p = obj.Appendp(p, newprog)
        p.As = obj.ANOP // zero-width place holder
-       to_done.Pcond = p
+       to_done.To.SetTarget(p)
 
        return p
 }
index 29182ea8059274bf4187183eb62aff4f1aaa05db..68f01f1c5d8634f3ece428f6e166e749c28a82ee 100644 (file)
@@ -3001,8 +3001,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
        case 11: // br/bl
                v := int32(0)
 
-               if p.Pcond != nil {
-                       v = int32((p.Pcond.Pc - p.Pc) >> 1)
+               if p.To.Target() != nil {
+                       v = int32((p.To.Target().Pc - p.Pc) >> 1)
                }
 
                if p.As == ABR && p.To.Sym == nil && int32(int16(v)) == v {
@@ -3122,8 +3122,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
 
        case 16: // conditional branch
                v := int32(0)
-               if p.Pcond != nil {
-                       v = int32((p.Pcond.Pc - p.Pc) >> 1)
+               if p.To.Target() != nil {
+                       v = int32((p.To.Target().Pc - p.Pc) >> 1)
                }
                mask := uint32(c.branchMask(p))
                if p.To.Sym == nil && int32(int16(v)) == v {
@@ -3440,7 +3440,7 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
 
        case 41: // branch on count
                r1 := p.From.Reg
-               ri2 := (p.Pcond.Pc - p.Pc) >> 1
+               ri2 := (p.To.Target().Pc - p.Pc) >> 1
                if int64(int16(ri2)) != ri2 {
                        c.ctxt.Diag("branch target too far away")
                }
@@ -3885,8 +3885,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
 
        case 89: // compare and branch reg reg
                var v int32
-               if p.Pcond != nil {
-                       v = int32((p.Pcond.Pc - p.Pc) >> 1)
+               if p.To.Target() != nil {
+                       v = int32((p.To.Target().Pc - p.Pc) >> 1)
                }
 
                // Some instructions take a mask as the first argument.
@@ -3930,8 +3930,8 @@ func (c *ctxtz) asmout(p *obj.Prog, asm *[]byte) {
 
        case 90: // compare and branch reg $constant
                var v int32
-               if p.Pcond != nil {
-                       v = int32((p.Pcond.Pc - p.Pc) >> 1)
+               if p.To.Target() != nil {
+                       v = int32((p.To.Target().Pc - p.Pc) >> 1)
                }
 
                // Some instructions take a mask as the first argument.
index ef6335d8492d1d958e3867d6b98182197cd38af8..625bb0f7b4e5084d58e5c53c53842c7cb4d4e60b 100644 (file)
@@ -454,8 +454,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q = obj.Appendp(q, c.newprog)
 
                                q.As = obj.ANOP
-                               p1.Pcond = q
-                               p2.Pcond = q
+                               p1.To.SetTarget(q)
+                               p2.To.SetTarget(q)
                        }
 
                case obj.ARET:
@@ -679,14 +679,14 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog,
 
        // MOVD LR, R5
        p = obj.Appendp(pcdata, c.newprog)
-       pPre.Pcond = p
+       pPre.To.SetTarget(p)
        p.As = AMOVD
        p.From.Type = obj.TYPE_REG
        p.From.Reg = REG_LR
        p.To.Type = obj.TYPE_REG
        p.To.Reg = REG_R5
        if pPreempt != nil {
-               pPreempt.Pcond = p
+               pPreempt.To.SetTarget(p)
        }
 
        // BL   runtime.morestack(SB)
@@ -709,7 +709,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog,
 
        p.As = ABR
        p.To.Type = obj.TYPE_BRANCH
-       p.Pcond = c.cursym.Func.Text.Link
+       p.To.SetTarget(c.cursym.Func.Text.Link)
        return p
 }
 
index d0200264452cd90468687c2efce0e41ceb4dfd61..a30ccf0564523b09afc4e9be3dcda12823cc3871 100644 (file)
@@ -251,10 +251,8 @@ func WriteDconv(w io.Writer, p *Prog, a *Addr) {
        case TYPE_BRANCH:
                if a.Sym != nil {
                        fmt.Fprintf(w, "%s(SB)", a.Sym.Name)
-               } else if p != nil && p.Pcond != nil {
-                       fmt.Fprint(w, p.Pcond.Pc)
-               } else if a.Val != nil {
-                       fmt.Fprint(w, a.Val.(*Prog).Pc)
+               } else if a.Target() != nil {
+                       fmt.Fprint(w, a.Target().Pc)
                } else {
                        fmt.Fprintf(w, "%d(PC)", a.Offset)
                }
index a53063637385287222fe5c55acc9ffb592babab1..fb99c620ad69afb5fec2cae2b876f2f5488f1ce4 100644 (file)
@@ -1855,7 +1855,7 @@ func spadjop(ctxt *obj.Link, l, q obj.As) obj.As {
 // no standalone or macro-fused jump will straddle or end on a 32 byte boundary
 // by inserting NOPs before the jumps
 func isJump(p *obj.Prog) bool {
-       return p.Pcond != nil || p.As == obj.AJMP || p.As == obj.ACALL ||
+       return p.To.Target() != nil || p.As == obj.AJMP || p.As == obj.ACALL ||
                p.As == obj.ARET || p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO
 }
 
@@ -1867,7 +1867,7 @@ func lookForJCC(p *obj.Prog) *obj.Prog {
        for q = p.Link; q != nil && (q.As == obj.APCDATA || q.As == obj.AFUNCDATA || q.As == obj.ANOP); q = q.Link {
        }
 
-       if q == nil || q.Pcond == nil || p.As == obj.AJMP || p.As == obj.ACALL {
+       if q == nil || q.To.Target() == nil || p.As == obj.AJMP || p.As == obj.ACALL {
                return nil
        }
 
@@ -2051,8 +2051,8 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
        }
 
        for p := s.Func.Text; p != nil; p = p.Link {
-               if p.To.Type == obj.TYPE_BRANCH && p.Pcond == nil {
-                       p.Pcond = p
+               if p.To.Type == obj.TYPE_BRANCH && p.To.Target() == nil {
+                       p.To.SetTarget(p)
                }
                if p.As == AADJSP {
                        p.To.Type = obj.TYPE_REG
@@ -2088,7 +2088,7 @@ func span6(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
        for p := s.Func.Text; p != nil; p = p.Link {
                count++
                p.Back = branchShort // use short branches first time through
-               if q := p.Pcond; q != nil && (q.Back&branchShort != 0) {
+               if q := p.To.Target(); q != nil && (q.Back&branchShort != 0) {
                        p.Back |= branchBackwards
                        q.Back |= branchLoopHead
                }
@@ -4886,7 +4886,7 @@ func (ab *AsmBuf) doasm(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog) {
                                // TODO: Check in input, preserve in brchain.
 
                                // Fill in backward jump now.
-                               q = p.Pcond
+                               q = p.To.Target()
 
                                if q == nil {
                                        ctxt.Diag("jmp/branch/loop without target")
index 016c247ff553a93ace09d40e919f9bb85478ff38..18a6afcd778f0b773a7da23e9e0f5c951ce24169 100644 (file)
@@ -765,7 +765,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                }
 
                // Set jne branch target.
-               jne.Pcond = p
+               jne.To.SetTarget(p)
 
                // CMPQ panic_argp(BX), DI
                p = obj.Appendp(p, newprog)
@@ -783,7 +783,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                p = obj.Appendp(p, newprog)
                p.As = AJNE
                p.To.Type = obj.TYPE_BRANCH
-               p.Pcond = end
+               p.To.SetTarget(end)
 
                // MOVQ SP, panic_argp(BX)
                p = obj.Appendp(p, newprog)
@@ -801,7 +801,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                p = obj.Appendp(p, newprog)
                p.As = obj.AJMP
                p.To.Type = obj.TYPE_BRANCH
-               p.Pcond = end
+               p.To.SetTarget(end)
 
                // Reset p for following code.
                p = end
@@ -1144,12 +1144,12 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA
        jmp := obj.Appendp(pcdata, newprog)
        jmp.As = obj.AJMP
        jmp.To.Type = obj.TYPE_BRANCH
-       jmp.Pcond = cursym.Func.Text.Link
+       jmp.To.SetTarget(cursym.Func.Text.Link)
        jmp.Spadj = +framesize
 
-       jls.Pcond = call
+       jls.To.SetTarget(call)
        if q1 != nil {
-               q1.Pcond = call
+               q1.To.SetTarget(call)
        }
 
        return end