//===-- EmulationStateARM.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 "EmulationStateARM.h"

#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Utility/RegisterValue.h"
#include "lldb/Utility/Scalar.h"

#include "Utility/ARM_DWARF_Registers.h"

using namespace lldb;
using namespace lldb_private;

EmulationStateARM::EmulationStateARM() : m_vfp_regs(), m_memory() {
  ClearPseudoRegisters();
}

EmulationStateARM::~EmulationStateARM() = default;

bool EmulationStateARM::LoadPseudoRegistersFromFrame(StackFrame &frame) {
  RegisterContext *reg_ctx = frame.GetRegisterContext().get();
  bool success = true;
  uint32_t reg_num;

  for (int i = dwarf_r0; i < dwarf_r0 + 17; ++i) {
    reg_num =
        reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
    RegisterValue reg_value;
    if (reg_ctx->ReadRegister(reg_info, reg_value)) {
      m_gpr[i - dwarf_r0] = reg_value.GetAsUInt32();
    } else
      success = false;
  }

  for (int i = dwarf_d0; i < dwarf_d0 + 32; ++i) {
    reg_num =
        reg_ctx->ConvertRegisterKindToRegisterNumber(eRegisterKindDWARF, i);
    RegisterValue reg_value;
    const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);

    if (reg_ctx->ReadRegister(reg_info, reg_value)) {
      uint64_t value = reg_value.GetAsUInt64();
      uint32_t idx = i - dwarf_d0;
      if (i < 16) {
        m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
        m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
      } else
        m_vfp_regs.d_regs[idx - 16] = value;
    } else
      success = false;
  }

  return success;
}

bool EmulationStateARM::StorePseudoRegisterValue(uint32_t reg_num,
                                                 uint64_t value) {
  if (reg_num <= dwarf_cpsr)
    m_gpr[reg_num - dwarf_r0] = (uint32_t)value;
  else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
    uint32_t idx = reg_num - dwarf_s0;
    m_vfp_regs.s_regs[idx] = (uint32_t)value;
  } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
    uint32_t idx = reg_num - dwarf_d0;
    if (idx < 16) {
      m_vfp_regs.s_regs[idx * 2] = (uint32_t)value;
      m_vfp_regs.s_regs[idx * 2 + 1] = (uint32_t)(value >> 32);
    } else
      m_vfp_regs.d_regs[idx - 16] = value;
  } else
    return false;

  return true;
}

uint64_t EmulationStateARM::ReadPseudoRegisterValue(uint32_t reg_num,
                                                    bool &success) {
  uint64_t value = 0;
  success = true;

  if (reg_num <= dwarf_cpsr)
    value = m_gpr[reg_num - dwarf_r0];
  else if ((dwarf_s0 <= reg_num) && (reg_num <= dwarf_s31)) {
    uint32_t idx = reg_num - dwarf_s0;
    value = m_vfp_regs.d_regs[idx];
  } else if ((dwarf_d0 <= reg_num) && (reg_num <= dwarf_d31)) {
    uint32_t idx = reg_num - dwarf_d0;
    if (idx < 16)
      value = (uint64_t)m_vfp_regs.s_regs[idx * 2] |
              ((uint64_t)m_vfp_regs.s_regs[idx * 2 + 1] << 32);
    else
      value = m_vfp_regs.d_regs[idx - 16];
  } else
    success = false;

  return value;
}

void EmulationStateARM::ClearPseudoRegisters() {
  for (int i = 0; i < 17; ++i)
    m_gpr[i] = 0;

  for (int i = 0; i < 32; ++i)
    m_vfp_regs.s_regs[i] = 0;

  for (int i = 0; i < 16; ++i)
    m_vfp_regs.d_regs[i] = 0;
}

void EmulationStateARM::ClearPseudoMemory() { m_memory.clear(); }

bool EmulationStateARM::StoreToPseudoAddress(lldb::addr_t p_address,
                                             uint32_t value) {
  m_memory[p_address] = value;
  return true;
}

uint32_t EmulationStateARM::ReadFromPseudoAddress(lldb::addr_t p_address,
                                                  bool &success) {
  std::map<lldb::addr_t, uint32_t>::iterator pos;
  uint32_t ret_val = 0;

  success = true;
  pos = m_memory.find(p_address);
  if (pos != m_memory.end())
    ret_val = pos->second;
  else
    success = false;

  return ret_val;
}

size_t EmulationStateARM::ReadPseudoMemory(
    EmulateInstruction *instruction, void *baton,
    const EmulateInstruction::Context &context, lldb::addr_t addr, void *dst,
    size_t length) {
  if (!baton)
    return 0;

  bool success = true;
  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
  if (length <= 4) {
    uint32_t value = pseudo_state->ReadFromPseudoAddress(addr, success);
    if (!success)
      return 0;

    if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
      value = llvm::ByteSwap_32(value);
    *((uint32_t *)dst) = value;
  } else if (length == 8) {
    uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success);
    if (!success)
      return 0;

    uint32_t value2 = pseudo_state->ReadFromPseudoAddress(addr + 4, success);
    if (!success)
      return 0;

    if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
      value1 = llvm::ByteSwap_32(value1);
      value2 = llvm::ByteSwap_32(value2);
    }
    ((uint32_t *)dst)[0] = value1;
    ((uint32_t *)dst)[1] = value2;
  } else
    success = false;

  if (success)
    return length;

  return 0;
}

size_t EmulationStateARM::WritePseudoMemory(
    EmulateInstruction *instruction, void *baton,
    const EmulateInstruction::Context &context, lldb::addr_t addr,
    const void *dst, size_t length) {
  if (!baton)
    return 0;

  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;

  if (length <= 4) {
    uint32_t value;
    memcpy (&value, dst, sizeof (uint32_t));
    if (endian::InlHostByteOrder() == lldb::eByteOrderBig)
      value = llvm::ByteSwap_32(value);

    pseudo_state->StoreToPseudoAddress(addr, value);
    return length;
  } else if (length == 8) {
    uint32_t value1;
    uint32_t value2;
    memcpy (&value1, dst, sizeof (uint32_t));
    memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t),
           sizeof(uint32_t));
    if (endian::InlHostByteOrder() == lldb::eByteOrderBig) {
      value1 = llvm::ByteSwap_32(value1);
      value2 = llvm::ByteSwap_32(value2);
    }

    pseudo_state->StoreToPseudoAddress(addr, value1);
    pseudo_state->StoreToPseudoAddress(addr + 4, value2);
    return length;
  }

  return 0;
}

bool EmulationStateARM::ReadPseudoRegister(
    EmulateInstruction *instruction, void *baton,
    const lldb_private::RegisterInfo *reg_info,
    lldb_private::RegisterValue &reg_value) {
  if (!baton || !reg_info)
    return false;

  bool success = true;
  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
  const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
  assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
  uint64_t reg_uval =
      pseudo_state->ReadPseudoRegisterValue(dwarf_reg_num, success);

  if (success)
    success = reg_value.SetUInt(reg_uval, reg_info->byte_size);
  return success;
}

bool EmulationStateARM::WritePseudoRegister(
    EmulateInstruction *instruction, void *baton,
    const EmulateInstruction::Context &context,
    const lldb_private::RegisterInfo *reg_info,
    const lldb_private::RegisterValue &reg_value) {
  if (!baton || !reg_info)
    return false;

  EmulationStateARM *pseudo_state = (EmulationStateARM *)baton;
  const uint32_t dwarf_reg_num = reg_info->kinds[eRegisterKindDWARF];
  assert(dwarf_reg_num != LLDB_INVALID_REGNUM);
  return pseudo_state->StorePseudoRegisterValue(dwarf_reg_num,
                                                reg_value.GetAsUInt64());
}

bool EmulationStateARM::CompareState(EmulationStateARM &other_state) {
  bool match = true;

  for (int i = 0; match && i < 17; ++i) {
    if (m_gpr[i] != other_state.m_gpr[i])
      match = false;
  }

  for (int i = 0; match && i < 32; ++i) {
    if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i])
      match = false;
  }

  for (int i = 0; match && i < 16; ++i) {
    if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i])
      match = false;
  }

  return match;
}

bool EmulationStateARM::LoadRegistersStateFromDictionary(
    OptionValueDictionary *reg_dict, char kind, int first_reg, int num) {
  StreamString sstr;
  for (int i = 0; i < num; ++i) {
    sstr.Clear();
    sstr.Printf("%c%d", kind, i);
    OptionValueSP value_sp =
        reg_dict->GetValueForKey(ConstString(sstr.GetString()));
    if (value_sp.get() == nullptr)
      return false;
    uint64_t reg_value = value_sp->GetUInt64Value();
    StorePseudoRegisterValue(first_reg + i, reg_value);
  }

  return true;
}

bool EmulationStateARM::LoadStateFromDictionary(
    OptionValueDictionary *test_data) {
  static ConstString memory_key("memory");
  static ConstString registers_key("registers");

  if (!test_data)
    return false;

  OptionValueSP value_sp = test_data->GetValueForKey(memory_key);

  // Load memory, if present.

  if (value_sp.get() != nullptr) {
    static ConstString address_key("address");
    static ConstString data_key("data");
    uint64_t start_address = 0;

    OptionValueDictionary *mem_dict = value_sp->GetAsDictionary();
    value_sp = mem_dict->GetValueForKey(address_key);
    if (value_sp.get() == nullptr)
      return false;
    else
      start_address = value_sp->GetUInt64Value();

    value_sp = mem_dict->GetValueForKey(data_key);
    OptionValueArray *mem_array = value_sp->GetAsArray();
    if (!mem_array)
      return false;

    uint32_t num_elts = mem_array->GetSize();
    uint32_t address = (uint32_t)start_address;

    for (uint32_t i = 0; i < num_elts; ++i) {
      value_sp = mem_array->GetValueAtIndex(i);
      if (value_sp.get() == nullptr)
        return false;
      uint64_t value = value_sp->GetUInt64Value();
      StoreToPseudoAddress(address, value);
      address = address + 4;
    }
  }

  value_sp = test_data->GetValueForKey(registers_key);
  if (value_sp.get() == nullptr)
    return false;

  // Load General Registers

  OptionValueDictionary *reg_dict = value_sp->GetAsDictionary();
  if (!LoadRegistersStateFromDictionary(reg_dict, 'r', dwarf_r0, 16))
    return false;

  static ConstString cpsr_name("cpsr");
  value_sp = reg_dict->GetValueForKey(cpsr_name);
  if (value_sp.get() == nullptr)
    return false;
  StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value());

  // Load s/d Registers
  // To prevent you giving both types in a state and overwriting
  // one or the other, we'll expect to get either all S registers,
  // or all D registers. Not a mix of the two.
  bool found_s_registers =
      LoadRegistersStateFromDictionary(reg_dict, 's', dwarf_s0, 32);
  bool found_d_registers =
      LoadRegistersStateFromDictionary(reg_dict, 'd', dwarf_d0, 32);

  return found_s_registers != found_d_registers;
}
