diff --git a/lib/Target/Mips/MicroMipsInstrInfo.td b/lib/Target/Mips/MicroMipsInstrInfo.td index 93c33307c08..54564e2b857 100644 --- a/lib/Target/Mips/MicroMipsInstrInfo.td +++ b/lib/Target/Mips/MicroMipsInstrInfo.td @@ -218,8 +218,10 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in { def MSUBU_MM : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM_MM<0x3ec>; /// Count Leading - def CLZ_MM : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM_MM<0x16c>; - def CLO_MM : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM_MM<0x12c>; + def CLZ_MM : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM_MM<0x16c>, + ISA_MIPS32; + def CLO_MM : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM_MM<0x12c>, + ISA_MIPS32; /// Sign Ext In Register Instructions. def SEB_MM : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, diff --git a/lib/Target/Mips/Mips.td b/lib/Target/Mips/Mips.td index 66b3d742503..e84c5f6980c 100644 --- a/lib/Target/Mips/Mips.td +++ b/lib/Target/Mips/Mips.td @@ -75,8 +75,6 @@ def FeatureEABI : SubtargetFeature<"eabi", "MipsABI", "EABI", "Enable eabi ABI">; def FeatureVFPU : SubtargetFeature<"vfpu", "HasVFPU", "true", "Enable vector FPU instructions.">; -def FeatureBitCount : SubtargetFeature<"bitcount", "HasBitCount", "true", - "Enable 'count leading bits' instructions.">; def FeatureMips1 : SubtargetFeature<"mips1", "MipsArchVersion", "Mips1", "Mips I ISA Support [highly experimental]">; def FeatureMips2 : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2", @@ -105,7 +103,7 @@ def FeatureMips5 : SubtargetFeature<"mips5", "MipsArchVersion", "Mips5", def FeatureMips32 : SubtargetFeature<"mips32", "MipsArchVersion", "Mips32", "Mips32 ISA Support", [FeatureMips2, FeatureMips3_32, - FeatureMips4_32, FeatureBitCount]>; + FeatureMips4_32]>; def FeatureMips32r2 : SubtargetFeature<"mips32r2", "MipsArchVersion", "Mips32r2", "Mips32r2 ISA Support", [FeatureMips4_32r2, FeatureMips32]>; diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index e70817b0c33..12c6e087c54 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -216,8 +216,8 @@ def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd, II_SEH>, SEB_FM<0x18, 0x20>, } /// Count Leading -def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>; -def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>; +def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>, ISA_MIPS64; +def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>, ISA_MIPS64; /// Double Word Swap Bytes/HalfWords def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>, ISA_MIPS64R2; diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 64244ee1096..7efd34db990 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -357,10 +357,11 @@ MipsTargetLowering::MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); } - if (!Subtarget->hasBitCount()) { + // MIPS16 lacks MIPS32's clz and clo instructions. + if (!Subtarget->hasMips32() || Subtarget->inMips16Mode()) setOperationAction(ISD::CTLZ, MVT::i32, Expand); + if (!Subtarget->hasMips64()) setOperationAction(ISD::CTLZ, MVT::i64, Expand); - } if (!Subtarget->hasMips32r2()) setOperationAction(ISD::BSWAP, MVT::i32, Expand); diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index 52a57824e43..af9c9285769 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -146,8 +146,6 @@ def MipsSDR : SDNode<"MipsISD::SDR", SDTStore, //===----------------------------------------------------------------------===// // Mips Instruction Predicate Definitions. //===----------------------------------------------------------------------===// -def HasBitCount : Predicate<"Subtarget.hasBitCount()">, - AssemblerPredicate<"FeatureBitCount">; def HasMips2 : Predicate<"Subtarget.hasMips2()">, AssemblerPredicate<"FeatureMips2">; def HasMips3_32 : Predicate<"Subtarget.hasMips3_32()">, @@ -210,7 +208,9 @@ class GPR_64 { list GPRPredicates = [IsGP64bit]; } class ISA_MIPS2 { list InsnPredicates = [HasMips2]; } class ISA_MIPS3 { list InsnPredicates = [HasMips3]; } +class ISA_MIPS32 { list InsnPredicates = [HasMips32]; } class ISA_MIPS32R2 { list InsnPredicates = [HasMips32r2]; } +class ISA_MIPS64 { list InsnPredicates = [HasMips64]; } class ISA_MIPS64R2 { list InsnPredicates = [HasMips64r2]; } // The portions of MIPS-III that were also added to MIPS32 @@ -823,13 +823,11 @@ class EffectiveAddress : // Count Leading Ones/Zeros in Word class CountLeading0: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>, - AdditionalRequires<[HasBitCount]>; + [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>; class CountLeading1: InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), - [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>, - AdditionalRequires<[HasBitCount]>; + [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>; // Sign Extend in Register. class SignExtInReg, SEB_FM<0x18, 0x20>, ISA_MIPS32R2; /// Count Leading -def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>; -def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>; +def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>, ISA_MIPS32; +def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>, ISA_MIPS32; /// Word Swap Bytes Within Halfwords def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2; diff --git a/lib/Target/Mips/MipsSubtarget.cpp b/lib/Target/Mips/MipsSubtarget.cpp index fa71106f5b8..0596153a652 100644 --- a/lib/Target/Mips/MipsSubtarget.cpp +++ b/lib/Target/Mips/MipsSubtarget.cpp @@ -81,7 +81,7 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false), IsFP64bit(false), IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), HasCnMips(false), IsLinux(true), HasMips3_32(false), HasMips4_32(false), - HasMips4_32r2(false), HasBitCount(false), InMips16Mode(false), + HasMips4_32r2(false), InMips16Mode(false), InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false), HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasMSA(false), RM(_RM), OverrideMode(NoOverride), TM(_TM), @@ -154,9 +154,6 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU, // TODO: Investigate the IsLinux check. I suspect it's really checking for // bare-metal. UseSmallSection = !IsLinux && (RM == Reloc::Static); - // set some subtarget specific features - if (inMips16Mode()) - HasBitCount=false; } bool diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index 6897133f35a..2da92e61670 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -88,9 +88,6 @@ protected: // HasMips4_32r2 - Has the subset of MIPS-IV present in MIPS32r2 bool HasMips4_32r2; - // HasBitCount - Count leading '1' and '0' bits. - bool HasBitCount; - // InMips16 -- can process Mips16 instructions bool InMips16Mode; @@ -208,7 +205,6 @@ public: } /// Features related to the presence of specific instructions. - bool hasBitCount() const { return HasBitCount; } bool hasExtractInsert() const { return !inMips16Mode() && hasMips32r2(); } const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } diff --git a/test/MC/Mips/mips32/invalid-mips64.s b/test/MC/Mips/mips32/invalid-mips64.s new file mode 100644 index 00000000000..41040edb7db --- /dev/null +++ b/test/MC/Mips/mips32/invalid-mips64.s @@ -0,0 +1,9 @@ +# Instructions that are invalid +# +# RUN: not llvm-mc %s -triple=mips64-unknown-linux -show-encoding -mcpu=mips32 \ +# RUN: 2>%t1 +# RUN: FileCheck %s < %t1 + + .set noat + dclo $s2,$a2 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled + dclz $s0,$t9 # CHECK: :[[@LINE]]:{{[0-9]+}}: error: instruction requires a CPU feature not currently enabled