Revision: 7279
Author:   [email protected]
Date:     Mon Mar 21 02:59:58 2011
Log:      Improve ARM-Simulator.

This patch
- removes the unimplemented code crash when rendering invalid/unknown instructions and prints "unknown" instead.
- prints the beginning of the constant pool marker.
- adds "da" as a shortcut for "disasm".
- print hexadecimal representation of double and single registers. This makes it easier to debug move/conversion code that uses temporary int32 values in floating point registers. - annotates the stack with short prints of the values (HeapObjects and smis), - makes disasm take an address or a register as second argument without a third argument, which defaults to printing ten instructions.

Review URL: http://codereview.chromium.org/6676042
http://code.google.com/p/v8/source/detail?r=7279

Modified:
 /branches/bleeding_edge/src/arm/assembler-arm.cc
 /branches/bleeding_edge/src/arm/constants-arm.h
 /branches/bleeding_edge/src/arm/disasm-arm.cc
 /branches/bleeding_edge/src/arm/simulator-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Fri Mar 18 13:35:07 2011 +++ /branches/bleeding_edge/src/arm/assembler-arm.cc Mon Mar 21 02:59:58 2011
@@ -2748,8 +2748,8 @@
   RecordComment("[ Constant Pool");

   // Put down constant pool marker "Undefined instruction" as specified by
-  // A3.1 Instruction set encoding.
-  emit(0x03000000 | num_prinfo_);
+  // A5.6 (ARMv7) Instruction set encoding.
+  emit(kConstantPoolMarker | num_prinfo_);

   // Emit constant pool entries.
   for (int i = 0; i < num_prinfo_; i++) {
=======================================
--- /branches/bleeding_edge/src/arm/constants-arm.h     Tue Mar 15 04:19:13 2011
+++ /branches/bleeding_edge/src/arm/constants-arm.h     Mon Mar 21 02:59:58 2011
@@ -89,6 +89,11 @@
 namespace v8 {
 namespace internal {

+// Constant pool marker.
+static const int kConstantPoolMarkerMask = 0xffe00000;
+static const int kConstantPoolMarker = 0x0c000000;
+static const int kConstantPoolLengthMask = 0x001ffff;
+
 // Number of registers in normal ARM mode.
 static const int kNumRegisters = 16;

=======================================
--- /branches/bleeding_edge/src/arm/disasm-arm.cc       Fri Mar 18 13:35:07 2011
+++ /branches/bleeding_edge/src/arm/disasm-arm.cc       Mon Mar 21 02:59:58 2011
@@ -89,6 +89,9 @@
   // Returns the length of the disassembled machine instruction in bytes.
   int InstructionDecode(byte* instruction);

+  static bool IsConstantPoolAt(byte* instr_ptr);
+  static int ConstantPoolSizeAt(byte* instr_ptr);
+
  private:
   // Bottleneck functions to print into the out_buffer.
   void PrintChar(const char ch);
@@ -899,6 +902,7 @@
     case da_x: {
       if (instr->HasW()) {
         Unknown(instr);  // not used in V8
+        return;
       }
       Format(instr, "'memop'cond'b 'rd, ['rn], #-'off12");
       break;
@@ -906,6 +910,7 @@
     case ia_x: {
       if (instr->HasW()) {
         Unknown(instr);  // not used in V8
+        return;
       }
       Format(instr, "'memop'cond'b 'rd, ['rn], #+'off12");
       break;
@@ -992,11 +997,15 @@


 void Decoder::DecodeType4(Instruction* instr) {
-  ASSERT(instr->Bit(22) == 0);  // Privileged mode currently not supported.
-  if (instr->HasL()) {
-    Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
+  if (instr->Bit(22) != 0) {
+    // Privileged mode currently not supported.
+    Unknown(instr);
   } else {
-    Format(instr, "stm'cond'pu 'rn'w, 'rlist");
+    if (instr->HasL()) {
+      Format(instr, "ldm'cond'pu 'rn'w, 'rlist");
+    } else {
+      Format(instr, "stm'cond'pu 'rn'w, 'rlist");
+    }
   }
 }

@@ -1042,6 +1051,8 @@
 // vmov: Rt = Sn
 // vcvt: Dd = Sm
 // vcvt: Sd = Dm
+// Dd = vabs(Dm)
+// Dd = vneg(Dm)
 // Dd = vadd(Dn, Dm)
 // Dd = vsub(Dn, Dm)
 // Dd = vmul(Dn, Dm)
@@ -1297,9 +1308,25 @@
         break;
     }
   } else {
-    UNIMPLEMENTED();  // Not used by V8.
+    Unknown(instr);  // Not used by V8.
   }
 }
+
+
+bool Decoder::IsConstantPoolAt(byte* instr_ptr) {
+  int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
+ return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker;
+}
+
+
+int Decoder::ConstantPoolSizeAt(byte* instr_ptr) {
+  if (IsConstantPoolAt(instr_ptr)) {
+    int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
+    return instruction_bits & kConstantPoolLengthMask;
+  } else {
+    return -1;
+  }
+}


 // Disassemble the instruction at *instr_ptr into the output buffer.
@@ -1310,9 +1337,17 @@
                                   "%08x       ",
                                   instr->InstructionBits());
   if (instr->ConditionField() == kSpecialCondition) {
-    UNIMPLEMENTED();
+    Unknown(instr);
     return Instruction::kInstrSize;
   }
+  int instruction_bits = *(reinterpret_cast<int*>(instr_ptr));
+ if ((instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker) {
+    out_buffer_pos_ += OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+                                    "constant pool begin (length %d)",
+                                    instruction_bits &
+                                    kConstantPoolLengthMask);
+    return Instruction::kInstrSize;
+  }
   switch (instr->TypeValue()) {
     case 0:
     case 1: {
@@ -1413,12 +1448,7 @@


 int Disassembler::ConstantPoolSizeAt(byte* instruction) {
-  int instruction_bits = *(reinterpret_cast<int*>(instruction));
-  if ((instruction_bits & 0xfff00000) == 0x03000000) {
-    return instruction_bits & 0x0000ffff;
-  } else {
-    return -1;
-  }
+  return v8::internal::Decoder::ConstantPoolSizeAt(instruction);
 }


=======================================
--- /branches/bleeding_edge/src/arm/simulator-arm.cc Fri Mar 18 13:35:07 2011 +++ /branches/bleeding_edge/src/arm/simulator-arm.cc Mon Mar 21 02:59:58 2011
@@ -316,16 +316,26 @@
             }
             for (int i = 0; i < kNumVFPDoubleRegisters; i++) {
               dvalue = GetVFPDoubleRegisterValue(i);
-              PrintF("%3s: %f\n",
-                  VFPRegisters::Name(i, true), dvalue);
+              uint64_t as_words = BitCast<uint64_t>(dvalue);
+              PrintF("%3s: %f 0x%08x %08x\n",
+                     VFPRegisters::Name(i, true),
+                     dvalue,
+                     static_cast<uint32_t>(as_words >> 32),
+                     static_cast<uint32_t>(as_words & 0xffffffff));
             }
           } else {
             if (GetValue(arg1, &value)) {
               PrintF("%s: 0x%08x %d \n", arg1, value, value);
             } else if (GetVFPSingleValue(arg1, &svalue)) {
-              PrintF("%s: %f \n", arg1, svalue);
+              uint32_t as_word = BitCast<uint32_t>(svalue);
+              PrintF("%s: %f 0x%08x\n", arg1, svalue, as_word);
             } else if (GetVFPDoubleValue(arg1, &dvalue)) {
-              PrintF("%s: %f \n", arg1, dvalue);
+              uint64_t as_words = BitCast<uint64_t>(dvalue);
+              PrintF("%s: %f 0x%08x %08x\n",
+                     arg1,
+                     dvalue,
+                     static_cast<uint32_t>(as_words >> 32),
+                     static_cast<uint32_t>(as_words & 0xffffffff));
             } else {
               PrintF("%s unrecognized\n", arg1);
             }
@@ -380,11 +390,24 @@
         end = cur + words;

         while (cur < end) {
-          PrintF("  0x%08x:  0x%08x %10d\n",
+          PrintF("  0x%08x:  0x%08x %10d",
                  reinterpret_cast<intptr_t>(cur), *cur, *cur);
+          HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
+          int value = *cur;
+          Heap* current_heap = v8::internal::Isolate::Current()->heap();
+          if (current_heap->Contains(obj) || ((value & 1) == 0)) {
+            PrintF(" (");
+            if ((value & 1) == 0) {
+              PrintF("smi %d", value / 2);
+            } else {
+              obj->ShortPrint();
+            }
+            PrintF(")");
+          }
+          PrintF("\n");
           cur++;
         }
-      } else if (strcmp(cmd, "disasm") == 0) {
+      } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
         disasm::NameConverter converter;
         disasm::Disassembler dasm(converter);
         // use a reasonably large buffer
@@ -398,11 +421,23 @@
           cur = reinterpret_cast<byte*>(sim_->get_pc());
           end = cur + (10 * Instruction::kInstrSize);
         } else if (argc == 2) {
-          int32_t value;
-          if (GetValue(arg1, &value)) {
-            cur = reinterpret_cast<byte*>(sim_->get_pc());
-            // Disassemble <arg1> instructions.
-            end = cur + (value * Instruction::kInstrSize);
+          int regnum = Registers::Number(arg1);
+          if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
+            // The argument is an address or a register name.
+            int32_t value;
+            if (GetValue(arg1, &value)) {
+              cur = reinterpret_cast<byte*>(value);
+              // Disassemble 10 instructions at <arg1>.
+              end = cur + (10 * Instruction::kInstrSize);
+            }
+          } else {
+            // The argument is the number of instructions.
+            int32_t value;
+            if (GetValue(arg1, &value)) {
+              cur = reinterpret_cast<byte*>(sim_->get_pc());
+              // Disassemble <arg1> instructions.
+              end = cur + (value * Instruction::kInstrSize);
+            }
           }
         } else {
           int32_t value1;
@@ -524,8 +559,10 @@
         PrintF("mem <address> [<words>]\n");
         PrintF("  dump memory content, default dump 10 words)\n");
         PrintF("disasm [<instructions>]\n");
-        PrintF("disasm [[<address>] <instructions>]\n");
-        PrintF("  disassemble code, default is 10 instructions from pc\n");
+        PrintF("disasm [<address/register>]\n");
+        PrintF("disasm [[<address/register>] <instructions>]\n");
+        PrintF("  disassemble code, default is 10 instructions\n");
+        PrintF("  from pc (alias 'di')\n");
         PrintF("gdb\n");
         PrintF("  enter gdb\n");
         PrintF("break <address>\n");
@@ -543,7 +580,7 @@
         PrintF("    The first %d stop codes are watched:\n",
                Simulator::kNumOfWatchedStops);
         PrintF("    - They can be enabled / disabled: the Simulator\n");
-        PrintF("       will / won't stop when hitting them.\n");
+        PrintF("      will / won't stop when hitting them.\n");
PrintF(" - The Simulator keeps track of how many times they \n");
         PrintF("      are met. (See the info command.) Going over a\n");
         PrintF("      disabled stop still increases its counter. \n");

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to