[mips] Fold FeatureBitCount into FeatureMips32 and FeatureMips64

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
This commit is contained in:
Daniel Sanders 2014-05-12 12:41:59 +00:00
parent ea27d2f50b
commit b396af3752
8 changed files with 26 additions and 25 deletions

View File

@ -218,8 +218,10 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
def MSUBU_MM : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM_MM<0x3ec>; def MSUBU_MM : MMRel, MArithR<"msubu", II_MSUBU>, MULT_FM_MM<0x3ec>;
/// Count Leading /// Count Leading
def CLZ_MM : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM_MM<0x16c>; def CLZ_MM : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM_MM<0x16c>,
def CLO_MM : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM_MM<0x12c>; ISA_MIPS32;
def CLO_MM : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM_MM<0x12c>,
ISA_MIPS32;
/// Sign Ext In Register Instructions. /// Sign Ext In Register Instructions.
def SEB_MM : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>, def SEB_MM : MMRel, SignExtInReg<"seb", i8, GPR32Opnd, II_SEB>,

View File

@ -75,8 +75,6 @@ def FeatureEABI : SubtargetFeature<"eabi", "MipsABI", "EABI",
"Enable eabi ABI">; "Enable eabi ABI">;
def FeatureVFPU : SubtargetFeature<"vfpu", "HasVFPU", def FeatureVFPU : SubtargetFeature<"vfpu", "HasVFPU",
"true", "Enable vector FPU instructions.">; "true", "Enable vector FPU instructions.">;
def FeatureBitCount : SubtargetFeature<"bitcount", "HasBitCount", "true",
"Enable 'count leading bits' instructions.">;
def FeatureMips1 : SubtargetFeature<"mips1", "MipsArchVersion", "Mips1", def FeatureMips1 : SubtargetFeature<"mips1", "MipsArchVersion", "Mips1",
"Mips I ISA Support [highly experimental]">; "Mips I ISA Support [highly experimental]">;
def FeatureMips2 : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2", def FeatureMips2 : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2",
@ -105,7 +103,7 @@ def FeatureMips5 : SubtargetFeature<"mips5", "MipsArchVersion", "Mips5",
def FeatureMips32 : SubtargetFeature<"mips32", "MipsArchVersion", "Mips32", def FeatureMips32 : SubtargetFeature<"mips32", "MipsArchVersion", "Mips32",
"Mips32 ISA Support", "Mips32 ISA Support",
[FeatureMips2, FeatureMips3_32, [FeatureMips2, FeatureMips3_32,
FeatureMips4_32, FeatureBitCount]>; FeatureMips4_32]>;
def FeatureMips32r2 : SubtargetFeature<"mips32r2", "MipsArchVersion", def FeatureMips32r2 : SubtargetFeature<"mips32r2", "MipsArchVersion",
"Mips32r2", "Mips32r2 ISA Support", "Mips32r2", "Mips32r2 ISA Support",
[FeatureMips4_32r2, FeatureMips32]>; [FeatureMips4_32r2, FeatureMips32]>;

View File

@ -216,8 +216,8 @@ def SEH64 : SignExtInReg<"seh", i16, GPR64Opnd, II_SEH>, SEB_FM<0x18, 0x20>,
} }
/// Count Leading /// Count Leading
def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>; def DCLZ : CountLeading0<"dclz", GPR64Opnd>, CLO_FM<0x24>, ISA_MIPS64;
def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>; def DCLO : CountLeading1<"dclo", GPR64Opnd>, CLO_FM<0x25>, ISA_MIPS64;
/// Double Word Swap Bytes/HalfWords /// Double Word Swap Bytes/HalfWords
def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>, ISA_MIPS64R2; def DSBH : SubwordSwap<"dsbh", GPR64Opnd>, SEB_FM<2, 0x24>, ISA_MIPS64R2;

View File

@ -357,10 +357,11 @@ MipsTargetLowering::MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 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); setOperationAction(ISD::CTLZ, MVT::i32, Expand);
if (!Subtarget->hasMips64())
setOperationAction(ISD::CTLZ, MVT::i64, Expand); setOperationAction(ISD::CTLZ, MVT::i64, Expand);
}
if (!Subtarget->hasMips32r2()) if (!Subtarget->hasMips32r2())
setOperationAction(ISD::BSWAP, MVT::i32, Expand); setOperationAction(ISD::BSWAP, MVT::i32, Expand);

View File

@ -146,8 +146,6 @@ def MipsSDR : SDNode<"MipsISD::SDR", SDTStore,
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Mips Instruction Predicate Definitions. // Mips Instruction Predicate Definitions.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def HasBitCount : Predicate<"Subtarget.hasBitCount()">,
AssemblerPredicate<"FeatureBitCount">;
def HasMips2 : Predicate<"Subtarget.hasMips2()">, def HasMips2 : Predicate<"Subtarget.hasMips2()">,
AssemblerPredicate<"FeatureMips2">; AssemblerPredicate<"FeatureMips2">;
def HasMips3_32 : Predicate<"Subtarget.hasMips3_32()">, 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_MIPS2 { list<Predicate> InsnPredicates = [HasMips2]; }
class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; } class ISA_MIPS3 { list<Predicate> InsnPredicates = [HasMips3]; }
class ISA_MIPS32 { list<Predicate> InsnPredicates = [HasMips32]; }
class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; } class ISA_MIPS32R2 { list<Predicate> InsnPredicates = [HasMips32r2]; }
class ISA_MIPS64 { list<Predicate> InsnPredicates = [HasMips64]; }
class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; } class ISA_MIPS64R2 { list<Predicate> InsnPredicates = [HasMips64r2]; }
// The portions of MIPS-III that were also added to MIPS32 // 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 // Count Leading Ones/Zeros in Word
class CountLeading0<string opstr, RegisterOperand RO>: class CountLeading0<string opstr, RegisterOperand RO>:
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
[(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>, [(set RO:$rd, (ctlz RO:$rs))], II_CLZ, FrmR, opstr>;
AdditionalRequires<[HasBitCount]>;
class CountLeading1<string opstr, RegisterOperand RO>: class CountLeading1<string opstr, RegisterOperand RO>:
InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"), InstSE<(outs RO:$rd), (ins RO:$rs), !strconcat(opstr, "\t$rd, $rs"),
[(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>, [(set RO:$rd, (ctlz (not RO:$rs)))], II_CLO, FrmR, opstr>;
AdditionalRequires<[HasBitCount]>;
// Sign Extend in Register. // Sign Extend in Register.
class SignExtInReg<string opstr, ValueType vt, RegisterOperand RO, 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; SEB_FM<0x18, 0x20>, ISA_MIPS32R2;
/// Count Leading /// Count Leading
def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>; def CLZ : MMRel, CountLeading0<"clz", GPR32Opnd>, CLO_FM<0x20>, ISA_MIPS32;
def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>; def CLO : MMRel, CountLeading1<"clo", GPR32Opnd>, CLO_FM<0x21>, ISA_MIPS32;
/// Word Swap Bytes Within Halfwords /// Word Swap Bytes Within Halfwords
def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2; def WSBH : MMRel, SubwordSwap<"wsbh", GPR32Opnd>, SEB_FM<2, 0x20>, ISA_MIPS32R2;

View File

@ -81,7 +81,7 @@ MipsSubtarget::MipsSubtarget(const std::string &TT, const std::string &CPU,
MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false), MipsABI(UnknownABI), IsLittle(little), IsSingleFloat(false),
IsFP64bit(false), IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false), IsFP64bit(false), IsNaN2008bit(false), IsGP64bit(false), HasVFPU(false),
HasCnMips(false), IsLinux(true), HasMips3_32(false), HasMips4_32(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), InMips16HardFloat(Mips16HardFloat), InMicroMipsMode(false), HasDSP(false),
HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16), HasDSPR2(false), AllowMixed16_32(Mixed16_32 | Mips_Os16), Os16(Mips_Os16),
HasMSA(false), RM(_RM), OverrideMode(NoOverride), TM(_TM), 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 // TODO: Investigate the IsLinux check. I suspect it's really checking for
// bare-metal. // bare-metal.
UseSmallSection = !IsLinux && (RM == Reloc::Static); UseSmallSection = !IsLinux && (RM == Reloc::Static);
// set some subtarget specific features
if (inMips16Mode())
HasBitCount=false;
} }
bool bool

View File

@ -88,9 +88,6 @@ protected:
// HasMips4_32r2 - Has the subset of MIPS-IV present in MIPS32r2 // HasMips4_32r2 - Has the subset of MIPS-IV present in MIPS32r2
bool HasMips4_32r2; bool HasMips4_32r2;
// HasBitCount - Count leading '1' and '0' bits.
bool HasBitCount;
// InMips16 -- can process Mips16 instructions // InMips16 -- can process Mips16 instructions
bool InMips16Mode; bool InMips16Mode;
@ -208,7 +205,6 @@ public:
} }
/// Features related to the presence of specific instructions. /// Features related to the presence of specific instructions.
bool hasBitCount() const { return HasBitCount; }
bool hasExtractInsert() const { return !inMips16Mode() && hasMips32r2(); } bool hasExtractInsert() const { return !inMips16Mode() && hasMips32r2(); }
const InstrItineraryData &getInstrItineraryData() const { return InstrItins; } const InstrItineraryData &getInstrItineraryData() const { return InstrItins; }

View File

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