blob: 823aa8ab6487e054bf155d96eb569b6ba48ad09b [file] [log] [blame]
// 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