diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 27cfe960483..f93504fddb8 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -247,6 +247,8 @@ class t2InstAlias : InstAlias, Requires<[IsThumb2]>; class VFP2InstAlias : InstAlias, Requires<[HasVFP2]>; +class VFP2DPInstAlias + : InstAlias, Requires<[HasVFP2,HasDPVFP]>; class VFP3InstAlias : InstAlias, Requires<[HasVFP3]>; class NEONInstAlias @@ -1570,6 +1572,8 @@ class ADuI opcod1, bits<2> opcod2, bits<4> opcod3, bits<2> opcod4, let Inst{8} = 1; // Double precision let Inst{7-6} = opcod4; let Inst{4} = opcod5; + + let Predicates = [HasVFP2, HasDPVFP]; } // Double precision, unary, not-predicated @@ -1622,6 +1626,8 @@ class ADbI opcod1, bits<2> opcod2, bit op6, bit op4, dag oops, let Inst{8} = 1; // Double precision let Inst{6} = op6; let Inst{4} = op4; + + let Predicates = [HasVFP2, HasDPVFP]; } // FP, binary, not predicated @@ -1651,6 +1657,8 @@ class ADbInp opcod1, bits<2> opcod2, bit opcod3, dag oops, dag iops, let Inst{8} = 1; // double precision let Inst{6} = opcod3; let Inst{4} = 0; + + let Predicates = [HasVFP2, HasDPVFP]; } // Single precision, unary, predicated diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 01fce697005..a200ba44f5f 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -212,6 +212,9 @@ def HasVFP3 : Predicate<"Subtarget->hasVFP3()">, AssemblerPredicate<"FeatureVFP3", "VFP3">; def HasVFP4 : Predicate<"Subtarget->hasVFP4()">, AssemblerPredicate<"FeatureVFP4", "VFP4">; +def HasDPVFP : Predicate<"!Subtarget->isFPOnlySP()">, + AssemblerPredicate<"!FeatureVFPOnlySP", + "double precision VFP">; def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">, AssemblerPredicate<"FeatureFPARMv8", "FPARMv8">; def HasNEON : Predicate<"Subtarget->hasNEON()">, diff --git a/lib/Target/ARM/ARMInstrVFP.td b/lib/Target/ARM/ARMInstrVFP.td index e5ddf03e484..ff1087fe65c 100644 --- a/lib/Target/ARM/ARMInstrVFP.td +++ b/lib/Target/ARM/ARMInstrVFP.td @@ -346,7 +346,7 @@ multiclass vsel_inst opc, int CC> { (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"), [(set DPR:$Dd, (ARMcmov (f64 DPR:$Dm), (f64 DPR:$Dn), CC))]>, - Requires<[HasFPARMv8]>; + Requires<[HasFPARMv8, HasDPVFP]>; } } @@ -368,7 +368,7 @@ multiclass vmaxmin_inst { (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"), [(set DPR:$Dd, (f64 (SD (f64 DPR:$Dn), (f64 DPR:$Dm))))]>, - Requires<[HasFPARMv8]>; + Requires<[HasFPARMv8, HasDPVFP]>; } } @@ -377,7 +377,8 @@ defm VMINNM : vmaxmin_inst<"vminnm", 1, ARMvminnm>; // Match reassociated forms only if not sign dependent rounding. def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)), - (VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>; + (VNMULD DPR:$a, DPR:$b)>, + Requires<[NoHonorSignDependentRounding,HasDPVFP]>; def : Pat<(fmul (fneg SPR:$a), SPR:$b), (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>; @@ -508,6 +509,8 @@ def VCVTSD : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm, let Inst{11-8} = 0b1011; let Inst{7-6} = 0b11; let Inst{4} = 0; + + let Predicates = [HasVFP2, HasDPVFP]; } // Between half, single and double-precision. For disassembly only. @@ -538,7 +541,7 @@ def VCVTTSH: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm), def VCVTBHD : ADuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs DPR:$Dd), (ins SPR:$Sm), NoItinerary, "vcvtb", ".f64.f16\t$Dd, $Sm", - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { // Instruction operands. bits<5> Sm; @@ -550,7 +553,7 @@ def VCVTBHD : ADuI<0b11101, 0b11, 0b0010, 0b01, 0, def VCVTBDH : ADuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$Sd), (ins DPR:$Dm), NoItinerary, "vcvtb", ".f16.f64\t$Sd, $Dm", - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { // Instruction operands. bits<5> Sd; bits<5> Dm; @@ -565,7 +568,7 @@ def VCVTBDH : ADuI<0b11101, 0b11, 0b0011, 0b01, 0, def VCVTTHD : ADuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs DPR:$Dd), (ins SPR:$Sm), NoItinerary, "vcvtt", ".f64.f16\t$Dd, $Sm", - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { // Instruction operands. bits<5> Sm; @@ -577,7 +580,7 @@ def VCVTTHD : ADuI<0b11101, 0b11, 0b0010, 0b11, 0, def VCVTTDH : ADuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$Sd), (ins DPR:$Dm), NoItinerary, "vcvtt", ".f16.f64\t$Sd, $Dm", - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { // Instruction operands. bits<5> Sd; bits<5> Dm; @@ -608,7 +611,7 @@ multiclass vcvt_inst rm> { def SD : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0, (outs SPR:$Sd), (ins DPR:$Dm), NoItinerary, !strconcat("vcvt", opc, ".s32.f64\t$Sd, $Dm"), - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { bits<5> Dm; let Inst{17-16} = rm; @@ -622,7 +625,7 @@ multiclass vcvt_inst rm> { def UD : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0, (outs SPR:$Sd), (ins DPR:$Dm), NoItinerary, !strconcat("vcvt", opc, ".u32.f64\t$Sd, $Dm"), - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { bits<5> Dm; let Inst{17-16} = rm; @@ -665,7 +668,7 @@ multiclass vrint_inst_zrx { def D : ADuI<0b11101, 0b11, 0b0110, 0b11, 0, (outs DPR:$Dd), (ins DPR:$Dm), NoItinerary, !strconcat("vrint", opc), ".f64\t$Dd, $Dm", - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { let Inst{7} = op2; let Inst{16} = op; } @@ -675,7 +678,7 @@ multiclass vrint_inst_zrx { Requires<[HasFPARMv8]>; def : InstAlias(NAME#"D") DPR:$Dd, DPR:$Dm, pred:$p)>, - Requires<[HasFPARMv8]>; + Requires<[HasFPARMv8,HasDPVFP]>; } defm VRINTZ : vrint_inst_zrx<"z", 0, 1>; @@ -693,7 +696,7 @@ multiclass vrint_inst_anpm rm> { def D : ADuInp<0b11101, 0b11, 0b1000, 0b01, 0, (outs DPR:$Dd), (ins DPR:$Dm), NoItinerary, !strconcat("vrint", opc, ".f64\t$Dd, $Dm"), - []>, Requires<[HasFPARMv8]> { + []>, Requires<[HasFPARMv8, HasDPVFP]> { let Inst{17-16} = rm; } } @@ -703,7 +706,7 @@ multiclass vrint_inst_anpm rm> { Requires<[HasFPARMv8]>; def : InstAlias(NAME#"D") DPR:$Dd, DPR:$Dm)>, - Requires<[HasFPARMv8]>; + Requires<[HasFPARMv8,HasDPVFP]>; } defm VRINTA : vrint_inst_anpm<"a", 0b00>; @@ -900,6 +903,8 @@ class AVConv1IDs_Encode opcod1, bits<2> opcod2, bits<4> opcod3, let Inst{5} = Sm{0}; let Inst{15-12} = Dd{3-0}; let Inst{22} = Dd{4}; + + let Predicates = [HasVFP2, HasDPVFP]; } class AVConv1InSs_Encode opcod1, bits<2> opcod2, bits<4> opcod3, @@ -971,6 +976,8 @@ class AVConv1IsD_Encode opcod1, bits<2> opcod2, bits<4> opcod3, let Inst{5} = Dm{4}; let Inst{15-12} = Sd{4-1}; let Inst{22} = Sd{0}; + + let Predicates = [HasVFP2, HasDPVFP]; } class AVConv1InsS_Encode opcod1, bits<2> opcod2, bits<4> opcod3, @@ -1092,6 +1099,8 @@ class AVConv1XInsD_Encode op1, bits<2> op2, bits<4> op3, bits<4> op4, // if dp_operation then UInt(D:Vd) else UInt(Vd:D); let Inst{22} = dst{4}; let Inst{15-12} = dst{3-0}; + + let Predicates = [HasVFP2, HasDPVFP]; } def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0, @@ -1204,7 +1213,7 @@ def VMLAD : ADbI<0b11100, 0b00, 0, 0, [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def VMLAS : ASbIn<0b11100, 0b00, 0, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1220,7 +1229,7 @@ def VMLAS : ASbIn<0b11100, 0b00, 0, 0, def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP2,DontUseNEONForFP, UseFPVMLx,DontUseFusedMAC]>; @@ -1231,7 +1240,7 @@ def VMLSD : ADbI<0b11100, 0b00, 1, 0, [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def VMLSS : ASbIn<0b11100, 0b00, 1, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1247,7 +1256,7 @@ def VMLSS : ASbIn<0b11100, 0b00, 1, 0, def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>; @@ -1258,7 +1267,7 @@ def VNMLAD : ADbI<0b11100, 0b01, 1, 0, [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def VNMLAS : ASbI<0b11100, 0b01, 1, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1274,7 +1283,7 @@ def VNMLAS : ASbI<0b11100, 0b01, 1, 0, def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>; @@ -1285,7 +1294,7 @@ def VNMLSD : ADbI<0b11100, 0b01, 0, 0, [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def VNMLSS : ASbI<0b11100, 0b01, 0, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1300,7 +1309,7 @@ def VNMLSS : ASbI<0b11100, 0b01, 0, 0, def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP2,UseFPVMLx,DontUseFusedMAC]>; + Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>; @@ -1314,7 +1323,7 @@ def VFMAD : ADbI<0b11101, 0b10, 0, 0, [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def VFMAS : ASbIn<0b11101, 0b10, 0, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1329,7 +1338,7 @@ def VFMAS : ASbIn<0b11101, 0b10, 0, 0, def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), (VFMAD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; @@ -1338,7 +1347,7 @@ def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), // (fma x, y, z) -> (vfms z, x, y) def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, DPR:$Ddin)), (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, SPR:$Sdin)), (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; @@ -1349,7 +1358,7 @@ def VFMSD : ADbI<0b11101, 0b10, 1, 0, [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def VFMSS : ASbIn<0b11101, 0b10, 1, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1364,7 +1373,7 @@ def VFMSS : ASbIn<0b11101, 0b10, 1, 0, def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), (VFMSD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), (VFMSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; @@ -1373,14 +1382,14 @@ def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), // (fma (fneg x), y, z) -> (vfms z, x, y) def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin)), (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin)), (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; // (fma x, (fneg y), z) -> (vfms z, x, y) def : Pat<(f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin)), (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin)), (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; @@ -1391,7 +1400,7 @@ def VFNMAD : ADbI<0b11101, 0b01, 1, 0, [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def VFNMAS : ASbI<0b11101, 0b01, 1, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1406,7 +1415,7 @@ def VFNMAS : ASbI<0b11101, 0b01, 1, 0, def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), (VFNMAD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), (VFNMAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; @@ -1415,14 +1424,14 @@ def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), // (fneg (fma x, y, z)) -> (vfnma z, x, y) def : Pat<(fneg (fma (f64 DPR:$Dn), (f64 DPR:$Dm), (f64 DPR:$Ddin))), (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(fneg (fma (f32 SPR:$Sn), (f32 SPR:$Sm), (f32 SPR:$Sdin))), (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; // (fma (fneg x), y, (fneg z)) -> (vfnma z, x, y) def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, (fneg DPR:$Ddin))), (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, (fneg SPR:$Sdin))), (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; @@ -1433,7 +1442,7 @@ def VFNMSD : ADbI<0b11101, 0b01, 0, 0, [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), (f64 DPR:$Ddin)))]>, RegConstraint<"$Ddin = $Dd">, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def VFNMSS : ASbI<0b11101, 0b01, 0, 0, (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), @@ -1447,7 +1456,7 @@ def VFNMSS : ASbI<0b11101, 0b01, 0, 0, def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), (VFNMSD DPR:$dstin, DPR:$a, DPR:$b)>, - Requires<[HasVFP4,UseFusedMAC]>; + Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), (VFNMSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; @@ -1457,21 +1466,21 @@ def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), // (fma x, y, (fneg z)) -> (vfnms z, x, y)) def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, (fneg DPR:$Ddin))), (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, (fneg SPR:$Sdin))), (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; // (fneg (fma (fneg x), y, z)) -> (vfnms z, x, y) def : Pat<(fneg (f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin))), (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(fneg (f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin))), (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; // (fneg (fma x, (fneg y), z) -> (vfnms z, x, y) def : Pat<(fneg (f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin))), (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, - Requires<[HasVFP4]>; + Requires<[HasVFP4,HasDPVFP]>; def : Pat<(fneg (f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin))), (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, Requires<[HasVFP4]>; @@ -1485,7 +1494,7 @@ def VMOVDcc : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p), IIC_fpUNA64, [(set (f64 DPR:$Dd), (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>, - RegConstraint<"$Dn = $Dd">, Requires<[HasVFP2]>; + RegConstraint<"$Dn = $Dd">, Requires<[HasVFP2,HasDPVFP]>; def VMOVScc : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p), IIC_fpUNA32, @@ -1590,7 +1599,8 @@ let isReMaterializable = 1 in { def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm), VFPMiscFrm, IIC_fpUNA64, "vmov", ".f64\t$Dd, $imm", - [(set DPR:$Dd, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> { + [(set DPR:$Dd, vfp_f64imm:$imm)]>, + Requires<[HasVFP3,HasDPVFP]> { bits<5> Dd; bits<8> imm; @@ -1672,23 +1682,23 @@ def : VFP2MnemonicAlias<"fmrx", "vmrs">; def : VFP2MnemonicAlias<"fmxr", "vmsr">; // Be friendly and accept the old form of zero-compare -def : VFP2InstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>; +def : VFP2DPInstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>; def : VFP2InstAlias<"fcmpzs${p} $val", (VCMPZS SPR:$val, pred:$p)>; def : VFP2InstAlias<"fmstat${p}", (FMSTAT pred:$p)>; def : VFP2InstAlias<"fadds${p} $Sd, $Sn, $Sm", (VADDS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; -def : VFP2InstAlias<"faddd${p} $Dd, $Dn, $Dm", - (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; +def : VFP2DPInstAlias<"faddd${p} $Dd, $Dn, $Dm", + (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; def : VFP2InstAlias<"fsubs${p} $Sd, $Sn, $Sm", (VSUBS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; -def : VFP2InstAlias<"fsubd${p} $Dd, $Dn, $Dm", - (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; +def : VFP2DPInstAlias<"fsubd${p} $Dd, $Dn, $Dm", + (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; // No need for the size suffix on VSQRT. It's implied by the register classes. def : VFP2InstAlias<"vsqrt${p} $Sd, $Sm", (VSQRTS SPR:$Sd, SPR:$Sm, pred:$p)>; -def : VFP2InstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>; +def : VFP2DPInstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>; // VLDR/VSTR accept an optional type suffix. def : VFP2InstAlias<"vldr${p}.32 $Sd, $addr", diff --git a/test/MC/ARM/single-precision-fp.s b/test/MC/ARM/single-precision-fp.s new file mode 100644 index 00000000000..84e096d7d2b --- /dev/null +++ b/test/MC/ARM/single-precision-fp.s @@ -0,0 +1,192 @@ +@ RUN: not llvm-mc < %s -triple thumbv8-unknown-unknown -show-encoding -mattr=+fp-only-sp,-neon 2> %t > %t2 +@ RUN: FileCheck %s < %t --check-prefix=CHECK-ERRORS +@ RUN: FileCheck %s < %t2 + + vadd.f64 d0, d1, d2 + vsub.f64 d2, d3, d4 + vdiv.f64 d4, d5, d6 + vmul.f64 d6, d7, d8 + vnmul.f64 d8, d9, d10 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vadd.f64 d0, d1, d2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vsub.f64 d2, d3, d4 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vdiv.f64 d4, d5, d6 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vmul.f64 d6, d7, d8 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vnmul.f64 d8, d9, d10 + + vmla.f64 d11, d10, d9 + vmls.f64 d8, d7, d6 + vnmla.f64 d5, d4, d3 + vnmls.f64 d2, d1, d0 + vfma.f64 d1, d2, d3 + vfms.f64 d4, d5, d6 + vfnma.f64 d7, d8, d9 + vfnms.f64 d10, d11, d12 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vmla.f64 d11, d10, d9 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vmls.f64 d8, d7, d6 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vnmla.f64 d5, d4, d3 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vnmls.f64 d2, d1, d0 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vfma.f64 d1, d2, d3 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vfms.f64 d4, d5, d6 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vfnma.f64 d7, d8, d9 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vfnms.f64 d10, d11, d12 + + vneg.f64 d15, d14 + vsqrt.f64 d13, d12 + vsqrt d13, d14 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vneg.f64 d15, d14 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vsqrt.f64 d13, d12 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vsqrt d13, d14 + + vcmpe.f64 d0, d1 + vcmp.f64 d2, d3 + vabs.f64 d4, d5 + vcmpe.f64 d5, #0 + vcmp.f64 d6, #0 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcmpe.f64 d0, d1 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcmp.f64 d2, d3 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vabs.f64 d4, d5 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcmpe.f64 d5, #0 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcmp.f64 d6, #0 + + vmov.f64 d11, d10 +@ CHECK-ERRORS: error: instruction requires: NEON +@ CHECK-ERRORS-NEXT: vmov.f64 d11, d10 + + vcvt.f64.s32 d9, s8 + vcvt.f64.u32 d7, s6 + vcvt.s32.f64 s5, d4 + vcvt.u32.f64 s3, d2 + vcvtr.s32.f64 s1, d0 + vcvtr.u32.f64 s1, d2 + vcvt.s16.f64 d3, d4, #1 + vcvt.u16.f64 d5, d6, #2 + vcvt.s32.f64 d7, d8, #3 + vcvt.u32.f64 d9, d10, #4 + vcvt.f64.s16 d11, d12, #3 + vcvt.f64.u16 d13, d14, #2 + vcvt.f64.s32 d15, d14, #1 + vcvt.f64.u32 d13, d12, #1 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.f64.s32 d9, s8 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.f64.u32 d7, s6 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.s32.f64 s5, d4 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.u32.f64 s3, d2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvtr.s32.f64 s1, d0 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvtr.u32.f64 s1, d2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.s16.f64 d3, d4, #1 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.u16.f64 d5, d6, #2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.s32.f64 d7, d8, #3 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.u32.f64 d9, d10, #4 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.f64.s16 d11, d12, #3 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.f64.u16 d13, d14, #2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.f64.s32 d15, d14, #1 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvt.f64.u32 d13, d12, #1 + + @ v8 operations, also double precision so make sure they're rejected. + vselgt.f64 d0, d1, d2 + vselge.f64 d3, d4, d5 + vseleq.f64 d6, d7, d8 + vselvs.f64 d9, d10, d11 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vselgt.f64 d0, d1, d2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vselge.f64 d3, d4, d5 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vseleq.f64 d6, d7, d8 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vselvs.f64 d9, d10, d11 + + vmaxnm.f64 d12, d13, d14 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vmaxnm.f64 d12, d13, d14 + + vcvtb.f64.f16 d7, s8 + vcvtb.f16.f64 s9, d10 + vcvtt.f64.f16 d11, s12 + vcvtt.f16.f64 s13, d14 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvtb.f64.f16 d7, s8 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvtb.f16.f64 s9, d10 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvtt.f64.f16 d11, s12 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vcvtt.f16.f64 s13, d14 + + vrintz.f64 d15, d14 + vrintr.f64.f64 d13, d12 + vrintx.f64 d11, d10 + vrinta.f64.f64 d9, d8 + vrintn.f64 d7, d6 + vrintp.f64.f64 d5, d4 + vrintm.f64 d3, d2 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrintz.f64 d15, d14 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrintr.f64.f64 d13, d12 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrintx.f64 d11, d10 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrinta.f64.f64 d9, d8 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrintn.f64 d7, d6 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrintp.f64.f64 d5, d4 +@ CHECK-ERRORS: error: instruction requires: double precision VFP +@ CHECK-ERRORS-NEXT: vrintm.f64 d3, d2 + + @ Double precisionish operations that actually *are* allowed. + vldr d0, [sp] + vstr d3, [sp] + vldm r0, {d0, d1} + vstm r4, {d3, d4} + vpush {d6, d7} + vpop {d8, d9} + vmov r1, r0, d1 + vmov d2, r3, r4 + vmov.f64 r5, r6, d7 + vmov.f64 d8, r9, r10 +@ CHECK: vldr d0, [sp] +@ CHECK: vstr d3, [sp] +@ CHECK: vldmia r0, {d0, d1} +@ CHECK: vstmia r4, {d3, d4} +@ CHECK: vpush {d6, d7} +@ CHECK: vpop {d8, d9} +@ CHECK: vmov r1, r0, d1 +@ CHECK: vmov d2, r3, r4 +@ CHECK: vmov r5, r6, d7 +@ CHECK: vmov d8, r9, r10 diff --git a/test/MC/ARM/vfp4.s b/test/MC/ARM/vfp4.s index 53d97a44fd4..8b1b0e0c538 100644 --- a/test/MC/ARM/vfp4.s +++ b/test/MC/ARM/vfp4.s @@ -6,6 +6,8 @@ @ ARM: vfma.f64 d16, d18, d17 @ encoding: [0xa1,0x0b,0xe2,0xee] @ THUMB: vfma.f64 d16, d18, d17 @ encoding: [0xe2,0xee,0xa1,0x0b] +@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP +@ THUMB_V7EM-ERRORS-NEXT: vfma.f64 d16, d18, d17 vfma.f64 d16, d18, d17 @ ARM: vfma.f32 s2, s4, s0 @ encoding: [0x00,0x1a,0xa2,0xee] @@ -27,6 +29,8 @@ vfma.f32 q2, q4, q0 @ ARM: vfnma.f64 d16, d18, d17 @ encoding: [0xe1,0x0b,0xd2,0xee] @ THUMB: vfnma.f64 d16, d18, d17 @ encoding: [0xd2,0xee,0xe1,0x0b] +@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP +@ THUMB_V7EM-ERRORS-NEXT: vfnma.f64 d16, d18, d17 vfnma.f64 d16, d18, d17 @ ARM: vfnma.f32 s2, s4, s0 @ encoding: [0x40,0x1a,0x92,0xee] @@ -36,6 +40,8 @@ vfnma.f32 s2, s4, s0 @ ARM: vfms.f64 d16, d18, d17 @ encoding: [0xe1,0x0b,0xe2,0xee] @ THUMB: vfms.f64 d16, d18, d17 @ encoding: [0xe2,0xee,0xe1,0x0b] +@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP +@ THUMB_V7EM-ERRORS-NEXT: vfms.f64 d16, d18, d17 vfms.f64 d16, d18, d17 @ ARM: vfms.f32 s2, s4, s0 @ encoding: [0x40,0x1a,0xa2,0xee] @@ -57,6 +63,8 @@ vfms.f32 q2, q4, q0 @ ARM: vfnms.f64 d16, d18, d17 @ encoding: [0xa1,0x0b,0xd2,0xee] @ THUMB: vfnms.f64 d16, d18, d17 @ encoding: [0xd2,0xee,0xa1,0x0b] +@ THUMB_V7EM-ERRORS: error: instruction requires: double precision VFP +@ THUMB_V7EM-ERRORS-NEXT: vfnms.f64 d16, d18, d17 vfnms.f64 d16, d18, d17 @ ARM: vfnms.f32 s2, s4, s0 @ encoding: [0x00,0x1a,0x92,0xee]