[mips] Fold FeatureBitCount into FeatureMips32 and FeatureMips64
authorDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 12 May 2014 12:41:59 +0000 (12:41 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 12 May 2014 12:41:59 +0000 (12:41 +0000)
Summary:
DCL[ZO] are now correctly marked as being MIPS64 instructions. This has no
effect on the CodeGen tests since expansion of i64 prevented their use
anyway.

The check for MIPS16 to prevent the use of CLZ no longer prevents DCLZ as
well. This is not a functional change since DCLZ is still prohibited by
being a MIPS64 instruction (MIPS16 is only compatible with MIPS32).

No functional change

Reviewers: vmedic

Reviewed By: vmedic

Differential Revision: http://reviews.llvm.org/D3694

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208544 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MicroMipsInstrInfo.td
lib/Target/Mips/Mips.td
lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsInstrInfo.td
lib/Target/Mips/MipsSubtarget.cpp
lib/Target/Mips/MipsSubtarget.h
test/MC/Mips/mips32/invalid-mips64.s [new file with mode: 0644]

index 93c33307c08e6492fd838b09f79f2d9189ca4d04..54564e2b85749cc1d6953991bfb7ff751887cd8d 100644 (file)
@@ -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>,
index 66b3d742503eec3109ab839e128327282b4e412d..e84c5f6980c3beba74eccb729477072946c7fdc9 100644 (file)
@@ -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]>;
index e70817b0c3359dbdb6be8447a20e147ab45683dd..12c6e087c543ad370f8fc3a9f61a96e6800c9cd6 100644 (file)
@@ -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;
index 64244ee109653477eb16125806931e67729cb1c5..7efd34db99061f0201281a78c69ddf352d261326 100644 (file)
@@ -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);
index 52a57824e435cd3f17016f7ef06584a68b6d0786..af9c92857694a898930cf86745b730f9ba396f71 100644 (file)
@@ -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<Predicate> GPRPredicates = [IsGP64bit]; }
 
 class ISA_MIPS2    { list<Predicate> InsnPredicates = [HasMips2]; }
 class ISA_MIPS3    { list<Predicate> InsnPredicates = [HasMips3]; }
+class ISA_MIPS32   { list<Predicate> InsnPredicates = [HasMips32]; }
 class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
+class ISA_MIPS64   { list<Predicate> InsnPredicates = [HasMips64]; }
 class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
 
 // The portions of MIPS-III that were also added to MIPS32
@@ -823,13 +823,11 @@ class EffectiveAddress<string opstr, RegisterOperand RO> :
 // Count Leading Ones/Zeros in Word
 class CountLeading0<string opstr, RegisterOperand RO>:
   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<string opstr, RegisterOperand RO>:
   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<string opstr, ValueType vt, RegisterOperand RO,
@@ -1166,8 +1164,8 @@ def SEH : MMRel, SignExtInReg<"seh", i16, GPR32Opnd, II_SEH>,
           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;
index fa71106f5b88b16d90d7c583b4140bf7d2f2ba57..0596153a6523cad200a6891849cd2614943f1e8d 100644 (file)
@@ -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
index 6897133f35a35e796e5c9c1a8b0b49822711275b..2da92e61670fd24f69b9ec957b98158747d1553c 100644 (file)
@@ -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 (file)
index 0000000..41040ed
--- /dev/null
@@ -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