Add X86 RORX instruction
authorCraig Topper <craig.topper@gmail.com>
Sun, 23 Oct 2011 07:34:00 +0000 (07:34 +0000)
committerCraig Topper <craig.topper@gmail.com>
Sun, 23 Oct 2011 07:34:00 +0000 (07:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142741 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/MCTargetDesc/X86BaseInfo.h
lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86InstrFormats.td
lib/Target/X86/X86InstrShiftRotate.td
test/MC/Disassembler/X86/simple-tests.txt
test/MC/Disassembler/X86/x86-32.txt
test/MC/X86/x86_64-bmi-encoding.s
utils/TableGen/X86RecognizableInstr.cpp

index 007e620cae3672c6879d22385ad1d84de263d78f..c50f78517273fcfb9d95171b7ddf0d5185ba508f 100644 (file)
@@ -301,6 +301,9 @@ namespace X86II {
     // T8XS - Prefix before and after 0x0F. Combination of T8 and XS.
     T8XS = 18 << Op0Shift,
 
+    // TAXD - Prefix before and after 0x0F. Combination of TA and XD.
+    TAXD = 19 << 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,
index 8ae7a3c42af23143957cade1ac33499286389e0d..1ab469cc009dc9022e89818435c7f6346d1d5355 100644 (file)
@@ -472,6 +472,10 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
     VEX_PP = 0x3;
     VEX_5M = 0x2;
     break;
+  case X86II::TAXD: // F2 0F 3A
+    VEX_PP = 0x3;
+    VEX_5M = 0x3;
+    break;
   case X86II::XS:  // F3 0F
     VEX_PP = 0x2;
     break;
@@ -802,6 +806,10 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
     EmitByte(0xF2, CurByte, OS);
     Need0FPrefix = true;
     break;
+  case X86II::TAXD: // F2 0F 3A
+    EmitByte(0xF2, CurByte, OS);
+    Need0FPrefix = true;
+    break;
   case X86II::XS:   // F3 0F
     EmitByte(0xF3, CurByte, OS);
     Need0FPrefix = true;
@@ -838,6 +846,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
   case X86II::T8:    // 0F 38
     EmitByte(0x38, CurByte, OS);
     break;
+  case X86II::TAXD:  // F2 0F 3A
   case X86II::TA:    // 0F 3A
     EmitByte(0x3A, CurByte, OS);
     break;
index a15060462e5fc705bb88804c3e1d44597c7926a3..d94ba331fb177e06b6e09829b55246ff73a58a28 100644 (file)
@@ -656,6 +656,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
     Need0FPrefix = true;
     break;
   case X86II::T8XD: // F2 0F 38
+  case X86II::TAXD: // F2 0F 3A
   case X86II::XD:   // F2 0F
     MCE.emitByte(0xF2);
     Need0FPrefix = true;
@@ -686,6 +687,7 @@ void Emitter<CodeEmitter>::emitInstruction(MachineInstr &MI,
   case X86II::T8:    // 0F 38
     MCE.emitByte(0x38);
     break;
+  case X86II::TAXD:  // F2 0F 38
   case X86II::TA:    // 0F 3A
     MCE.emitByte(0x3A);
     break;
index 5b7adf311bd73fa8fbec30bca0a0463cb49c4a3a..5236dafd9924dfed0a055210c633e33d3d455bab 100644 (file)
@@ -109,6 +109,7 @@ class A6     { bits<5> Prefix = 15; }
 class A7     { bits<5> Prefix = 16; }
 class T8XD   { bits<5> Prefix = 17; }
 class T8XS   { bits<5> Prefix = 18; }
+class TAXD   { bits<5> Prefix = 19; }
 class VEX    { bit hasVEXPrefix = 1; }
 class VEX_W  { bit hasVEX_WPrefix = 1; }
 class VEX_4V : VEX { bit hasVEX_4VPrefix = 1; }
index 8278568184ff08942c72c06beac2dd711de43dd1..a32f0665d308f326d6c35b1fde6d39bcea1af4ea 100644 (file)
@@ -744,3 +744,24 @@ def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
 
 } // Defs = [EFLAGS]
 
+let Predicates = [HasBMI2], neverHasSideEffects = 1 in {
+  def RORX32ri : Ii8<0xF0, MRMSrcReg, (outs GR32:$dst),
+                     (ins GR32:$src1, i8imm:$src2),
+                     "rorx{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
+                     TAXD, VEX;
+  let mayLoad = 1 in
+  def RORX32mi : Ii8<0xF0, MRMSrcMem, (outs GR32:$dst),
+                     (ins i32mem:$src1, i8imm:$src2),
+                     "rorx{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
+                     TAXD, VEX;
+
+  def RORX64ri : Ii8<0xF0, MRMSrcReg, (outs GR64:$dst),
+                     (ins GR64:$src1, i8imm:$src2),
+                     "rorx{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
+                     TAXD, VEX, VEX_W;
+  let mayLoad = 1 in
+  def RORX64mi : Ii8<0xF0, MRMSrcMem, (outs GR64:$dst),
+                     (ins i64mem:$src1, i8imm:$src2),
+                     "rorx{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", []>,
+                     TAXD, VEX, VEX_W;
+}
index 23c30f8f45953e70839caf3adfcb341542d69ee0..229c10dc1d78114facb38c601841d62d6ebdda77 100644 (file)
 
 # CHECK: mulxq (%rax), %r11, %r10
 0xc4 0x62 0xa3 0xf6 0x10
+
+# CHECK: rorxl $1, %r12d, %r10d
+0xc4 0x43 0x7b 0xf0 0xd4 0x01
+
+# CHECK: rorxl $31, (%rax), %r10d
+0xc4 0x63 0x7b 0xf0 0x10 0x1f
+
+# CHECK: rorxq $1, %r12, %r10
+0xc4 0x43 0xfb 0xf0 0xd4 0x01
+
+# CHECK: rorxq $63, (%rax), %r10
+0xc4 0x63 0xfb 0xf0 0x10 0x3f
index b01c4eff5ccb61592d6374e3dbcbdce9363b279b..10d3c1fea6c645056b5d86ea98311e74d4cf4282 100644 (file)
 
 # CHECK: mulxl (%eax), %ecx, %edx
 0xc4 0xe2 0xf3 0xf6 0x10
+
+# CHECK: rorxl $1, %esp, %edx
+0xc4 0xe3 0x7b 0xf0 0xd4 0x01
+
+# CHECK: rorxl $31, (%eax), %edx
+0xc4 0xe3 0x7b 0xf0 0x10 0x1f
index 005ded2a1b03ee0aaac62ef2873950111ff0e864..aa5aa9aa2021b0fb09bd9e276b1f7b03da9507d6 100644 (file)
 // CHECK: pdepq (%rax), %r11, %r10
 // CHECK: encoding: [0xc4,0x62,0xa3,0xf5,0x10]
           pdepq (%rax), %r11, %r10
+
+// CHECK: mulxl %r12d, %r11d, %r10d
+// CHECK: encoding: [0xc4,0x42,0x23,0xf6,0xd4]
+          mulxl %r12d, %r11d, %r10d
+
+// CHECK: mulxl (%rax), %r11d, %r10d
+// CHECK: encoding: [0xc4,0x62,0x23,0xf6,0x10]
+          mulxl (%rax), %r11d, %r10d
+
+// CHECK: mulxq %r12, %r11, %r10
+// CHECK: encoding: [0xc4,0x42,0xa3,0xf6,0xd4]
+          mulxq %r12, %r11, %r10
+
+// CHECK: mulxq (%rax), %r11, %r10
+// CHECK: encoding: [0xc4,0x62,0xa3,0xf6,0x10]
+          mulxq (%rax), %r11, %r10
+
+// CHECK: rorxl $10, %r12d, %r10d
+// CHECK: encoding: [0xc4,0x43,0x7b,0xf0,0xd4,0x0a]
+          rorxl $10, %r12d, %r10d
+
+// CHECK: rorxl $31, (%rax), %r10d
+// CHECK: encoding: [0xc4,0x63,0x7b,0xf0,0x10,0x1f]
+          rorxl $31, (%rax), %r10d
+
+// CHECK: rorxq $1, %r12, %r10
+// CHECK: encoding: [0xc4,0x43,0xfb,0xf0,0xd4,0x01]
+          rorxq $1, %r12, %r10
+
+// CHECK: rorxq $63, (%rax), %r10
+// CHECK: encoding: [0xc4,0x63,0xfb,0xf0,0x10,0x3f]
+          rorxq $63, (%rax), %r10
index 68e03738cff4028fd6096421e4e434c754f915ad..d4c9629226f77ed4eb43c637c8c7433dc8a4c7ed 100644 (file)
@@ -68,7 +68,7 @@ namespace X86Local {
     DC = 7, DD = 8, DE = 9, DF = 10,
     XD = 11,  XS = 12,
     T8 = 13,  P_TA = 14,
-    A6 = 15,  A7 = 16, T8XD = 17, T8XS = 18
+    A6 = 15,  A7 = 16, T8XD = 17, T8XS = 18, TAXD = 19
   };
 }
 
@@ -296,20 +296,23 @@ InstructionContext RecognizableInstr::insnContext() const {
     else if (HasVEX_LPrefix &&
              (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
       insnContext = IC_VEX_L_XS;
-    else if (HasVEX_LPrefix &&
-             (Prefix == X86Local::XD || Prefix == X86Local::T8XD))
+    else if (HasVEX_LPrefix && (Prefix == X86Local::XD ||
+                                Prefix == X86Local::T8XD ||
+                                Prefix == X86Local::TAXD))
       insnContext = IC_VEX_L_XD;
     else if (HasVEX_WPrefix &&
              (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
       insnContext = IC_VEX_W_XS;
-    else if (HasVEX_WPrefix &&
-             (Prefix == X86Local::XD || Prefix == X86Local::T8XD))
+    else if (HasVEX_WPrefix && (Prefix == X86Local::XD ||
+                                Prefix == X86Local::T8XD ||
+                                Prefix == X86Local::TAXD))
       insnContext = IC_VEX_W_XD;
     else if (HasVEX_WPrefix)
       insnContext = IC_VEX_W;
     else if (HasVEX_LPrefix)
       insnContext = IC_VEX_L;
-    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD)
+    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+             Prefix == X86Local::TAXD)
       insnContext = IC_VEX_XD;
     else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
       insnContext = IC_VEX_XS;
@@ -318,8 +321,9 @@ InstructionContext RecognizableInstr::insnContext() const {
   } else if (Is64Bit || HasREX_WPrefix) {
     if (HasREX_WPrefix && HasOpSizePrefix)
       insnContext = IC_64BIT_REXW_OPSIZE;
-    else if (HasOpSizePrefix &&
-             (Prefix == X86Local::XD || Prefix == X86Local::T8XD))
+    else if (HasOpSizePrefix && (Prefix == X86Local::XD ||
+                                 Prefix == X86Local::T8XD ||
+                                 Prefix == X86Local::TAXD))
       insnContext = IC_64BIT_XD_OPSIZE;
     else if (HasOpSizePrefix &&
              (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
@@ -329,10 +333,12 @@ InstructionContext RecognizableInstr::insnContext() const {
     else if (HasREX_WPrefix &&
              (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
       insnContext = IC_64BIT_REXW_XS;
-    else if (HasREX_WPrefix &&
-             (Prefix == X86Local::XD || Prefix == X86Local::T8XD))
+    else if (HasREX_WPrefix && (Prefix == X86Local::XD ||
+                                Prefix == X86Local::T8XD ||
+                                Prefix == X86Local::TAXD))
       insnContext = IC_64BIT_REXW_XD;
-    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD)
+    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+             Prefix == X86Local::TAXD)
       insnContext = IC_64BIT_XD;
     else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS)
       insnContext = IC_64BIT_XS;
@@ -341,15 +347,17 @@ InstructionContext RecognizableInstr::insnContext() const {
     else
       insnContext = IC_64BIT;
   } else {
-    if (HasOpSizePrefix &&
-        (Prefix == X86Local::XD || Prefix == X86Local::T8XD))
+    if (HasOpSizePrefix && (Prefix == X86Local::XD ||
+                            Prefix == X86Local::T8XD ||
+                            Prefix == X86Local::TAXD))
       insnContext = IC_XD_OPSIZE;
     else if (HasOpSizePrefix &&
              (Prefix == X86Local::XS || Prefix == X86Local::T8XS))
       insnContext = IC_XS_OPSIZE;
     else if (HasOpSizePrefix)
       insnContext = IC_OPSIZE;
-    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD)
+    else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
+             Prefix == X86Local::TAXD)
       insnContext = IC_XD;
     else if (Prefix == X86Local::XS || Prefix == X86Local::T8XS ||
              Prefix == X86Local::REP)
@@ -908,6 +916,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
     opcodeToSet = Opcode;
     break;
   case X86Local::P_TA:
+  case X86Local::TAXD:
     opcodeType = THREEBYTE_3A;
     if (needsModRMForDecode(Form))
       filter = new ModFilter(isRegFormat(Form));