From d5b39237a1a57d49b9aeb0c349a9f335e6d38b11 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper@gmail.com>
Date: Fri, 26 Dec 2014 18:19:44 +0000
Subject: [PATCH] [X86] Don't fail disassembly if REX.R/REX.B is used on an MMX
 register. Similar fix to not fail to disassembler CR9-CR15 references.

llvm-svn: 224861
---
 .../Target/X86/Disassembler/X86DisassemblerDecoder.cpp   | 6 +-----
 .../lib/Target/X86/Disassembler/X86DisassemblerDecoder.h | 9 ++++++++-
 llvm/test/MC/Disassembler/X86/prefixes.txt               | 9 +++++++++
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
index 770d406a180b..d9766f5c1574 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.cpp
@@ -1447,9 +1447,7 @@ static int readModRM(struct InternalInstruction* insn) {
     case TYPE_MM64:                                       \
     case TYPE_MM32:                                       \
     case TYPE_MM:                                         \
-      if (index > 7)                                      \
-        *valid = 0;                                       \
-      return prefix##_MM0 + index;                        \
+      return prefix##_MM0 + (index & 0x7);                \
     case TYPE_SEGMENTREG:                                 \
       if (index > 5)                                      \
         *valid = 0;                                       \
@@ -1459,8 +1457,6 @@ static int readModRM(struct InternalInstruction* insn) {
         *valid = 0;                                       \
       return prefix##_DR0 + index;                        \
     case TYPE_CONTROLREG:                                 \
-      if (index > 8)                                      \
-        *valid = 0;                                       \
       return prefix##_CR0 + index;                        \
     }                                                     \
   }
diff --git a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
index 457b3820b461..46a74ab4e529 100644
--- a/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
+++ b/llvm/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h
@@ -352,7 +352,14 @@ namespace X86Disassembler {
   ENTRY(CR5)          \
   ENTRY(CR6)          \
   ENTRY(CR7)          \
-  ENTRY(CR8)
+  ENTRY(CR8)          \
+  ENTRY(CR9)          \
+  ENTRY(CR10)         \
+  ENTRY(CR11)         \
+  ENTRY(CR12)         \
+  ENTRY(CR13)         \
+  ENTRY(CR14)         \
+  ENTRY(CR15)
 
 #define ALL_EA_BASES  \
   EA_BASES_16BIT      \
diff --git a/llvm/test/MC/Disassembler/X86/prefixes.txt b/llvm/test/MC/Disassembler/X86/prefixes.txt
index b8830dc3f3b9..5f0a58c74376 100644
--- a/llvm/test/MC/Disassembler/X86/prefixes.txt
+++ b/llvm/test/MC/Disassembler/X86/prefixes.txt
@@ -54,6 +54,15 @@
 # CHECK-NEXT: stosq
 0xf3 0xf3 0x48 0xab
 
+
+# Test that we can disassembler control registers above CR8
+# CHECK: movq %cr15, %rax
+0x44 0x0f 0x20 0xf8
+
+# Test that MMX ignore REX.R and REX.B.
+# CHECK: movq %mm0, %mm1
+0x46 0x0f 0x7f 0xc1
+
 # Test that a prefix on it's own works. It's debatable as to if this is 
 # something that is considered valid, but however as LLVM's own disassembler
 # has decided to disassemble prefixes as being separate opcodes, it therefore