bool
IRExecutionUnit::GetArchitecture (lldb_private::ArchSpec &arch)
{
    ExecutionContext exe_ctx (GetBestExecutionContextScope());
    Target *target = exe_ctx.GetTargetPtr();
    if (target)
        arch = target->GetArchitecture();
    else
        arch.Clear();
    return arch.IsValid();
}
static uint32_t
PrivateGetRegisterCount(const lldb_private::ArchSpec &target_arch) {
  switch (target_arch.GetMachine()) {
  case llvm::Triple::x86_64:
    return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) /
                                 sizeof(g_register_infos_x86_64[0]));
  default:
    assert(false && "Unhandled target architecture.");
    return 0;
  }
}
uint32_t
RegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
                                           RegisterInfo *reg_info) {
  ExecutionContext exe_ctx(CalculateThread());

  // In MIPS, the floating point registers size is depends on FR bit of SR
  // register. if SR.FR  == 1 then all floating point registers are 64 bits.
  // else they are all 32 bits.

  int expr_result;
  uint32_t addr_size = arch.GetAddressByteSize();
  const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
  const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;

  DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
                           arch.GetByteOrder(), addr_size);
  ModuleSP opcode_ctx;
  DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr, 0,
                             dwarf_opcode_len);
  Value result;
  Status error;
  const lldb::offset_t offset = 0;
  if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
                          offset, dwarf_opcode_len, eRegisterKindDWARF, nullptr,
                          nullptr, result, &error)) {
    expr_result = result.GetScalar().SInt(-1);
    switch (expr_result) {
    case 0:
      return 4;
    case 1:
      return 8;
    default:
      return reg_info->byte_size;
    }
  } else {
    printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
    return reg_info->byte_size;
  }
}
bool
DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
{
    llvm::Triple triple = arch.GetTriple();
    if (flavor == NULL || strcmp (flavor, "default") == 0)
        return true;
    
    if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
    {
        if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
            return true;
        else
            return false;
    }
    else
        return false;
}
EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &arch) :
    EmulateInstruction (arch)
{
    /* Create instance of llvm::MCDisassembler */
    std::string Error;
    llvm::Triple triple = arch.GetTriple();
    const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);

    /*
     * If we fail to get the target then we haven't registered it. The SystemInitializerCommon 
     * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler 
     * to decode the instructions so that the decoding complexity stays with LLVM. 
     * Initialize the MIPS targets and disassemblers.
    */
#ifdef __mips__
    if (!target)
    {
        LLVMInitializeMipsTargetInfo ();
        LLVMInitializeMipsTarget ();
        LLVMInitializeMipsAsmPrinter ();
        LLVMInitializeMipsTargetMC ();
        LLVMInitializeMipsDisassembler ();
        target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error);
    }
#endif

    assert (target);

    llvm::StringRef cpu;

    switch (arch.GetCore())
    {
        case ArchSpec::eCore_mips32:
        case ArchSpec::eCore_mips32el:
            cpu = "mips32"; break;
        case ArchSpec::eCore_mips32r2:
        case ArchSpec::eCore_mips32r2el:
            cpu = "mips32r2"; break;
        case ArchSpec::eCore_mips32r3:
        case ArchSpec::eCore_mips32r3el:
            cpu = "mips32r3"; break;
        case ArchSpec::eCore_mips32r5:
        case ArchSpec::eCore_mips32r5el:
            cpu = "mips32r5"; break;
        case ArchSpec::eCore_mips32r6:
        case ArchSpec::eCore_mips32r6el:
            cpu = "mips32r6"; break;
        case ArchSpec::eCore_mips64:
        case ArchSpec::eCore_mips64el:
            cpu = "mips64"; break;
        case ArchSpec::eCore_mips64r2:
        case ArchSpec::eCore_mips64r2el:
            cpu = "mips64r2"; break;
        case ArchSpec::eCore_mips64r3:
        case ArchSpec::eCore_mips64r3el:
            cpu = "mips64r3"; break;
        case ArchSpec::eCore_mips64r5:
        case ArchSpec::eCore_mips64r5el:
            cpu = "mips64r5"; break;
        case ArchSpec::eCore_mips64r6:
        case ArchSpec::eCore_mips64r6el:
            cpu = "mips64r6"; break;
        default:
            cpu = "generic"; break;
    }

    m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
    assert (m_reg_info.get());

    m_insn_info.reset (target->createMCInstrInfo());
    assert (m_insn_info.get());

    m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
    m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, ""));
    assert (m_asm_info.get() && m_subtype_info.get());

    m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
    assert (m_context.get());

    m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context));
    assert (m_disasm.get());
}