DebugCommand* ExamineCommand::Build(std::vector<Token*> args) { if (args.size() < 2) { return new InvalidCommand(args, -1, "too few arguments"); } Token* target = args[1]; if (!target->CanAddressMemory()) { return new InvalidCommand(args, 1, "expects address"); } FormatToken* format = NULL; IntegerToken* count = NULL; switch (args.size()) { case 2: { // mem addr[.x64] [10] format = new Format<uint64_t>("%016" PRIx64, 'x'); count = new IntegerToken(10); break; } case 3: { // mem addr.format [10] // mem addr[.x64] n Token* second = args[2]; if (second->IsFormat()) { format = FormatToken::Cast(second); count = new IntegerToken(10); break; } else if (second->IsInteger()) { format = new Format<uint64_t>("%016" PRIx64, 'x'); count = IntegerToken::Cast(second); } else { return new InvalidCommand(args, 2, "expects format or integer"); } VIXL_UNREACHABLE(); break; } case 4: { // mem addr.format n Token* second = args[2]; Token* third = args[3]; if (!second->IsFormat() || !third->IsInteger()) { return new InvalidCommand(args, -1, "expects addr[.format] [n]"); } format = FormatToken::Cast(second); count = IntegerToken::Cast(third); break; } default: return new InvalidCommand(args, -1, "too many arguments"); } return new ExamineCommand(args[0], target, format, count); }
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); }