bool PrintCommand::Run(Debugger* debugger) { VIXL_ASSERT(debugger->IsDebuggerRunning()); Token* tok = target(); if (tok->IsIdentifier()) { char* identifier = IdentifierToken::Cast(tok)->value(); if (strcmp(identifier, "regs") == 0) { debugger->PrintRegisters(); } else if (strcmp(identifier, "fpregs") == 0) { debugger->PrintFPRegisters(); } else if (strcmp(identifier, "sysregs") == 0) { debugger->PrintSystemRegisters(); } else if (strcmp(identifier, "pc") == 0) { printf("pc = %16p\n", reinterpret_cast<const void*>(debugger->pc())); } else { printf(" ** Unknown identifier to print: %s **\n", identifier); } return false; } FormatToken* format_tok = format(); VIXL_ASSERT(format_tok != NULL); if (format_tok->type_code() == 'i') { // TODO(all): Add support for instruction disassembly. printf(" ** unsupported format: instructions **\n"); return false; } if (tok->IsRegister()) { RegisterToken* reg_tok = RegisterToken::Cast(tok); Register reg = reg_tok->value(); debugger->PrintRegister(reg, reg_tok->Name(), format_tok); return false; } if (tok->IsFPRegister()) { FPRegister fpreg = FPRegisterToken::Cast(tok)->value(); debugger->PrintFPRegister(fpreg, format_tok); return false; } VIXL_UNREACHABLE(); return false; }
DebugCommand* PrintCommand::Build(std::vector<Token*> args) { if (args.size() < 2) { return new InvalidCommand(args, -1, "too few arguments"); } Token* target = args[1]; if (!target->IsRegister() && !target->IsFPRegister() && !target->IsIdentifier()) { return new InvalidCommand(args, 1, "expects reg or identifier"); } FormatToken* format = NULL; int target_size = 0; if (target->IsRegister()) { Register reg = RegisterToken::Cast(target)->value(); target_size = reg.SizeInBytes(); } else if (target->IsFPRegister()) { FPRegister fpreg = FPRegisterToken::Cast(target)->value(); target_size = fpreg.SizeInBytes(); } // If the target is an identifier there must be no format. This is checked // in the switch statement below. switch (args.size()) { case 2: { if (target->IsRegister()) { switch (target_size) { case 4: format = new Format<uint32_t>("%08" PRIx32, 'x'); break; case 8: format = new Format<uint64_t>("%016" PRIx64, 'x'); break; default: VIXL_UNREACHABLE(); } } else if (target->IsFPRegister()) { switch (target_size) { case 4: format = new Format<float>("%8g", 'f'); break; case 8: format = new Format<double>("%8g", 'f'); break; default: VIXL_UNREACHABLE(); } } break; } case 3: { if (target->IsIdentifier()) { return new InvalidCommand(args, 2, "format is only allowed with registers"); } Token* second = args[2]; if (!second->IsFormat()) { return new InvalidCommand(args, 2, "expects format"); } format = FormatToken::Cast(second); if (format->SizeOf() > target_size) { return new InvalidCommand(args, 2, "format too wide"); } break; } default: return new InvalidCommand(args, -1, "too many arguments"); } return new PrintCommand(args[0], target, format); }