Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -86,7 +86,8 @@ Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 | Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips | - Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008; + Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008 | + Mips::FeatureSoftFloat; private: unsigned ATReg; @@ -431,8 +432,10 @@ 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 RegNo is the current assembler temporary. void warnIfAssemblerTemporary(int RegNo, SMLoc Loc); Index: lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h +++ lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.h @@ -68,6 +68,7 @@ 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 @@ 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 @@ 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: lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.cpp +++ lib/Target/Mips/MCTargetDesc/MipsABIFlagsSection.cpp @@ -15,6 +15,8 @@ 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: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -69,6 +69,8 @@ "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: lib/Target/Mips/Mips16ISelLowering.cpp =================================================================== --- lib/Target/Mips/Mips16ISelLowering.cpp +++ lib/Target/Mips/Mips16ISelLowering.cpp @@ -127,7 +127,7 @@ // 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: lib/Target/Mips/Mips32r6InstrInfo.td =================================================================== --- lib/Target/Mips/Mips32r6InstrInfo.td +++ lib/Target/Mips/Mips32r6InstrInfo.td @@ -186,6 +186,7 @@ multiclass CMP_CC_M { +let AdditionalPredicates = [IsNotSoftFloat] in { def CMP_F_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>, ISA_MIPS32R6; @@ -235,6 +236,7 @@ CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>, ISA_MIPS32R6; } +} //===----------------------------------------------------------------------===// // @@ -649,8 +651,10 @@ def AUIPC : AUIPC_ENC, AUIPC_DESC, ISA_MIPS32R6; def BAL : BAL_ENC, BAL_DESC, ISA_MIPS32R6; def BALC : 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, + AdditionalRequires<[IsNotSoftFloat]>; +def BC1NEZ : BC1NEZ_ENC, BC1NEZ_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; def BC2EQZ : BC2EQZ_ENC, BC2EQZ_DESC, ISA_MIPS32R6; def BC2NEZ : BC2NEZ_ENC, BC2NEZ_DESC, ISA_MIPS32R6; def BC : BC_ENC, BC_DESC, ISA_MIPS32R6; @@ -676,8 +680,10 @@ def BNVC : BNVC_ENC, BNVC_DESC, ISA_MIPS32R6; def BOVC : BOVC_ENC, BOVC_DESC, ISA_MIPS32R6; def CACHE_R6 : 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, + AdditionalRequires<[IsNotSoftFloat]>; +def CLASS_S : CLASS_S_ENC, CLASS_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; 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; @@ -693,39 +699,59 @@ 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, + AdditionalRequires<[IsNotSoftFloat]>; +def MADDF_D : MADDF_D_ENC, MADDF_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MAXA_D : MAXA_D_ENC, MAXA_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MAXA_S : MAXA_S_ENC, MAXA_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MAX_D : MAX_D_ENC, MAX_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MAX_S : MAX_S_ENC, MAX_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MINA_D : MINA_D_ENC, MINA_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MINA_S : MINA_S_ENC, MINA_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MIN_D : MIN_D_ENC, MIN_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def MIN_S : MIN_S_ENC, MIN_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; 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, + AdditionalRequires<[IsNotSoftFloat]>; +def MSUBF_D : MSUBF_D_ENC, MSUBF_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; def MUH : MUH_ENC, MUH_DESC, ISA_MIPS32R6; def MUHU : MUHU_ENC, MUHU_DESC, ISA_MIPS32R6; def MUL_R6 : MUL_R6_ENC, MUL_R6_DESC, ISA_MIPS32R6; def MULU : MULU_ENC, MULU_DESC, ISA_MIPS32R6; def NAL; // BAL with rd=0 def PREF_R6 : 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, + AdditionalRequires<[IsNotSoftFloat]>; +def RINT_S : RINT_S_ENC, RINT_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; 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, + AdditionalRequires<[IsNotSoftFloat]>; +def SELEQZ_S : SELEQZ_S_ENC, SELEQZ_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; 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, + AdditionalRequires<[IsNotSoftFloat]>; +def SELNEZ_S : SELNEZ_S_ENC, SELNEZ_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def SEL_D : SEL_D_ENC, SEL_D_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; +def SEL_S : SEL_S_ENC, SEL_S_DESC, ISA_MIPS32R6, + AdditionalRequires<[IsNotSoftFloat]>; def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6; //===----------------------------------------------------------------------===// Index: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -26,7 +26,7 @@ // cond:int, data:float class CMov_I_F_FT : - InstSE<(outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F), + InstFP<(outs DRC:$fd), (ins DRC:$fs, CRC:$rt, DRC:$F), !strconcat(opstr, "\t$fd, $fs, $rt"), [], Itin, FrmFR, opstr> { let Constraints = "$F = $fd"; } @@ -34,7 +34,7 @@ // cond:float, data:int class CMov_F_I_FT : - InstSE<(outs RC:$rd), (ins RC:$rs, FCCRegsOpnd:$fcc, RC:$F), + InstFP<(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> { @@ -44,7 +44,7 @@ // cond:float, data:float class CMov_F_F_FT : - InstSE<(outs RC:$fd), (ins RC:$fs, FCCRegsOpnd:$fcc, RC:$F), + InstFP<(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> { Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -65,6 +65,8 @@ AssemblerPredicate<"FeatureSingleFloat">; def IsNotSingleFloat : Predicate<"!Subtarget->isSingleFloat()">, AssemblerPredicate<"!FeatureSingleFloat">; +def IsNotSoftFloat : Predicate<"!Subtarget->abiUsesSoftFloat()">, + AssemblerPredicate<"!FeatureSoftFloat">; //===----------------------------------------------------------------------===// // Mips FGR size adjectives. @@ -98,10 +100,15 @@ // // Only S32 and D32 are supported right now. //===----------------------------------------------------------------------===// +class InstFP pattern, + InstrItinClass itin, Format f, string opstr = ""> : + InstSE { + let AdditionalPredicates = [IsNotSoftFloat]; +} class ADDS_FT : - InstSE<(outs RC:$fd), (ins RC:$fs, RC:$ft), + InstFP<(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> { let isCommutable = IsComm; @@ -110,52 +117,52 @@ multiclass ADDS_M { def _D32 : MMRel, ADDS_FT, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def _D64 : ADDS_FT, - AdditionalRequires<[IsFP64bit]> { + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]> { string DecoderNamespace = "Mips64"; } } class ABSS_FT : - InstSE<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"), + InstFP<(outs DstRC:$fd), (ins SrcRC:$fs), !strconcat(opstr, "\t$fd, $fs"), [(set DstRC:$fd, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>, NeverHasSideEffects; multiclass ABSS_M { def _D32 : MMRel, ABSS_FT, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def _D64 : ABSS_FT, - AdditionalRequires<[IsFP64bit]> { + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]> { string DecoderNamespace = "Mips64"; } } multiclass ROUND_M { def _D32 : MMRel, ABSS_FT, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def _D64 : ABSS_FT, - AdditionalRequires<[IsFP64bit]> { + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]> { let DecoderNamespace = "Mips64"; } } class MFC1_FT : - InstSE<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), + InstFP<(outs DstRC:$rt), (ins SrcRC:$fs), !strconcat(opstr, "\t$rt, $fs"), [(set DstRC:$rt, (OpNode SrcRC:$fs))], Itin, FrmFR, opstr>; class MTC1_FT : - InstSE<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), + InstFP<(outs DstRC:$fs), (ins SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), [(set DstRC:$fs, (OpNode SrcRC:$rt))], Itin, FrmFR, opstr>; class MTC1_64_FT : - InstSE<(outs DstRC:$fs), (ins DstRC:$fs_in, SrcRC:$rt), + InstFP<(outs DstRC:$fs), (ins DstRC:$fs_in, SrcRC:$rt), !strconcat(opstr, "\t$rt, $fs"), [], Itin, FrmFR, opstr> { // $fs_in is part of a white lie to work around a widespread bug in the FPU // implementation. See expandBuildPairF64 for details. @@ -164,7 +171,7 @@ class LW_FT : - InstSE<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + InstFP<(outs RC:$rt), (ins mem:$addr), !strconcat(opstr, "\t$rt, $addr"), [(set RC:$rt, (OpNode addrDefault:$addr))], Itin, FrmFI, opstr> { let DecoderMethod = "DecodeFMem"; let mayLoad = 1; @@ -172,7 +179,7 @@ class SW_FT : - InstSE<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), + InstFP<(outs), (ins RC:$rt, mem:$addr), !strconcat(opstr, "\t$rt, $addr"), [(OpNode RC:$rt, addrDefault:$addr)], Itin, FrmFI, opstr> { let DecoderMethod = "DecodeFMem"; let mayStore = 1; @@ -180,21 +187,21 @@ class MADDS_FT : - InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), + InstFP<(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>; class NMADDS_FT : - InstSE<(outs RC:$fd), (ins RC:$fr, RC:$fs, RC:$ft), + InstFP<(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>; class LWXC1_FT : - InstSE<(outs DRC:$fd), (ins PtrRC:$base, PtrRC:$index), + InstFP<(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> { @@ -203,7 +210,7 @@ class SWXC1_FT : - InstSE<(outs), (ins DRC:$fs, PtrRC:$base, PtrRC:$index), + InstFP<(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> { @@ -212,7 +219,7 @@ class BC1F_FT : - InstSE<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset), + InstFP<(outs), (ins FCCRegsOpnd:$fcc, opnd:$offset), !strconcat(opstr, "\t$fcc, $offset"), [(MipsFPBrcond Op, FCCRegsOpnd:$fcc, bb:$offset)], Itin, FrmFI, opstr> { @@ -224,7 +231,7 @@ class CEQS_FT : - InstSE<(outs), (ins RC:$fs, RC:$ft, condcode:$cond), + InstFP<(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)> { @@ -234,7 +241,7 @@ class C_COND_FT : - InstSE<(outs), (ins RC:$fs, RC:$ft), + InstFP<(outs), (ins RC:$fs, RC:$ft), !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], itin, FrmFR>; @@ -260,10 +267,10 @@ defm S : C_COND_M<"s", FGR32Opnd, 16, II_C_CC_S>, ISA_MIPS1_NOT_32R6_64R6; defm D32 : C_COND_M<"d", AFGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; let DecoderNamespace = "Mips64" in defm D64 : C_COND_M<"d", FGR64Opnd, 17, II_C_CC_D>, ISA_MIPS1_NOT_32R6_64R6, - AdditionalRequires<[IsFP64bit]>; + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]>; //===----------------------------------------------------------------------===// // Floating Point Instructions @@ -363,15 +370,19 @@ def MTC1 : MMRel, MTC1_FT<"mtc1", FGR32Opnd, GPR32Opnd, II_MTC1, bitconvert>, MFC1_FM<4>; def MFHC1_D32 : MMRel, MFC1_FT<"mfhc1", GPR32Opnd, AFGR64Opnd, II_MFHC1>, - MFC1_FM<3>, ISA_MIPS32R2, AdditionalRequires<[NotFP64bit]>; + MFC1_FM<3>, ISA_MIPS32R2, + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def MFHC1_D64 : MFC1_FT<"mfhc1", GPR32Opnd, FGR64Opnd, II_MFHC1>, - MFC1_FM<3>, ISA_MIPS32R2, AdditionalRequires<[IsFP64bit]> { + MFC1_FM<3>, ISA_MIPS32R2, + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]> { let DecoderNamespace = "Mips64"; } def MTHC1_D32 : MMRel, MTC1_64_FT<"mthc1", AFGR64Opnd, GPR32Opnd, II_MTHC1>, - MFC1_FM<7>, ISA_MIPS32R2, AdditionalRequires<[NotFP64bit]>; + MFC1_FM<7>, ISA_MIPS32R2, + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def MTHC1_D64 : MTC1_64_FT<"mthc1", FGR64Opnd, GPR32Opnd, II_MTHC1>, - MFC1_FM<7>, ISA_MIPS32R2, AdditionalRequires<[IsFP64bit]> { + MFC1_FM<7>, ISA_MIPS32R2, + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]> { let DecoderNamespace = "Mips64"; } def DMFC1 : MFC1_FT<"dmfc1", GPR64Opnd, FGR64Opnd, II_DMFC1, @@ -382,9 +393,11 @@ def FMOV_S : MMRel, ABSS_FT<"mov.s", FGR32Opnd, FGR32Opnd, II_MOV_S>, ABSS_FM<0x6, 16>; def FMOV_D32 : MMRel, ABSS_FT<"mov.d", AFGR64Opnd, AFGR64Opnd, II_MOV_D>, - ABSS_FM<0x6, 17>, AdditionalRequires<[NotFP64bit]>; + ABSS_FM<0x6, 17>, + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def FMOV_D64 : ABSS_FT<"mov.d", FGR64Opnd, FGR64Opnd, II_MOV_D>, - ABSS_FM<0x6, 17>, AdditionalRequires<[IsFP64bit]> { + ABSS_FM<0x6, 17>, + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]> { let DecoderNamespace = "Mips64"; } @@ -392,7 +405,8 @@ def LWC1 : MMRel, LW_FT<"lwc1", FGR32Opnd, II_LWC1, load>, LW_FM<0x31>; def SWC1 : MMRel, SW_FT<"swc1", FGR32Opnd, II_SWC1, store>, LW_FM<0x39>; -let DecoderNamespace = "Mips64" in { +let DecoderNamespace = "Mips64" +in { def LDC164 : LW_FT<"ldc1", FGR64Opnd, II_LDC1, load>, LW_FM<0x35>, ISA_MIPS2, FGR_64; def SDC164 : SW_FT<"sdc1", FGR64Opnd, II_SDC1, store>, LW_FM<0x3d>, ISA_MIPS2, @@ -407,20 +421,21 @@ // Indexed loads and stores. // Base register + offset register addressing mode (indicated by "x" in the // instruction mnemonic) is disallowed under NaCl. -let AdditionalPredicates = [IsNotNaCl] in { +let AdditionalPredicates = [IsNotNaCl, IsNotSoftFloat] in { def LWXC1 : MMRel, LWXC1_FT<"lwxc1", FGR32Opnd, II_LWXC1, load>, LWXC1_FM<0>, INSN_MIPS4_32R2_NOT_32R6_64R6; def SWXC1 : MMRel, SWXC1_FT<"swxc1", FGR32Opnd, II_SWXC1, store>, SWXC1_FM<8>, INSN_MIPS4_32R2_NOT_32R6_64R6; } -let AdditionalPredicates = [NotInMicroMips, IsNotNaCl] in { +let AdditionalPredicates = [NotInMicroMips, IsNotNaCl, IsNotSoftFloat] in { def LDXC1 : LWXC1_FT<"ldxc1", AFGR64Opnd, II_LDXC1, load>, LWXC1_FM<1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32; def SDXC1 : SWXC1_FT<"sdxc1", AFGR64Opnd, II_SDXC1, store>, SWXC1_FM<9>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32; } +// Does this work with +soft-float ?? let DecoderNamespace="Mips64" in { def LDXC164 : LWXC1_FT<"ldxc1", FGR64Opnd, II_LDXC1, load>, LWXC1_FM<1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64; @@ -429,7 +444,7 @@ } // Load/store doubleword indexed unaligned. -let AdditionalPredicates = [IsNotNaCl] in { +let AdditionalPredicates = [IsNotNaCl, IsNotSoftFloat] in { def LUXC1 : MMRel, LWXC1_FT<"luxc1", AFGR64Opnd, II_LUXC1>, LWXC1_FM<0x5>, INSN_MIPS5_32R2_NOT_32R6_64R6, FGR_32; def SUXC1 : MMRel, SWXC1_FT<"suxc1", AFGR64Opnd, II_SUXC1>, SWXC1_FM<0xd>, @@ -462,7 +477,7 @@ def MSUB_S : MMRel, MADDS_FT<"msub.s", FGR32Opnd, II_MSUB_S, fsub>, MADDS_FM<5, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6; -let AdditionalPredicates = [NoNaNsFPMath] in { +let AdditionalPredicates = [NoNaNsFPMath, IsNotSoftFloat] in { def NMADD_S : MMRel, NMADDS_FT<"nmadd.s", FGR32Opnd, II_NMADD_S, fadd>, MADDS_FM<6, 0>, INSN_MIPS4_32R2_NOT_32R6_64R6; def NMSUB_S : MMRel, NMADDS_FT<"nmsub.s", FGR32Opnd, II_NMSUB_S, fsub>, @@ -474,7 +489,7 @@ def MSUB_D32 : MMRel, MADDS_FT<"msub.d", AFGR64Opnd, II_MSUB_D, fsub>, MADDS_FM<5, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32; -let AdditionalPredicates = [NoNaNsFPMath] in { +let AdditionalPredicates = [NoNaNsFPMath, IsNotSoftFloat] in { def NMADD_D32 : MMRel, NMADDS_FT<"nmadd.d", AFGR64Opnd, II_NMADD_D, fadd>, MADDS_FM<6, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_32; def NMSUB_D32 : MMRel, NMADDS_FT<"nmsub.d", AFGR64Opnd, II_NMSUB_D, fsub>, @@ -488,7 +503,7 @@ MADDS_FM<5, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64; } -let AdditionalPredicates = [NoNaNsFPMath], +let AdditionalPredicates = [NoNaNsFPMath, IsNotSoftFloat], DecoderNamespace = "Mips64" in { def NMADD_D64 : NMADDS_FT<"nmadd.d", FGR64Opnd, II_NMADD_D, fadd>, MADDS_FM<6, 1>, INSN_MIPS4_32R2_NOT_32R6_64R6, FGR_64; @@ -539,10 +554,12 @@ def FCMP_S32 : MMRel, CEQS_FT<"s", FGR32, II_C_CC_S, MipsFPCmp>, CEQS_FM<16>, ISA_MIPS1_NOT_32R6_64R6; def FCMP_D32 : MMRel, CEQS_FT<"d", AFGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>, - ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[NotFP64bit]>; + ISA_MIPS1_NOT_32R6_64R6, + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; let DecoderNamespace = "Mips64" in def FCMP_D64 : CEQS_FT<"d", FGR64, II_C_CC_D, MipsFPCmp>, CEQS_FM<17>, - ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[IsFP64bit]>; + ISA_MIPS1_NOT_32R6_64R6, + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]>; //===----------------------------------------------------------------------===// // Floating Point Pseudo-Instructions @@ -555,9 +572,9 @@ [(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>; def BuildPairF64 : BuildPairF64Base, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def BuildPairF64_64 : BuildPairF64Base, - AdditionalRequires<[IsFP64bit]>; + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]>; // This pseudo instr gets expanded into 2 mfc1 instrs after register // allocation. @@ -568,21 +585,21 @@ [(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>; def ExtractElementF64 : ExtractElementF64Base, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit, IsNotSoftFloat]>; def ExtractElementF64_64 : ExtractElementF64Base, - AdditionalRequires<[IsFP64bit]>; + AdditionalRequires<[IsFP64bit, IsNotSoftFloat]>; //===----------------------------------------------------------------------===// // InstAliases. //===----------------------------------------------------------------------===// def : MipsInstAlias<"bc1t $offset", (BC1T FCC0, brtarget:$offset)>, - ISA_MIPS1_NOT_32R6_64R6; + ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[IsNotSoftFloat]>; def : MipsInstAlias<"bc1tl $offset", (BC1TL FCC0, brtarget:$offset)>, - ISA_MIPS2_NOT_32R6_64R6; + ISA_MIPS2_NOT_32R6_64R6, AdditionalRequires<[IsNotSoftFloat]>; def : MipsInstAlias<"bc1f $offset", (BC1F FCC0, brtarget:$offset)>, - ISA_MIPS1_NOT_32R6_64R6; + ISA_MIPS1_NOT_32R6_64R6, AdditionalRequires<[IsNotSoftFloat]>; def : MipsInstAlias<"bc1fl $offset", (BC1FL FCC0, brtarget:$offset)>, - ISA_MIPS2_NOT_32R6_64R6; + ISA_MIPS2_NOT_32R6_64R6, AdditionalRequires<[IsNotSoftFloat]>; //===----------------------------------------------------------------------===// // Floating Point Patterns Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -48,6 +48,9 @@ // 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. @@ -232,7 +235,9 @@ bool hasStandardEncoding() const { return !inMips16Mode(); } - bool abiUsesSoftFloat() const; + bool abiUsesSoftFloat() const { + return IsSoftFloat && !InMips16HardFloat; + } bool enableLongBranchPass() const { return hasStandardEncoding() || allowMixed16_32(); Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -63,11 +63,11 @@ 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 @@ // 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: lib/Target/Mips/MipsTargetMachine.cpp =================================================================== --- lib/Target/Mips/MipsTargetMachine.cpp +++ lib/Target/Mips/MipsTargetMachine.cpp @@ -139,9 +139,7 @@ // 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 @@ 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 Index: test/MC/Mips/target-soft-float.s =================================================================== --- /dev/null +++ test/MC/Mips/target-soft-float.s @@ -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