[mips] Add the SoftFloat MipsSubtarget feature.

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

llvm-svn: 236713
This commit is contained in:
Toma Tabacu 2015-05-07 10:29:52 +00:00
parent 2ce89617c9
commit 506cfd0b2b
12 changed files with 436 additions and 87 deletions

View 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);

View 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:

View 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())

View 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">;

View 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);

View 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;
//===----------------------------------------------------------------------===//

View 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";
}

View 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

View 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;

View 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();

View 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

View File

@ -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