]> granicus.if.org Git - llvm/commitdiff
[mips] Add the SoftFloat MipsSubtarget feature.
authorToma Tabacu <toma.tabacu@imgtec.com>
Thu, 7 May 2015 10:29:52 +0000 (10:29 +0000)
committerToma Tabacu <toma.tabacu@imgtec.com>
Thu, 7 May 2015 10:29:52 +0000 (10:29 +0000)
Summary: This will enable the IAS to reject floating point instructions if soft-float is enabled.

Reviewers: dsanders, echristo

Reviewed By: dsanders

Subscribers: jfb, llvm-commits, mpf

Differential Revision: http://reviews.llvm.org/D9053

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236713 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
lib/Target/Mips/AsmParser/MipsAsmParser.cpp
lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.cpp
lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h
lib/Target/Mips/Mips.td
lib/Target/Mips/Mips16ISelLowering.cpp
lib/Target/Mips/Mips32r6InstrInfo.td
lib/Target/Mips/MipsCondMov.td
lib/Target/Mips/MipsInstrFPU.td
lib/Target/Mips/MipsSubtarget.cpp
lib/Target/Mips/MipsSubtarget.h
lib/Target/Mips/MipsTargetMachine.cpp
test/MC/Mips/target-soft-float.s [new file with mode: 0644]

index 7046b7053e8247c20c4b93ee6e916c81797ff8ed..1aa895d9ca88f66a2a35bd841880a5ac68bb96d0 100644 (file)
@@ -433,8 +433,10 @@ public:
   bool inMips16Mode() const {
     return STI.getFeatureBits() & Mips::FeatureMips16;
   }
-  // TODO: see how can we get this info.
-  bool abiUsesSoftFloat() const { return false; }
+
+  bool abiUsesSoftFloat() const {
+    return (STI.getFeatureBits() & Mips::FeatureSoftFloat);
+  }
 
   /// Warn if RegIndex is the same as the current AT.
   void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
index 5b0f950b076ed906bef08aad3789d5501fe5299a..897e70033da801fccedb5e45f626c40a219b37e2 100644 (file)
@@ -15,6 +15,8 @@ uint8_t MipsABIFlagsSection::getFpABIValue() {
   switch (FpABI) {
   case FpABIKind::ANY:
     return Val_GNU_MIPS_ABI_FP_ANY;
+  case FpABIKind::SOFT:
+    return Val_GNU_MIPS_ABI_FP_SOFT;
   case FpABIKind::XX:
     return Val_GNU_MIPS_ABI_FP_XX;
   case FpABIKind::S32:
index 473f4f244d07a730631e45259b24fbef9f75b7d9..04189bedc6b13f5b0a2297e8f68507bd1fbf5378 100644 (file)
@@ -68,6 +68,7 @@ struct MipsABIFlagsSection {
   enum Val_GNU_MIPS_ABI {
     Val_GNU_MIPS_ABI_FP_ANY = 0,
     Val_GNU_MIPS_ABI_FP_DOUBLE = 1,
+    Val_GNU_MIPS_ABI_FP_SOFT = 3,
     Val_GNU_MIPS_ABI_FP_XX = 5,
     Val_GNU_MIPS_ABI_FP_64 = 6,
     Val_GNU_MIPS_ABI_FP_64A = 7
@@ -77,8 +78,8 @@ struct MipsABIFlagsSection {
     AFL_FLAGS1_ODDSPREG = 1
   };
 
-  // Internal representation of the values used in .module fp=value
-  enum class FpABIKind { ANY, XX, S32, S64 };
+  // Internal representation of the fp_abi related values used in .module.
+  enum class FpABIKind { ANY, XX, S32, S64, SOFT };
 
   // Version of flags structure.
   uint16_t Version;
@@ -217,7 +218,9 @@ public:
     Is32BitABI = P.isABI_O32();
 
     FpABI = FpABIKind::ANY;
-    if (P.isABI_N32() || P.isABI_N64())
+    if (P.abiUsesSoftFloat())
+      FpABI = FpABIKind::SOFT;
+    else if (P.isABI_N32() || P.isABI_N64())
       FpABI = FpABIKind::S64;
     else if (P.isABI_O32()) {
       if (P.isABI_FPXX())
index ca2474101ec6c085aa13ab38158069be83290e94..dbb5f7b71d8275918b5cfd885559234580e445cf 100644 (file)
@@ -28,12 +28,15 @@ class PredicateControl {
   list<Predicate> FGRPredicates = [];
   // Predicates for the instruction group membership such as ISA's and ASE's
   list<Predicate> InsnPredicates = [];
+  // Predicate for marking the instruction as usable in hard-float mode only.
+  list<Predicate> HardFloatPredicate = [];
   // Predicates for anything else
   list<Predicate> AdditionalPredicates = [];
   list<Predicate> Predicates = !listconcat(EncodingPredicates,
                                            GPRPredicates,
                                            FGRPredicates,
                                            InsnPredicates,
+                                           HardFloatPredicate,
                                            AdditionalPredicates);
 }
 
@@ -69,6 +72,8 @@ def FeatureNaN2008     : SubtargetFeature<"nan2008", "IsNaN2008bit", "true",
                                 "IEEE 754-2008 NaN encoding">;
 def FeatureSingleFloat : SubtargetFeature<"single-float", "IsSingleFloat",
                                 "true", "Only supports single precision float">;
+def FeatureSoftFloat   : SubtargetFeature<"soft-float", "IsSoftFloat", "true",
+                                "Does not support floating point instructions">;
 def FeatureNoOddSPReg  : SubtargetFeature<"nooddspreg", "UseOddSPReg", "false",
                               "Disable odd numbered single-precision "
                               "registers">;
index ede4f3748f154d723b67306c31893431b21abb2c..3e72c13ee02b4dcc659a1c56ea5b626064c8a27d 100644 (file)
@@ -127,7 +127,7 @@ Mips16TargetLowering::Mips16TargetLowering(const MipsTargetMachine &TM,
   // Set up the register classes
   addRegisterClass(MVT::i32, &Mips::CPU16RegsRegClass);
 
-  if (!TM.Options.UseSoftFloat)
+  if (!Subtarget.abiUsesSoftFloat())
     setMips16HardFloatLibCalls();
 
   setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Expand);
index 62c55144779c1a73e47138e4ab15de7e0af105d1..485a3e13972e476f72055504d9edbcfd4f490aa8 100644 (file)
@@ -188,52 +188,52 @@ multiclass CMP_CC_M <FIELD_CMP_FORMAT Format, string Typestr,
                      RegisterOperand FGROpnd>{
   def CMP_F_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_AF>,
                     CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>,
-                    ISA_MIPS32R6;
+                    ISA_MIPS32R6, HARDFLOAT;
   def CMP_UN_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_UN>,
                      CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd, setuo>,
-                     ISA_MIPS32R6;
+                     ISA_MIPS32R6, HARDFLOAT;
   def CMP_EQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_EQ>,
                      CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd, setoeq>,
-                     ISA_MIPS32R6;
+                     ISA_MIPS32R6, HARDFLOAT;
   def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_UEQ>,
                       CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd, setueq>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_LT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_LT>,
                      CMP_CONDN_DESC_BASE<"lt", Typestr, FGROpnd, setolt>,
-                     ISA_MIPS32R6;
+                     ISA_MIPS32R6, HARDFLOAT;
   def CMP_ULT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_ULT>,
                       CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd, setult>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_LE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_LE>,
                      CMP_CONDN_DESC_BASE<"le", Typestr, FGROpnd, setole>,
-                     ISA_MIPS32R6;
+                     ISA_MIPS32R6, HARDFLOAT;
   def CMP_ULE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_ULE>,
                       CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd, setule>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_SAF_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SAF>,
                       CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_SUN_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SUN>,
                       CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_SEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SEQ>,
                       CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_SUEQ_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SUEQ>,
                        CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd>,
-                       ISA_MIPS32R6;
+                       ISA_MIPS32R6, HARDFLOAT;
   def CMP_SLT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SLT>,
                       CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_SULT_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SULT>,
                        CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd>,
-                       ISA_MIPS32R6;
+                       ISA_MIPS32R6, HARDFLOAT;
   def CMP_SLE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SLE>,
                       CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd>,
-                      ISA_MIPS32R6;
+                      ISA_MIPS32R6, HARDFLOAT;
   def CMP_SULE_#NAME : COP1_CMP_CONDN_FM<Format, FIELD_CMP_COND_SULE>,
                        CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>,
-                       ISA_MIPS32R6;
+                       ISA_MIPS32R6, HARDFLOAT;
 }
 
 //===----------------------------------------------------------------------===//
@@ -651,8 +651,8 @@ def AUI : AUI_ENC, AUI_DESC, ISA_MIPS32R6;
 def AUIPC : AUIPC_ENC, AUIPC_DESC, ISA_MIPS32R6;
 def BAL : BAL_ENC, BAL_DESC, ISA_MIPS32R6;
 def BALC : R6MMR6Rel, BALC_ENC, BALC_DESC, ISA_MIPS32R6;
-def BC1EQZ : BC1EQZ_ENC, BC1EQZ_DESC, ISA_MIPS32R6;
-def BC1NEZ : BC1NEZ_ENC, BC1NEZ_DESC, ISA_MIPS32R6;
+def BC1EQZ : BC1EQZ_ENC, BC1EQZ_DESC, ISA_MIPS32R6, HARDFLOAT;
+def BC1NEZ : BC1NEZ_ENC, BC1NEZ_DESC, ISA_MIPS32R6, HARDFLOAT;
 def BC2EQZ : BC2EQZ_ENC, BC2EQZ_DESC, ISA_MIPS32R6;
 def BC2NEZ : BC2NEZ_ENC, BC2NEZ_DESC, ISA_MIPS32R6;
 def BC : R6MMR6Rel, BC_ENC, BC_DESC, ISA_MIPS32R6;
@@ -678,8 +678,8 @@ def BNEZC : BNEZC_ENC, BNEZC_DESC, ISA_MIPS32R6;
 def BNVC : BNVC_ENC, BNVC_DESC, ISA_MIPS32R6;
 def BOVC : BOVC_ENC, BOVC_DESC, ISA_MIPS32R6;
 def CACHE_R6 : R6MMR6Rel, CACHE_ENC, CACHE_DESC, ISA_MIPS32R6;
-def CLASS_D : CLASS_D_ENC, CLASS_D_DESC, ISA_MIPS32R6;
-def CLASS_S : CLASS_S_ENC, CLASS_S_DESC, ISA_MIPS32R6;
+def CLASS_D : CLASS_D_ENC, CLASS_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def CLASS_S : CLASS_S_ENC, CLASS_S_DESC, ISA_MIPS32R6, HARDFLOAT;
 def CLO_R6 : CLO_R6_ENC, CLO_R6_DESC, ISA_MIPS32R6;
 def CLZ_R6 : CLZ_R6_ENC, CLZ_R6_DESC, ISA_MIPS32R6;
 defm S : CMP_CC_M<FIELD_CMP_FORMAT_S, "s", FGR32Opnd>;
@@ -695,39 +695,39 @@ def LSA_R6 : LSA_R6_ENC, LSA_R6_DESC, ISA_MIPS32R6;
 def LWC2_R6 : LWC2_R6_ENC, LWC2_R6_DESC, ISA_MIPS32R6;
 def LWPC : LWPC_ENC, LWPC_DESC, ISA_MIPS32R6;
 def LWUPC : LWUPC_ENC, LWUPC_DESC, ISA_MIPS32R6;
-def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6;
-def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6;
-def MAXA_D : MAXA_D_ENC, MAXA_D_DESC, ISA_MIPS32R6;
-def MAXA_S : MAXA_S_ENC, MAXA_S_DESC, ISA_MIPS32R6;
-def MAX_D : MAX_D_ENC, MAX_D_DESC, ISA_MIPS32R6;
-def MAX_S : MAX_S_ENC, MAX_S_DESC, ISA_MIPS32R6;
-def MINA_D : MINA_D_ENC, MINA_D_DESC, ISA_MIPS32R6;
-def MINA_S : MINA_S_ENC, MINA_S_DESC, ISA_MIPS32R6;
-def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6;
-def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6;
+def MADDF_S : MADDF_S_ENC, MADDF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MAXA_D  : MAXA_D_ENC, MAXA_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MAXA_S  : MAXA_S_ENC, MAXA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MAX_D   : MAX_D_ENC, MAX_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MAX_S   : MAX_S_ENC, MAX_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MINA_D  : MINA_D_ENC, MINA_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MINA_S  : MINA_S_ENC, MINA_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MIN_D   : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MIN_S   : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, HARDFLOAT;
 def MOD : MOD_ENC, MOD_DESC, ISA_MIPS32R6;
 def MODU : MODU_ENC, MODU_DESC, ISA_MIPS32R6;
-def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6;
-def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6;
+def MSUBF_S : MSUBF_S_ENC, MSUBF_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, HARDFLOAT;
 def MUH    : R6MMR6Rel, MUH_ENC, MUH_DESC, ISA_MIPS32R6;
 def MUHU   : R6MMR6Rel, MUHU_ENC, MUHU_DESC, ISA_MIPS32R6;
 def MUL_R6 : R6MMR6Rel, MUL_R6_ENC, MUL_R6_DESC, ISA_MIPS32R6;
 def MULU   : R6MMR6Rel, MULU_ENC, MULU_DESC, ISA_MIPS32R6;
 def NAL; // BAL with rd=0
 def PREF_R6 : R6MMR6Rel, PREF_ENC, PREF_DESC, ISA_MIPS32R6;
-def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6;
-def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6;
+def RINT_D : RINT_D_ENC, RINT_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, HARDFLOAT;
 def SC_R6 : SC_R6_ENC, SC_R6_DESC, ISA_MIPS32R6;
 def SDBBP_R6 : SDBBP_R6_ENC, SDBBP_R6_DESC, ISA_MIPS32R6;
 def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6;
 def SELEQZ : SELEQZ_ENC, SELEQZ_DESC, ISA_MIPS32R6, GPR_32;
-def SELEQZ_D : SELEQZ_D_ENC, SELEQZ_D_DESC, ISA_MIPS32R6;
-def SELEQZ_S : SELEQZ_S_ENC, SELEQZ_S_DESC, ISA_MIPS32R6;
+def SELEQZ_D : SELEQZ_D_ENC, SELEQZ_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def SELEQZ_S : SELEQZ_S_ENC, SELEQZ_S_DESC, ISA_MIPS32R6, HARDFLOAT;
 def SELNEZ : SELNEZ_ENC, SELNEZ_DESC, ISA_MIPS32R6, GPR_32;
-def SELNEZ_D : SELNEZ_D_ENC, SELNEZ_D_DESC, ISA_MIPS32R6;
-def SELNEZ_S : SELNEZ_S_ENC, SELNEZ_S_DESC, ISA_MIPS32R6;
-def SEL_D : SEL_D_ENC, SEL_D_DESC, ISA_MIPS32R6;
-def SEL_S : SEL_S_ENC, SEL_S_DESC, ISA_MIPS32R6;
+def SELNEZ_D : SELNEZ_D_ENC, SELNEZ_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def SELNEZ_S : SELNEZ_S_ENC, SELNEZ_S_DESC, ISA_MIPS32R6, HARDFLOAT;
+def SEL_D    : SEL_D_ENC, SEL_D_DESC, ISA_MIPS32R6, HARDFLOAT;
+def SEL_S    : SEL_S_ENC, SEL_S_DESC, ISA_MIPS32R6, HARDFLOAT;
 def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6;
 
 //===----------------------------------------------------------------------===//
index af10cd4e576cb36a96610afdbde6afa0fb374e4a..2d96d9b48c0b043c56ea1932833a810030daf4f1 100644 (file)
@@ -27,7 +27,8 @@ class CMov_I_I_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC,
 class CMov_I_F_FT<string opstr, RegisterOperand CRC, RegisterOperand DRC,
                   InstrItinClass Itin> :
   InstSE<(outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F),
-         !strconcat(opstr, "\t$fd, $fs, $rt"), [], Itin, FrmFR, opstr> {
+         !strconcat(opstr, "\t$fd, $fs, $rt"), [], Itin, FrmFR, opstr>,
+  HARDFLOAT {
   let Constraints = "$F = $fd";
 }
 
@@ -37,7 +38,7 @@ class CMov_F_I_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
   InstSE<(outs RC:$rd), (ins RC:$rs, FCCRegsOpnd:$fcc, RC:$F),
          !strconcat(opstr, "\t$rd, $rs, $fcc"),
          [(set RC:$rd, (OpNode RC:$rs, FCCRegsOpnd:$fcc, RC:$F))],
-         Itin, FrmFR, opstr> {
+         Itin, FrmFR, opstr>, HARDFLOAT {
   let Constraints = "$F = $rd";
 }
 
@@ -47,7 +48,7 @@ class CMov_F_F_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
   InstSE<(outs RC:$fd), (ins RC:$fs, FCCRegsOpnd:$fcc, RC:$F),
          !strconcat(opstr, "\t$fd, $fs, $fcc"),
          [(set RC:$fd, (OpNode RC:$fs, FCCRegsOpnd:$fcc, RC:$F))],
-         Itin, FrmFR, opstr> {
+         Itin, FrmFR, opstr>, HARDFLOAT {
   let Constraints = "$F = $fd";
 }
 
index 7b7ef9194e5f81fdc5f56a91c4da398b4e564ae8..848cebcb99716f2b147a80ae991d37e9e289b800 100644 (file)
@@ -65,6 +65,8 @@ def IsSingleFloat    : Predicate<"Subtarget->isSingleFloat()">,
                        AssemblerPredicate<"FeatureSingleFloat">;
 def IsNotSingleFloat : Predicate<"!Subtarget->isSingleFloat()">,
                        AssemblerPredicate<"!FeatureSingleFloat">;
+def IsNotSoftFloat   : Predicate<"!Subtarget->abiUsesSoftFloat()">,
+                       AssemblerPredicate<"!FeatureSoftFloat">;
 
 //===----------------------------------------------------------------------===//
 // Mips FGR size adjectives.
@@ -73,6 +75,7 @@ def IsNotSingleFloat : Predicate<"!Subtarget->isSingleFloat()">,
 
 class FGR_32 { list<Predicate> FGRPredicates = [NotFP64bit]; }
 class FGR_64 { list<Predicate> FGRPredicates = [IsFP64bit]; }
+class HARDFLOAT { list<Predicate> HardFloatPredicate = [IsNotSoftFloat]; }
 
 //===----------------------------------------------------------------------===//
 
@@ -98,12 +101,12 @@ def fpimm0neg : PatLeaf<(fpimm), [{
 //
 // Only S32 and D32 are supported right now.
 //===----------------------------------------------------------------------===//
-
 class ADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin, bit IsComm,
               SDPatternOperator OpNode= null_frag> :
   InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft),
          !strconcat(opstr, "\t$fd, $fs, $ft"),
-         [(set RC:$fd, (OpNode RC:$fs, RC:$ft))], Itin, FrmFR, opstr> {
+         [(set RC:$fd, (OpNode RC:$fs, RC:$ft))], Itin, FrmFR, opstr>,
+  HARDFLOAT {
   let isCommutable = IsComm;
 }
 
@@ -122,6 +125,7 @@ class ABSS_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
               InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
   InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"),
          [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>,
+  HARDFLOAT,
   NeverHasSideEffects;
 
 multiclass ABSS_M<string opstr, InstrItinClass Itin,
@@ -146,17 +150,17 @@ multiclass ROUND_M<string opstr, InstrItinClass Itin> {
 class MFC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
               InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
   InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"),
-         [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>;
+         [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>, HARDFLOAT;
 
 class MTC1_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
               InstrItinClass Itin, SDPatternOperator OpNode= null_frag> :
   InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"),
-         [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR, opstr>;
+         [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR, opstr>, HARDFLOAT;
 
 class MTC1_64_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
                  InstrItinClass Itin> :
   InstSE<(outs DstRC:$fs), (ins DstRC:$fs_in, SrcRC:$rt),
-         !strconcat(opstr, "\t$rt, $fs"), [], Itin, FrmFR, opstr> {
+         !strconcat(opstr, "\t$rt, $fs"), [], Itin, FrmFR, opstr>, HARDFLOAT {
   // $fs_in is part of a white lie to work around a widespread bug in the FPU
   // implementation. See expandBuildPairF64 for details.
   let Constraints = "$fs = $fs_in";
@@ -165,7 +169,8 @@ class MTC1_64_FT<string opstr, RegisterOperand DstRC, RegisterOperand SrcRC,
 class LW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
             SDPatternOperator OpNode= null_frag> :
   InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
-         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> {
+         [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr>,
+  HARDFLOAT {
   let DecoderMethod = "DecodeFMem";
   let mayLoad = 1;
 }
@@ -173,7 +178,7 @@ class LW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
 class SW_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
             SDPatternOperator OpNode= null_frag> :
   InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"),
-         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> {
+         [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr>, HARDFLOAT {
   let DecoderMethod = "DecodeFMem";
   let mayStore = 1;
 }
@@ -183,21 +188,21 @@ class MADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
   InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft),
          !strconcat(opstr, "\t$fd, $fr, $fs, $ft"),
          [(set RC:$fd, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr))], Itin,
-         FrmFR, opstr>;
+         FrmFR, opstr>, HARDFLOAT;
 
 class NMADDS_FT<string opstr, RegisterOperand RC, InstrItinClass Itin,
                 SDPatternOperator OpNode = null_frag> :
   InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft),
          !strconcat(opstr, "\t$fd, $fr, $fs, $ft"),
          [(set RC:$fd, (fsub fpimm0, (OpNode (fmul RC:$fs, RC:$ft), RC:$fr)))],
-         Itin, FrmFR, opstr>;
+         Itin, FrmFR, opstr>, HARDFLOAT;
 
 class LWXC1_FT<string opstr, RegisterOperand DRC,
                InstrItinClass Itin, SDPatternOperator OpNode = null_frag> :
   InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index),
          !strconcat(opstr, "\t$fd, ${index}(${base})"),
          [(set DRC:$fd, (OpNode (add iPTR:$base, iPTR:$index)))], Itin,
-         FrmFI, opstr> {
+         FrmFI, opstr>, HARDFLOAT {
   let AddedComplexity = 20;
 }
 
@@ -206,7 +211,7 @@ class SWXC1_FT<string opstr, RegisterOperand DRC,
   InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index),
          !strconcat(opstr, "\t$fs, ${index}(${base})"),
          [(OpNode DRC:$fs, (add iPTR:$base, iPTR:$index))], Itin,
-         FrmFI, opstr> {
+         FrmFI, opstr>, HARDFLOAT {
   let AddedComplexity = 20;
 }
 
@@ -215,7 +220,7 @@ class BC1F_FT<string opstr, DAGOperand opnd, InstrItinClass Itin,
   InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset),
          !strconcat(opstr, "\t$fcc, $offset"),
          [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin,
-         FrmFI, opstr> {
+         FrmFI, opstr>, HARDFLOAT {
   let isBranch = 1;
   let isTerminator = 1;
   let hasDelaySlot = DelaySlot;
@@ -227,7 +232,7 @@ class CEQS_FT<string typestr, RegisterClass RC, InstrItinClass Itin,
   InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond),
          !strconcat("c.$cond.", typestr, "\t$fs, $ft"),
          [(OpNode RC:$fs, RC:$ft, imm:$cond)], Itin, FrmFR,
-         !strconcat("c.$cond.", typestr)> {
+         !strconcat("c.$cond.", typestr)>, HARDFLOAT {
   let Defs = [FCC0];
   let isCodeGenOnly = 1;
 }
@@ -236,7 +241,7 @@ class C_COND_FT<string CondStr, string Typestr, RegisterOperand RC,
                 InstrItinClass itin>  :
    InstSE<(outs), (ins RC:$fs, RC:$ft),
           !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], itin,
-          FrmFR>;
+          FrmFR>, HARDFLOAT;
 
 multiclass C_COND_M<string TypeStr, RegisterOperand RC, bits<5> fmt,
                     InstrItinClass itin> {
@@ -533,9 +538,9 @@ class BuildPairF64Base<RegisterOperand RO> :
            [(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>;
 
 def BuildPairF64 : BuildPairF64Base<AFGR64Opnd>,
-                   AdditionalRequires<[NotFP64bit]>;
+                   AdditionalRequires<[NotFP64bit]>, HARDFLOAT;
 def BuildPairF64_64 : BuildPairF64Base<FGR64Opnd>,
-                      AdditionalRequires<[IsFP64bit]>;
+                      AdditionalRequires<[IsFP64bit]>, HARDFLOAT;
 
 // This pseudo instr gets expanded into 2 mfc1 instrs after register
 // allocation.
@@ -546,21 +551,21 @@ class ExtractElementF64Base<RegisterOperand RO> :
            [(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>;
 
 def ExtractElementF64 : ExtractElementF64Base<AFGR64Opnd>,
-                        AdditionalRequires<[NotFP64bit]>;
+                        AdditionalRequires<[NotFP64bit]>, HARDFLOAT;
 def ExtractElementF64_64 : ExtractElementF64Base<FGR64Opnd>,
-                           AdditionalRequires<[IsFP64bit]>;
+                           AdditionalRequires<[IsFP64bit]>, HARDFLOAT;
 
 //===----------------------------------------------------------------------===//
 // InstAliases.
 //===----------------------------------------------------------------------===//
 def : MipsInstAlias<"bc1t $offset", (BC1T FCC0, brtarget:$offset)>,
-      ISA_MIPS1_NOT_32R6_64R6;
+      ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT;
 def : MipsInstAlias<"bc1tl $offset", (BC1TL FCC0, brtarget:$offset)>,
-      ISA_MIPS2_NOT_32R6_64R6;
+      ISA_MIPS2_NOT_32R6_64R6, HARDFLOAT;
 def : MipsInstAlias<"bc1f $offset", (BC1F FCC0, brtarget:$offset)>,
-      ISA_MIPS1_NOT_32R6_64R6;
+      ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT;
 def : MipsInstAlias<"bc1fl $offset", (BC1FL FCC0, brtarget:$offset)>,
-      ISA_MIPS2_NOT_32R6_64R6;
+      ISA_MIPS2_NOT_32R6_64R6, HARDFLOAT;
 
 //===----------------------------------------------------------------------===//
 // Floating Point Patterns
index 26f39a2aa99a803314f3ac7b6a0bcffad1bdd34f..7ea10eb954f3d353be25b38ce2b8a53bdd257cc4 100644 (file)
@@ -63,11 +63,11 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
                              const std::string &FS, bool little,
                              const MipsTargetMachine &TM)
     : MipsGenSubtargetInfo(TT, CPU, FS), MipsArchVersion(MipsDefault),
-      IsLittle(little), IsSingleFloat(false), IsFPXX(false), NoABICalls(false),
-      IsFP64bit(false), UseOddSPReg(true), IsNaN2008bit(false),
-      IsGP64bit(false), HasVFPU(false), HasCnMips(false), HasMips3_32(false),
-      HasMips3_32r2(false), HasMips4_32(false), HasMips4_32r2(false),
-      HasMips5_32r2(false), InMips16Mode(false),
+      IsLittle(little), IsSoftFloat(false), IsSingleFloat(false), IsFPXX(false),
+      NoABICalls(false), IsFP64bit(false), UseOddSPReg(true),
+      IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false),
+      HasMips3_32(false), HasMips3_32r2(false), HasMips4_32(false),
+      HasMips4_32r2(false), HasMips5_32r2(false), InMips16Mode(false),
       InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
       HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16),
       HasMSA(false), TM(TM), TargetTriple(TT), TSInfo(*TM.getDataLayout()),
@@ -148,16 +148,12 @@ MipsSubtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS,
   // Initialize scheduling itinerary for the specified CPU.
   InstrItins = getInstrItineraryForCPU(CPUName);
 
-  if (InMips16Mode && !TM.Options.UseSoftFloat)
+  if (InMips16Mode && !IsSoftFloat)
     InMips16HardFloat = true;
 
   return *this;
 }
 
-bool MipsSubtarget::abiUsesSoftFloat() const {
-  return TM.Options.UseSoftFloat && !InMips16HardFloat;
-}
-
 bool MipsSubtarget::useConstantIslands() {
   DEBUG(dbgs() << "use constant islands " << Mips16ConstantIslands << "\n");
   return Mips16ConstantIslands;
index dda344b7d7ea87e38d4963449aaf9f46a4c3448d..932b5d5b0697a514e35bfc5aa0f015ef75b5afed 100644 (file)
@@ -48,6 +48,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
   // IsLittle - The target is Little Endian
   bool IsLittle;
 
+  // IsSoftFloat - The target does not support any floating point instructions.
+  bool IsSoftFloat;
+
   // IsSingleFloat - The target only supports single precision float
   // point operations. This enable the target to use all 32 32-bit
   // floating point registers instead of only using even ones.
@@ -233,7 +236,9 @@ public:
 
   bool hasStandardEncoding() const { return !inMips16Mode(); }
 
-  bool abiUsesSoftFloat() const;
+  bool abiUsesSoftFloat() const {
+    return IsSoftFloat && !InMips16HardFloat;
+  }
 
   bool enableLongBranchPass() const {
     return hasStandardEncoding() || allowMixed16_32();
index 79f6617fcabf651ca51564acf9bdfe296d502645..4d05eb84ce56f72e80ff96ce1245f2cdad05b6f3 100644 (file)
@@ -139,9 +139,7 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const {
 
   // FIXME: This is related to the code below to reset the target options,
   // we need to know whether or not the soft float flag is set on the
-  // function before we can generate a subtarget. We also need to use
-  // it as a key for the subtarget since that can be the only difference
-  // between two functions.
+  // function, so we can enable it as a subtarget feature.
   Attribute SFAttr = F.getFnAttribute("use-soft-float");
   bool softFloat = !SFAttr.hasAttribute(Attribute::None)
                        ? SFAttr.getValueAsString() == "true"
@@ -151,9 +149,10 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const {
     FS += FS.empty() ? "+mips16" : ",+mips16";
   else if (hasNoMips16Attr)
     FS += FS.empty() ? "-mips16" : ",-mips16";
+  if (softFloat)
+    FS += FS.empty() ? "+soft-float" : ",+soft-float";
 
-  auto &I = SubtargetMap[CPU + FS + (softFloat ? "use-soft-float=true"
-                                               : "use-soft-float=false")];
+  auto &I = SubtargetMap[CPU + FS];
   if (!I) {
     // This needs to be done before we create a new subtarget since any
     // creation will depend on the TM and the code generation flags on the
diff --git a/test/MC/Mips/target-soft-float.s b/test/MC/Mips/target-soft-float.s
new file mode 100644 (file)
index 0000000..5865d5a
--- /dev/null
@@ -0,0 +1,331 @@
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32 -mattr=+soft-float 2>&1 |\
+# RUN:   FileCheck %s --check-prefix=32
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips64 -mattr=+soft-float 2>&1 |\
+# RUN:   FileCheck %s --check-prefix=64
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r2 -mattr=+soft-float 2>&1 |\
+# RUN:   FileCheck %s --check-prefix=R2
+# RUN: not llvm-mc %s -triple=mips-unknown-linux -mcpu=mips32r6 -mattr=+soft-float 2>&1 |\
+# RUN:   FileCheck %s --check-prefix=R6
+
+foo:
+  dmfc1      $7, $f2
+  # 64: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  dmtc1      $6, $f2
+  # 64: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+
+  ceil.l.d   $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  ceil.l.s   $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.d.l    $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.l.d    $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.l.s    $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.s.l    $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  floor.l.d  $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  floor.l.s  $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  ldxc1      $f2, $4($6)
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  luxc1      $f2, $4($6)
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  lwxc1      $f2, $4($6)
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mfhc1      $7, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  msub.s     $f2, $f2, $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mthc1      $7, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  nmadd.s    $f2, $f2, $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  nmsub.s    $f2, $f2, $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  round.l.s  $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sdxc1      $f2, $4($6)
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  suxc1      $f2, $4($6)
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  swxc1      $f2, $4($6)
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  trunc.l.d  $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  trunc.l.s  $f2, $f2
+  # R2: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+
+  bc1eqz     $f2, 123
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  bc1nez     $f2, 456
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  class.d    $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  class.s    $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.af.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.af.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.eq.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.eq.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.le.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.le.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.lt.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.lt.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.saf.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.saf.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.seq.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.seq.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sle.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sle.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.slt.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.slt.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sueq.d $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sueq.s $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sule.d $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sule.s $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sult.d $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sult.s $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sun.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.sun.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.ueq.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.ueq.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.ule.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.ule.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.ult.d  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.ult.s  $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.un.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cmp.un.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  maddf.d    $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  maddf.s    $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  max.d      $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  max.s      $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  maxa.d     $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  maxa.s     $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  min.d      $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  min.s      $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mina.d     $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mina.s     $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  msubf.d    $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  msubf.s    $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  rint.d     $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  rint.s     $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sel.d      $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sel.s      $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  seleqz.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  seleqz.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  selnez.d   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  selnez.s   $f2, $f2, $f2
+  # R6: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+
+  abs.d      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  abs.s      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  add.d      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  add.s      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.eq.d     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.eq.s     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.f.d      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.f.s      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.le.d     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.le.s     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.lt.d     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.lt.s     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.nge.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.nge.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ngl.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ngl.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ngle.d   $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ngle.s   $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ngt.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ngt.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ole.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ole.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.olt.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.olt.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.seq.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.seq.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.sf.d     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.sf.s     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ueq.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ueq.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ule.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ule.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ult.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.ult.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.un.d     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  c.un.s     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  ceil.w.d   $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  ceil.w.s   $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.d.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.d.w    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.s.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.s.w    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.w.d    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  cvt.w.s    $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  div.d      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  div.s      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  floor.w.d  $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  floor.w.s  $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  ldc1       $f2, 16($7)
+  # FIXME: LDC1 is correctly rejected but the wrong error message is emitted.
+  # 32: :[[@LINE-2]]:19: error: invalid operand for instruction
+  lwc1       $f2, 16($7)
+  # FIXME: LWC1 is correctly rejected but the wrong error message is emitted.
+  # 32: :[[@LINE-2]]:19: error: invalid operand for instruction
+  madd.s     $f2, $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mfc1       $7, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mov.d      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mov.s      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movf.d     $f2, $f2, $fcc2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movf.s     $f2, $f2, $fcc5
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movn.d     $f2, $f2, $6
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movn.s     $f2, $f2, $6
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movt.d     $f2, $f2, $fcc0
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movt.s     $f2, $f2, $fcc1
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movz.d     $f2, $f2, $6
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  movz.s     $f2, $f2, $6
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mtc1       $7, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mul.d      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  mul.s      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  neg.d      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  neg.s      $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  round.w.d  $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  round.w.s  $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sdc1       $f2, 16($7)
+  # FIXME: SDC1 is correctly rejected but the wrong error message is emitted.
+  # 32: :[[@LINE-2]]:19: error: invalid operand for instruction
+  sqrt.d     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sqrt.s     $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sub.d      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  sub.s      $f2, $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  swc1       $f2, 16($7)
+  # FIXME: SWC1 is correctly rejected but the wrong error message is emitted.
+  # 32: :[[@LINE-2]]:19: error: invalid operand for instruction
+  trunc.w.d  $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled
+  trunc.w.s  $f2, $f2
+  # 32: :[[@LINE-1]]:3: error: instruction requires a CPU feature not currently enabled