forked from OSchip/llvm-project
Add X86 LZCNT instruction. Including instruction selection support.
llvm-svn: 141651
This commit is contained in:
parent
77c1f9f888
commit
271064e873
|
@ -7,8 +7,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This is a target description file for the Intel i386 architecture, referred to
|
||||
// here as the "X86" architecture.
|
||||
// This is a target description file for the Intel i386 architecture, referred
|
||||
// to here as the "X86" architecture.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
@ -102,6 +102,8 @@ def FeatureRDRAND : SubtargetFeature<"rdrand", "HasRDRAND", "true",
|
|||
"Support RDRAND instruction">;
|
||||
def FeatureF16C : SubtargetFeature<"f16c", "HasF16C", "true",
|
||||
"Support 16-bit floating point conversion instructions">;
|
||||
def FeatureLZCNT : SubtargetFeature<"lzcnt", "HasLZCNT", "true",
|
||||
"Support LZCNT instruction">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// X86 processors supported.
|
||||
|
|
|
@ -380,14 +380,19 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
|||
setOperationAction(ISD::FLT_ROUNDS_ , MVT::i32 , Custom);
|
||||
|
||||
setOperationAction(ISD::CTTZ , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::CTLZ , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::CTTZ , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::CTLZ , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::CTTZ , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::CTLZ , MVT::i32 , Custom);
|
||||
if (Subtarget->is64Bit()) {
|
||||
if (Subtarget->is64Bit())
|
||||
setOperationAction(ISD::CTTZ , MVT::i64 , Custom);
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Custom);
|
||||
|
||||
if (Subtarget->hasLZCNT()) {
|
||||
setOperationAction(ISD::CTLZ , MVT::i8 , Promote);
|
||||
} else {
|
||||
setOperationAction(ISD::CTLZ , MVT::i8 , Custom);
|
||||
setOperationAction(ISD::CTLZ , MVT::i16 , Custom);
|
||||
setOperationAction(ISD::CTLZ , MVT::i32 , Custom);
|
||||
if (Subtarget->is64Bit())
|
||||
setOperationAction(ISD::CTLZ , MVT::i64 , Custom);
|
||||
}
|
||||
|
||||
if (Subtarget->hasPOPCNT()) {
|
||||
|
|
|
@ -476,6 +476,7 @@ def HasFMA4 : Predicate<"Subtarget->hasFMA4()">;
|
|||
def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">;
|
||||
def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">;
|
||||
def HasF16C : Predicate<"Subtarget->hasF16C()">;
|
||||
def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">;
|
||||
def FPStackf32 : Predicate<"!Subtarget->hasXMM()">;
|
||||
def FPStackf64 : Predicate<"!Subtarget->hasXMMInt()">;
|
||||
def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">;
|
||||
|
@ -1339,6 +1340,32 @@ let Predicates = [HasRDRAND], Defs = [EFLAGS] in {
|
|||
"rdrand{q}\t$dst", []>, TB;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LZCNT Instruction
|
||||
//
|
||||
let Predicates = [HasLZCNT], Defs = [EFLAGS] in {
|
||||
def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
|
||||
"lzcnt{w}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR16:$dst, (ctlz GR16:$src))]>, XS, OpSize;
|
||||
def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
|
||||
"lzcnt{w}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR16:$dst, (ctlz (loadi16 addr:$src)))]>, XS, OpSize;
|
||||
|
||||
def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
|
||||
"lzcnt{l}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, (ctlz GR32:$src))]>, XS;
|
||||
def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
|
||||
"lzcnt{l}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR32:$dst, (ctlz (loadi32 addr:$src)))]>, XS;
|
||||
|
||||
def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
|
||||
"lzcnt{q}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR64:$dst, (ctlz GR64:$src))]>, XS;
|
||||
def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
|
||||
"lzcnt{q}\t{$src, $dst|$dst, $src}",
|
||||
[(set GR64:$dst, (ctlz (loadi64 addr:$src)))]>, XS;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Subsystems.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -255,6 +255,10 @@ void X86Subtarget::AutoDetectSubtargetFeatures() {
|
|||
HasX86_64 = true;
|
||||
ToggleFeature(X86::Feature64Bit);
|
||||
}
|
||||
if ((ECX >> 5) & 0x1) {
|
||||
HasLZCNT = true;
|
||||
ToggleFeature(X86::FeatureLZCNT);
|
||||
}
|
||||
if (IsAMD && ((ECX >> 6) & 0x1)) {
|
||||
HasSSE4A = true;
|
||||
ToggleFeature(X86::FeatureSSE4A);
|
||||
|
@ -285,6 +289,7 @@ X86Subtarget::X86Subtarget(const std::string &TT, const std::string &CPU,
|
|||
, HasMOVBE(false)
|
||||
, HasRDRAND(false)
|
||||
, HasF16C(false)
|
||||
, HasLZCNT(false)
|
||||
, IsBTMemSlow(false)
|
||||
, IsUAMemFast(false)
|
||||
, HasVectorUAMem(false)
|
||||
|
|
|
@ -99,6 +99,9 @@ protected:
|
|||
/// HasF16C - Processor has 16-bit floating point conversion instructions.
|
||||
bool HasF16C;
|
||||
|
||||
/// HasLZCNT - Processor has LZCNT instruction.
|
||||
bool HasLZCNT;
|
||||
|
||||
/// IsBTMemSlow - True if BT (bit test) of memory instructions are slow.
|
||||
bool IsBTMemSlow;
|
||||
|
||||
|
@ -184,6 +187,7 @@ public:
|
|||
bool hasMOVBE() const { return HasMOVBE; }
|
||||
bool hasRDRAND() const { return HasRDRAND; }
|
||||
bool hasF16C() const { return HasF16C; }
|
||||
bool hasLZCNT() const { return HasLZCNT; }
|
||||
bool isBTMemSlow() const { return IsBTMemSlow; }
|
||||
bool isUnalignedMemAccessFast() const { return IsUAMemFast; }
|
||||
bool hasVectorUAMem() const { return HasVectorUAMem; }
|
||||
|
|
|
@ -488,3 +488,12 @@
|
|||
|
||||
# CHECK: popcntq %rax, %rax
|
||||
0xf3 0x48 0x0f 0xb8 0xc0
|
||||
|
||||
# CHECK: lzcntl %eax, %eax
|
||||
0xf3 0x0f 0xbd 0xc0
|
||||
|
||||
# CHECK: lzcntw %ax, %ax
|
||||
0x66 0xf3 0x0f 0xbd 0xc0
|
||||
|
||||
# CHECK: lzcntq %rax, %rax
|
||||
0xf3 0x48 0x0f 0xbd 0xc0
|
||||
|
|
|
@ -471,3 +471,9 @@
|
|||
|
||||
# CHECK: popcntw %ax, %ax
|
||||
0x66 0xf3 0x0f 0xb8 0xc0
|
||||
|
||||
# CHECK: lzcntl %eax, %eax
|
||||
0xf3 0x0f 0xbd 0xc0
|
||||
|
||||
# CHECK: lzcntw %ax, %ax
|
||||
0x66 0xf3 0x0f 0xbd 0xc0
|
||||
|
|
Loading…
Reference in New Issue