summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2012-02-27 01:54:29 +0000
committerCraig Topper <craig.topper@gmail.com>2012-02-27 01:54:29 +0000
commit930a1ebd929aa0ab4c2610e7f7a721c18dcfe052 (patch)
tree83ccfe46e34d20ee3880401d436ca1c952cd7215
parent7497a9a7e816857402cf78ac930f286e800c69cf (diff)
downloadllvm-930a1ebd929aa0ab4c2610e7f7a721c18dcfe052.tar.gz
llvm-930a1ebd929aa0ab4c2610e7f7a721c18dcfe052.tar.bz2
llvm-930a1ebd929aa0ab4c2610e7f7a721c18dcfe052.tar.xz
X86 disassembler support for jcxz, jecxz, and jrcxz. Fixes PR11643. Patch by Kay Tiong Khoo.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151510 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoder.c2
-rw-r--r--lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h8
-rw-r--r--lib/Target/X86/X86InstrControl.td2
-rw-r--r--test/MC/Disassembler/X86/simple-tests.txt5
-rw-r--r--test/MC/Disassembler/X86/x86-32.txt6
-rw-r--r--utils/TableGen/X86DisassemblerTables.cpp9
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp5
-rw-r--r--utils/TableGen/X86RecognizableInstr.h2
8 files changed, 36 insertions, 3 deletions
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
index e2c76b7f08..b0e66f00c7 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c
@@ -763,6 +763,8 @@ static int getID(struct InternalInstruction* insn, void *miiArg) {
else {
if (isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation))
attrMask |= ATTR_OPSIZE;
+ else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation))
+ attrMask |= ATTR_ADSIZE;
else if (isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation))
attrMask |= ATTR_XS;
else if (isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation))
diff --git a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
index b5995c1e68..d5e7c69019 100644
--- a/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
+++ b/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h
@@ -54,8 +54,9 @@
ENUM_ENTRY(ATTR_XD, 0x04) \
ENUM_ENTRY(ATTR_REXW, 0x08) \
ENUM_ENTRY(ATTR_OPSIZE, 0x10) \
- ENUM_ENTRY(ATTR_VEX, 0x20) \
- ENUM_ENTRY(ATTR_VEXL, 0x40)
+ ENUM_ENTRY(ATTR_ADSIZE, 0x20) \
+ ENUM_ENTRY(ATTR_VEX, 0x40) \
+ ENUM_ENTRY(ATTR_VEXL, 0x80)
#define ENUM_ENTRY(n, v) n = v,
enum attributeBits {
@@ -77,6 +78,8 @@ enum attributeBits {
"64-bit mode but no more") \
ENUM_ENTRY(IC_OPSIZE, 3, "requires an OPSIZE prefix, so " \
"operands change width") \
+ ENUM_ENTRY(IC_ADSIZE, 3, "requires an ADSIZE prefix, so " \
+ "operands change width") \
ENUM_ENTRY(IC_XD, 2, "may say something about the opcode " \
"but not the operands") \
ENUM_ENTRY(IC_XS, 2, "may say something about the opcode " \
@@ -88,6 +91,7 @@ enum attributeBits {
ENUM_ENTRY(IC_64BIT_REXW, 4, "requires a REX.W prefix, so operands "\
"change width; overrides IC_OPSIZE") \
ENUM_ENTRY(IC_64BIT_OPSIZE, 3, "Just as meaningful as IC_OPSIZE") \
+ ENUM_ENTRY(IC_64BIT_ADSIZE, 3, "Just as meaningful as IC_ADSIZE") \
ENUM_ENTRY(IC_64BIT_XD, 5, "XD instructions are SSE; REX.W is " \
"secondary") \
ENUM_ENTRY(IC_64BIT_XS, 5, "Just as meaningful as IC_64BIT_XD") \
diff --git a/lib/Target/X86/X86InstrControl.td b/lib/Target/X86/X86InstrControl.td
index f3938751d7..ba86098390 100644
--- a/lib/Target/X86/X86InstrControl.td
+++ b/lib/Target/X86/X86InstrControl.td
@@ -77,7 +77,7 @@ defm JLE : ICBr<0x7E, 0x8E, "jle\t$dst", X86_COND_LE>;
defm JG : ICBr<0x7F, 0x8F, "jg\t$dst" , X86_COND_G>;
// jcx/jecx/jrcx instructions.
-let isAsmParserOnly = 1, isBranch = 1, isTerminator = 1 in {
+let isBranch = 1, isTerminator = 1 in {
// These are the 32-bit versions of this instruction for the asmparser. In
// 32-bit mode, the address size prefix is jcxz and the unprefixed version is
// jecxz.
diff --git a/test/MC/Disassembler/X86/simple-tests.txt b/test/MC/Disassembler/X86/simple-tests.txt
index 42213a647d..840d5fab2d 100644
--- a/test/MC/Disassembler/X86/simple-tests.txt
+++ b/test/MC/Disassembler/X86/simple-tests.txt
@@ -6,6 +6,11 @@
# CHECK: int $33
0xCD 0x21
+# CHECK: jrcxz -127
+0xe3 0x81
+
+# CHECK: jecxz -127
+0x67 0xe3 0x81
# CHECK: addb %al, (%rax)
0 0
diff --git a/test/MC/Disassembler/X86/x86-32.txt b/test/MC/Disassembler/X86/x86-32.txt
index 4120ed0c88..5f2f6085a3 100644
--- a/test/MC/Disassembler/X86/x86-32.txt
+++ b/test/MC/Disassembler/X86/x86-32.txt
@@ -11,6 +11,12 @@
# CHECK: calll
0xff 0xd0
+# CHECK: jecxz -127
+0xe3 0x81
+
+# CHECK: jcxz -127
+0x67 0xe3 0x81
+
# CHECK: incl
0x40
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp
index 33cc017aba..52b2486a0d 100644
--- a/utils/TableGen/X86DisassemblerTables.cpp
+++ b/utils/TableGen/X86DisassemblerTables.cpp
@@ -41,15 +41,20 @@ static inline bool inheritsFrom(InstructionContext child,
case IC:
return(inheritsFrom(child, IC_64BIT) ||
inheritsFrom(child, IC_OPSIZE) ||
+ inheritsFrom(child, IC_ADSIZE) ||
inheritsFrom(child, IC_XD) ||
inheritsFrom(child, IC_XS));
case IC_64BIT:
return(inheritsFrom(child, IC_64BIT_REXW) ||
inheritsFrom(child, IC_64BIT_OPSIZE) ||
+ inheritsFrom(child, IC_64BIT_ADSIZE) ||
inheritsFrom(child, IC_64BIT_XD) ||
inheritsFrom(child, IC_64BIT_XS));
case IC_OPSIZE:
return inheritsFrom(child, IC_64BIT_OPSIZE);
+ case IC_ADSIZE:
+ case IC_64BIT_ADSIZE:
+ return false;
case IC_XD:
return inheritsFrom(child, IC_64BIT_XD);
case IC_XS:
@@ -553,6 +558,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
o << "IC_64BIT_XD";
else if ((index & ATTR_64BIT) && (index & ATTR_OPSIZE))
o << "IC_64BIT_OPSIZE";
+ else if ((index & ATTR_64BIT) && (index & ATTR_ADSIZE))
+ o << "IC_64BIT_ADSIZE";
else if ((index & ATTR_64BIT) && (index & ATTR_REXW))
o << "IC_64BIT_REXW";
else if ((index & ATTR_64BIT))
@@ -567,6 +574,8 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, uint32_t &i) const {
o << "IC_XD";
else if (index & ATTR_OPSIZE)
o << "IC_OPSIZE";
+ else if (index & ATTR_ADSIZE)
+ o << "IC_ADSIZE";
else
o << "IC";
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 0055291368..5bf473d95e 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -225,6 +225,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
SegOvr = byteFromRec(Rec, "SegOvrBits");
HasOpSizePrefix = Rec->getValueAsBit("hasOpSizePrefix");
+ HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix");
HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix");
HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix");
@@ -343,6 +344,8 @@ InstructionContext RecognizableInstr::insnContext() const {
insnContext = IC_64BIT_XS_OPSIZE;
else if (HasOpSizePrefix)
insnContext = IC_64BIT_OPSIZE;
+ else if (HasAdSizePrefix)
+ insnContext = IC_64BIT_ADSIZE;
else if (HasREX_WPrefix &&
(Prefix == X86Local::XS || Prefix == X86Local::T8XS))
insnContext = IC_64BIT_REXW_XS;
@@ -369,6 +372,8 @@ InstructionContext RecognizableInstr::insnContext() const {
insnContext = IC_XS_OPSIZE;
else if (HasOpSizePrefix)
insnContext = IC_OPSIZE;
+ else if (HasAdSizePrefix)
+ insnContext = IC_ADSIZE;
else if (Prefix == X86Local::XD || Prefix == X86Local::T8XD ||
Prefix == X86Local::TAXD)
insnContext = IC_XD;
diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h
index 3ae112b1e7..6c0a234b5e 100644
--- a/utils/TableGen/X86RecognizableInstr.h
+++ b/utils/TableGen/X86RecognizableInstr.h
@@ -50,6 +50,8 @@ private:
uint8_t SegOvr;
/// The hasOpSizePrefix field from the record
bool HasOpSizePrefix;
+ /// The hasAdSizePrefix field from the record
+ bool HasAdSizePrefix;
/// The hasREX_WPrefix field from the record
bool HasREX_WPrefix;
/// The hasVEXPrefix field from the record