X86: Compute PCI config addresses correctly.
[gem5.git] / src / arch / x86 / insts / static_inst.cc
index 948a74bc178af63118087af251cdbd29c89661b7..f4ed446036a8f3032d6ae171cfc62c11288c66a6 100644 (file)
  */
 
 #include "arch/x86/insts/static_inst.hh"
+#include "arch/x86/segmentregs.hh"
 
 namespace X86ISA
 {
     void X86StaticInst::printMnemonic(std::ostream &os,
             const char * mnemonic) const
     {
-        ccprintf(os, "\t%s   ", mnemonic);
+        ccprintf(os, "  %s   ", mnemonic);
     }
 
     void X86StaticInst::printMnemonic(std::ostream &os,
             const char * instMnemonic, const char * mnemonic) const
     {
-        ccprintf(os, "\t%s : %s   ", instMnemonic, mnemonic);
+        ccprintf(os, "  %s : %s   ", instMnemonic, mnemonic);
     }
 
     void X86StaticInst::printSegment(std::ostream &os, int segment) const
     {
         switch (segment)
         {
-          case 0:
+          case SEGMENT_REG_ES:
             ccprintf(os, "ES");
             break;
-          case 1:
+          case SEGMENT_REG_CS:
             ccprintf(os, "CS");
             break;
-          case 2:
+          case SEGMENT_REG_SS:
             ccprintf(os, "SS");
             break;
-          case 3:
+          case SEGMENT_REG_DS:
             ccprintf(os, "DS");
             break;
-          case 4:
+          case SEGMENT_REG_FS:
             ccprintf(os, "FS");
             break;
-          case 5:
+          case SEGMENT_REG_GS:
             ccprintf(os, "GS");
             break;
+          case SEGMENT_REG_HS:
+            ccprintf(os, "HS");
+            break;
+          case SEGMENT_REG_TSL:
+            ccprintf(os, "TSL");
+            break;
+          case SEGMENT_REG_TSG:
+            ccprintf(os, "TSG");
+            break;
+          case SEGMENT_REG_LS:
+            ccprintf(os, "LS");
+            break;
+          case SEGMENT_REG_MS:
+            ccprintf(os, "MS");
+            break;
+          case SYS_SEGMENT_REG_TR:
+            ccprintf(os, "TR");
+            break;
+          case SYS_SEGMENT_REG_IDTR:
+            ccprintf(os, "IDTR");
+            break;
           default:
             panic("Unrecognized segment %d\n", segment);
         }
@@ -126,7 +148,7 @@ namespace X86ISA
             {"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
 
         if (reg < FP_Base_DepTag) {
-            char * suffix = "";
+            const char * suffix = "";
             bool fold = reg & (1 << 6);
             reg &= ~(1 << 6);
 
@@ -192,7 +214,24 @@ namespace X86ISA
             }
             ccprintf(os, suffix);
         } else if (reg < Ctrl_Base_DepTag) {
-            ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
+            int fpindex = reg - FP_Base_DepTag;
+            if(fpindex < NumMMXRegs) {
+                ccprintf(os, "%%mmx%d", reg - FP_Base_DepTag);
+                return;
+            }
+            fpindex -= NumMMXRegs;
+            if(fpindex < NumXMMRegs * 2) {
+                ccprintf(os, "%%xmm%d_%s", fpindex / 2,
+                        (fpindex % 2) ? "high": "low");
+                return;
+            }
+            fpindex -= NumXMMRegs * 2;
+            if(fpindex < NumMicroFpRegs) {
+                ccprintf(os, "%%ufp%d", fpindex);
+                return;
+            }
+            fpindex -= NumMicroFpRegs;
+            ccprintf(os, "%%st(%d)", fpindex);
         } else {
             switch (reg - Ctrl_Base_DepTag) {
               default:
@@ -201,6 +240,44 @@ namespace X86ISA
         }
     }
 
+    void X86StaticInst::printMem(std::ostream &os, uint8_t segment,
+            uint8_t scale, RegIndex index, RegIndex base,
+            uint64_t disp, uint8_t addressSize, bool rip) const
+    {
+        bool someAddr = false;
+        printSegment(os, segment);
+        os << ":[";
+        if (rip) {
+            os << "rip";
+            someAddr = true;
+        } else {
+            if (scale != 0 && index != ZeroReg)
+            {
+                if(scale != 1)
+                    ccprintf(os, "%d*", scale);
+                printReg(os, index, addressSize);
+                someAddr = true;
+            }
+            if (base != ZeroReg)
+            {
+                if(someAddr)
+                    os << " + ";
+                printReg(os, base, addressSize);
+                someAddr = true;
+            }
+        }
+        if (disp != 0)
+        {
+            if(someAddr)
+                os << " + ";
+            ccprintf(os, "%#x", disp);
+            someAddr = true;
+        }
+        if (!someAddr)
+            os << "0";
+        os << "]";
+    }
+
     std::string X86StaticInst::generateDisassembly(Addr pc,
         const SymbolTable *symtab) const
     {