Index: lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- lib/Target/Mips/MicroMipsInstrInfo.td +++ lib/Target/Mips/MicroMipsInstrInfo.td @@ -218,8 +218,10 @@ 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>, Index: lib/Target/Mips/Mips.td =================================================================== --- lib/Target/Mips/Mips.td +++ lib/Target/Mips/Mips.td @@ -75,8 +75,6 @@ "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 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]>; Index: lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- lib/Target/Mips/Mips64InstrInfo.td +++ lib/Target/Mips/Mips64InstrInfo.td @@ -216,8 +216,8 @@ } /// 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; Index: lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- lib/Target/Mips/MipsISelLowering.cpp +++ lib/Target/Mips/MipsISelLowering.cpp @@ -357,10 +357,11 @@ 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); Index: lib/Target/Mips/MipsInstrInfo.td =================================================================== --- lib/Target/Mips/MipsInstrInfo.td +++ lib/Target/Mips/MipsInstrInfo.td @@ -146,8 +146,6 @@ //===----------------------------------------------------------------------===// // 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 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 @@ // 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, 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; Index: lib/Target/Mips/MipsSubtarget.h =================================================================== --- lib/Target/Mips/MipsSubtarget.h +++ lib/Target/Mips/MipsSubtarget.h @@ -88,9 +88,6 @@ // 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 @@ } /// 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; } Index: lib/Target/Mips/MipsSubtarget.cpp =================================================================== --- lib/Target/Mips/MipsSubtarget.cpp +++ lib/Target/Mips/MipsSubtarget.cpp @@ -81,7 +81,7 @@ 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 @@ // 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 Index: test/MC/Mips/mips32/invalid-mips64.s =================================================================== --- /dev/null +++ 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