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