ssa.BlockAMD64ULT, ssa.BlockAMD64UGT,
ssa.BlockAMD64ULE, ssa.BlockAMD64UGE:
jmp := blockJump[b.Kind]
- var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
default:
ssa.BlockARMULT, ssa.BlockARMUGT,
ssa.BlockARMULE, ssa.BlockARMUGE:
jmp := blockJump[b.Kind]
- var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
default:
var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ p = s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ p = s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
if !b.Control.Type.IsFlags() {
p.From.Type = obj.TYPE_REG
var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- p.From.Offset = b.Aux.(int64)
- p.From.Type = obj.TYPE_CONST
- p.Reg = b.Control.Reg()
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- p.From.Offset = b.Aux.(int64)
- p.From.Type = obj.TYPE_CONST
- p.Reg = b.Control.Reg()
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ p = s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- p.From.Offset = b.Aux.(int64)
- p.From.Type = obj.TYPE_CONST
- p.Reg = b.Control.Reg()
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ p = s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
+ p.From.Offset = b.Aux.(int64)
+ p.From.Type = obj.TYPE_CONST
+ p.Reg = b.Control.Reg()
default:
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
s.pp.pos = pos
}
+// Br emits a single branch instruction and returns the instruction.
+// Not all architectures need the returned instruction, but otherwise
+// the boilerplate is common to all.
+func (s *SSAGenState) Br(op obj.As, target *ssa.Block) *obj.Prog {
+ p := s.Prog(op)
+ p.To.Type = obj.TYPE_BRANCH
+ s.Branches = append(s.Branches, Branch{P: p, B: target})
+ return p
+}
+
// DebugFriendlySetPos sets the position subject to heuristics
// that reduce "jumpy" line number churn when debugging.
// Spill/fill/copy instructions from the register allocator,
var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ p = s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ p = s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
if !b.Control.Type.IsFlags() {
p.From.Type = obj.TYPE_REG
var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ p = s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ p = s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ p = s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
if !b.Control.Type.IsFlags() {
p.From.Type = obj.TYPE_REG
ssa.BlockPPC64FLT, ssa.BlockPPC64FGE,
ssa.BlockPPC64FLE, ssa.BlockPPC64FGT:
jmp := blockJump[b.Kind]
- var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ s.Br(jmp.invasm, b.Succs[1].Block())
if jmp.invasmun {
// TODO: The second branch is probably predict-not-taken since it is for FP unordered
- q := s.Prog(ppc64.ABVS)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ s.Br(ppc64.ABVS, b.Succs[1].Block())
}
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ s.Br(jmp.asm, b.Succs[0].Block())
if jmp.asmeq {
- q := s.Prog(ppc64.ABEQ)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[0].Block()})
+ s.Br(ppc64.ABEQ, b.Succs[0].Block())
}
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- if jmp.asmeq {
- q := s.Prog(ppc64.ABEQ)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[0].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ s.Br(jmp.asm, b.Succs[0].Block())
+ if jmp.asmeq {
+ s.Br(ppc64.ABEQ, b.Succs[0].Block())
+ }
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ s.Br(jmp.invasm, b.Succs[1].Block())
+ if jmp.invasmun {
+ // TODO: The second branch is probably predict-not-taken since it is for FP unordered
+ s.Br(ppc64.ABVS, b.Succs[1].Block())
+ }
+ s.Br(obj.AJMP, b.Succs[0].Block())
}
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
}
-
default:
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
}
ssa.BlockS390XLE, ssa.BlockS390XGT,
ssa.BlockS390XGEF, ssa.BlockS390XGTF:
jmp := blockJump[b.Kind]
- var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(s390x.ABR)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(s390x.ABR, b.Succs[1].Block())
+ } else {
+ s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(s390x.ABR, b.Succs[0].Block())
+ }
}
default:
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
ssa.Block386ULT, ssa.Block386UGT,
ssa.Block386ULE, ssa.Block386UGE:
jmp := blockJump[b.Kind]
- var p *obj.Prog
switch next {
case b.Succs[0].Block():
- p = s.Prog(jmp.invasm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[1].Block()})
+ s.Br(jmp.invasm, b.Succs[1].Block())
case b.Succs[1].Block():
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
+ s.Br(jmp.asm, b.Succs[0].Block())
default:
- p = s.Prog(jmp.asm)
- p.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: p, B: b.Succs[0].Block()})
- q := s.Prog(obj.AJMP)
- q.To.Type = obj.TYPE_BRANCH
- s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
+ if b.Likely != ssa.BranchUnlikely {
+ s.Br(jmp.asm, b.Succs[0].Block())
+ s.Br(obj.AJMP, b.Succs[1].Block())
+ } else {
+ s.Br(jmp.invasm, b.Succs[1].Block())
+ s.Br(obj.AJMP, b.Succs[0].Block())
+ }
}
-
default:
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
}