]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/ppc64/ssa.go
cmd/compile/internal/ssa: on PPC64, merge (CMPconst [0] (op ...)) more aggressively
[gostls13.git] / src / cmd / compile / internal / ppc64 / ssa.go
index 3c2a7713064eaae870bd04dd9cba152c824e876b..d20a31e38a292bb14d8e607957d8c307ed95be63 100644 (file)
@@ -347,9 +347,9 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                // 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
@@ -381,7 +381,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                // 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)
@@ -402,22 +402,24 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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
@@ -556,7 +558,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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
@@ -568,19 +570,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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
@@ -603,7 +593,8 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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())
@@ -613,6 +604,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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
@@ -623,21 +621,34 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 
                // 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()
@@ -649,7 +660,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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
 
@@ -663,7 +674,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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
 
@@ -717,7 +728,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 
        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
@@ -725,19 +736,18 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
 
        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:
@@ -976,9 +986,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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 {
@@ -1867,9 +1878,9 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
                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