summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2011-10-23 07:34:00 +0000
committerCraig Topper <craig.topper@gmail.com>2011-10-23 07:34:00 +0000
commit75485d6746f8b5b23c17cf6d2364e7e1e0705992 (patch)
treeba768e50e36bc64df8943978485bfda422749295
parent90747e34e6ca7162eaf8dde032649071045f161d (diff)
downloadllvm-75485d6746f8b5b23c17cf6d2364e7e1e0705992.tar.gz
llvm-75485d6746f8b5b23c17cf6d2364e7e1e0705992.tar.bz2
llvm-75485d6746f8b5b23c17cf6d2364e7e1e0705992.tar.xz
Add X86 RORX instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142741 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/MCTargetDesc/X86BaseInfo.h3
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp9
-rw-r--r--lib/Target/X86/X86CodeEmitter.cpp2
-rw-r--r--lib/Target/X86/X86InstrFormats.td1
-rw-r--r--lib/Target/X86/X86InstrShiftRotate.td21
-rw-r--r--test/MC/Disassembler/X86/simple-tests.txt12
-rw-r--r--test/MC/Disassembler/X86/x86-32.txt6
-rw-r--r--test/MC/X86/x86_64-bmi-encoding.s32
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp37
9 files changed, 109 insertions, 14 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
index 007e620cae..c50f785172 100644
--- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
+++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
@@ -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,
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index 8ae7a3c42a..1ab469cc00 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -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;
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp
index a15060462e..d94ba331fb 100644
--- a/lib/Target/X86/X86CodeEmitter.cpp
+++ b/lib/Target/X86/X86CodeEmitter.cpp
@@ -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;
diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td
index 5b7adf311b..5236dafd99 100644
--- a/lib/Target/X86/X86InstrFormats.td
+++ b/lib/Target/X86/X86InstrFormats.td
@@ -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; }
diff --git a/lib/Target/X86/X86InstrShiftRotate.td b/lib/Target/X86/X86InstrShiftRotate.td
index 8278568184..a32f0665d3 100644
--- a/lib/Target/X86/X86InstrShiftRotate.td
+++ b/lib/Target/X86/X86InstrShiftRotate.td
@@ -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;
+}
diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt
index 23c30f8f45..229c10dc1d 100644
--- a/test/MC/Disassembler/X86/simple-tests.txt
+++ b/test/MC/Disassembler/X86/simple-tests.txt
@@ -599,3 +599,15 @@
# 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
diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt
index b01c4eff5c..10d3c1fea6 100644
--- a/test/MC/Disassembler/X86/x86-32.txt
+++ b/test/MC/Disassembler/X86/x86-32.txt
@@ -543,3 +543,9 @@
# 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
diff --git a/test/MC/X86/x86_64-bmi-encoding.s b/test/MC/X86/x86_64-bmi-encoding.s
index 005ded2a1b..aa5aa9aa20 100644
--- a/test/MC/X86/x86_64-bmi-encoding.s
+++ b/test/MC/X86/x86_64-bmi-encoding.s
@@ -119,3 +119,35 @@
// 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
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 68e03738cf..d4c9629226 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -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));