// 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/zxdb/expr/abi_x64.h"

#include <lib/syslog/cpp/macros.h>

#include <algorithm>

#include "src/developer/debug/zxdb/expr/builtin_types.h"
#include "src/developer/debug/zxdb/symbols/base_type.h"
#include "src/developer/debug/zxdb/symbols/collection.h"
#include "src/developer/debug/zxdb/symbols/visit_scopes.h"

namespace zxdb {

namespace {

using debug::RegisterID;

// Notes on returning collections by value
// ---------------------------------------
//
// The x64 ABI Fuchsia uses:
// https://software.intel.com/content/www/us/en/develop/articles/linux-abi.html
//
// The ABI rules for passing and returning collections by value are quite complicated (the LLVM code
// is about 1000 lines). This code doesn't attempt to implement the whole thing, but tries to get
// the common cases and give up for anything complex. Fortunately, this will support the vast
// majority of practical uses.
//
// Fortunately, many of the rules for passing collections don't apply because we know already that
// the collection is passed by value (DWARF tells us). This means that we don't have to worry about
// unaligned values and C++ rules about non-trivial copy constructors. Additionally, we don't
// support x87 floating-point, the C "complex" type, and vectors. This leaves only the POINTER,
// INTEGER, and SSE classes.
//
// POINTER and INTEGER classes are returned in the general-purpose registers, so the only thing we
// have to worry about is finding which things are SSE class. All pass-by-value collections are less
// than 16 bytes except those consisting of SSE vectors which we don't support, so we can also
// assume <= 16 bytes.
//
// The ABI wants to return things in 8-byte chunks. If a chunk is all floating-point, it's returned
// in xmm0, xmm1. If it's integer, pointer, or a combination (possibly including floating-point),
// it's returned in rax, rdx.
//
// Some examples for structure returning:
//
//  - {double, int64} -> {xmm0 (8 bytes), rax}
//  - {float, int64} -> {xmm0 (4 bytes), rax}
//  - {float, float} -> {xmm0[0] (low 4 bytes), xmm0[1] (next higher 4 bytes)}
//  - {float, float, int64} -> {xmm0[0], xmm0[1], rax}
//  - {float, char} -> {rax (low 4 bytes), rax (5th byte)}                           (!)
//  - {float, char, float} -> {rax (low 4 bytes), rax (5th byte), xmm0[0] (4 bytes)} (!)
//
// For the examples marked with (!) you can see floating-point values getting passed in integer
// registers. This is because the first two values fit into one eightbyte. When comparing the first
// two values according to the ABI parameter classification rule "If one of the classes is INTEGER,
// the result is INTEGER.", the float/char combination is assigned class INTEGER and therefore rax.
//
// For the {float, char, float} case, the second float falls into a different eightbyte, and
// according to the API parameter classification rule "If the size of the aggregate exceeds a single
// eightbyte, each is classified separately." Therefore, the 2nd float and the earlier parameters
// are never compared and keep their separate classes.

// Register classes from the ABI. We do not support SSEUP, X87, X87UP, COMPLEX_X87. The MEMORY
// class isn't handled here because that means it's not passed in registers and we already know
// the answer from the calling convention in DWARF.
enum class RegisterClass {
  kEmpty,    // Not allocated (NO_CLASS).
  kGeneral,  // Used for both the POINTER and INTEGER types from the ABI.
  kSse       // The SSE type (this counts only the low 4 or 8 bytes, not a vector).
};

struct DataMemberInfo {
  // Offset from the beginning of the collection of this member. There can be multiple members
  // at the same offset in the case of unions.
  uint32_t byte_offset;

  // This type will be concrete.
  fxl::RefPtr<Type> type;
};

// Makes a list of all data members and their locations inside of a collection for the purposes of
// allocating registers for returning it by value.
//
// Returns true on success or false if there are some member types that we don't support for
// computing by-value returns.
bool GetDataMembersForByValueReturning(const fxl::RefPtr<EvalContext>& context,
                                       const Collection* collection,
                                       std::vector<DataMemberInfo>& result) {
  VisitResult visit_result = VisitDataMembers(
      collection,
      [context, &result](bool is_leaf, uint32_t net_byte_offset,
                         const DataMember* member) -> VisitResult {
        if (!is_leaf)
          return VisitResult::kContinue;  // Intermediate collections, we'll catch members later.
        if (member->is_external())
          return VisitResult::kContinue;  // Static member, doesn't count toward returning.

        // Don't support bitfields.
        if (member->is_bitfield())
          return VisitResult::kAbort;

        // Decode the member type.
        auto type = context->GetConcreteType(member->type());
        if (!type)
          return VisitResult::kAbort;

        // Save the mapping.
        result.push_back({net_byte_offset, std::move(type)});
        return VisitResult::kContinue;
      });
  return visit_result != VisitResult::kAbort;
}

// Performs the merge step from the ABI document to get the allocations for a structure. Returns
// true on success, false means there was an unsupported feature or error.
//
// As per the above algorithm, we should have at most 2 "eightbyte" values. Check each one to
// see if there is anything of type "SSE" (floating point values). Everything else we can assume
// is either a pointer or integer type that goes into a general-purpose register.
bool MergeDataMembersForByValueReturning(const std::vector<DataMemberInfo>& members,
                                         std::vector<RegisterClass>& classes) {
  // The current algorithm assumes a maximum of two "eightbytes".
  classes.resize(2);
  classes[0] = RegisterClass::kEmpty;
  classes[1] = RegisterClass::kEmpty;

  // The ABI algorithm requires everything be aligned to be passed by value (which we know it is).
  // This means that as long as all values are < 8 bytes and not bitfields, nothing will cross this
  // boundary.
  for (const auto& member : members) {
    // Figure out which eightbyte value this member belongs in.
    size_t class_index;
    if (member.byte_offset < 8) {
      class_index = 0;
    } else if (member.byte_offset < 16) {
      class_index = 1;
    } else {
      return false;  // Value beyond type size.
    }

    // Simplifying assumption: don't support members greater than 8 bytes. This eliminates "long
    // double" which is "x87" class, uint128, SSE vectors, and arrays.
    if (member.type->byte_size() > 8)
      return false;

    if (const BaseType* base_type = member.type->As<BaseType>()) {
      if (base_type->base_type() == BaseType::kBaseTypeFloat) {
        // Class SSE, but don't overwrite a "general" class (this can happen if there's a uint32
        // followed by a 32-bit float). The integer takes precedence.
        if (classes[class_index] != RegisterClass::kGeneral)
          classes[class_index] = RegisterClass::kSse;
      } else {
        // All other base types are "general" (pointers or integers). This also overwrites SSE if
        // there is a 32-bit float followed by a int32.
        classes[class_index] = RegisterClass::kGeneral;
      }
    } else if (DwarfTagIsPointerOrReference(member.type->tag())) {
      // Pointers or reference types. "General" takes precedence over SSE so overwrite.
      classes[class_index] = RegisterClass::kGeneral;
    } else {
      // Any other member types we don't support, give up.
      return false;
    }
  }

  return true;
}

// Given a sequence of register classes, allocates it to the registers that would be used. This
// step can not fail.
Abi::CollectionByValueReturn AllocateRegistersForByValueReturning(
    uint32_t dest_byte_size, const std::vector<RegisterClass>& classes) {
  // Currently expect exactly 2 entries in the list generated by Merge above.
  constexpr size_t kMaxRegs = 2;
  FX_DCHECK(classes.size() <= kMaxRegs);

  // These are the registers to use for each class.
  static const debug::RegisterID kGeneralRegs[kMaxRegs] = {debug::RegisterID::kX64_rax,
                                                           debug::RegisterID::kX64_rdx};
  static const debug::RegisterID kSseRegs[kMaxRegs] = {debug::RegisterID::kX64_xmm0,
                                                       debug::RegisterID::kX64_xmm1};

  // The next register of each category to use.
  int next_general = 0;
  int next_sse = 0;

  // The number of bytes in the collection left to allocate to registers.
  uint32_t remaining_bytes = dest_byte_size;

  Abi::CollectionByValueReturn result;
  for (size_t i = 0; i < classes.size(); i++) {
    switch (classes[i]) {
      case RegisterClass::kGeneral:
        result.regs.push_back(
            {.reg = kGeneralRegs[next_general], .bytes = std::min(remaining_bytes, 8u)});
        remaining_bytes -= 8u;
        next_general++;
        break;
      case RegisterClass::kSse:
        result.regs.push_back({.reg = kSseRegs[next_sse], .bytes = std::min(remaining_bytes, 8u)});
        remaining_bytes -= 8u;
        next_sse++;
        break;
      case RegisterClass::kEmpty:
        break;
    }
  }

  return result;
}

}  // namespace

bool AbiX64::IsRegisterCalleeSaved(debug::RegisterID reg) const {
  switch (reg) {
    case debug::RegisterID::kX64_rbx:
    case debug::RegisterID::kX64_bh:  // All variants of "rbx".
    case debug::RegisterID::kX64_bl:
    case debug::RegisterID::kX64_bx:
    case debug::RegisterID::kX64_ebx:
    case debug::RegisterID::kX64_rsp:
    case debug::RegisterID::kX64_rbp:
    case debug::RegisterID::kX64_r12:
    case debug::RegisterID::kX64_r13:
    case debug::RegisterID::kX64_r14:
    case debug::RegisterID::kX64_r15:
    case debug::RegisterID::kX64_rip:
      return true;
    default:
      return false;
  }
}

std::optional<debug::RegisterID> AbiX64::GetReturnRegisterForBaseType(const BaseType* base_type) {
  switch (base_type->base_type()) {
    case BaseType::kBaseTypeFloat:
      if (base_type->byte_size() <= 8)
        return RegisterID::kX64_xmm0;

      // Don't support larger floating-point numbers.
      return std::nullopt;

    case BaseType::kBaseTypeBoolean:
    case BaseType::kBaseTypeSigned:
    case BaseType::kBaseTypeSignedChar:
    case BaseType::kBaseTypeUnsigned:
    case BaseType::kBaseTypeUnsignedChar:
    case BaseType::kBaseTypeUTF:
      if (base_type->byte_size() <= 8)
        return GetReturnRegisterForMachineInt();

      // Larger numbers are spread across multiple registers which we don't support yet.
      return std::nullopt;

    case BaseType::kBaseTypeNone:
    case BaseType::kBaseTypeAddress:  // Not used in C.
    default:
      return std::nullopt;
  }
}

std::optional<Abi::CollectionReturn> AbiX64::GetCollectionReturnByRefLocation(
    const Collection* collection) {
  FX_DCHECK(collection->calling_convention() == Collection::kPassByReference);

  // Pass-by-reference collections are placed into a location indicated by the caller and that
  // location is echoed back upon return in the rax register.
  return CollectionReturn{.addr_return_reg = RegisterID::kX64_rax};
}

std::optional<Abi::CollectionByValueReturn> AbiX64::GetCollectionReturnByValueLocation(
    const fxl::RefPtr<EvalContext>& eval_context, const Collection* collection) {
  if (collection->byte_size() == 0 || collection->byte_size() > 16)
    return std::nullopt;  // Too big.

  // Get all the data members.
  std::vector<DataMemberInfo> members;
  if (!GetDataMembersForByValueReturning(eval_context, collection, members))
    return std::nullopt;

  // Merge into classes representing each eightbyte section.
  std::vector<RegisterClass> classes;
  if (!MergeDataMembersForByValueReturning(members, classes))
    return std::nullopt;

  return AllocateRegistersForByValueReturning(collection->byte_size(), classes);
}

}  // namespace zxdb
