Index: lib/Target/Mips/AsmParser/MipsAsmParser.cpp =================================================================== --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -433,8 +433,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 RegIndex is the same as the current AT. void warnIfRegIndexIsAT(unsigned RegIndex, 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 @@ -28,12 +28,15 @@ list FGRPredicates = []; // Predicates for the instruction group membership such as ISA's and ASE's list InsnPredicates = []; + // Predicate for marking the instruction as usable in hard-float mode only. + list HardFloatPredicate = []; // Predicates for anything else list AdditionalPredicates = []; list Predicates = !listconcat(EncodingPredicates, GPRPredicates, FGRPredicates, InsnPredicates, + HardFloatPredicate, AdditionalPredicates); } @@ -69,6 +72,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 @@ -188,52 +188,52 @@ RegisterOperand FGROpnd>{ def CMP_F_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"af", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_UN_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"un", Typestr, FGROpnd, setuo>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_EQ_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"eq", Typestr, FGROpnd, setoeq>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_UEQ_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"ueq", Typestr, FGROpnd, setueq>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_LT_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"lt", Typestr, FGROpnd, setolt>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_ULT_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"ult", Typestr, FGROpnd, setult>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_LE_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"le", Typestr, FGROpnd, setole>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_ULE_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"ule", Typestr, FGROpnd, setule>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SAF_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"saf", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SUN_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"sun", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SEQ_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"seq", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SUEQ_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"sueq", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SLT_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"slt", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SULT_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"sult", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SLE_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"sle", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; def CMP_SULE_#NAME : COP1_CMP_CONDN_FM, CMP_CONDN_DESC_BASE<"sule", Typestr, FGROpnd>, - ISA_MIPS32R6; + ISA_MIPS32R6, HARDFLOAT; } //===----------------------------------------------------------------------===// @@ -651,8 +651,8 @@ 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 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; @@ -695,39 +695,39 @@ 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: lib/Target/Mips/MipsCondMov.td =================================================================== --- lib/Target/Mips/MipsCondMov.td +++ lib/Target/Mips/MipsCondMov.td @@ -27,7 +27,8 @@ class CMov_I_F_FT : 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 @@ 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 @@ 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: 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. @@ -73,6 +75,7 @@ class FGR_32 { list FGRPredicates = [NotFP64bit]; } class FGR_64 { list FGRPredicates = [IsFP64bit]; } +class HARDFLOAT { list HardFloatPredicate = [IsNotSoftFloat]; } //===----------------------------------------------------------------------===// @@ -98,12 +101,12 @@ // // Only S32 and D32 are supported right now. //===----------------------------------------------------------------------===// - class ADDS_FT : 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 @@ 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 : 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 : 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 : 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 LW_FT : 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 SW_FT : 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 @@ 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 : 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 : 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 @@ 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 @@ 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 @@ 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 @@ InstrItinClass itin> : InstSE<(outs), (ins RC:$fs, RC:$ft), !strconcat("c.", CondStr, ".", Typestr, "\t$fs, $ft"), [], itin, - FrmFR>; + FrmFR>, HARDFLOAT; multiclass C_COND_M fmt, InstrItinClass itin> { @@ -533,9 +538,9 @@ [(set RO:$dst, (MipsBuildPairF64 GPR32Opnd:$lo, GPR32Opnd:$hi))]>; def BuildPairF64 : BuildPairF64Base, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit]>, HARDFLOAT; def BuildPairF64_64 : BuildPairF64Base, - AdditionalRequires<[IsFP64bit]>; + AdditionalRequires<[IsFP64bit]>, HARDFLOAT; // This pseudo instr gets expanded into 2 mfc1 instrs after register // allocation. @@ -546,21 +551,21 @@ [(set GPR32Opnd:$dst, (MipsExtractElementF64 RO:$src, imm:$n))]>; def ExtractElementF64 : ExtractElementF64Base, - AdditionalRequires<[NotFP64bit]>; + AdditionalRequires<[NotFP64bit]>, HARDFLOAT; def ExtractElementF64_64 : ExtractElementF64Base, - 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: 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. @@ -233,7 +236,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