case OpAdd64F:
v.Op = OpPPC64FADD
return true
- case OpAdd64carry:
- v.Op = OpPPC64LoweredAdd64Carry
- return true
case OpAdd8:
v.Op = OpPPC64ADD
return true
return true
case OpPPC64ADD:
return rewriteValuePPC64_OpPPC64ADD(v)
+ case OpPPC64ADDE:
+ return rewriteValuePPC64_OpPPC64ADDE(v)
case OpPPC64ADDconst:
return rewriteValuePPC64_OpPPC64ADDconst(v)
case OpPPC64AND:
return rewriteValuePPC64_OpPPC64SRWconst(v)
case OpPPC64SUB:
return rewriteValuePPC64_OpPPC64SUB(v)
+ case OpPPC64SUBE:
+ return rewriteValuePPC64_OpPPC64SUBE(v)
case OpPPC64SUBFCconst:
return rewriteValuePPC64_OpPPC64SUBFCconst(v)
case OpPPC64XOR:
return rewriteValuePPC64_OpRsh8x64(v)
case OpRsh8x8:
return rewriteValuePPC64_OpRsh8x8(v)
+ case OpSelect0:
+ return rewriteValuePPC64_OpSelect0(v)
+ case OpSelect1:
+ return rewriteValuePPC64_OpSelect1(v)
case OpSelectN:
return rewriteValuePPC64_OpSelectN(v)
case OpSignExt16to32:
}
return false
}
+func rewriteValuePPC64_OpPPC64ADDE(v *Value) bool {
+ v_2 := v.Args[2]
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (ADDE x y (Select1 <typ.UInt64> (ADDCconst (MOVDconst [0]) [-1])))
+ // result: (ADDC x y)
+ for {
+ x := v_0
+ y := v_1
+ if v_2.Op != OpSelect1 || v_2.Type != typ.UInt64 {
+ break
+ }
+ v_2_0 := v_2.Args[0]
+ if v_2_0.Op != OpPPC64ADDCconst || auxIntToInt64(v_2_0.AuxInt) != -1 {
+ break
+ }
+ v_2_0_0 := v_2_0.Args[0]
+ if v_2_0_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 {
+ break
+ }
+ v.reset(OpPPC64ADDC)
+ v.AddArg2(x, y)
+ return true
+ }
+ return false
+}
func rewriteValuePPC64_OpPPC64ADDconst(v *Value) bool {
v_0 := v.Args[0]
// match: (ADDconst [c] (ADDconst [d] x))
}
return false
}
+func rewriteValuePPC64_OpPPC64SUBE(v *Value) bool {
+ v_2 := v.Args[2]
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (SUBE x y (Select1 <typ.UInt64> (SUBCconst (MOVDconst [0]) [0])))
+ // result: (SUBC x y)
+ for {
+ x := v_0
+ y := v_1
+ if v_2.Op != OpSelect1 || v_2.Type != typ.UInt64 {
+ break
+ }
+ v_2_0 := v_2.Args[0]
+ if v_2_0.Op != OpPPC64SUBCconst || auxIntToInt64(v_2_0.AuxInt) != 0 {
+ break
+ }
+ v_2_0_0 := v_2_0.Args[0]
+ if v_2_0_0.Op != OpPPC64MOVDconst || auxIntToInt64(v_2_0_0.AuxInt) != 0 {
+ break
+ }
+ v.reset(OpPPC64SUBC)
+ v.AddArg2(x, y)
+ return true
+ }
+ return false
+}
func rewriteValuePPC64_OpPPC64SUBFCconst(v *Value) bool {
v_0 := v.Args[0]
// match: (SUBFCconst [c] (NEG x))
return true
}
}
+func rewriteValuePPC64_OpSelect0(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (Select0 (Add64carry x y c))
+ // result: (Select0 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1]))))
+ for {
+ if v_0.Op != OpAdd64carry {
+ break
+ }
+ c := v_0.Args[2]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ v.reset(OpSelect0)
+ v.Type = typ.UInt64
+ v0 := b.NewValue0(v.Pos, OpPPC64ADDE, types.NewTuple(typ.UInt64, typ.UInt64))
+ v1 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+ v2 := b.NewValue0(v.Pos, OpPPC64ADDCconst, types.NewTuple(typ.UInt64, typ.UInt64))
+ v2.AuxInt = int64ToAuxInt(-1)
+ v2.AddArg(c)
+ v1.AddArg(v2)
+ v0.AddArg3(x, y, v1)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (Select0 (Sub64borrow x y c))
+ // result: (Select0 <typ.UInt64> (SUBE x y (Select1 <typ.UInt64> (SUBCconst c [0]))))
+ for {
+ if v_0.Op != OpSub64borrow {
+ break
+ }
+ c := v_0.Args[2]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ v.reset(OpSelect0)
+ v.Type = typ.UInt64
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBE, types.NewTuple(typ.UInt64, typ.UInt64))
+ v1 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+ v2 := b.NewValue0(v.Pos, OpPPC64SUBCconst, types.NewTuple(typ.UInt64, typ.UInt64))
+ v2.AuxInt = int64ToAuxInt(0)
+ v2.AddArg(c)
+ v1.AddArg(v2)
+ v0.AddArg3(x, y, v1)
+ v.AddArg(v0)
+ return true
+ }
+ return false
+}
+func rewriteValuePPC64_OpSelect1(v *Value) bool {
+ v_0 := v.Args[0]
+ b := v.Block
+ typ := &b.Func.Config.Types
+ // match: (Select1 (Add64carry x y c))
+ // result: (ADDZEzero (Select1 <typ.UInt64> (ADDE x y (Select1 <typ.UInt64> (ADDCconst c [-1])))))
+ for {
+ if v_0.Op != OpAdd64carry {
+ break
+ }
+ c := v_0.Args[2]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ v.reset(OpPPC64ADDZEzero)
+ v0 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+ v1 := b.NewValue0(v.Pos, OpPPC64ADDE, types.NewTuple(typ.UInt64, typ.UInt64))
+ v2 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+ v3 := b.NewValue0(v.Pos, OpPPC64ADDCconst, types.NewTuple(typ.UInt64, typ.UInt64))
+ v3.AuxInt = int64ToAuxInt(-1)
+ v3.AddArg(c)
+ v2.AddArg(v3)
+ v1.AddArg3(x, y, v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (Select1 (ADDCconst n:(ADDZEzero x) [-1]))
+ // cond: n.Uses <= 2
+ // result: x
+ for {
+ if v_0.Op != OpPPC64ADDCconst || auxIntToInt64(v_0.AuxInt) != -1 {
+ break
+ }
+ n := v_0.Args[0]
+ if n.Op != OpPPC64ADDZEzero {
+ break
+ }
+ x := n.Args[0]
+ if !(n.Uses <= 2) {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
+ // match: (Select1 (Sub64borrow x y c))
+ // result: (NEG (SUBZEzero (Select1 <typ.UInt64> (SUBE x y (Select1 <typ.UInt64> (SUBCconst c [0]))))))
+ for {
+ if v_0.Op != OpSub64borrow {
+ break
+ }
+ c := v_0.Args[2]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ v.reset(OpPPC64NEG)
+ v0 := b.NewValue0(v.Pos, OpPPC64SUBZEzero, typ.UInt64)
+ v1 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+ v2 := b.NewValue0(v.Pos, OpPPC64SUBE, types.NewTuple(typ.UInt64, typ.UInt64))
+ v3 := b.NewValue0(v.Pos, OpSelect1, typ.UInt64)
+ v4 := b.NewValue0(v.Pos, OpPPC64SUBCconst, types.NewTuple(typ.UInt64, typ.UInt64))
+ v4.AuxInt = int64ToAuxInt(0)
+ v4.AddArg(c)
+ v3.AddArg(v4)
+ v2.AddArg3(x, y, v3)
+ v1.AddArg(v2)
+ v0.AddArg(v1)
+ v.AddArg(v0)
+ return true
+ }
+ // match: (Select1 (SUBCconst n:(NEG (SUBZEzero x)) [0]))
+ // cond: n.Uses <= 2
+ // result: x
+ for {
+ if v_0.Op != OpPPC64SUBCconst || auxIntToInt64(v_0.AuxInt) != 0 {
+ break
+ }
+ n := v_0.Args[0]
+ if n.Op != OpPPC64NEG {
+ break
+ }
+ n_0 := n.Args[0]
+ if n_0.Op != OpPPC64SUBZEzero {
+ break
+ }
+ x := n_0.Args[0]
+ if !(n.Uses <= 2) {
+ break
+ }
+ v.copyOf(x)
+ return true
+ }
+ return false
+}
func rewriteValuePPC64_OpSelectN(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
{as: AMOVD, a1: C_LACON, a6: C_REG, type_: 26, size: 8},
{as: AMOVD, a1: C_ADDR, a6: C_REG, type_: 75, size: 8},
{as: AMOVD, a1: C_SOREG, a6: C_REG, type_: 8, size: 4},
+ {as: AMOVD, a1: C_SOREG, a6: C_SPR, type_: 107, size: 8},
{as: AMOVD, a1: C_LOREG, a6: C_REG, type_: 36, size: 8},
{as: AMOVD, a1: C_TLS_LE, a6: C_REG, type_: 79, size: 8},
{as: AMOVD, a1: C_TLS_IE, a6: C_REG, type_: 80, size: 12},
{as: AMOVD, a1: C_SPR, a6: C_REG, type_: 66, size: 4},
{as: AMOVD, a1: C_REG, a6: C_ADDR, type_: 74, size: 8},
{as: AMOVD, a1: C_REG, a6: C_SOREG, type_: 7, size: 4},
+ {as: AMOVD, a1: C_SPR, a6: C_SOREG, type_: 106, size: 8},
{as: AMOVD, a1: C_REG, a6: C_LOREG, type_: 35, size: 8},
{as: AMOVD, a1: C_REG, a6: C_SPR, type_: 66, size: 4},
{as: AMOVD, a1: C_REG, a6: C_REG, type_: 13, size: 4},
case 105: /* PNOP */
o1 = 0x07000000
o2 = 0x00000000
+
+ case 106: /* MOVD spr, soreg */
+ v := int32(p.From.Reg)
+ o1 = OPVCC(31, 339, 0, 0) /* mfspr */
+ o1 = AOP_RRR(o1, uint32(REGTMP), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
+ so := c.regoff(&p.To)
+ o2 = AOP_IRR(c.opstore(AMOVD), uint32(REGTMP), uint32(p.To.Reg), uint32(so))
+ if so&0x3 != 0 {
+ log.Fatalf("invalid offset for DS form load/store %v", p)
+ }
+ if p.To.Reg == REGTMP {
+ log.Fatalf("SPR move to memory will clobber R31 %v", p)
+ }
+
+ case 107: /* MOVD soreg, spr */
+ v := int32(p.From.Reg)
+ so := c.regoff(&p.From)
+ o1 = AOP_IRR(c.opload(AMOVD), uint32(REGTMP), uint32(v), uint32(so))
+ o2 = OPVCC(31, 467, 0, 0) /* mtspr */
+ v = int32(p.To.Reg)
+ o2 = AOP_RRR(o2, uint32(REGTMP), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
+ if so&0x3 != 0 {
+ log.Fatalf("invalid offset for DS form load/store %v", p)
+ }
}
out[0] = o1
func Add(x, y, ci uint) (r, co uint) {
// arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
+ // ppc64: "ADDC", "ADDE", "ADDZE"
+ // ppc64le: "ADDC", "ADDE", "ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
return bits.Add(x, y, ci)
}
func AddC(x, ci uint) (r, co uint) {
// arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
// amd64:"NEGL","ADCQ","SBBQ","NEGQ"
+ // ppc64: "ADDC", "ADDE", "ADDZE"
+ // ppc64le: "ADDC", "ADDE", "ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
return bits.Add(x, 7, ci)
}
func AddZ(x, y uint) (r, co uint) {
// arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
// amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
+ // ppc64: "ADDC", -"ADDE", "ADDZE"
+ // ppc64le: "ADDC", -"ADDE", "ADDZE"
// s390x:"ADDC",-"ADDC\t[$]-1,"
return bits.Add(x, y, 0)
}
func AddR(x, y, ci uint) uint {
// arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
// amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
+ // ppc64: "ADDC", "ADDE", -"ADDZE"
+ // ppc64le: "ADDC", "ADDE", -"ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
r, _ := bits.Add(x, y, ci)
return r
func Add64Z(x, y uint64) (r, co uint64) {
// arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
// amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
- // ppc64: "ADDC", "ADDE", "ADDZE"
- // ppc64le: "ADDC", "ADDE", "ADDZE"
+ // ppc64: "ADDC", -"ADDE", "ADDZE"
+ // ppc64le: "ADDC", -"ADDE", "ADDZE"
// s390x:"ADDC",-"ADDC\t[$]-1,"
return bits.Add64(x, y, 0)
}
func Add64R(x, y, ci uint64) uint64 {
// arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
// amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
- // ppc64: "ADDC", "ADDE", "ADDZE"
- // ppc64le: "ADDC", "ADDE", "ADDZE"
+ // ppc64: "ADDC", "ADDE", -"ADDZE"
+ // ppc64le: "ADDC", "ADDE", -"ADDZE"
// s390x:"ADDE","ADDC\t[$]-1,"
r, _ := bits.Add64(x, y, ci)
return r
r[0], c = bits.Add64(p[0], q[0], c)
// arm64:"ADCS",-"ADD\t",-"CMP"
// amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
- // ppc64: "ADDC", "ADDE", "ADDZE"
- // ppc64le: "ADDC", "ADDE", "ADDZE"
+ // ppc64: -"ADDC", "ADDE", -"ADDZE"
+ // ppc64le: -"ADDC", "ADDE", -"ADDZE"
// s390x:"ADDE",-"ADDC\t[$]-1,"
r[1], c = bits.Add64(p[1], q[1], c)
r[2], c = bits.Add64(p[2], q[2], c)
}
+func Add64MSaveC(p, q, r, c *[2]uint64) {
+ // ppc64: "ADDC\tR", "ADDZE"
+ // ppc64le: "ADDC\tR", "ADDZE"
+ r[0], c[0] = bits.Add64(p[0], q[0], 0)
+ // ppc64: "ADDC\t[$]-1", "ADDE", "ADDZE"
+ // ppc64le: "ADDC\t[$]-1", "ADDE", "ADDZE"
+ r[1], c[1] = bits.Add64(p[1], q[1], c[0])
+}
+
func Add64PanicOnOverflowEQ(a, b uint64) uint64 {
r, c := bits.Add64(a, b, 0)
// s390x:"BRC\t[$]3,",-"ADDE"
func Sub(x, y, ci uint) (r, co uint) {
// amd64:"NEGL","SBBQ","NEGQ"
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
+ // ppc64:"SUBC", "SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG"
// s390x:"SUBE"
return bits.Sub(x, y, ci)
}
func SubC(x, ci uint) (r, co uint) {
// amd64:"NEGL","SBBQ","NEGQ"
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
+ // ppc64:"SUBC", "SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG"
// s390x:"SUBE"
return bits.Sub(x, 7, ci)
}
func SubZ(x, y uint) (r, co uint) {
// amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
// arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
+ // ppc64:"SUBC", -"SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC", -"SUBE", "SUBZE", "NEG"
// s390x:"SUBC"
return bits.Sub(x, y, 0)
}
func SubR(x, y, ci uint) uint {
// amd64:"NEGL","SBBQ",-"NEGQ"
// arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
+ // ppc64:"SUBC", "SUBE", -"SUBZE", -"NEG"
+ // ppc64le:"SUBC", "SUBE", -"SUBZE", -"NEG"
// s390x:"SUBE"
r, _ := bits.Sub(x, y, ci)
return r
r[0], c = bits.Sub(p[0], q[0], c)
// amd64:"SBBQ",-"NEGL",-"NEGQ"
// arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
+ // ppc64:-"SUBC", "SUBE", -"SUBZE", -"NEG"
+ // ppc64le:-"SUBC", "SUBE", -"SUBZE", -"NEG"
// s390x:"SUBE"
r[1], c = bits.Sub(p[1], q[1], c)
r[2], c = bits.Sub(p[2], q[2], c)
func Sub64(x, y, ci uint64) (r, co uint64) {
// amd64:"NEGL","SBBQ","NEGQ"
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
+ // ppc64:"SUBC", "SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG"
// s390x:"SUBE"
return bits.Sub64(x, y, ci)
}
func Sub64C(x, ci uint64) (r, co uint64) {
// amd64:"NEGL","SBBQ","NEGQ"
// arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
+ // ppc64:"SUBC", "SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC", "SUBE", "SUBZE", "NEG"
// s390x:"SUBE"
return bits.Sub64(x, 7, ci)
}
func Sub64Z(x, y uint64) (r, co uint64) {
// amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
// arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
+ // ppc64:"SUBC", -"SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC", -"SUBE", "SUBZE", "NEG"
// s390x:"SUBC"
return bits.Sub64(x, y, 0)
}
func Sub64R(x, y, ci uint64) uint64 {
// amd64:"NEGL","SBBQ",-"NEGQ"
// arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
+ // ppc64:"SUBC", "SUBE", -"SUBZE", -"NEG"
+ // ppc64le:"SUBC", "SUBE", -"SUBZE", -"NEG"
// s390x:"SUBE"
r, _ := bits.Sub64(x, y, ci)
return r
r[2], c = bits.Sub64(p[2], q[2], c)
}
+func Sub64MSaveC(p, q, r, c *[2]uint64) {
+ // ppc64:"SUBC\tR\\d+, R\\d+,", "SUBZE", "NEG"
+ // ppc64le:"SUBC\tR\\d+, R\\d+,", "SUBZE", "NEG"
+ r[0], c[0] = bits.Sub64(p[0], q[0], 0)
+ // ppc64:"SUBC\tR\\d+, [$]0,", "SUBE", "SUBZE", "NEG"
+ // ppc64le:"SUBC\tR\\d+, [$]0,", "SUBE", "SUBZE", "NEG"
+ r[1], c[1] = bits.Sub64(p[1], q[1], c[0])
+}
+
func Sub64PanicOnOverflowEQ(a, b uint64) uint64 {
r, b := bits.Sub64(a, b, 0)
// s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"