summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2013-12-31 17:21:44 +0000
committerCraig Topper <craig.topper@gmail.com>2013-12-31 17:21:44 +0000
commit5cbbd7e1a5fb86e5495326c02f77356a357ec439 (patch)
tree2b6b3dd5ba8117f007b5111075bafbc452b13878 /utils
parent31b27056a6b3585ddd2bd21689434a73d79fe888 (diff)
downloadllvm-5cbbd7e1a5fb86e5495326c02f77356a357ec439.tar.gz
llvm-5cbbd7e1a5fb86e5495326c02f77356a357ec439.tar.bz2
llvm-5cbbd7e1a5fb86e5495326c02f77356a357ec439.tar.xz
Revert r198238 and add FP disassembler tests. It didn't work and I didn't realized we had no FP disassembler test cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198265 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/X86ModRMFilters.cpp2
-rw-r--r--utils/TableGen/X86ModRMFilters.h20
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp54
3 files changed, 51 insertions, 25 deletions
diff --git a/utils/TableGen/X86ModRMFilters.cpp b/utils/TableGen/X86ModRMFilters.cpp
index 1641613aa3..a311603df9 100644
--- a/utils/TableGen/X86ModRMFilters.cpp
+++ b/utils/TableGen/X86ModRMFilters.cpp
@@ -17,6 +17,8 @@ void DumbFilter::anchor() { }
void ModFilter::anchor() { }
+void AddRegEscapeFilter::anchor() { }
+
void ExtendedFilter::anchor() { }
void ExactFilter::anchor() { }
diff --git a/utils/TableGen/X86ModRMFilters.h b/utils/TableGen/X86ModRMFilters.h
index 049cfc1d3b..5ab1a48846 100644
--- a/utils/TableGen/X86ModRMFilters.h
+++ b/utils/TableGen/X86ModRMFilters.h
@@ -84,6 +84,26 @@ public:
}
};
+/// AddRegEscapeFilter - Some escape opcodes have one of the register operands
+/// added to the ModR/M byte, meaning that a range of eight ModR/M values
+/// maps to a single instruction. Such instructions require the ModR/M byte
+/// to fall between 0xc0 and 0xff.
+class AddRegEscapeFilter : public ModRMFilter {
+ virtual void anchor();
+ uint8_t ModRM;
+public:
+ /// Constructor
+ ///
+ /// \param modRM The value of the ModR/M byte when the register operand
+ /// refers to the first register in the register set.
+ AddRegEscapeFilter(uint8_t modRM) : ModRM(modRM) {
+ }
+
+ bool accepts(uint8_t modRM) const {
+ return (modRM >= ModRM && modRM < ModRM + 8);
+ }
+};
+
/// ExtendedFilter - Extended opcodes are classified based on the value of the
/// mod field [bits 7-6] and the value of the nnn field [bits 5-3].
class ExtendedFilter : public ModRMFilter {
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 6a2a0d504f..1eb579df3f 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -1075,9 +1075,14 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::DE:
case X86Local::DF:
assert(Opcode >= 0xc0 && "Unexpected opcode for an escape opcode");
- assert(Form == X86Local::RawFrm);
opcodeType = ONEBYTE;
- filter = new ExactFilter(Opcode);
+ if (Form == X86Local::AddRegFrm) {
+ Spec->modifierType = MODIFIER_MODRM;
+ Spec->modifierBase = Opcode;
+ filter = new AddRegEscapeFilter(Opcode);
+ } else {
+ filter = new ExactFilter(Opcode);
+ }
opcodeToSet = 0xd8 + (Prefix - X86Local::D8);
break;
case X86Local::REP:
@@ -1125,16 +1130,6 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
switch (Form) {
default:
llvm_unreachable("Unhandled escape opcode form");
- case X86Local::MRM0r:
- case X86Local::MRM1r:
- case X86Local::MRM2r:
- case X86Local::MRM3r:
- case X86Local::MRM4r:
- case X86Local::MRM5r:
- case X86Local::MRM6r:
- case X86Local::MRM7r:
- filter = new ExtendedFilter(true, Form - X86Local::MRM0r);
- break;
case X86Local::MRM0m:
case X86Local::MRM1m:
case X86Local::MRM2m:
@@ -1162,22 +1157,31 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
assert(filter && "Filter not set");
if (Form == X86Local::AddRegFrm) {
- assert(opcodeToSet < 0xf9 &&
- "Not enough room for all ADDREG_FRM operands");
-
- uint8_t currentOpcode;
-
- for (currentOpcode = opcodeToSet;
- currentOpcode < opcodeToSet + 8;
- ++currentOpcode)
+ if(Spec->modifierType != MODIFIER_MODRM) {
+ assert(opcodeToSet < 0xf9 &&
+ "Not enough room for all ADDREG_FRM operands");
+
+ uint8_t currentOpcode;
+
+ for (currentOpcode = opcodeToSet;
+ currentOpcode < opcodeToSet + 8;
+ ++currentOpcode)
+ tables.setTableFields(opcodeType,
+ insnContext(),
+ currentOpcode,
+ *filter,
+ UID, Is32Bit, IgnoresVEX_L);
+
+ Spec->modifierType = MODIFIER_OPCODE;
+ Spec->modifierBase = opcodeToSet;
+ } else {
+ // modifierBase was set where MODIFIER_MODRM was set
tables.setTableFields(opcodeType,
insnContext(),
- currentOpcode,
+ opcodeToSet,
*filter,
UID, Is32Bit, IgnoresVEX_L);
-
- Spec->modifierType = MODIFIER_OPCODE;
- Spec->modifierBase = opcodeToSet;
+ }
} else {
tables.setTableFields(opcodeType,
insnContext(),
@@ -1337,7 +1341,6 @@ OperandEncoding RecognizableInstr::immediateEncodingFromString
OperandEncoding RecognizableInstr::rmRegisterEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
- ENCODING("RST", ENCODING_I)
ENCODING("GR16", ENCODING_RM)
ENCODING("GR32", ENCODING_RM)
ENCODING("GR32orGR64", ENCODING_RM)
@@ -1490,6 +1493,7 @@ OperandEncoding RecognizableInstr::relocationEncodingFromString
OperandEncoding RecognizableInstr::opcodeModifierEncodingFromString
(const std::string &s,
bool hasOpSizePrefix) {
+ ENCODING("RST", ENCODING_I)
ENCODING("GR32", ENCODING_Rv)
ENCODING("GR64", ENCODING_RO)
ENCODING("GR16", ENCODING_Rv)