// BNE end
// STDCCC Rarg2, (Rarg0)
// BNE loop
- // LWSYNC // Only for sequential consistency; not required in CasRel.
// MOVD $1, Rout
// end:
+ // LWSYNC // Only for sequential consistency; not required in CasRel.
ld := ppc64.ALDAR
st := ppc64.ASTDCCC
cmp := ppc64.ACMP
// If it is a Compare-and-Swap-Release operation, set the EH field with
// the release hint.
if v.AuxInt == 0 {
- p0.SetFrom3Const(0)
+ p0.AddRestSourceConst(0)
}
// CMP reg1,reg2
p1 := s.Prog(cmp)
p4 := s.Prog(ppc64.ABNE)
p4.To.Type = obj.TYPE_BRANCH
p4.To.SetTarget(p0)
+ // return value true
+ p5 := s.Prog(ppc64.AMOVD)
+ p5.From.Type = obj.TYPE_CONST
+ p5.From.Offset = 1
+ p5.To.Type = obj.TYPE_REG
+ p5.To.Reg = out
// LWSYNC - Assuming shared data not write-through-required nor
// caching-inhibited. See Appendix B.2.1.1 in the ISA 2.07b.
// If the operation is a CAS-Release, then synchronization is not necessary.
if v.AuxInt != 0 {
plwsync2 := s.Prog(ppc64.ALWSYNC)
plwsync2.To.Type = obj.TYPE_NONE
+ p2.To.SetTarget(plwsync2)
+ } else {
+ // done (label)
+ p6 := s.Prog(obj.ANOP)
+ p2.To.SetTarget(p6)
}
- // return value true
- p5 := s.Prog(ppc64.AMOVD)
- p5.From.Type = obj.TYPE_CONST
- p5.From.Offset = 1
- p5.To.Type = obj.TYPE_REG
- p5.To.Reg = out
- // done (label)
- p6 := s.Prog(obj.ANOP)
- p2.To.SetTarget(p6)
case ssa.OpPPC64LoweredPubBarrier:
// LWSYNC
p := s.Prog(v.Op.Asm())
// clrlslwi ra,rs,mb,sh will become rlwinm ra,rs,sh,mb-sh,31-sh as described in ISA
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
- p.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
+ p.AddRestSourceConst(ssa.GetPPC64Shiftsh(shifts))
p.Reg = r1
p.To.Type = obj.TYPE_REG
p.To.Reg = r
p := s.Prog(v.Op.Asm())
// clrlsldi ra,rs,mb,sh will become rldic ra,rs,sh,mb-sh
p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftmb(shifts)}
- p.SetFrom3Const(ssa.GetPPC64Shiftsh(shifts))
- p.Reg = r1
- p.To.Type = obj.TYPE_REG
- p.To.Reg = r
-
- // Mask has been set as sh
- case ssa.OpPPC64RLDICL:
- r := v.Reg()
- r1 := v.Args[0].Reg()
- shifts := v.AuxInt
- p := s.Prog(v.Op.Asm())
- p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: ssa.GetPPC64Shiftsh(shifts)}
- p.SetFrom3Const(ssa.GetPPC64Shiftmb(shifts))
+ p.AddRestSourceConst(ssa.GetPPC64Shiftsh(shifts))
p.Reg = r1
p.To.Type = obj.TYPE_REG
p.To.Reg = r
p.To.Type = obj.TYPE_REG
p.To.Reg = r
- case ssa.OpPPC64ANDCC, ssa.OpPPC64ORCC, ssa.OpPPC64XORCC:
+ case ssa.OpPPC64ADDCC, ssa.OpPPC64ANDCC, ssa.OpPPC64SUBCC, ssa.OpPPC64ORCC, ssa.OpPPC64XORCC, ssa.OpPPC64NORCC,
+ ssa.OpPPC64ANDNCC:
r1 := v.Args[0].Reg()
r2 := v.Args[1].Reg()
p := s.Prog(v.Op.Asm())
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg0()
+ case ssa.OpPPC64NEGCC, ssa.OpPPC64CNTLZDCC:
+ p := s.Prog(v.Op.Asm())
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = v.Reg0()
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = v.Args[0].Reg()
+
case ssa.OpPPC64ROTLconst, ssa.OpPPC64ROTLWconst:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_CONST
// Auxint holds encoded rotate + mask
case ssa.OpPPC64RLWINM, ssa.OpPPC64RLWMI:
- rot, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
+ sh, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
p := s.Prog(v.Op.Asm())
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.Reg = v.Args[0].Reg()
- p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(rot)}
- p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
-
+ p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(sh)}
+ p.AddRestSourceArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
// Auxint holds mask
+
+ case ssa.OpPPC64RLDICL, ssa.OpPPC64RLDICR:
+ sh, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
+ p := s.Prog(v.Op.Asm())
+ p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: sh}
+ switch v.Op {
+ case ssa.OpPPC64RLDICL:
+ p.AddRestSourceConst(mb)
+ case ssa.OpPPC64RLDICR:
+ p.AddRestSourceConst(me)
+ }
+ p.Reg = v.Args[0].Reg()
+ p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
+
case ssa.OpPPC64RLWNM:
_, mb, me, _ := ssa.DecodePPC64RotateMask(v.AuxInt)
p := s.Prog(v.Op.Asm())
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.Reg = v.Args[0].Reg()
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: v.Args[1].Reg()}
- p.SetRestArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
+ p.AddRestSourceArgs([]obj.Addr{{Type: obj.TYPE_CONST, Offset: mb}, {Type: obj.TYPE_CONST, Offset: me}})
case ssa.OpPPC64MADDLD:
r := v.Reg()
p.From.Type = obj.TYPE_REG
p.From.Reg = r1
p.Reg = r2
- p.SetFrom3Reg(r3)
+ p.AddRestSourceReg(r3)
p.To.Type = obj.TYPE_REG
p.To.Reg = r
p.From.Type = obj.TYPE_REG
p.From.Reg = r1
p.Reg = r3
- p.SetFrom3Reg(r2)
+ p.AddRestSourceReg(r2)
p.To.Type = obj.TYPE_REG
p.To.Reg = r
case ssa.OpPPC64SUBCconst:
p := s.Prog(v.Op.Asm())
- p.SetFrom3Const(v.AuxInt)
+ p.AddRestSourceConst(v.AuxInt)
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
case ssa.OpPPC64SUBFCconst:
p := s.Prog(v.Op.Asm())
- p.SetFrom3Const(v.AuxInt)
+ p.AddRestSourceConst(v.AuxInt)
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[0].Reg()
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
- case ssa.OpPPC64ANDCCconst:
+ case ssa.OpPPC64ADDCCconst, ssa.OpPPC64ANDCCconst:
p := s.Prog(v.Op.Asm())
p.Reg = v.Args[0].Reg()
p.From.Type = obj.TYPE_CONST
p.From.Offset = v.AuxInt
p.To.Type = obj.TYPE_REG
- // p.To.Reg = ppc64.REGTMP // discard result
p.To.Reg = v.Reg0()
case ssa.OpPPC64MOVDaddr:
p := s.Prog(v.Op.Asm())
p.To = obj.Addr{Type: obj.TYPE_REG, Reg: v.Reg()}
p.Reg = v.Args[0].Reg()
- p.SetFrom3Reg(ppc64.REG_R0)
if v.Op == ssa.OpPPC64ISEL {
- p.SetFrom3Reg(v.Args[1].Reg())
+ p.AddRestSourceReg(v.Args[1].Reg())
+ } else {
+ p.AddRestSourceReg(ppc64.REG_R0)
}
// AuxInt values 4,5,6 implemented with reverse operand order from 0,1,2
if v.AuxInt > 3 {
pp.From.Offset = ppc64.BO_ALWAYS
pp.Reg = ppc64.REG_CR0LT // The preferred value if BI is ignored.
pp.To.Reg = ppc64.REG_LR
- pp.SetFrom3Const(1)
+ pp.AddRestSourceConst(1)
- if base.Ctxt.Flag_shared {
+ if ppc64.NeedTOCpointer(base.Ctxt) {
// When compiling Go into PIC, the function we just
// called via pointer might have been implemented in
// a separate module and so overwritten the TOC