| // Copyright 2021 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "src/developer/debug/ipc/automation_instruction.h" | |
| #include <sstream> | |
| #include "src/developer/debug/shared/register_info.h" | |
| namespace debug_ipc { | |
| std::string AutomationOperand::ToString() { | |
| std::stringstream output_stream; | |
| switch (kind_) { | |
| case AutomationOperandKind::kZero: | |
| return "zero"; | |
| case AutomationOperandKind::kRegister: | |
| output_stream << debug::RegisterIDToString(static_cast<debug::RegisterID>(index_)); | |
| return output_stream.str(); | |
| case AutomationOperandKind::kConstant: | |
| output_stream << value_; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kStackSlot: | |
| output_stream << "[xsp + 0x" << std::hex << index_ << std::dec << "]/64"; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kRegisterTimesConstant: | |
| output_stream << debug::RegisterIDToString(static_cast<debug::RegisterID>(index_)) << " * " | |
| << value_; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kIndirectUInt32: | |
| output_stream << "[" << debug::RegisterIDToString(static_cast<debug::RegisterID>(index_)) | |
| << " + 0x" << std::hex << value_ << std::dec << "]/32"; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kIndirectUInt64: | |
| output_stream << "[" << debug::RegisterIDToString(static_cast<debug::RegisterID>(index_)) | |
| << " + 0x" << std::hex << value_ << std::dec << "]/64"; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kIndirectUInt32Loop: | |
| output_stream << "[loop_offset + 0x" << std::hex << value_ << std::dec << "]/32"; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kIndirectUInt64Loop: | |
| output_stream << "[loop_offset + 0x" << std::hex << value_ << std::dec << "]/64"; | |
| return output_stream.str(); | |
| case AutomationOperandKind::kStoredValue: | |
| output_stream << "stored_value(" << index_ << ")"; | |
| return output_stream.str(); | |
| } | |
| } | |
| std::string AutomationCondition::ToString() { | |
| std::stringstream output_stream; | |
| switch (kind_) { | |
| case AutomationConditionKind::kFalse: | |
| return "false"; | |
| case AutomationConditionKind::kEquals: | |
| output_stream << operand_.ToString() << " == " << constant_; | |
| return output_stream.str(); | |
| case AutomationConditionKind::kNotEquals: | |
| output_stream << operand_.ToString() << " != " << constant_; | |
| return output_stream.str(); | |
| case AutomationConditionKind::kMaskAndEquals: | |
| output_stream << "(" << operand_.ToString() << " & 0x" << std::hex << mask_ << ") == 0x" | |
| << constant_ << std::dec; | |
| return output_stream.str(); | |
| case AutomationConditionKind::kMaskAndNotEquals: | |
| output_stream << "(" << operand_.ToString() << " & 0x" << std::hex << mask_ << ") != 0x" | |
| << constant_ << std::dec; | |
| return output_stream.str(); | |
| } | |
| } | |
| std::string AutomationInstruction::ToString() { | |
| std::stringstream output_stream; | |
| switch (kind_) { | |
| case AutomationInstructionKind::kNop: | |
| output_stream << "nop"; | |
| break; | |
| case AutomationInstructionKind::kLoadMemory: | |
| output_stream << "load_memory " << address_.ToString() << ", " << length_.ToString(); | |
| break; | |
| case AutomationInstructionKind::kLoopLoadMemory: | |
| output_stream << "loop_load_memory " << address_.ToString() << ", " << length_.ToString() | |
| << ", " << extra_1_.ToString() << ", " << extra_2_.ToString() << ", " << value_; | |
| break; | |
| case AutomationInstructionKind::kComputeAndStore: | |
| output_stream << "stored_value(" << value_ << ") = " << extra_1_.ToString(); | |
| break; | |
| case AutomationInstructionKind::kClearStoredValues: | |
| output_stream << "clear_stored_values"; | |
| break; | |
| } | |
| if (!conditions_.empty()) { | |
| output_stream << ". conditions: "; | |
| const char* separator = ""; | |
| for (auto condition : conditions_) { | |
| output_stream << separator << condition.ToString(); | |
| separator = " && "; | |
| } | |
| } | |
| output_stream << "\n"; | |
| return output_stream.str(); | |
| } | |
| } // namespace debug_ipc |