Adding intrinsics to the llvm backend for TBM instruction set.
Phabricator code review is located here: http://llvm-reviews.chandlerc.com/D1750

llvm-svn: 191539
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index 25d1af3..1ef9814 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -354,6 +354,9 @@
     // XOP9 - Prefix to exclude use of imm byte.
     XOP9 = 21 << Op0Shift,
 
+    // XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions.
+    XOPA = 22 << Op0Shift,
+
     //===------------------------------------------------------------------===//
     // REX_W - REX prefixes are instruction prefixes used in 64-bit mode.
     // They are used to specify GPRs and SSE registers, 64-bit operand size,
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 0c9fd91..032c52c 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -665,6 +665,9 @@
   case X86II::XOP9:
     VEX_5M = 0x9;
     break;
+  case X86II::XOPA:
+    VEX_5M = 0xA;
+    break;
   case X86II::A6:  // Bypass: Not used by VEX
   case X86II::A7:  // Bypass: Not used by VEX
   case X86II::TB:  // Bypass: Not used by VEX
diff --git a/llvm/lib/Target/X86/X86CodeEmitter.cpp b/llvm/lib/Target/X86/X86CodeEmitter.cpp
index e786ebb..122d291 100644
--- a/llvm/lib/Target/X86/X86CodeEmitter.cpp
+++ b/llvm/lib/Target/X86/X86CodeEmitter.cpp
@@ -919,6 +919,9 @@
     case X86II::XOP9:
       VEX_5M = 0x9;
       break;
+    case X86II::XOPA:
+      VEX_5M = 0xA;
+      break;
     case X86II::A6:  // Bypass: Not used by VEX
     case X86II::A7:  // Bypass: Not used by VEX
     case X86II::TB:  // Bypass: Not used by VEX
diff --git a/llvm/lib/Target/X86/X86InstrFormats.td b/llvm/lib/Target/X86/X86InstrFormats.td
index fb07ed0..ebe94a5 100644
--- a/llvm/lib/Target/X86/X86InstrFormats.td
+++ b/llvm/lib/Target/X86/X86InstrFormats.td
@@ -139,6 +139,7 @@
 class TAXD   { bits<5> Prefix = 19; }
 class XOP8   { bits<5> Prefix = 20; }
 class XOP9   { bits<5> Prefix = 21; }
+class XOPA   { bits<5> Prefix = 22; }
 class VEX    { bit hasVEXPrefix = 1; }
 class VEX_W  { bit hasVEX_WPrefix = 1; }
 class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 148ac6d..3b16fb0 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -664,6 +664,7 @@
 def UseFMAOnAVX  : Predicate<"Subtarget->hasFMA() && !Subtarget->hasAVX512()">;
 def HasFMA4      : Predicate<"Subtarget->hasFMA4()">;
 def HasXOP       : Predicate<"Subtarget->hasXOP()">;
+def HasTBM       : Predicate<"Subtarget->hasTBM()">;
 def HasMOVBE     : Predicate<"Subtarget->hasMOVBE()">;
 def HasRDRAND    : Predicate<"Subtarget->hasRDRAND()">;
 def HasF16C      : Predicate<"Subtarget->hasF16C()">;
@@ -1907,6 +1908,84 @@
 }
 
 //===----------------------------------------------------------------------===//
+// TBM Instructions
+//
+let isAsmParserOnly = 1, Predicates = [HasTBM], Defs = [EFLAGS] in {
+
+multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr,
+                                X86MemOperand x86memop, PatFrag ld_frag,
+                                Intrinsic Int> {
+  def rr : Ii32<opc,  MRMSrcReg, (outs RC:$dst), (ins RC:$src1, i32imm:$cntl),
+                !strconcat(OpcodeStr,
+                           "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
+                [(set RC:$dst, (Int RC:$src1, imm:$cntl))]>,
+           XOP, XOPA, VEX;
+  def mr : Ii32<opc,  MRMSrcMem, (outs RC:$dst),
+                (ins x86memop:$src1, i32imm:$cntl),
+                !strconcat(OpcodeStr,
+                           "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"),
+                [(set RC:$dst, (Int (ld_frag addr:$src1), imm:$cntl))]>,
+           XOP, XOPA, VEX;
+}
+
+defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32,
+                                     int_x86_tbm_bextri_u32>;
+defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64,
+                                     int_x86_tbm_bextri_u64>, VEX_W;
+
+multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem,
+                         RegisterClass RC, string OpcodeStr,
+                         X86MemOperand x86memop, PatFrag ld_frag,
+                         Intrinsic Int> {
+  def rr : I<opc,  FormReg, (outs RC:$dst), (ins RC:$src),
+             !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
+             [(set RC:$dst, (Int RC:$src))]>,
+           XOP, XOP9,  VEX_4V;
+  def rm : I<opc,  FormMem, (outs RC:$dst), (ins x86memop:$src),
+             !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"),
+             [(set RC:$dst, (Int (ld_frag addr:$src)))]>,
+           XOP, XOP9,  VEX_4V;
+}
+
+multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr,
+                           Format FormReg, Format FormMem,
+                           Intrinsic Int32, Intrinsic Int64> {
+  defm _32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr, i32mem,
+                           loadi32, Int32>;
+  defm _64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr, i64mem,
+                           loadi64, Int64>, VEX_W;
+}
+
+defm BLCFILL : tbm_binary_intr<0x01, "blcfill", MRM1r, MRM1m,
+                               int_x86_tbm_blcfill_u32,
+                               int_x86_tbm_blcfill_u64>;
+defm BLCI    : tbm_binary_intr<0x02, "blci", MRM6r, MRM6m,
+                               int_x86_tbm_blci_u32,
+                               int_x86_tbm_blci_u64>;
+defm BLCIC   : tbm_binary_intr<0x01, "blcic", MRM5r, MRM5m,
+                               int_x86_tbm_blcic_u32,
+                               int_x86_tbm_blcic_u64>;
+defm BLCMSK  : tbm_binary_intr<0x02, "blcmsk", MRM1r, MRM1m,
+                               int_x86_tbm_blcmsk_u32,
+                               int_x86_tbm_blcmsk_u64>;
+defm BLCS    : tbm_binary_intr<0x01, "blcs", MRM3r, MRM3m,
+                               int_x86_tbm_blcs_u32,
+                               int_x86_tbm_blcs_u64>;
+defm BLSFILL : tbm_binary_intr<0x01, "blsfill", MRM2r, MRM2m,
+                               int_x86_tbm_blsfill_u32,
+                               int_x86_tbm_blsfill_u64>;
+defm BLSIC   : tbm_binary_intr<0x01, "blsic", MRM6r, MRM6m,
+                               int_x86_tbm_blsic_u32,
+                               int_x86_tbm_blsic_u64>;
+defm T1MSKC  : tbm_binary_intr<0x01, "t1mskc", MRM7r, MRM7m,
+                               int_x86_tbm_t1mskc_u32,
+                               int_x86_tbm_t1mskc_u64>;
+defm TZMSK   : tbm_binary_intr<0x01, "tzmsk", MRM4r, MRM4m,
+                               int_x86_tbm_tzmsk_u32,
+                               int_x86_tbm_tzmsk_u64>;
+} // isAsmParserOnly, HasTBM, EFLAGS
+
+//===----------------------------------------------------------------------===//
 // Subsystems.
 //===----------------------------------------------------------------------===//