//===-- DumpRegisterValue.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Core/DumpRegisterValue.h"
#include "lldb/Core/DumpDataExtractor.h"
#include "lldb/DataFormatters/DumpValueObjectOptions.h"
#include "lldb/Target/RegisterFlags.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "lldb/lldb-private-types.h"
#include "llvm/ADT/bit.h"

using namespace lldb;

template <typename T>
static void dump_type_value(lldb_private::CompilerType &fields_type, T value,
                            lldb_private::ExecutionContextScope *exe_scope,
                            const lldb_private::RegisterInfo &reg_info,
                            lldb_private::Stream &strm) {
  lldb::ByteOrder target_order = exe_scope->CalculateProcess()->GetByteOrder();

  // For the bitfield types we generate, it is expected that the fields are
  // in what is usually a big endian order. Most significant field first.
  // This is also clang's internal ordering and the order we want to print
  // them. On a big endian host this all matches up, for a little endian
  // host we have to swap the order of the fields before display.
  if (target_order == lldb::ByteOrder::eByteOrderLittle) {
    value = reg_info.flags_type->ReverseFieldOrder(value);
  }

  // Then we need to match the target's endian on a byte level as well.
  if (lldb_private::endian::InlHostByteOrder() != target_order)
    value = llvm::byteswap(value);

  lldb_private::DataExtractor data_extractor{
      &value, sizeof(T), lldb_private::endian::InlHostByteOrder(), 8};

  lldb::ValueObjectSP vobj_sp = lldb_private::ValueObjectConstResult::Create(
      exe_scope, fields_type, lldb_private::ConstString(), data_extractor);
  lldb_private::DumpValueObjectOptions dump_options;
  lldb_private::DumpValueObjectOptions::ChildPrintingDecider decider =
      [](lldb_private::ConstString varname) {
        // Unnamed bit-fields are padding that we don't want to show.
        return varname.GetLength();
      };
  dump_options.SetChildPrintingDecider(decider).SetHideRootType(true);

  if (llvm::Error error = vobj_sp->Dump(strm, dump_options))
    strm << "error: " << toString(std::move(error));
}

void lldb_private::DumpRegisterValue(const RegisterValue &reg_val, Stream &s,
                                     const RegisterInfo &reg_info,
                                     bool prefix_with_name,
                                     bool prefix_with_alt_name, Format format,
                                     uint32_t reg_name_right_align_at,
                                     ExecutionContextScope *exe_scope,
                                     bool print_flags, TargetSP target_sp) {
  DataExtractor data;
  if (!reg_val.GetData(data))
    return;

  bool name_printed = false;
  // For simplicity, alignment of the register name printing applies only in
  // the most common case where:
  //
  //     prefix_with_name^prefix_with_alt_name is true
  //
  StreamString format_string;
  if (reg_name_right_align_at && (prefix_with_name ^ prefix_with_alt_name))
    format_string.Printf("%%%us", reg_name_right_align_at);
  else
    format_string.Printf("%%s");
  std::string fmt = std::string(format_string.GetString());
  if (prefix_with_name) {
    if (reg_info.name) {
      s.Printf(fmt.c_str(), reg_info.name);
      name_printed = true;
    } else if (reg_info.alt_name) {
      s.Printf(fmt.c_str(), reg_info.alt_name);
      prefix_with_alt_name = false;
      name_printed = true;
    }
  }
  if (prefix_with_alt_name) {
    if (name_printed)
      s.PutChar('/');
    if (reg_info.alt_name) {
      s.Printf(fmt.c_str(), reg_info.alt_name);
      name_printed = true;
    } else if (!name_printed) {
      // No alternate name but we were asked to display a name, so show the
      // main name
      s.Printf(fmt.c_str(), reg_info.name);
      name_printed = true;
    }
  }
  if (name_printed)
    s.PutCString(" = ");

  if (format == eFormatDefault)
    format = reg_info.format;

  DumpDataExtractor(data, &s,
                    0,                    // Offset in "data"
                    format,               // Format to use when dumping
                    reg_info.byte_size,   // item_byte_size
                    1,                    // item_count
                    UINT32_MAX,           // num_per_line
                    LLDB_INVALID_ADDRESS, // base_addr
                    0,                    // item_bit_size
                    0,                    // item_bit_offset
                    exe_scope);

  if (!print_flags || !reg_info.flags_type || !exe_scope || !target_sp ||
      (reg_info.byte_size != 4 && reg_info.byte_size != 8))
    return;

  CompilerType fields_type = target_sp->GetRegisterType(
      reg_info.name, *reg_info.flags_type, reg_info.byte_size);

  // Use a new stream so we can remove a trailing newline later.
  StreamString fields_stream;

  if (reg_info.byte_size == 4) {
    dump_type_value(fields_type, reg_val.GetAsUInt32(), exe_scope, reg_info,
                    fields_stream);
  } else {
    dump_type_value(fields_type, reg_val.GetAsUInt64(), exe_scope, reg_info,
                    fields_stream);
  }

  // Registers are indented like:
  // (lldb) register read foo
  //     foo = 0x12345678
  // So we need to indent to match that.

  // First drop the extra newline that the value printer added. The register
  // command will add one itself.
  llvm::StringRef fields_str = fields_stream.GetString().drop_back();

  // End the line that contains "    foo = 0x12345678".
  s.EOL();

  // Then split the value lines and indent each one.
  bool first = true;
  while (fields_str.size()) {
    std::pair<llvm::StringRef, llvm::StringRef> split = fields_str.split('\n');
    fields_str = split.second;
    // Indent as far as the register name did.
    s.Printf(fmt.c_str(), "");

    // Lines after the first won't have " = " so compensate for that.
    if (!first)
      s << "   ";
    first = false;

    s << split.first;

    // On the last line we don't want a newline because the command will add
    // one too.
    if (fields_str.size())
      s.EOL();
  }
}
