[LLDB][MIPS] Emulation of MIPS64 floating-point branch instructions
Patch by Jaydeep Patil

SUMMARY:
1. Added emulation of MIPS64 floating-point branch instructions
2. Updated GetRegisterInfo to recognize floating-point registers
3. Provided CPU information while creating createMCSubtargetInfo in disassembler
4. Bug fix in emulation of JIC and JIALC
5. Correct identification of breakpoint when set in a delay slot of a branch instruction

Reviewers: clayborg
Subscribers: bhushan, mohit.bhakkad, sagar, nitesh.jain, lldb-commits.
Differential Revision: http://reviews.llvm.org/D10355

llvm-svn: 239996
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
index 679ed5b..ba9bad7 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
@@ -415,7 +415,7 @@
 
 
 
-DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
+DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, const char *cpu, unsigned flavor, DisassemblerLLVMC &owner):
     m_is_valid(true)
 {
     std::string Error;
@@ -431,7 +431,7 @@
 
     std::string features_str;
 
-    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
+    m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, cpu,
                                                                 features_str));
 
     std::unique_ptr<llvm::MCRegisterInfo> reg_info(curr_target->createMCRegInfo(triple));
@@ -637,7 +637,45 @@
         triple = thumb_arch.GetTriple().getTriple().c_str();
     }
 
-    m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
+    const char *cpu = "";
+    
+    switch (arch.GetCore())
+    {
+        case ArchSpec::eCore_mips32:
+        case ArchSpec::eCore_mips32el:
+            cpu = "mips32"; break;
+        case ArchSpec::eCore_mips32r2:
+        case ArchSpec::eCore_mips32r2el:
+            cpu = "mips32r2"; break;
+        case ArchSpec::eCore_mips32r3:
+        case ArchSpec::eCore_mips32r3el:
+            cpu = "mips32r3"; break;
+        case ArchSpec::eCore_mips32r5:
+        case ArchSpec::eCore_mips32r5el:
+            cpu = "mips32r5"; break;
+        case ArchSpec::eCore_mips32r6:
+        case ArchSpec::eCore_mips32r6el:
+            cpu = "mips32r6"; break;
+        case ArchSpec::eCore_mips64:
+        case ArchSpec::eCore_mips64el:
+            cpu = "mips64"; break;
+        case ArchSpec::eCore_mips64r2:
+        case ArchSpec::eCore_mips64r2el:
+            cpu = "mips64r2"; break;
+        case ArchSpec::eCore_mips64r3:
+        case ArchSpec::eCore_mips64r3el:
+            cpu = "mips64r3"; break;
+        case ArchSpec::eCore_mips64r5:
+        case ArchSpec::eCore_mips64r5el:
+            cpu = "mips64r5"; break;
+        case ArchSpec::eCore_mips64r6:
+        case ArchSpec::eCore_mips64r6el:
+            cpu = "mips64r6"; break;
+        default:
+            cpu = ""; break;
+    }
+    
+    m_disasm_ap.reset (new LLVMCDisassembler(triple, cpu, flavor, *this));
     if (!m_disasm_ap->IsValid())
     {
         // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
@@ -649,7 +687,7 @@
     if (arch.GetTriple().getArch() == llvm::Triple::arm)
     {
         std::string thumb_triple(thumb_arch.GetTriple().getTriple());
-        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
+        m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), nullptr, flavor, *this));
         if (!m_alternate_disasm_ap->IsValid())
         {
             m_disasm_ap.reset();
diff --git a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
index 6ab9e9a..4c32e25 100644
--- a/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
+++ b/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
@@ -41,7 +41,7 @@
     class LLVMCDisassembler
     {
     public:
-        LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner);
+        LLVMCDisassembler (const char *triple, const char *cpu, unsigned flavor, DisassemblerLLVMC &owner);
 
         ~LLVMCDisassembler();