diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc index 09a68f3ad1..b57602c4e0 100644 --- a/src/arm/assembler-arm.cc +++ b/src/arm/assembler-arm.cc @@ -2748,8 +2748,8 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) { 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++) { diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h index 3adb916a54..0ac567cb11 100644 --- a/src/arm/constants-arm.h +++ b/src/arm/constants-arm.h @@ -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; diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc index 09a26260ee..899b88a6d3 100644 --- a/src/arm/disasm-arm.cc +++ b/src/arm/disasm-arm.cc @@ -89,6 +89,9 @@ class Decoder { // 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 @@ void Decoder::DecodeType2(Instruction* instr) { 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 @@ void Decoder::DecodeType2(Instruction* instr) { 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::DecodeType3(Instruction* instr) { 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 @@ int Decoder::DecodeType7(Instruction* instr) { // 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,7 +1308,23 @@ void Decoder::DecodeType6CoprocessorIns(Instruction* instr) { break; } } else { - UNIMPLEMENTED(); // Not used by V8. + Unknown(instr); // Not used by V8. + } +} + + +bool Decoder::IsConstantPoolAt(byte* instr_ptr) { + int instruction_bits = *(reinterpret_cast(instr_ptr)); + return (instruction_bits & kConstantPoolMarkerMask) == kConstantPoolMarker; +} + + +int Decoder::ConstantPoolSizeAt(byte* instr_ptr) { + if (IsConstantPoolAt(instr_ptr)) { + int instruction_bits = *(reinterpret_cast(instr_ptr)); + return instruction_bits & kConstantPoolLengthMask; + } else { + return -1; } } @@ -1310,7 +1337,15 @@ int Decoder::InstructionDecode(byte* instr_ptr) { "%08x ", instr->InstructionBits()); if (instr->ConditionField() == kSpecialCondition) { - UNIMPLEMENTED(); + Unknown(instr); + return Instruction::kInstrSize; + } + int instruction_bits = *(reinterpret_cast(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()) { @@ -1413,12 +1448,7 @@ int Disassembler::InstructionDecode(v8::internal::Vector buffer, int Disassembler::ConstantPoolSizeAt(byte* instruction) { - int instruction_bits = *(reinterpret_cast(instruction)); - if ((instruction_bits & 0xfff00000) == 0x03000000) { - return instruction_bits & 0x0000ffff; - } else { - return -1; - } + return v8::internal::Decoder::ConstantPoolSizeAt(instruction); } diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 28954f6300..46797d950c 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -316,16 +316,26 @@ void ArmDebugger::Debug() { } for (int i = 0; i < kNumVFPDoubleRegisters; i++) { dvalue = GetVFPDoubleRegisterValue(i); - PrintF("%3s: %f\n", - VFPRegisters::Name(i, true), dvalue); + uint64_t as_words = BitCast(dvalue); + PrintF("%3s: %f 0x%08x %08x\n", + VFPRegisters::Name(i, true), + dvalue, + static_cast(as_words >> 32), + static_cast(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(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(dvalue); + PrintF("%s: %f 0x%08x %08x\n", + arg1, + dvalue, + static_cast(as_words >> 32), + static_cast(as_words & 0xffffffff)); } else { PrintF("%s unrecognized\n", arg1); } @@ -380,11 +390,24 @@ void ArmDebugger::Debug() { end = cur + words; while (cur < end) { - PrintF(" 0x%08x: 0x%08x %10d\n", + PrintF(" 0x%08x: 0x%08x %10d", reinterpret_cast(cur), *cur, *cur); + HeapObject* obj = reinterpret_cast(*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 @@ void ArmDebugger::Debug() { cur = reinterpret_cast(sim_->get_pc()); end = cur + (10 * Instruction::kInstrSize); } else if (argc == 2) { - int32_t value; - if (GetValue(arg1, &value)) { - cur = reinterpret_cast(sim_->get_pc()); - // Disassemble 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(value); + // Disassemble 10 instructions at . + end = cur + (10 * Instruction::kInstrSize); + } + } else { + // The argument is the number of instructions. + int32_t value; + if (GetValue(arg1, &value)) { + cur = reinterpret_cast(sim_->get_pc()); + // Disassemble instructions. + end = cur + (value * Instruction::kInstrSize); + } } } else { int32_t value1; @@ -524,8 +559,10 @@ void ArmDebugger::Debug() { PrintF("mem
[]\n"); PrintF(" dump memory content, default dump 10 words)\n"); PrintF("disasm []\n"); - PrintF("disasm [[
] ]\n"); - PrintF(" disassemble code, default is 10 instructions from pc\n"); + PrintF("disasm [
]\n"); + PrintF("disasm [[
] ]\n"); + PrintF(" disassemble code, default is 10 instructions\n"); + PrintF(" from pc (alias 'di')\n"); PrintF("gdb\n"); PrintF(" enter gdb\n"); PrintF("break
\n"); @@ -543,7 +580,7 @@ void ArmDebugger::Debug() { 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");