//===-- 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::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();

  StreamString sstr;
  for (int i = 0; i < 16; ++i) {
    sstr.Clear();
    sstr.Printf("r%d", i);
    ConstString reg_name(sstr.GetString());
    value_sp = reg_dict->GetValueForKey(reg_name);
    if (value_sp.get() == nullptr)
      return false;
    uint64_t reg_value = value_sp->GetUInt64Value();
    StorePseudoRegisterValue(dwarf_r0 + i, reg_value);
  }

  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
  for (int i = 0; i < 32; ++i) {
    sstr.Clear();
    sstr.Printf("s%d", i);
    ConstString reg_name(sstr.GetString());
    value_sp = reg_dict->GetValueForKey(reg_name);
    if (value_sp.get() == nullptr)
      return false;
    uint64_t reg_value = value_sp->GetUInt64Value();
    StorePseudoRegisterValue(dwarf_s0 + i, reg_value);
  }

  return true;
}
