p.Reg = r1
p.To.Type = obj.TYPE_REG
p.To.Reg = r
+ case ssa.OpARMMULAF, ssa.OpARMMULAD, ssa.OpARMMULSF, ssa.OpARMMULSD:
+ r := v.Reg()
+ r0 := v.Args[0].Reg()
+ r1 := v.Args[1].Reg()
+ r2 := v.Args[2].Reg()
+ if r != r0 {
+ v.Fatalf("result and addend are not in the same register: %v", v.LongString())
+ }
+ p := s.Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = r2
+ p.Reg = r1
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = r
case ssa.OpARMADDS,
ssa.OpARMSUBS:
r := v.Reg0()
(NMULF (NEGF x) y) -> (MULF x y)
(NMULD (NEGD x) y) -> (MULD x y)
+// the result will overwrite the addend, since they are in the same register
+(ADDF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAF a x y)
+(ADDF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSF a x y)
+(ADDD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAD a x y)
+(ADDD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSD a x y)
+(SUBF a (MULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSF a x y)
+(SUBF a (NMULF x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAF a x y)
+(SUBD a (MULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULSD a x y)
+(SUBD a (NMULD x y)) && a.Uses == 1 && objabi.GOARM >= 6 -> (MULAD a x y)
+
(AND x (MVN y)) -> (BIC x y)
// simplification with *shift ops
fpgp = regInfo{inputs: []regMask{fp}, outputs: []regMask{gp}, clobbers: buildReg("F15")} // int-float conversion uses F15 as tmp
gpfp = regInfo{inputs: []regMask{gp}, outputs: []regMask{fp}, clobbers: buildReg("F15")}
fp21 = regInfo{inputs: []regMask{fp, fp}, outputs: []regMask{fp}}
+ fp31 = regInfo{inputs: []regMask{fp, fp, fp}, outputs: []regMask{fp}}
fp2flags = regInfo{inputs: []regMask{fp, fp}}
fpload = regInfo{inputs: []regMask{gpspsbg}, outputs: []regMask{fp}}
fpstore = regInfo{inputs: []regMask{gpspsbg, fp}}
{name: "DIVF", argLength: 2, reg: fp21, asm: "DIVF"}, // arg0 / arg1
{name: "DIVD", argLength: 2, reg: fp21, asm: "DIVD"}, // arg0 / arg1
+ {name: "MULAF", argLength: 3, reg: fp31, asm: "MULAF", resultInArg0: true}, // arg0 + (arg1 * arg2)
+ {name: "MULAD", argLength: 3, reg: fp31, asm: "MULAD", resultInArg0: true}, // arg0 + (arg1 * arg2)
+ {name: "MULSF", argLength: 3, reg: fp31, asm: "MULSF", resultInArg0: true}, // arg0 - (arg1 * arg2)
+ {name: "MULSD", argLength: 3, reg: fp31, asm: "MULSD", resultInArg0: true}, // arg0 - (arg1 * arg2)
+
{name: "AND", argLength: 2, reg: gp21, asm: "AND", commutative: true}, // arg0 & arg1
{name: "ANDconst", argLength: 1, reg: gp11, asm: "AND", aux: "Int32"}, // arg0 & auxInt
{name: "OR", argLength: 2, reg: gp21, asm: "ORR", commutative: true}, // arg0 | arg1
OpARMNMULD
OpARMDIVF
OpARMDIVD
+ OpARMMULAF
+ OpARMMULAD
+ OpARMMULSF
+ OpARMMULSD
OpARMAND
OpARMANDconst
OpARMOR
},
},
},
+ {
+ name: "MULAF",
+ argLen: 3,
+ resultInArg0: true,
+ asm: arm.AMULAF,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
+ {
+ name: "MULAD",
+ argLen: 3,
+ resultInArg0: true,
+ asm: arm.AMULAD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
+ {
+ name: "MULSF",
+ argLen: 3,
+ resultInArg0: true,
+ asm: arm.AMULSF,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
+ {
+ name: "MULSD",
+ argLen: 3,
+ resultInArg0: true,
+ asm: arm.AMULSD,
+ reg: regInfo{
+ inputs: []inputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {1, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ {2, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ outputs: []outputInfo{
+ {0, 4294901760}, // F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15
+ },
+ },
+ },
{
name: "AND",
argLen: 2,
return rewriteValueARM_OpARMADCshiftRLreg_0(v)
case OpARMADD:
return rewriteValueARM_OpARMADD_0(v) || rewriteValueARM_OpARMADD_10(v)
+ case OpARMADDD:
+ return rewriteValueARM_OpARMADDD_0(v)
+ case OpARMADDF:
+ return rewriteValueARM_OpARMADDF_0(v)
case OpARMADDS:
return rewriteValueARM_OpARMADDS_0(v) || rewriteValueARM_OpARMADDS_10(v)
case OpARMADDSshiftLL:
return rewriteValueARM_OpARMSRLconst_0(v)
case OpARMSUB:
return rewriteValueARM_OpARMSUB_0(v) || rewriteValueARM_OpARMSUB_10(v)
+ case OpARMSUBD:
+ return rewriteValueARM_OpARMSUBD_0(v)
+ case OpARMSUBF:
+ return rewriteValueARM_OpARMSUBF_0(v)
case OpARMSUBS:
return rewriteValueARM_OpARMSUBS_0(v) || rewriteValueARM_OpARMSUBS_10(v)
case OpARMSUBSshiftLL:
}
return false
}
+func rewriteValueARM_OpARMADDD_0(v *Value) bool {
+ // match: (ADDD a (MULD x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULAD a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMMULD {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULAD)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (ADDD (MULD x y) a)
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULAD a x y)
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpARMMULD {
+ break
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ a := v.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULAD)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (ADDD a (NMULD x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULSD a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMNMULD {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULSD)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (ADDD (NMULD x y) a)
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULSD a x y)
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpARMNMULD {
+ break
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ a := v.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULSD)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ return false
+}
+func rewriteValueARM_OpARMADDF_0(v *Value) bool {
+ // match: (ADDF a (MULF x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULAF a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMMULF {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULAF)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (ADDF (MULF x y) a)
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULAF a x y)
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpARMMULF {
+ break
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ a := v.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULAF)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (ADDF a (NMULF x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULSF a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMNMULF {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULSF)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (ADDF (NMULF x y) a)
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULSF a x y)
+ for {
+ _ = v.Args[1]
+ v_0 := v.Args[0]
+ if v_0.Op != OpARMNMULF {
+ break
+ }
+ _ = v_0.Args[1]
+ x := v_0.Args[0]
+ y := v_0.Args[1]
+ a := v.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULSF)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ return false
+}
func rewriteValueARM_OpARMADDS_0(v *Value) bool {
// match: (ADDS x (MOVWconst [c]))
// cond:
}
return false
}
+func rewriteValueARM_OpARMSUBD_0(v *Value) bool {
+ // match: (SUBD a (MULD x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULSD a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMMULD {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULSD)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (SUBD a (NMULD x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULAD a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMNMULD {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULAD)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ return false
+}
+func rewriteValueARM_OpARMSUBF_0(v *Value) bool {
+ // match: (SUBF a (MULF x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULSF a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMMULF {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULSF)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ // match: (SUBF a (NMULF x y))
+ // cond: a.Uses == 1 && objabi.GOARM >= 6
+ // result: (MULAF a x y)
+ for {
+ _ = v.Args[1]
+ a := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpARMNMULF {
+ break
+ }
+ _ = v_1.Args[1]
+ x := v_1.Args[0]
+ y := v_1.Args[1]
+ if !(a.Uses == 1 && objabi.GOARM >= 6) {
+ break
+ }
+ v.reset(OpARMMULAF)
+ v.AddArg(a)
+ v.AddArg(x)
+ v.AddArg(y)
+ return true
+ }
+ return false
+}
func rewriteValueARM_OpARMSUBS_0(v *Value) bool {
// match: (SUBS x (MOVWconst [c]))
// cond: