//===-- DNBArchImpl.cpp -----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Created by Greg Clayton on 6/25/07.
//
//===----------------------------------------------------------------------===//

#if defined (__arm__)

#include "MacOSX/arm/DNBArchImpl.h"
#include "MacOSX/MachProcess.h"
#include "MacOSX/MachThread.h"
#include "DNBBreakpoint.h"
#include "DNBLog.h"
#include "DNBRegisterInfo.h"
#include "DNB.h"
#include "ARM_GCC_Registers.h"
#include "ARM_DWARF_Registers.h"

#include <sys/sysctl.h>

// BCR address match type
#define BCR_M_IMVA_MATCH        ((uint32_t)(0u << 21))
#define BCR_M_CONTEXT_ID_MATCH  ((uint32_t)(1u << 21))
#define BCR_M_IMVA_MISMATCH     ((uint32_t)(2u << 21))
#define BCR_M_RESERVED          ((uint32_t)(3u << 21))

// Link a BVR/BCR or WVR/WCR pair to another
#define E_ENABLE_LINKING        ((uint32_t)(1u << 20))

// Byte Address Select
#define BAS_IMVA_PLUS_0         ((uint32_t)(1u << 5))
#define BAS_IMVA_PLUS_1         ((uint32_t)(1u << 6))
#define BAS_IMVA_PLUS_2         ((uint32_t)(1u << 7))
#define BAS_IMVA_PLUS_3         ((uint32_t)(1u << 8))
#define BAS_IMVA_0_1            ((uint32_t)(3u << 5))
#define BAS_IMVA_2_3            ((uint32_t)(3u << 7))
#define BAS_IMVA_ALL            ((uint32_t)(0xfu << 5))

// Break only in priveleged or user mode
#define S_RSVD                  ((uint32_t)(0u << 1))
#define S_PRIV                  ((uint32_t)(1u << 1))
#define S_USER                  ((uint32_t)(2u << 1))
#define S_PRIV_USER             ((S_PRIV) | (S_USER))

#define BCR_ENABLE              ((uint32_t)(1u))
#define WCR_ENABLE              ((uint32_t)(1u))

// Watchpoint load/store
#define WCR_LOAD                ((uint32_t)(1u << 3))
#define WCR_STORE               ((uint32_t)(1u << 4))

//#define DNB_ARCH_MACH_ARM_DEBUG_SW_STEP 1

static const uint8_t g_arm_breakpoint_opcode[] = { 0xFE, 0xDE, 0xFF, 0xE7 };
static const uint8_t g_thumb_breakpooint_opcode[] = { 0xFE, 0xDE };

// ARM constants used during decoding
#define REG_RD          0
#define LDM_REGLIST     1
#define PC_REG          15
#define PC_REGLIST_BIT  0x8000

// ARM conditions
#define COND_EQ     0x0
#define COND_NE     0x1
#define COND_CS     0x2
#define COND_HS     0x2
#define COND_CC     0x3
#define COND_LO     0x3
#define COND_MI     0x4
#define COND_PL     0x5
#define COND_VS     0x6
#define COND_VC     0x7
#define COND_HI     0x8
#define COND_LS     0x9
#define COND_GE     0xA
#define COND_LT     0xB
#define COND_GT     0xC
#define COND_LE     0xD
#define COND_AL     0xE
#define COND_UNCOND 0xF

#define MASK_CPSR_T (1u << 5)
#define MASK_CPSR_J (1u << 24)

#define MNEMONIC_STRING_SIZE 32
#define OPERAND_STRING_SIZE 128

const uint8_t * const
DNBArchMachARM::SoftwareBreakpointOpcode (nub_size_t byte_size)
{
    switch (byte_size)
    {
    case 2: return g_thumb_breakpooint_opcode;
    case 4: return g_arm_breakpoint_opcode;
    }
    return NULL;
}

uint32_t
DNBArchMachARM::GetCPUType()
{
    return CPU_TYPE_ARM;
}

uint64_t
DNBArchMachARM::GetPC(uint64_t failValue)
{
    // Get program counter
    if (GetGPRState(false) == KERN_SUCCESS)
        return m_state.context.gpr.__pc;
    return failValue;
}

kern_return_t
DNBArchMachARM::SetPC(uint64_t value)
{
    // Get program counter
    kern_return_t err = GetGPRState(false);
    if (err == KERN_SUCCESS)
    {
        m_state.context.gpr.__pc = value;
        err = SetGPRState();
    }
    return err == KERN_SUCCESS;
}

uint64_t
DNBArchMachARM::GetSP(uint64_t failValue)
{
    // Get stack pointer
    if (GetGPRState(false) == KERN_SUCCESS)
        return m_state.context.gpr.__sp;
    return failValue;
}

kern_return_t
DNBArchMachARM::GetGPRState(bool force)
{
    int set = e_regSetGPR;
    // Check if we have valid cached registers
    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
        return KERN_SUCCESS;

    // Read the registers from our thread
    mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT;
    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, &count);
    uint32_t *r = &m_state.context.gpr.__r[0];
    DNBLogThreadedIf(LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u) => 0x%8.8x regs r0=%8.8x r1=%8.8x r2=%8.8x r3=%8.8x r4=%8.8x r5=%8.8x r6=%8.8x r7=%8.8x r8=%8.8x r9=%8.8x r10=%8.8x r11=%8.8x s12=%8.8x sp=%8.8x lr=%8.8x pc=%8.8x cpsr=%8.8x", m_thread->ThreadID(), ARM_THREAD_STATE, ARM_THREAD_STATE_COUNT, kret,
     r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15], r[16]);
    m_state.SetError(set, Read, kret);
    return kret;
}

kern_return_t
DNBArchMachARM::GetVFPState(bool force)
{
    int set = e_regSetVFP;
    // Check if we have valid cached registers
    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
        return KERN_SUCCESS;

    // Read the registers from our thread
    mach_msg_type_number_t count = ARM_VFP_STATE_COUNT;
    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, &count);
    m_state.SetError(set, Read, kret);
    return kret;
}

kern_return_t
DNBArchMachARM::GetEXCState(bool force)
{
    int set = e_regSetEXC;
    // Check if we have valid cached registers
    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
        return KERN_SUCCESS;

    // Read the registers from our thread
    mach_msg_type_number_t count = ARM_EXCEPTION_STATE_COUNT;
    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, &count);
    m_state.SetError(set, Read, kret);
    return kret;
}

static void
DumpDBGState(const arm_debug_state_t& dbg)
{
    uint32_t i = 0;
    for (i=0; i<16; i++)
        DNBLogThreadedIf(LOG_STEP, "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
            i, i, dbg.__bvr[i], dbg.__bcr[i],
            i, i, dbg.__wvr[i], dbg.__wcr[i]);
}

kern_return_t
DNBArchMachARM::GetDBGState(bool force)
{
    int set = e_regSetDBG;

    // Check if we have valid cached registers
    if (!force && m_state.GetError(set, Read) == KERN_SUCCESS)
        return KERN_SUCCESS;

    // Read the registers from our thread
    mach_msg_type_number_t count = ARM_DEBUG_STATE_COUNT;
    kern_return_t kret = ::thread_get_state(m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, &count);
    m_state.SetError(set, Read, kret);
    return kret;
}

kern_return_t
DNBArchMachARM::SetGPRState()
{
    int set = e_regSetGPR;
    kern_return_t kret = ::thread_set_state(m_thread->ThreadID(), ARM_THREAD_STATE, (thread_state_t)&m_state.context.gpr, ARM_THREAD_STATE_COUNT);
    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
    return kret;                                // Return the error code
}

kern_return_t
DNBArchMachARM::SetVFPState()
{
    int set = e_regSetVFP;
    kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_VFP_STATE, (thread_state_t)&m_state.context.vfp, ARM_VFP_STATE_COUNT);
    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
    return kret;                                // Return the error code
}

kern_return_t
DNBArchMachARM::SetEXCState()
{
    int set = e_regSetEXC;
    kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_EXCEPTION_STATE, (thread_state_t)&m_state.context.exc, ARM_EXCEPTION_STATE_COUNT);
    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
    return kret;                                // Return the error code
}

kern_return_t
DNBArchMachARM::SetDBGState()
{
    int set = e_regSetDBG;
    kern_return_t kret = ::thread_set_state (m_thread->ThreadID(), ARM_DEBUG_STATE, (thread_state_t)&m_state.dbg, ARM_DEBUG_STATE_COUNT);
    m_state.SetError(set, Write, kret);         // Set the current write error for this register set
    m_state.InvalidateRegisterSetState(set);    // Invalidate the current register state in case registers are read back differently
    return kret;                                // Return the error code
}

void
DNBArchMachARM::ThreadWillResume()
{
    // Do we need to step this thread? If so, let the mach thread tell us so.
    if (m_thread->IsStepping())
    {
        bool step_handled = false;
        // This is the primary thread, let the arch do anything it needs
        if (NumSupportedHardwareBreakpoints() > 0)
        {
#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP)
            bool half_step = m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS;
#endif
            step_handled = EnableHardwareSingleStep(true) == KERN_SUCCESS;
#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP)
            if (!half_step)
                step_handled = false;
#endif
        }

        if (!step_handled)
        {
            SetSingleStepSoftwareBreakpoints();
        }
    }
}

bool
DNBArchMachARM::ThreadDidStop()
{
    bool success = true;

    m_state.InvalidateRegisterSetState (e_regSetALL);

    // Are we stepping a single instruction?
    if (GetGPRState(true) == KERN_SUCCESS)
    {
        // We are single stepping, was this the primary thread?
        if (m_thread->IsStepping())
        {
#if defined (DNB_ARCH_MACH_ARM_DEBUG_SW_STEP)
            success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
            // Hardware single step must work if we are going to test software
            // single step functionality
            assert(success);
            if (m_hw_single_chained_step_addr == INVALID_NUB_ADDRESS && m_sw_single_step_next_pc != INVALID_NUB_ADDRESS)
            {
                uint32_t sw_step_next_pc = m_sw_single_step_next_pc & 0xFFFFFFFEu;
                bool sw_step_next_pc_is_thumb = (m_sw_single_step_next_pc & 1) != 0;
                bool actual_next_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0;
                if (m_state.context.gpr.__pc != sw_step_next_pc)
                {
                    DNBLogError("curr pc = 0x%8.8x - calculated single step target PC was incorrect: 0x%8.8x != 0x%8.8x", m_state.context.gpr.__pc, sw_step_next_pc, m_state.context.gpr.__pc);
                    exit(1);
                }
                if (actual_next_pc_is_thumb != sw_step_next_pc_is_thumb)
                {
                    DNBLogError("curr pc = 0x%8.8x - calculated single step calculated mode mismatch: sw single mode = %s != %s",
                                m_state.context.gpr.__pc,
                                actual_next_pc_is_thumb ? "Thumb" : "ARM",
                                sw_step_next_pc_is_thumb ? "Thumb" : "ARM");
                    exit(1);
                }
                m_sw_single_step_next_pc = INVALID_NUB_ADDRESS;
            }
#else
            // Are we software single stepping?
            if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id) || m_sw_single_step_itblock_break_count)
            {
                // Remove any software single stepping breakpoints that we have set

                // Do we have a normal software single step breakpoint?
                if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id))
                {
                    DNBLogThreadedIf(LOG_STEP, "%s: removing software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_break_id);
                    success = m_thread->Process()->DisableBreakpoint(m_sw_single_step_break_id, true);
                    m_sw_single_step_break_id = INVALID_NUB_BREAK_ID;
                }

                // Do we have any Thumb IT breakpoints?
                if (m_sw_single_step_itblock_break_count > 0)
                {
                    // See if we hit one of our Thumb IT breakpoints?
                    DNBBreakpoint *step_bp = m_thread->Process()->Breakpoints().FindByAddress(m_state.context.gpr.__pc);

                    if (step_bp)
                    {
                        // We did hit our breakpoint, tell the breakpoint it was
                        // hit so that it can run its callback routine and fixup
                        // the PC.
                        DNBLogThreadedIf(LOG_STEP, "%s: IT software single step breakpoint hit (breakID=%u)", __FUNCTION__, step_bp->GetID());
                        step_bp->BreakpointHit(m_thread->Process()->ProcessID(), m_thread->ThreadID());
                    }

                    // Remove all Thumb IT breakpoints
                    for (int i = 0; i < m_sw_single_step_itblock_break_count; i++)
                    {
                        if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
                        {
                            DNBLogThreadedIf(LOG_STEP, "%s: removing IT software single step breakpoint (breakID=%d)", __FUNCTION__, m_sw_single_step_itblock_break_id[i]);
                            success = m_thread->Process()->DisableBreakpoint(m_sw_single_step_itblock_break_id[i], true);
                            m_sw_single_step_itblock_break_id[i] = INVALID_NUB_BREAK_ID;
                        }
                    }
                    m_sw_single_step_itblock_break_count = 0;

                    // Decode instructions up to the current PC to ensure the internal decoder state is valid for the IT block
                    // The decoder has to decode each instruction in the IT block even if it is not executed so that
                    // the fields are correctly updated
                    DecodeITBlockInstructions(m_state.context.gpr.__pc);
                }

            }
            else
                success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
#endif
        }
        else
        {
            // The MachThread will automatically restore the suspend count
            // in ThreadDidStop(), so we don't need to do anything here if
            // we weren't the primary thread the last time
        }
    }
    return success;
}

bool
DNBArchMachARM::StepNotComplete ()
{
    if (m_hw_single_chained_step_addr != INVALID_NUB_ADDRESS)
    {
        kern_return_t kret = KERN_INVALID_ARGUMENT;
        kret = GetGPRState(false);
        if (kret == KERN_SUCCESS)
        {
            if (m_state.context.gpr.__pc == m_hw_single_chained_step_addr)
            {
                DNBLogThreadedIf(LOG_STEP, "Need to step some more at 0x%8.8x", m_hw_single_chained_step_addr);
                return true;
            }
        }
    }

    m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;
    return false;
}


void
DNBArchMachARM::DecodeITBlockInstructions(nub_addr_t curr_pc)

{
    uint16_t opcode16;
    uint32_t opcode32;
    nub_addr_t next_pc_in_itblock;
    nub_addr_t pc_in_itblock = m_last_decode_pc;

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc);

    // Decode IT block instruction from the instruction following the m_last_decoded_instruction at
    // PC m_last_decode_pc upto and including the instruction at curr_pc
    if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2)
    {
        opcode32 = opcode16;
        pc_in_itblock += 2;
        // Check for 32 bit thumb opcode and read the upper 16 bits if needed
        if (((opcode32 & 0xE000) == 0xE000) && opcode32 & 0x1800)
        {
            // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for
            // a 32 bit Thumb opcode
            // Read bits 31:16 of a 32 bit Thumb opcode
            if (m_thread->Process()->Task().ReadMemory(pc_in_itblock, 2, &opcode16) == 2)
            {
                pc_in_itblock += 2;
                // 32 bit thumb opcode
                opcode32 = (opcode32 << 16) | opcode16;
            }
            else
            {
                DNBLogError("%s: Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8lx", __FUNCTION__, pc_in_itblock);
            }
        }
    }
    else
    {
        DNBLogError("%s: Error reading 16-bit Thumb instruction at pc=0x%8.8x", __FUNCTION__, pc_in_itblock);
    }

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc_in_itblock=0x%8.8x, curr_pc=0x%8.8x", __FUNCTION__, pc_in_itblock, curr_pc);

    next_pc_in_itblock = pc_in_itblock;
    while (next_pc_in_itblock <= curr_pc)
    {
        arm_error_t decodeError;

        m_last_decode_pc = pc_in_itblock;
        decodeError = DecodeInstructionUsingDisassembler(pc_in_itblock, m_state.context.gpr.__cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc_in_itblock);

        pc_in_itblock = next_pc_in_itblock;
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: next_pc_in_itblock=0x%8.8x", __FUNCTION__, next_pc_in_itblock);
    }
}


// Set the single step bit in the processor status register.
kern_return_t
DNBArchMachARM::EnableHardwareSingleStep (bool enable)
{
    DNBError err;
    DNBLogThreadedIf(LOG_STEP, "%s( enable = %d )", __FUNCTION__, enable);

    err = GetGPRState(false);

    if (err.Fail())
    {
        err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__);
        return err.Error();
    }

    err = GetDBGState(false);

    if (err.Fail())
    {
        err.LogThreaded("%s: failed to read the DBG registers", __FUNCTION__);
        return err.Error();
    }

    const uint32_t i = 0;
    if (enable)
    {
        m_hw_single_chained_step_addr = INVALID_NUB_ADDRESS;

        // Save our previous state
        m_dbg_save = m_state.dbg;
        // Set a breakpoint that will stop when the PC doesn't match the current one!
        m_state.dbg.__bvr[i] = m_state.context.gpr.__pc & 0xFFFFFFFCu;      // Set the current PC as the breakpoint address
        m_state.dbg.__bcr[i] = BCR_M_IMVA_MISMATCH |    // Stop on address mismatch
                               S_USER |                 // Stop only in user mode
                               BCR_ENABLE;              // Enable this breakpoint
        if (m_state.context.gpr.__cpsr & 0x20)
        {
            // Thumb breakpoint
            if (m_state.context.gpr.__pc & 2)
                m_state.dbg.__bcr[i] |= BAS_IMVA_2_3;
            else
                m_state.dbg.__bcr[i] |= BAS_IMVA_0_1;

            uint16_t opcode;
            if (sizeof(opcode) == m_thread->Process()->Task().ReadMemory(m_state.context.gpr.__pc, sizeof(opcode), &opcode))
            {
                if (((opcode & 0xE000) == 0xE000) && opcode & 0x1800)
                {
                    // 32 bit thumb opcode...
                    if (m_state.context.gpr.__pc & 2)
                    {
                        // We can't take care of a 32 bit thumb instruction single step
                        // with just IVA mismatching. We will need to chain an extra
                        // hardware single step in order to complete this single step...
                        m_hw_single_chained_step_addr = m_state.context.gpr.__pc + 2;
                    }
                    else
                    {
                        // Extend the number of bits to ignore for the mismatch
                        m_state.dbg.__bcr[i] |= BAS_IMVA_ALL;
                    }
                }
            }
        }
        else
        {
            // ARM breakpoint
            m_state.dbg.__bcr[i] |= BAS_IMVA_ALL; // Stop when any address bits change
        }

        DNBLogThreadedIf(LOG_STEP, "%s: BVR%u=0x%8.8x  BCR%u=0x%8.8x", __FUNCTION__, i, m_state.dbg.__bvr[i], i, m_state.dbg.__bcr[i]);

        for (uint32_t j=i+1; j<16; ++j)
        {
            // Disable all others
            m_state.dbg.__bvr[j] = 0;
            m_state.dbg.__bcr[j] = 0;
        }
    }
    else
    {
        // Just restore the state we had before we did single stepping
        m_state.dbg = m_dbg_save;
    }

    return SetDBGState();
}

// return 1 if bit "BIT" is set in "value"
static inline uint32_t bit(uint32_t value, uint32_t bit)
{
    return (value >> bit) & 1u;
}

// return the bitfield "value[msbit:lsbit]".
static inline uint32_t bits(uint32_t value, uint32_t msbit, uint32_t lsbit)
{
    assert(msbit >= lsbit);
    uint32_t shift_left = sizeof(value) * 8 - 1 - msbit;
    value <<= shift_left;           // shift anything above the msbit off of the unsigned edge
    value >>= shift_left + lsbit;   // shift it back again down to the lsbit (including undoing any shift from above)
    return value;                   // return our result
}

bool
DNBArchMachARM::ConditionPassed(uint8_t condition, uint32_t cpsr)
{
    uint32_t cpsr_n = bit(cpsr, 31); // Negative condition code flag
    uint32_t cpsr_z = bit(cpsr, 30); // Zero condition code flag
    uint32_t cpsr_c = bit(cpsr, 29); // Carry condition code flag
    uint32_t cpsr_v = bit(cpsr, 28); // Overflow condition code flag

    switch (condition) {
        case COND_EQ: // (0x0)
            if (cpsr_z == 1) return true;
            break;
        case COND_NE: // (0x1)
            if (cpsr_z == 0) return true;
            break;
        case COND_CS: // (0x2)
            if (cpsr_c == 1) return true;
            break;
        case COND_CC: // (0x3)
            if (cpsr_c == 0) return true;
            break;
        case COND_MI: // (0x4)
            if (cpsr_n == 1) return true;
            break;
        case COND_PL: // (0x5)
            if (cpsr_n == 0) return true;
            break;
        case COND_VS: // (0x6)
            if (cpsr_v == 1) return true;
            break;
        case COND_VC: // (0x7)
            if (cpsr_v == 0) return true;
            break;
        case COND_HI: // (0x8)
            if ((cpsr_c == 1) && (cpsr_z == 0)) return true;
            break;
        case COND_LS: // (0x9)
            if ((cpsr_c == 0) || (cpsr_z == 1)) return true;
            break;
        case COND_GE: // (0xA)
            if (cpsr_n == cpsr_v) return true;
            break;
        case COND_LT: // (0xB)
            if (cpsr_n != cpsr_v) return true;
            break;
        case COND_GT: // (0xC)
            if ((cpsr_z == 0) && (cpsr_n == cpsr_v)) return true;
            break;
        case COND_LE: // (0xD)
            if ((cpsr_z == 1) || (cpsr_n != cpsr_v)) return true;
            break;
        default:
            return true;
            break;
    }

    return false;
}

bool
DNBArchMachARM::ComputeNextPC(nub_addr_t currentPC, arm_decoded_instruction_t decodedInstruction, bool currentPCIsThumb, nub_addr_t *targetPC)
{
    nub_addr_t myTargetPC, addressWherePCLives;
    pid_t mypid;

    uint32_t cpsr_c = bit(m_state.context.gpr.__cpsr, 29); // Carry condition code flag

    uint32_t firstOperand=0, secondOperand=0, shiftAmount=0, secondOperandAfterShift=0, immediateValue=0;
    uint32_t halfwords=0, baseAddress=0, immediateOffset=0, addressOffsetFromRegister=0, addressOffsetFromRegisterAfterShift;
    uint32_t baseAddressIndex=INVALID_NUB_HW_INDEX;
    uint32_t firstOperandIndex=INVALID_NUB_HW_INDEX;
    uint32_t secondOperandIndex=INVALID_NUB_HW_INDEX;
    uint32_t addressOffsetFromRegisterIndex=INVALID_NUB_HW_INDEX;
    uint32_t shiftRegisterIndex=INVALID_NUB_HW_INDEX;
    uint16_t registerList16, registerList16NoPC;
    uint8_t registerList8;
    uint32_t numRegistersToLoad=0;

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: instruction->code=%d", __FUNCTION__, decodedInstruction.instruction->code);

    // Get the following in this switch statement:
    //   - firstOperand, secondOperand, immediateValue, shiftAmount: For arithmetic, logical and move instructions
    //   - baseAddress, immediateOffset, shiftAmount: For LDR
    //   - numRegistersToLoad: For LDM and POP instructions
    switch (decodedInstruction.instruction->code)
    {
            // Arithmetic operations that can change the PC
        case ARM_INST_ADC:
        case ARM_INST_ADCS:
        case ARM_INST_ADD:
        case ARM_INST_ADDS:
        case ARM_INST_AND:
        case ARM_INST_ANDS:
        case ARM_INST_ASR:
        case ARM_INST_ASRS:
        case ARM_INST_BIC:
        case ARM_INST_BICS:
        case ARM_INST_EOR:
        case ARM_INST_EORS:
        case ARM_INST_ORR:
        case ARM_INST_ORRS:
        case ARM_INST_RSB:
        case ARM_INST_RSBS:
        case ARM_INST_RSC:
        case ARM_INST_RSCS:
        case ARM_INST_SBC:
        case ARM_INST_SBCS:
        case ARM_INST_SUB:
        case ARM_INST_SUBS:
            switch (decodedInstruction.addressMode)
            {
                case ARM_ADDR_DATA_IMM:
                    if (decodedInstruction.numOperands != 3)
                    {
                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get firstOperand register value (at index=1)
                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];

                    // Get immediateValue (at index=2)
                    immediateValue = decodedInstruction.op[2].value;

                    break;

                case ARM_ADDR_DATA_REG:
                    if (decodedInstruction.numOperands != 3)
                    {
                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get firstOperand register value (at index=1)
                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];

                    // Get secondOperand register value (at index=2)
                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    break;

                case ARM_ADDR_DATA_SCALED_IMM:
                    if (decodedInstruction.numOperands != 4)
                    {
                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get firstOperand register value (at index=1)
                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];

                    // Get secondOperand register value (at index=2)
                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    // Get shiftAmount as immediate value (at index=3)
                    shiftAmount = decodedInstruction.op[3].value;

                    break;


                case ARM_ADDR_DATA_SCALED_REG:
                    if (decodedInstruction.numOperands != 4)
                    {
                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get firstOperand register value (at index=1)
                    firstOperandIndex = decodedInstruction.op[1].value; // first operand register index
                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];

                    // Get secondOperand register value (at index=2)
                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    // Get shiftAmount from register (at index=3)
                    shiftRegisterIndex = decodedInstruction.op[3].value; // second operand register index
                    shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];

                    break;

                case THUMB_ADDR_HR_HR:
                    if (decodedInstruction.numOperands != 2)
                    {
                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get firstOperand register value (at index=0)
                    firstOperandIndex = decodedInstruction.op[0].value; // first operand register index
                    firstOperand = m_state.context.gpr.__r[firstOperandIndex];

                    // Get secondOperand register value (at index=1)
                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    break;

                default:
                    break;
            }
            break;

            // Logical shifts and move operations that can change the PC
        case ARM_INST_LSL:
        case ARM_INST_LSLS:
        case ARM_INST_LSR:
        case ARM_INST_LSRS:
        case ARM_INST_MOV:
        case ARM_INST_MOVS:
        case ARM_INST_MVN:
        case ARM_INST_MVNS:
        case ARM_INST_ROR:
        case ARM_INST_RORS:
        case ARM_INST_RRX:
        case ARM_INST_RRXS:
            // In these cases, the firstOperand is always 0, as if it does not exist
            switch (decodedInstruction.addressMode)
            {
                case ARM_ADDR_DATA_IMM:
                    if (decodedInstruction.numOperands != 2)
                    {
                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get immediateValue (at index=1)
                    immediateValue = decodedInstruction.op[1].value;

                    break;

                case ARM_ADDR_DATA_REG:
                    if (decodedInstruction.numOperands != 2)
                    {
                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get secondOperand register value (at index=1)
                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    break;

                case ARM_ADDR_DATA_SCALED_IMM:
                    if (decodedInstruction.numOperands != 3)
                    {
                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get secondOperand register value (at index=1)
                    secondOperandIndex = decodedInstruction.op[2].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    // Get shiftAmount as immediate value (at index=2)
                    shiftAmount = decodedInstruction.op[2].value;

                    break;


                case ARM_ADDR_DATA_SCALED_REG:
                    if (decodedInstruction.numOperands != 3)
                    {
                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get secondOperand register value (at index=1)
                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    // Get shiftAmount from register (at index=2)
                    shiftRegisterIndex = decodedInstruction.op[2].value; // second operand register index
                    shiftAmount = m_state.context.gpr.__r[shiftRegisterIndex];

                    break;

                case THUMB_ADDR_HR_HR:
                    if (decodedInstruction.numOperands != 2)
                    {
                        DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    if (decodedInstruction.op[0].value != PC_REG)
                    {
                        DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                        return false;
                    }

                    // Get secondOperand register value (at index=1)
                    secondOperandIndex = decodedInstruction.op[1].value; // second operand register index
                    secondOperand = m_state.context.gpr.__r[secondOperandIndex];

                    break;

                default:
                    break;
            }

            break;

            // Simple branches, used to hop around within a routine
        case ARM_INST_B:
            *targetPC = decodedInstruction.targetPC; // Known targetPC
            return true;
            break;

            // Branch-and-link, used to call ARM subroutines
        case ARM_INST_BL:
            *targetPC = decodedInstruction.targetPC; // Known targetPC
            return true;
            break;

            // Branch-and-link with exchange, used to call opposite-mode subroutines
        case ARM_INST_BLX:
            if ((decodedInstruction.addressMode == ARM_ADDR_BRANCH_IMM) ||
                (decodedInstruction.addressMode == THUMB_ADDR_UNCOND))
            {
                *targetPC = decodedInstruction.targetPC; // Known targetPC
                return true;
            }
            else    // addressMode == ARM_ADDR_BRANCH_REG
            {
                // Unknown target unless we're branching to the PC itself,
                //  although this may not work properly with BLX
                if (decodedInstruction.op[REG_RD].value == PC_REG)
                {
                    // this should (almost) never happen
                    *targetPC = decodedInstruction.targetPC; // Known targetPC
                    return true;
                }

                // Get the branch address and return
                if (decodedInstruction.numOperands != 1)
                {
                    DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                    return false;
                }

                // Get branch address in register (at index=0)
                *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
                return true;
            }
            break;

            // Branch with exchange, used to hop to opposite-mode code
            // Branch to Jazelle code, used to execute Java; included here since it
            //  acts just like BX unless the Jazelle unit is active and JPC is
            //  already loaded into it.
        case ARM_INST_BX:
        case ARM_INST_BXJ:
            // Unknown target unless we're branching to the PC itself,
            //  although this can never switch to Thumb mode and is
            //  therefore pretty much useless
            if (decodedInstruction.op[REG_RD].value == PC_REG)
            {
                // this should (almost) never happen
                *targetPC = decodedInstruction.targetPC; // Known targetPC
                return true;
            }

            // Get the branch address and return
            if (decodedInstruction.numOperands != 1)
            {
                DNBLogError("Expected 1 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                return false;
            }

            // Get branch address in register (at index=0)
            *targetPC = m_state.context.gpr.__r[decodedInstruction.op[0].value];
            return true;
            break;

            // Compare and branch on zero/non-zero (Thumb-16 only)
            // Unusual condition check built into the instruction
        case ARM_INST_CBZ:
        case ARM_INST_CBNZ:
            // Branch address is known at compile time
            // Get the branch address and return
            if (decodedInstruction.numOperands != 2)
            {
                DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                return false;
            }

            // Get branch address as an immediate value (at index=1)
            *targetPC = decodedInstruction.op[1].value;
            return true;
            break;

            // Load register can be used to load PC, usually with a function pointer
        case ARM_INST_LDR:
            if (decodedInstruction.op[REG_RD].value != PC_REG)
            {
                DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                return false;
            }
            switch (decodedInstruction.addressMode)
            {
                case ARM_ADDR_LSWUB_IMM:
                case ARM_ADDR_LSWUB_IMM_PRE:
                case ARM_ADDR_LSWUB_IMM_POST:
                    if (decodedInstruction.numOperands != 3)
                    {
                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    // Get baseAddress from register (at index=1)
                    baseAddressIndex = decodedInstruction.op[1].value;
                    baseAddress = m_state.context.gpr.__r[baseAddressIndex];

                    // Get immediateOffset (at index=2)
                    immediateOffset = decodedInstruction.op[2].value;
                    break;

                case ARM_ADDR_LSWUB_REG:
                case ARM_ADDR_LSWUB_REG_PRE:
                case ARM_ADDR_LSWUB_REG_POST:
                    if (decodedInstruction.numOperands != 3)
                    {
                        DNBLogError("Expected 3 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    // Get baseAddress from register (at index=1)
                    baseAddressIndex = decodedInstruction.op[1].value;
                    baseAddress = m_state.context.gpr.__r[baseAddressIndex];

                    // Get immediateOffset from register (at index=2)
                    addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
                    addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];

                    break;

                case ARM_ADDR_LSWUB_SCALED:
                case ARM_ADDR_LSWUB_SCALED_PRE:
                case ARM_ADDR_LSWUB_SCALED_POST:
                    if (decodedInstruction.numOperands != 4)
                    {
                        DNBLogError("Expected 4 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                        return false;
                    }

                    // Get baseAddress from register (at index=1)
                    baseAddressIndex = decodedInstruction.op[1].value;
                    baseAddress = m_state.context.gpr.__r[baseAddressIndex];

                    // Get immediateOffset from register (at index=2)
                    addressOffsetFromRegisterIndex = decodedInstruction.op[2].value;
                    addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];

                    // Get shiftAmount (at index=3)
                    shiftAmount = decodedInstruction.op[3].value;

                    break;

                default:
                    break;
            }
            break;

            // 32b load multiple operations can load the PC along with everything else,
            //  usually to return from a function call
        case ARM_INST_LDMDA:
        case ARM_INST_LDMDB:
        case ARM_INST_LDMIA:
        case ARM_INST_LDMIB:
            if (decodedInstruction.op[LDM_REGLIST].value & PC_REGLIST_BIT)
            {
                if (decodedInstruction.numOperands != 2)
                {
                    DNBLogError("Expected 2 operands in decoded instruction structure. numOperands is %d!", decodedInstruction.numOperands);
                    return false;
                }

                // Get baseAddress from register (at index=0)
                baseAddressIndex = decodedInstruction.op[0].value;
                baseAddress = m_state.context.gpr.__r[baseAddressIndex];

                // Get registerList from register (at index=1)
                registerList16 = (uint16_t)decodedInstruction.op[1].value;

                // Count number of registers to load in the multiple register list excluding the PC
                registerList16NoPC = registerList16&0x3FFF; // exclude the PC
                numRegistersToLoad=0;
                for (int i = 0; i < 16; i++)
                {
                    if (registerList16NoPC & 0x1) numRegistersToLoad++;
                    registerList16NoPC = registerList16NoPC >> 1;
                }
            }
            else
            {
                DNBLogError("Destination register is not a PC! %s routine should be called on on instructions that modify the PC. Destination register is R%d!", __FUNCTION__, decodedInstruction.op[0].value);
                return false;
            }
            break;

            // Normal 16-bit LD multiple can't touch R15, but POP can
        case ARM_INST_POP:  // Can also get the PC & updates SP
            // Get baseAddress from SP (at index=0)
            baseAddress = m_state.context.gpr.__sp;

            if (decodedInstruction.thumb16b)
            {
                // Get registerList from register (at index=0)
                registerList8 = (uint8_t)decodedInstruction.op[0].value;

                // Count number of registers to load in the multiple register list
                numRegistersToLoad=0;
                for (int i = 0; i < 8; i++)
                {
                    if (registerList8 & 0x1) numRegistersToLoad++;
                    registerList8 = registerList8 >> 1;
                }
            }
            else
            {
                // Get registerList from register (at index=0)
                registerList16 = (uint16_t)decodedInstruction.op[0].value;

                // Count number of registers to load in the multiple register list excluding the PC
                registerList16NoPC = registerList16&0x3FFF; // exclude the PC
                numRegistersToLoad=0;
                for (int i = 0; i < 16; i++)
                {
                    if (registerList16NoPC & 0x1) numRegistersToLoad++;
                    registerList16NoPC = registerList16NoPC >> 1;
                }
            }
            break;

            // 16b TBB and TBH instructions load a jump address from a table
        case ARM_INST_TBB:
        case ARM_INST_TBH:
            // Get baseAddress from register (at index=0)
            baseAddressIndex = decodedInstruction.op[0].value;
            baseAddress = m_state.context.gpr.__r[baseAddressIndex];

            // Get immediateOffset from register (at index=1)
            addressOffsetFromRegisterIndex = decodedInstruction.op[1].value;
            addressOffsetFromRegister = m_state.context.gpr.__r[addressOffsetFromRegisterIndex];
            break;

            // ThumbEE branch-to-handler instructions: Jump to handlers at some offset
            //  from a special base pointer register (which is unknown at disassembly time)
        case ARM_INST_HB:
        case ARM_INST_HBP:
//          TODO: ARM_INST_HB, ARM_INST_HBP
            break;

        case ARM_INST_HBL:
        case ARM_INST_HBLP:
//          TODO: ARM_INST_HBL, ARM_INST_HBLP
            break;

            // Breakpoint and software interrupt jump to interrupt handler (always ARM)
        case ARM_INST_BKPT:
        case ARM_INST_SMC:
        case ARM_INST_SVC:

            // Return from exception, obviously modifies PC [interrupt only!]
        case ARM_INST_RFEDA:
        case ARM_INST_RFEDB:
        case ARM_INST_RFEIA:
        case ARM_INST_RFEIB:

            // Other instructions either can't change R15 or are "undefined" if you do,
            //  so no sane compiler should ever generate them & we don't care here.
            //  Also, R15 can only legally be used in a read-only manner for the
            //  various ARM addressing mode (to get PC-relative addressing of constants),
            //  but can NOT be used with any of the update modes.
        default:
            DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code);
            return false;
            break;
    }

    // Adjust PC if PC is one of the input operands
    if (baseAddressIndex == PC_REG)
    {
        if (currentPCIsThumb)
            baseAddress += 4;
        else
            baseAddress += 8;
    }

    if (firstOperandIndex == PC_REG)
    {
        if (currentPCIsThumb)
            firstOperand += 4;
        else
            firstOperand += 8;
    }

    if (secondOperandIndex == PC_REG)
    {
        if (currentPCIsThumb)
            secondOperand += 4;
        else
            secondOperand += 8;
    }

    if (addressOffsetFromRegisterIndex == PC_REG)
    {
        if (currentPCIsThumb)
            addressOffsetFromRegister += 4;
        else
            addressOffsetFromRegister += 8;
    }

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE,
        "%s: firstOperand=%8.8x, secondOperand=%8.8x, immediateValue = %d, shiftAmount = %d, baseAddress = %8.8x, addressOffsetFromRegister = %8.8x, immediateOffset = %d, numRegistersToLoad = %d",
        __FUNCTION__,
        firstOperand,
        secondOperand,
        immediateValue,
        shiftAmount,
        baseAddress,
        addressOffsetFromRegister,
        immediateOffset,
        numRegistersToLoad);


    // Calculate following values after applying shiftAmount:
    //   - immediateOffsetAfterShift, secondOperandAfterShift

    switch (decodedInstruction.scaleMode)
    {
        case ARM_SCALE_NONE:
            addressOffsetFromRegisterAfterShift = addressOffsetFromRegister;
            secondOperandAfterShift = secondOperand;
            break;

        case ARM_SCALE_LSL:             // Logical shift left
            addressOffsetFromRegisterAfterShift = addressOffsetFromRegister << shiftAmount;
            secondOperandAfterShift = secondOperand << shiftAmount;
            break;

        case ARM_SCALE_LSR:             // Logical shift right
            addressOffsetFromRegisterAfterShift = addressOffsetFromRegister >> shiftAmount;
            secondOperandAfterShift = secondOperand >> shiftAmount;
            break;

        case ARM_SCALE_ASR:             // Arithmetic shift right
            asm("mov %0, %1, asr %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount));
            asm("mov %0, %1, asr %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount));
            break;

        case ARM_SCALE_ROR:             // Rotate right
            asm("mov %0, %1, ror %2" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister), "r" (shiftAmount));
            asm("mov %0, %1, ror %2" : "=r" (secondOperandAfterShift) : "r" (secondOperand), "r" (shiftAmount));
            break;

        case ARM_SCALE_RRX:             // Rotate right, pulling in carry (1-bit shift only)
            asm("mov %0, %1, rrx" : "=r" (addressOffsetFromRegisterAfterShift) : "r" (addressOffsetFromRegister));
            asm("mov %0, %1, rrx" : "=r" (secondOperandAfterShift) : "r" (secondOperand));
            break;
    }

    // Emulate instruction to calculate targetPC
    // All branches are already handled in the first switch statement. A branch should not reach this switch
    switch (decodedInstruction.instruction->code)
    {
            // Arithmetic operations that can change the PC
        case ARM_INST_ADC:
        case ARM_INST_ADCS:
            // Add with Carry
            *targetPC = firstOperand + (secondOperandAfterShift + immediateValue) + cpsr_c;
            break;

        case ARM_INST_ADD:
        case ARM_INST_ADDS:
            *targetPC = firstOperand + (secondOperandAfterShift + immediateValue);
            break;

        case ARM_INST_AND:
        case ARM_INST_ANDS:
            *targetPC = firstOperand & (secondOperandAfterShift + immediateValue);
            break;

        case ARM_INST_ASR:
        case ARM_INST_ASRS:
            asm("mov %0, %1, asr %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
            *targetPC = myTargetPC;
            break;

        case ARM_INST_BIC:
        case ARM_INST_BICS:
            asm("bic %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
            *targetPC = myTargetPC;
            break;

        case ARM_INST_EOR:
        case ARM_INST_EORS:
            asm("eor %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
            *targetPC = myTargetPC;
            break;

        case ARM_INST_ORR:
        case ARM_INST_ORRS:
            asm("orr %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
            *targetPC = myTargetPC;
            break;

        case ARM_INST_RSB:
        case ARM_INST_RSBS:
            asm("rsb %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
            *targetPC = myTargetPC;
            break;

        case ARM_INST_RSC:
        case ARM_INST_RSCS:
            myTargetPC = secondOperandAfterShift - (firstOperand + !cpsr_c);
            *targetPC = myTargetPC;
            break;

        case ARM_INST_SBC:
        case ARM_INST_SBCS:
            asm("sbc %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue  + !cpsr_c));
            *targetPC = myTargetPC;
            break;

        case ARM_INST_SUB:
        case ARM_INST_SUBS:
            asm("sub %0, %1, %2" : "=r" (myTargetPC) : "r" (firstOperand), "r" (secondOperandAfterShift + immediateValue));
            *targetPC = myTargetPC;
            break;

            // Logical shifts and move operations that can change the PC
        case ARM_INST_LSL:
        case ARM_INST_LSLS:
        case ARM_INST_LSR:
        case ARM_INST_LSRS:
        case ARM_INST_MOV:
        case ARM_INST_MOVS:
        case ARM_INST_ROR:
        case ARM_INST_RORS:
        case ARM_INST_RRX:
        case ARM_INST_RRXS:
            myTargetPC = secondOperandAfterShift + immediateValue;
            *targetPC = myTargetPC;
            break;

        case ARM_INST_MVN:
        case ARM_INST_MVNS:
            myTargetPC = !(secondOperandAfterShift + immediateValue);
            *targetPC = myTargetPC;
            break;

            // Load register can be used to load PC, usually with a function pointer
        case ARM_INST_LDR:
            switch (decodedInstruction.addressMode) {
                case ARM_ADDR_LSWUB_IMM_POST:
                case ARM_ADDR_LSWUB_REG_POST:
                case ARM_ADDR_LSWUB_SCALED_POST:
                    addressWherePCLives = baseAddress;
                    break;

                case ARM_ADDR_LSWUB_IMM:
                case ARM_ADDR_LSWUB_REG:
                case ARM_ADDR_LSWUB_SCALED:
                case ARM_ADDR_LSWUB_IMM_PRE:
                case ARM_ADDR_LSWUB_REG_PRE:
                case ARM_ADDR_LSWUB_SCALED_PRE:
                    addressWherePCLives = baseAddress + (addressOffsetFromRegisterAfterShift + immediateOffset);
                    break;

                default:
                    break;
            }

            mypid = m_thread->ProcessID();
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
                return false;
            }

            *targetPC = myTargetPC;
            break;

            // 32b load multiple operations can load the PC along with everything else,
            //  usually to return from a function call
        case ARM_INST_LDMDA:
            mypid = m_thread->ProcessID();
            addressWherePCLives = baseAddress;
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
                return false;
            }

            *targetPC = myTargetPC;
            break;

        case ARM_INST_LDMDB:
            mypid = m_thread->ProcessID();
            addressWherePCLives = baseAddress - 4;
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
                return false;
            }

            *targetPC = myTargetPC;
            break;

        case ARM_INST_LDMIB:
            mypid = m_thread->ProcessID();
            addressWherePCLives = baseAddress + numRegistersToLoad*4 + 4;
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
                return false;
            }

            *targetPC = myTargetPC;
            break;

        case ARM_INST_LDMIA: // same as pop
            // Normal 16-bit LD multiple can't touch R15, but POP can
        case ARM_INST_POP:  // Can also get the PC & updates SP
            mypid = m_thread->ProcessID();
            addressWherePCLives = baseAddress + numRegistersToLoad*4;
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, sizeof(nub_addr_t), &myTargetPC) !=  sizeof(nub_addr_t))
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the pop instruction!", addressWherePCLives);
                return false;
            }

            *targetPC = myTargetPC;
            break;

            // 16b TBB and TBH instructions load a jump address from a table
        case ARM_INST_TBB:
            mypid = m_thread->ProcessID();
            addressWherePCLives = baseAddress + addressOffsetFromRegisterAfterShift;
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, 1, &halfwords) !=  1)
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBB instruction!", addressWherePCLives);
                return false;
            }
            // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords
            *targetPC = (currentPC + 4) + 2*halfwords;
            break;

        case ARM_INST_TBH:
            mypid = m_thread->ProcessID();
            addressWherePCLives = ((baseAddress + (addressOffsetFromRegisterAfterShift << 1)) & ~0x1);
            if (DNBProcessMemoryRead(mypid, addressWherePCLives, 2, &halfwords) !=  2)
            {
                DNBLogError("Could not read memory at %8.8x to get targetPC when processing the TBH instruction!", addressWherePCLives);
                return false;
            }
            // add 4 to currentPC since we are in Thumb mode and then add 2*halfwords
            *targetPC = (currentPC + 4) + 2*halfwords;
            break;

            // ThumbEE branch-to-handler instructions: Jump to handlers at some offset
            //  from a special base pointer register (which is unknown at disassembly time)
        case ARM_INST_HB:
        case ARM_INST_HBP:
            //          TODO: ARM_INST_HB, ARM_INST_HBP
            break;

        case ARM_INST_HBL:
        case ARM_INST_HBLP:
            //          TODO: ARM_INST_HBL, ARM_INST_HBLP
            break;

            // Breakpoint and software interrupt jump to interrupt handler (always ARM)
        case ARM_INST_BKPT:
        case ARM_INST_SMC:
        case ARM_INST_SVC:
            //          TODO: ARM_INST_BKPT, ARM_INST_SMC, ARM_INST_SVC
            break;

            // Return from exception, obviously modifies PC [interrupt only!]
        case ARM_INST_RFEDA:
        case ARM_INST_RFEDB:
        case ARM_INST_RFEIA:
        case ARM_INST_RFEIB:
            //          TODO: ARM_INST_RFEDA, ARM_INST_RFEDB, ARM_INST_RFEIA, ARM_INST_RFEIB
            break;

            // Other instructions either can't change R15 or are "undefined" if you do,
            //  so no sane compiler should ever generate them & we don't care here.
            //  Also, R15 can only legally be used in a read-only manner for the
            //  various ARM addressing mode (to get PC-relative addressing of constants),
            //  but can NOT be used with any of the update modes.
        default:
            DNBLogError("%s should not be called for instruction code %d!", __FUNCTION__, decodedInstruction.instruction->code);
            return false;
            break;
    }

    return true;
}

void
DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup(nub_addr_t currentPC, uint32_t cpsr, bool currentPCIsThumb, nub_addr_t *nextPC, bool *nextPCIsThumb)
{
    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "DNBArchMachARM::EvaluateNextInstructionForSoftwareBreakpointSetup() called");

    nub_addr_t targetPC = INVALID_NUB_ADDRESS;
    uint32_t registerValue;
    arm_error_t decodeError;
    nub_addr_t currentPCInITBlock, nextPCInITBlock;
    int i;
    bool last_decoded_instruction_executes = true;

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: default nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM");

    // Update *nextPC and *nextPCIsThumb for special cases
    if (m_last_decode_thumb.itBlockRemaining) // we are in an IT block
    {
        // Set the nextPC to the PC of the instruction which will execute in the IT block
        // If none of the instruction execute in the IT block based on the condition flags,
        // then point to the instruction immediately following the IT block
        const int itBlockRemaining = m_last_decode_thumb.itBlockRemaining;
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%8.8x", __FUNCTION__, itBlockRemaining);

        // Determine the PC at which the next instruction resides
        if (m_last_decode_arm.thumb16b)
            currentPCInITBlock = currentPC + 2;
        else
            currentPCInITBlock = currentPC + 4;

        for (i = 0; i < itBlockRemaining; i++)
        {
            DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: currentPCInITBlock=%8.8x", __FUNCTION__, currentPCInITBlock);
            decodeError = DecodeInstructionUsingDisassembler(currentPCInITBlock, cpsr, &m_last_decode_arm, &m_last_decode_thumb, &nextPCInITBlock);

            if (decodeError != ARM_SUCCESS)
                DNBLogError("unable to disassemble instruction at 0x%8.8lx", currentPCInITBlock);

            DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: condition=%d", __FUNCTION__, m_last_decode_arm.condition);
            if (ConditionPassed(m_last_decode_arm.condition, cpsr))
            {
                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes matched for instruction %d", __FUNCTION__, i);
                break; // break from the for loop
            }
            else
            {
                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition codes DID NOT matched for instruction %d", __FUNCTION__, i);
            }

            // update currentPC and nextPCInITBlock
            currentPCInITBlock = nextPCInITBlock;
        }

        if (i == itBlockRemaining) // We came out of the IT block without executing any instructions
            last_decoded_instruction_executes = false;

        *nextPC = currentPCInITBlock;
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: After IT block step-through: *nextPC=%8.8x", __FUNCTION__, *nextPC);
    }

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE,
                    "%s: cpsr = %8.8x, thumb16b = %d, thumb = %d, branch = %d, conditional = %d, knownTarget = %d, links = %d, canSwitchMode = %d, doesSwitchMode = %d",
                    __FUNCTION__,
                    cpsr,
                    m_last_decode_arm.thumb16b,
                    m_last_decode_arm.thumb,
                    m_last_decode_arm.branch,
                    m_last_decode_arm.conditional,
                    m_last_decode_arm.knownTarget,
                    m_last_decode_arm.links,
                    m_last_decode_arm.canSwitchMode,
                    m_last_decode_arm.doesSwitchMode);


    if (last_decoded_instruction_executes &&                    // Was this a conditional instruction that did execute?
        m_last_decode_arm.branch &&                             // Can this instruction change the PC?
        (m_last_decode_arm.instruction->code != ARM_INST_SVC))  // If this instruction is not an SVC instruction
    {
        // Set targetPC. Compute if needed.
        if (m_last_decode_arm.knownTarget)
        {
            // Fixed, known PC-relative
            targetPC = m_last_decode_arm.targetPC;
        }
        else
        {
            // if targetPC is not known at compile time (PC-relative target), compute targetPC
            if (!ComputeNextPC(currentPC, m_last_decode_arm, currentPCIsThumb, &targetPC))
            {
                DNBLogError("%s: Unable to compute targetPC for instruction at 0x%8.8lx", __FUNCTION__, currentPC);
                targetPC = INVALID_NUB_ADDRESS;
            }
        }

        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: targetPC=0x%8.8x, cpsr=0x%8.8x, condition=0x%hhx", __FUNCTION__, targetPC, cpsr, m_last_decode_arm.condition);

        // Refine nextPC computation
        if ((m_last_decode_arm.instruction->code == ARM_INST_CBZ) ||
            (m_last_decode_arm.instruction->code == ARM_INST_CBNZ))
        {
            // Compare and branch on zero/non-zero (Thumb-16 only)
            // Unusual condition check built into the instruction
            registerValue = m_state.context.gpr.__r[m_last_decode_arm.op[REG_RD].value];

            if (m_last_decode_arm.instruction->code == ARM_INST_CBZ)
            {
                if (registerValue == 0)
                    *nextPC = targetPC;
            }
            else
            {
                if (registerValue != 0)
                    *nextPC = targetPC;
            }
        }
        else if (m_last_decode_arm.conditional) // Is the change conditional on flag results?
        {
            if (ConditionPassed(m_last_decode_arm.condition, cpsr)) // conditions match
            {
                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition matched!", __FUNCTION__);
                *nextPC = targetPC;
            }
            else
            {
                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Condition did not match!", __FUNCTION__);
            }
        }
        else
        {
            *nextPC = targetPC;
        }

        // Refine nextPCIsThumb computation
        if (m_last_decode_arm.doesSwitchMode)
        {
            *nextPCIsThumb = !currentPCIsThumb;
        }
        else if (m_last_decode_arm.canSwitchMode)
        {
            // Legal to switch ARM <--> Thumb mode with this branch
            // dependent on bit[0] of targetPC
            *nextPCIsThumb = (*nextPC & 1u) != 0;
        }
        else
        {
            *nextPCIsThumb = currentPCIsThumb;
        }
    }

    DNBLogThreadedIf(LOG_STEP, "%s: calculated nextPC=0x%8.8x (%s)", __FUNCTION__, *nextPC, *nextPCIsThumb ? "Thumb" : "ARM");
}


arm_error_t
DNBArchMachARM::DecodeInstructionUsingDisassembler(nub_addr_t curr_pc, uint32_t curr_cpsr, arm_decoded_instruction_t *decodedInstruction, thumb_static_data_t *thumbStaticData, nub_addr_t *next_pc)
{

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: pc=0x%8.8x, cpsr=0x%8.8x", __FUNCTION__, curr_pc, curr_cpsr);

    const uint32_t isetstate_mask = MASK_CPSR_T | MASK_CPSR_J;
    const uint32_t curr_isetstate = curr_cpsr & isetstate_mask;
    uint32_t opcode32;
    nub_addr_t nextPC = curr_pc;
    arm_error_t decodeReturnCode = ARM_SUCCESS;

    m_last_decode_pc = curr_pc;
    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: last_decode_pc=0x%8.8x", __FUNCTION__, m_last_decode_pc);

    switch (curr_isetstate) {
        case 0x0: // ARM Instruction
            // Read the ARM opcode
            if (m_thread->Process()->Task().ReadMemory(curr_pc, 4, &opcode32) != 4)
            {
                DNBLogError("unable to read opcode bits 31:0 for an ARM opcode at 0x%8.8lx", curr_pc);
                decodeReturnCode = ARM_ERROR;
            }
            else
            {
                nextPC += 4;
                decodeReturnCode = ArmDisassembler((uint64_t)curr_pc, opcode32, false, decodedInstruction, NULL, 0, NULL, 0);

                if (decodeReturnCode != ARM_SUCCESS)
                    DNBLogError("Unable to decode ARM instruction 0x%8.8x at 0x%8.8lx", opcode32, curr_pc);
            }
            break;

        case 0x20: // Thumb Instruction
            uint16_t opcode16;
            // Read the a 16 bit Thumb opcode
            if (m_thread->Process()->Task().ReadMemory(curr_pc, 2, &opcode16) != 2)
            {
                DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8lx", curr_pc);
                decodeReturnCode = ARM_ERROR;
            }
            else
            {
                nextPC += 2;
                opcode32 = opcode16;

                decodeReturnCode = ThumbDisassembler((uint64_t)curr_pc, opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0);

                switch (decodeReturnCode) {
                    case ARM_SKIP:
                        // 32 bit thumb opcode
                        nextPC += 2;
                        if (m_thread->Process()->Task().ReadMemory(curr_pc+2, 2, &opcode16) != 2)
                        {
                            DNBLogError("unable to read opcode bits 15:0 for a thumb opcode at 0x%8.8lx", curr_pc+2);
                        }
                        else
                        {
                            opcode32 = (opcode32 << 16) | opcode16;

                            decodeReturnCode = ThumbDisassembler((uint64_t)(curr_pc+2), opcode16, false, false, thumbStaticData, decodedInstruction, NULL, 0, NULL, 0);

                            if (decodeReturnCode != ARM_SUCCESS)
                                DNBLogError("Unable to decode 2nd half of Thumb instruction 0x%8.4hx at 0x%8.8lx", opcode16, curr_pc+2);
                            break;
                        }
                        break;

                    case ARM_SUCCESS:
                        // 16 bit thumb opcode; at this point we are done decoding the opcode
                        break;

                    default:
                        DNBLogError("Unable to decode Thumb instruction 0x%8.4hx at 0x%8.8lx", opcode16, curr_pc);
                        decodeReturnCode = ARM_ERROR;
                        break;
                }
            }
            break;

        default:
            break;
    }

    if (next_pc)
        *next_pc = nextPC;

    return decodeReturnCode;
}

nub_bool_t
DNBArchMachARM::BreakpointHit (nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *baton)
{
    nub_addr_t bkpt_pc = (nub_addr_t)baton;
    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s(pid = %i, tid = %4.4x, breakID = %u, baton = %p): Setting PC to 0x%8.8x", __FUNCTION__, pid, tid, breakID, baton, bkpt_pc);
    
    DNBRegisterValue pc_value;
    DNBThreadGetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
    pc_value.value.uint32 = bkpt_pc;
    return DNBThreadSetRegisterValueByID (pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_PC, &pc_value);
}

// Set the single step bit in the processor status register.
kern_return_t
DNBArchMachARM::SetSingleStepSoftwareBreakpoints()
{
    DNBError err;
    err = GetGPRState(false);

    if (err.Fail())
    {
        err.LogThreaded("%s: failed to read the GPR registers", __FUNCTION__);
        return err.Error();
    }

    nub_addr_t curr_pc = m_state.context.gpr.__pc;
    uint32_t curr_cpsr = m_state.context.gpr.__cpsr;
    nub_addr_t next_pc = curr_pc;

    bool curr_pc_is_thumb = (m_state.context.gpr.__cpsr & 0x20) != 0;
    bool next_pc_is_thumb = curr_pc_is_thumb;

    uint32_t curr_itstate = ((curr_cpsr & 0x6000000) >> 25) | ((curr_cpsr & 0xFC00) >> 8);
    bool inITBlock = (curr_itstate & 0xF) ? 1 : 0;
    bool lastInITBlock = ((curr_itstate & 0xF) == 0x8) ? 1 : 0;

    DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: curr_pc=0x%8.8x (%s), curr_itstate=0x%x, inITBlock=%d, lastInITBlock=%d", __FUNCTION__, curr_pc, curr_pc_is_thumb ? "Thumb" : "ARM", curr_itstate, inITBlock, lastInITBlock);

    // If the instruction is not in the IT block, then decode using the Disassembler and compute next_pc
    if (!inITBlock)
    {
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Decoding an instruction NOT in the IT block", __FUNCTION__);

        arm_error_t decodeReturnCode =  DecodeInstructionUsingDisassembler(curr_pc, curr_cpsr, &m_last_decode_arm, &m_last_decode_thumb, &next_pc);

        if (decodeReturnCode != ARM_SUCCESS)
        {
            err = KERN_INVALID_ARGUMENT;
            DNBLogError("DNBArchMachARM::SetSingleStepSoftwareBreakpoints: Unable to disassemble instruction at 0x%8.8lx", curr_pc);
        }
    }
    else
    {
        next_pc = curr_pc + ((m_last_decode_arm.thumb16b) ? 2 : 4);
    }

    // Instruction is NOT in the IT block OR
    if (!inITBlock)
    {
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: normal instruction", __FUNCTION__);
        EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
    }
    else if (inITBlock && !m_last_decode_arm.setsFlags)
    {
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that doesn't set flags", __FUNCTION__);
        EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
    }
    else if (lastInITBlock && m_last_decode_arm.branch)
    {
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction which last in the IT block and is a branch", __FUNCTION__);
        EvaluateNextInstructionForSoftwareBreakpointSetup(curr_pc, m_state.context.gpr.__cpsr, curr_pc_is_thumb, &next_pc, &next_pc_is_thumb);
    }
    else
    {
        // Instruction is in IT block and can modify the CPSR flags
        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: IT instruction that sets flags", __FUNCTION__);

        // NOTE: When this point of code is reached, the instruction at curr_pc has already been decoded
        // inside the function ThreadDidStop(). Therefore m_last_decode_arm, m_last_decode_thumb
        // reflect the decoded instruction at curr_pc

        // If we find an instruction inside the IT block which will set/modify the condition flags (NZCV bits in CPSR),
        // we set breakpoints at all remaining instructions inside the IT block starting from the instruction immediately
        // following this one AND a breakpoint at the instruction immediately following the IT block. We do this because
        // we cannot determine the next_pc until the instruction at which we are currently stopped executes. Hence we
        // insert (m_last_decode_thumb.itBlockRemaining+1) 16-bit Thumb breakpoints at consecutive memory locations
        // starting at addrOfNextInstructionInITBlock. We record these breakpoints in class variable m_sw_single_step_itblock_break_id[],
        // and also record the total number of IT breakpoints set in the variable 'm_sw_single_step_itblock_break_count'.

        // The instructions inside the IT block, which are replaced by the 16-bit Thumb breakpoints (opcode=0xDEFE)
        // instructions, can be either Thumb-16 or Thumb-32. When a Thumb-32 instruction (say, inst#1) is replaced  Thumb
        // by a 16-bit breakpoint (OS only supports 16-bit breakpoints in Thumb mode and 32-bit breakpoints in ARM mode), the
        // breakpoint for the next instruction (say instr#2) is saved in the upper half of this Thumb-32 (instr#1)
        // instruction. Hence if the execution stops at Breakpoint2 corresponding to instr#2, the PC is offset by 16-bits.
        // We therefore have to keep track of PC of each instruction in the IT block that is being replaced with the 16-bit
        // Thumb breakpoint, to ensure that when the breakpoint is hit, the PC is adjusted to the correct value. We save
        // the actual PC corresponding to each instruction in the IT block by associating a call back with each breakpoint
        // we set and passing it as a baton. When the breakpoint hits and the callback routine is called, the routine
        // adjusts the PC based on the baton that is passed to it.

        nub_addr_t addrOfNextInstructionInITBlock, pcInITBlock, nextPCInITBlock, bpAddressInITBlock;
        uint16_t opcode16;
        uint32_t opcode32;

        addrOfNextInstructionInITBlock = (m_last_decode_arm.thumb16b) ? curr_pc + 2 : curr_pc + 4;

        pcInITBlock = addrOfNextInstructionInITBlock;

        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: itBlockRemaining=%d", __FUNCTION__, m_last_decode_thumb.itBlockRemaining);

        m_sw_single_step_itblock_break_count = 0;
        for (int i = 0; i <= m_last_decode_thumb.itBlockRemaining; i++)
        {
            if (NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
            {
                DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Array m_sw_single_step_itblock_break_id should not contain any valid breakpoint IDs at this point. But found a valid breakID=%d at index=%d", m_sw_single_step_itblock_break_id[i], i);
            }
            else
            {
                nextPCInITBlock = pcInITBlock;
                // Compute nextPCInITBlock based on opcode present at pcInITBlock
                if (m_thread->Process()->Task().ReadMemory(pcInITBlock, 2, &opcode16) == 2)
                {
                    opcode32 = opcode16;
                    nextPCInITBlock += 2;

                    // Check for 32 bit thumb opcode and read the upper 16 bits if needed
                    if (((opcode32 & 0xE000) == 0xE000) && (opcode32 & 0x1800))
                    {
                        // Adjust 'next_pc_in_itblock' to point to the default next Thumb instruction for
                        // a 32 bit Thumb opcode
                        // Read bits 31:16 of a 32 bit Thumb opcode
                        if (m_thread->Process()->Task().ReadMemory(pcInITBlock+2, 2, &opcode16) == 2)
                        {
                            // 32 bit thumb opcode
                            opcode32 = (opcode32 << 16) | opcode16;
                            nextPCInITBlock += 2;
                        }
                        else
                        {
                            DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Unable to read opcode bits 31:16 for a 32 bit thumb opcode at pc=0x%8.8lx", nextPCInITBlock);
                        }
                    }
                }
                else
                {
                    DNBLogError("FunctionProfiler::SetSingleStepSoftwareBreakpoints(): Error reading 16-bit Thumb instruction at pc=0x%8.8x", nextPCInITBlock);
                }


                // Set breakpoint and associate a callback function with it
                bpAddressInITBlock = addrOfNextInstructionInITBlock + 2*i;
                DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Setting IT breakpoint[%d] at address: 0x%8.8x", __FUNCTION__, i, bpAddressInITBlock);

                m_sw_single_step_itblock_break_id[i] = m_thread->Process()->CreateBreakpoint(bpAddressInITBlock, 2, false, m_thread->ThreadID());
                if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_itblock_break_id[i]))
                    err = KERN_INVALID_ARGUMENT;
                else
                {
                    DNBLogThreadedIf(LOG_STEP, "%s: Set IT breakpoint[%i]=%d set at 0x%8.8x for instruction at 0x%8.8x", __FUNCTION__, i, m_sw_single_step_itblock_break_id[i], bpAddressInITBlock, pcInITBlock);

                    // Set the breakpoint callback for these special IT breakpoints
                    // so that if one of these breakpoints gets hit, it knows to
                    // update the PC to the original address of the conditional
                    // IT instruction.
                    DNBBreakpointSetCallback(m_thread->ProcessID(), m_sw_single_step_itblock_break_id[i], DNBArchMachARM::BreakpointHit, (void*)pcInITBlock);
                    m_sw_single_step_itblock_break_count++;
                }
            }

            pcInITBlock = nextPCInITBlock;
        }

        DNBLogThreadedIf(LOG_STEP | LOG_VERBOSE, "%s: Set %u IT software single breakpoints.", __FUNCTION__, m_sw_single_step_itblock_break_count);

    }

    DNBLogThreadedIf(LOG_STEP, "%s: next_pc=0x%8.8x (%s)", __FUNCTION__, next_pc, next_pc_is_thumb ? "Thumb" : "ARM");

    if (next_pc & 0x1)
    {
        assert(next_pc_is_thumb);
    }

    if (next_pc_is_thumb)
    {
        next_pc &= ~0x1;
    }
    else
    {
        assert((next_pc & 0x3) == 0);
    }

    if (!inITBlock || (inITBlock && !m_last_decode_arm.setsFlags) || (lastInITBlock && m_last_decode_arm.branch))
    {
        err = KERN_SUCCESS;

#if defined DNB_ARCH_MACH_ARM_DEBUG_SW_STEP
        m_sw_single_step_next_pc = next_pc;
        if (next_pc_is_thumb)
            m_sw_single_step_next_pc |= 1;  // Set bit zero if the next PC is expected to be Thumb
#else
        const DNBBreakpoint *bp = m_thread->Process()->Breakpoints().FindByAddress(next_pc);

        if (bp == NULL)
        {
            m_sw_single_step_break_id = m_thread->Process()->CreateBreakpoint(next_pc, next_pc_is_thumb ? 2 : 4, false, m_thread->ThreadID());
            if (!NUB_BREAK_ID_IS_VALID(m_sw_single_step_break_id))
                err = KERN_INVALID_ARGUMENT;
            DNBLogThreadedIf(LOG_STEP, "%s: software single step breakpoint with breakID=%d set at 0x%8.8x", __FUNCTION__, m_sw_single_step_break_id, next_pc);
        }
#endif
    }

    return err.Error();
}

uint32_t
DNBArchMachARM::NumSupportedHardwareBreakpoints()
{
    // Set the init value to something that will let us know that we need to
    // autodetect how many breakpoints are supported dynamically...
    static uint32_t g_num_supported_hw_breakpoints = UINT_MAX;
    if (g_num_supported_hw_breakpoints == UINT_MAX)
    {
        // Set this to zero in case we can't tell if there are any HW breakpoints
        g_num_supported_hw_breakpoints = 0;

        // Read the DBGDIDR to get the number of available hardware breakpoints
        // However, in some of our current armv7 processors, hardware
        // breakpoints/watchpoints were not properly connected. So detect those
        // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
        // field to distinguish CPU architectures. This is a hack until we can
        // get <rdar://problem/6372672> fixed, at which point we will switch to
        // using a different sysctl string that will tell us how many BRPs
        // are available to us directly without having to read DBGDIDR.
        uint32_t register_DBGDIDR;

        asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
        uint32_t numBRPs = bits(register_DBGDIDR, 27, 24);
        // Zero is reserved for the BRP count, so don't increment it if it is zero
        if (numBRPs > 0)
            numBRPs++;
        DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, numBRPs);

        if (numBRPs > 0)
        {
            uint32_t cpusubtype;
            size_t len;
            len = sizeof(cpusubtype);
            // TODO: remove this hack and change to using hw.optional.xx when implmented
            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
            {
                DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);
                if (cpusubtype == CPU_SUBTYPE_ARM_V7)
                    DNBLogThreadedIf(LOG_THREAD, "Hardware breakpoints disabled for armv7 (rdar://problem/6372672)");
                else
                    g_num_supported_hw_breakpoints = numBRPs;
            }
        }

    }
    return g_num_supported_hw_breakpoints;
}


uint32_t
DNBArchMachARM::NumSupportedHardwareWatchpoints()
{
    // Set the init value to something that will let us know that we need to
    // autodetect how many watchpoints are supported dynamically...
    static uint32_t g_num_supported_hw_watchpoints = UINT_MAX;
    if (g_num_supported_hw_watchpoints == UINT_MAX)
    {
        // Set this to zero in case we can't tell if there are any HW breakpoints
        g_num_supported_hw_watchpoints = 0;
        // Read the DBGDIDR to get the number of available hardware breakpoints
        // However, in some of our current armv7 processors, hardware
        // breakpoints/watchpoints were not properly connected. So detect those
        // cases using a field in a sysctl. For now we are using "hw.cpusubtype"
        // field to distinguish CPU architectures. This is a hack until we can
        // get <rdar://problem/6372672> fixed, at which point we will switch to
        // using a different sysctl string that will tell us how many WRPs
        // are available to us directly without having to read DBGDIDR.

        uint32_t register_DBGDIDR;
        asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
        uint32_t numWRPs = bits(register_DBGDIDR, 31, 28) + 1;
        DNBLogThreadedIf(LOG_THREAD, "DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, numWRPs);

        if (numWRPs > 0)
        {
            uint32_t cpusubtype;
            size_t len;
            len = sizeof(cpusubtype);
            // TODO: remove this hack and change to using hw.optional.xx when implmented
            if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
            {
                DNBLogThreadedIf(LOG_THREAD, "hw.cpusubtype=0x%d", cpusubtype);

                if (cpusubtype == CPU_SUBTYPE_ARM_V7)
                    DNBLogThreadedIf(LOG_THREAD, "Hardware watchpoints disabled for armv7 (rdar://problem/6372672)");
                else
                    g_num_supported_hw_watchpoints = numWRPs;
            }
        }

    }
    return g_num_supported_hw_watchpoints;
}


uint32_t
DNBArchMachARM::EnableHardwareBreakpoint (nub_addr_t addr, nub_size_t size)
{
    // Make sure our address isn't bogus
    if (addr & 1)
        return INVALID_NUB_HW_INDEX;

    kern_return_t kret = GetDBGState(false);

    if (kret == KERN_SUCCESS)
    {
        const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
        uint32_t i;
        for (i=0; i<num_hw_breakpoints; ++i)
        {
            if ((m_state.dbg.__bcr[i] & BCR_ENABLE) == 0)
                break; // We found an available hw breakpoint slot (in i)
        }

        // See if we found an available hw breakpoint slot above
        if (i < num_hw_breakpoints)
        {
            // Make sure bits 1:0 are clear in our address
            m_state.dbg.__bvr[i] = addr & ~((nub_addr_t)3);

            if (size == 2 || addr & 2)
            {
                uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;

                // We have a thumb breakpoint
                // We have an ARM breakpoint
                m_state.dbg.__bcr[i] =  BCR_M_IMVA_MATCH |  // Stop on address mismatch
                                        byte_addr_select |  // Set the correct byte address select so we only trigger on the correct opcode
                                        S_USER |            // Which modes should this breakpoint stop in?
                                        BCR_ENABLE;         // Enable this hardware breakpoint
                DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
                        addr,
                        size,
                        i,
                        i,
                        m_state.dbg.__bvr[i],
                        m_state.dbg.__bcr[i]);
            }
            else if (size == 4)
            {
                // We have an ARM breakpoint
                m_state.dbg.__bcr[i] =  BCR_M_IMVA_MATCH |  // Stop on address mismatch
                                        BAS_IMVA_ALL |      // Stop on any of the four bytes following the IMVA
                                        S_USER |            // Which modes should this breakpoint stop in?
                                        BCR_ENABLE;         // Enable this hardware breakpoint
                DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
                        addr,
                        size,
                        i,
                        i,
                        m_state.dbg.__bvr[i],
                        m_state.dbg.__bcr[i]);
            }

            kret = SetDBGState();
            DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint() SetDBGState() => 0x%8.8x.", kret);

            if (kret == KERN_SUCCESS)
                return i;
        }
        else
        {
            DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size);
        }
    }

    return INVALID_NUB_HW_INDEX;
}

bool
DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index)
{
    kern_return_t kret = GetDBGState(false);

    const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
    if (kret == KERN_SUCCESS)
    {
        if (hw_index < num_hw_points)
        {
            m_state.dbg.__bcr[hw_index] = 0;
            DNBLogThreadedIf(LOG_BREAKPOINTS, "DNBArchMachARM::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
                    hw_index,
                    hw_index,
                    m_state.dbg.__bvr[hw_index],
                    hw_index,
                    m_state.dbg.__bcr[hw_index]);

            kret = SetDBGState();

            if (kret == KERN_SUCCESS)
                return true;
        }
    }
    return false;
}

uint32_t
DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
{
    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);

    const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();

    // Can't watch zero bytes
    if (size == 0)
        return INVALID_NUB_HW_INDEX;

    // We must watch for either read or write
    if (read == false && write == false)
        return INVALID_NUB_HW_INDEX;

    // Can't watch more than 4 bytes per WVR/WCR pair
    if (size > 4)
        return INVALID_NUB_HW_INDEX;

    // We can only watch up to four bytes that follow a 4 byte aligned address
    // per watchpoint register pair. Since we have at most so we can only watch
    // until the next 4 byte boundary and we need to make sure we can properly
    // encode this.
    uint32_t addr_word_offset = addr % 4;
    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);

    uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
    if (byte_mask > 0xfu)
        return INVALID_NUB_HW_INDEX;

    // Read the debug state
    kern_return_t kret = GetDBGState(false);

    if (kret == KERN_SUCCESS)
    {
        // Check to make sure we have the needed hardware support
        uint32_t i = 0;

        for (i=0; i<num_hw_watchpoints; ++i)
        {
            if ((m_state.dbg.__wcr[i] & WCR_ENABLE) == 0)
                break; // We found an available hw breakpoint slot (in i)
        }

        // See if we found an available hw breakpoint slot above
        if (i < num_hw_watchpoints)
        {
            // Make the byte_mask into a valid Byte Address Select mask
            uint32_t byte_address_select = byte_mask << 5;
            // Make sure bits 1:0 are clear in our address
            m_state.dbg.__wvr[i] = addr & ~((nub_addr_t)3);
            m_state.dbg.__wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
                                    S_USER |                    // Stop only in user mode
                                    (read ? WCR_LOAD : 0) |     // Stop on read access?
                                    (write ? WCR_STORE : 0) |   // Stop on write access?
                                    WCR_ENABLE;                 // Enable this watchpoint;

            kret = SetDBGState();
            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint() SetDBGState() => 0x%8.8x.", kret);

            if (kret == KERN_SUCCESS)
                return i;
        }
        else
        {
            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
        }
    }
    return INVALID_NUB_HW_INDEX;
}

bool
DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index)
{
    kern_return_t kret = GetDBGState(false);

    const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
    if (kret == KERN_SUCCESS)
    {
        if (hw_index < num_hw_points)
        {
            m_state.dbg.__wcr[hw_index] = 0;
            DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
                    hw_index,
                    hw_index,
                    m_state.dbg.__wvr[hw_index],
                    hw_index,
                    m_state.dbg.__wcr[hw_index]);

            kret = SetDBGState();

            if (kret == KERN_SUCCESS)
                return true;
        }
    }
    return false;
}

//----------------------------------------------------------------------
// Register information defintions for 32 bit ARMV6.
//----------------------------------------------------------------------
enum gpr_regnums
{
    gpr_r0 = 0,
    gpr_r1,
    gpr_r2,
    gpr_r3,
    gpr_r4,
    gpr_r5,
    gpr_r6,
    gpr_r7,
    gpr_r8,
    gpr_r9,
    gpr_r10,
    gpr_r11,
    gpr_r12,
    gpr_sp,
    gpr_lr,
    gpr_pc,
    gpr_cpsr
};

enum 
{
    vfp_s0 = 0,
    vfp_s1,
    vfp_s2,
    vfp_s3,
    vfp_s4,
    vfp_s5,
    vfp_s6,
    vfp_s7,
    vfp_s8,
    vfp_s9,
    vfp_s10,
    vfp_s11,
    vfp_s12,
    vfp_s13,
    vfp_s14,
    vfp_s15,
    vfp_s16,
    vfp_s17,
    vfp_s18,
    vfp_s19,
    vfp_s20,
    vfp_s21,
    vfp_s22,
    vfp_s23,
    vfp_s24,
    vfp_s25,
    vfp_s26,
    vfp_s27,
    vfp_s28,
    vfp_s29,
    vfp_s30,
    vfp_s31,
    vfp_d16,
    vfp_d17,
    vfp_d18,
    vfp_d19,
    vfp_d20,
    vfp_d21,
    vfp_d22,
    vfp_d23,
    vfp_d24,
    vfp_d25,
    vfp_d26,
    vfp_d27,
    vfp_d28,
    vfp_d29,
    vfp_d30,
    vfp_d31,
    vfp_fpscr
};

enum
{
    exc_exception,
	exc_fsr,
	exc_far,
};

enum
{
    gdb_r0 = 0,
    gdb_r1,
    gdb_r2,
    gdb_r3,
    gdb_r4,
    gdb_r5,
    gdb_r6,
    gdb_r7,
    gdb_r8,
    gdb_r9,
    gdb_r10,
    gdb_r11,
    gdb_r12,
    gdb_sp,
    gdb_lr,
    gdb_pc,
    gdb_f0,
    gdb_f1,
    gdb_f2,
    gdb_f3,
    gdb_f4,
    gdb_f5,
    gdb_f6,
    gdb_f7,
    gdb_f8,
    gdb_cpsr,
    gdb_s0,
    gdb_s1,
    gdb_s2,
    gdb_s3,
    gdb_s4,
    gdb_s5,
    gdb_s6,
    gdb_s7,
    gdb_s8,
    gdb_s9,
    gdb_s10,
    gdb_s11,
    gdb_s12,
    gdb_s13,
    gdb_s14,
    gdb_s15,
    gdb_s16,
    gdb_s17,
    gdb_s18,
    gdb_s19,
    gdb_s20,
    gdb_s21,
    gdb_s22,
    gdb_s23,
    gdb_s24,
    gdb_s25,
    gdb_s26,
    gdb_s27,
    gdb_s28,
    gdb_s29,
    gdb_s30,
    gdb_s31,
    gdb_fpscr,
    gdb_d0,
    gdb_d1,
    gdb_d2,
    gdb_d3,
    gdb_d4,
    gdb_d5,
    gdb_d6,
    gdb_d7,
    gdb_d8,
    gdb_d9,
    gdb_d10,
    gdb_d11,
    gdb_d12,
    gdb_d13,
    gdb_d14,
    gdb_d15
};

#define GPR_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::GPR, __r[idx]))
#define GPR_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::GPR, __##reg))
#define VFP_S_OFFSET_IDX(idx) (offsetof (DNBArchMachARM::FPU, __r[idx]) + offsetof (DNBArchMachARM::Context, vfp))
#define VFP_D_OFFSET_IDX(idx) (VFP_S_OFFSET_IDX (32) + (((idx) - 16) * 8))
#define VFP_OFFSET_NAME(reg) (offsetof (DNBArchMachARM::FPU, __##reg) + offsetof (DNBArchMachARM::Context, vfp))
#define EXC_OFFSET(reg)      (offsetof (DNBArchMachARM::EXC, __##reg)  + offsetof (DNBArchMachARM::Context, exc))

// These macros will auto define the register name, alt name, register size,
// register offset, encoding, format and native register. This ensures that
// the register state structures are defined correctly and have the correct
// sizes and offsets.
#define DEFINE_GPR_IDX(idx, reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_IDX(idx), gcc_##reg, dwarf_##reg, gen, gdb_##reg }
#define DEFINE_GPR_NAME(reg, alt, gen) { e_regSetGPR, gpr_##reg, #reg, alt, Uint, Hex, 4, GPR_OFFSET_NAME(reg), gcc_##reg, dwarf_##reg, gen, gdb_##reg }

#define DEFINE_VFP_S_IDX(idx) { e_regSetVFP, vfp_s##idx, "s" #idx, NULL, IEEE754, 4, Float, VFP_S_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }
#define DEFINE_VFP_D_IDX(idx) { e_regSetVFP, vfp_d##idx, "d" #idx, NULL, IEEE754, 8, Float, VFP_D_OFFSET_IDX(idx), INVALID_NUB_REGNUM, dwarf_s##idx, INVALID_NUB_REGNUM, gdb_s##idx }

// General purpose registers
const DNBRegisterInfo
DNBArchMachARM::g_gpr_registers[] =
{
    DEFINE_GPR_IDX ( 0,  r0,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 1,  r1,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 2,  r2,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 3,  r3,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 4,  r4,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 5,  r5,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 6,  r6,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 7,  r7,  NULL, GENERIC_REGNUM_FP    ),
    DEFINE_GPR_IDX ( 8,  r8,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX ( 9,  r9,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX (10, r10,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX (11, r11,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_IDX (12, r12,  NULL, INVALID_NUB_REGNUM   ),
    DEFINE_GPR_NAME (sp, "r13", GENERIC_REGNUM_SP    ),
    DEFINE_GPR_NAME (lr, "r14", GENERIC_REGNUM_RA    ),
    DEFINE_GPR_NAME (pc, "r15", GENERIC_REGNUM_PC    ),
    DEFINE_GPR_NAME (cpsr,  NULL, GENERIC_REGNUM_FLAGS )
};

// Floating point registers
const DNBRegisterInfo
DNBArchMachARM::g_vfp_registers[] =
{
    DEFINE_VFP_S_IDX ( 0),
    DEFINE_VFP_S_IDX ( 1),
    DEFINE_VFP_S_IDX ( 2),
    DEFINE_VFP_S_IDX ( 3),
    DEFINE_VFP_S_IDX ( 4),
    DEFINE_VFP_S_IDX ( 5),
    DEFINE_VFP_S_IDX ( 6),
    DEFINE_VFP_S_IDX ( 7),
    DEFINE_VFP_S_IDX ( 8),
    DEFINE_VFP_S_IDX ( 9),
    DEFINE_VFP_S_IDX (10),
    DEFINE_VFP_S_IDX (11),
    DEFINE_VFP_S_IDX (12),
    DEFINE_VFP_S_IDX (13),
    DEFINE_VFP_S_IDX (14),
    DEFINE_VFP_S_IDX (15),
    DEFINE_VFP_S_IDX (16),
    DEFINE_VFP_S_IDX (17),
    DEFINE_VFP_S_IDX (18),
    DEFINE_VFP_S_IDX (19),
    DEFINE_VFP_S_IDX (20),
    DEFINE_VFP_S_IDX (21),
    DEFINE_VFP_S_IDX (22),
    DEFINE_VFP_S_IDX (23),
    DEFINE_VFP_S_IDX (24),
    DEFINE_VFP_S_IDX (25),
    DEFINE_VFP_S_IDX (26),
    DEFINE_VFP_S_IDX (27),
    DEFINE_VFP_S_IDX (28),
    DEFINE_VFP_S_IDX (29),
    DEFINE_VFP_S_IDX (30),
    DEFINE_VFP_S_IDX (31),
    DEFINE_VFP_D_IDX (16),
    DEFINE_VFP_D_IDX (17),
    DEFINE_VFP_D_IDX (18),
    DEFINE_VFP_D_IDX (19),
    DEFINE_VFP_D_IDX (20),
    DEFINE_VFP_D_IDX (21),
    DEFINE_VFP_D_IDX (22),
    DEFINE_VFP_D_IDX (23),
    DEFINE_VFP_D_IDX (24),
    DEFINE_VFP_D_IDX (25),
    DEFINE_VFP_D_IDX (26),
    DEFINE_VFP_D_IDX (27),
    DEFINE_VFP_D_IDX (28),
    DEFINE_VFP_D_IDX (29),
    DEFINE_VFP_D_IDX (30),
    DEFINE_VFP_D_IDX (31),
    { e_regSetVFP, vfp_fpscr, "fpscr", NULL, Uint, 4, Hex, VFP_OFFSET_NAME(fpscr), INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, gdb_fpscr }
};

// Exception registers

const DNBRegisterInfo
DNBArchMachARM::g_exc_registers[] =
{
  { e_regSetVFP, exc_exception  , "exception"   , NULL, Uint, 4, Hex, EXC_OFFSET(exception) , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
  { e_regSetVFP, exc_fsr        , "fsr"         , NULL, Uint, 4, Hex, EXC_OFFSET(fsr)       , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM },
  { e_regSetVFP, exc_far        , "far"         , NULL, Uint, 4, Hex, EXC_OFFSET(far)       , INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM, INVALID_NUB_REGNUM }
};

// Number of registers in each register set
const size_t DNBArchMachARM::k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo);
const size_t DNBArchMachARM::k_num_vfp_registers = sizeof(g_vfp_registers)/sizeof(DNBRegisterInfo);
const size_t DNBArchMachARM::k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo);
const size_t DNBArchMachARM::k_num_all_registers = k_num_gpr_registers + k_num_vfp_registers + k_num_exc_registers;

//----------------------------------------------------------------------
// Register set definitions. The first definitions at register set index
// of zero is for all registers, followed by other registers sets. The
// register information for the all register set need not be filled in.
//----------------------------------------------------------------------
const DNBRegisterSetInfo
DNBArchMachARM::g_reg_sets[] =
{
    { "ARM Registers",              NULL,               k_num_all_registers     },
    { "General Purpose Registers",  g_gpr_registers,    k_num_gpr_registers     },
    { "Floating Point Registers",   g_vfp_registers,    k_num_vfp_registers     },
    { "Exception State Registers",  g_exc_registers,    k_num_exc_registers     }
};
// Total number of register sets for this architecture
const size_t DNBArchMachARM::k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);


const DNBRegisterSetInfo *
DNBArchMachARM::GetRegisterSetInfo(nub_size_t *num_reg_sets)
{
    *num_reg_sets = k_num_register_sets;
    return g_reg_sets;
}

bool
DNBArchMachARM::GetRegisterValue(int set, int reg, DNBRegisterValue *value)
{
    if (set == REGISTER_SET_GENERIC)
    {
        switch (reg)
        {
        case GENERIC_REGNUM_PC:     // Program Counter
            set = e_regSetGPR;
            reg = gpr_pc;
            break;

        case GENERIC_REGNUM_SP:     // Stack Pointer
            set = e_regSetGPR;
            reg = gpr_sp;
            break;

        case GENERIC_REGNUM_FP:     // Frame Pointer
            set = e_regSetGPR;
            reg = gpr_r7;   // is this the right reg?
            break;

        case GENERIC_REGNUM_RA:     // Return Address
            set = e_regSetGPR;
            reg = gpr_lr;
            break;

        case GENERIC_REGNUM_FLAGS:  // Processor flags register
            set = e_regSetGPR;
            reg = gpr_cpsr;
            break;

        default:
            return false;
        }
    }

    if (GetRegisterState(set, false) != KERN_SUCCESS)
        return false;

    const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
    if (regInfo)
    {
        value->info = *regInfo;
        switch (set)
        {
        case e_regSetGPR:
            if (reg < k_num_gpr_registers)
            {
                value->value.uint32 = m_state.context.gpr.__r[reg];
                return true;
            }
            break;

        case e_regSetVFP:
            if (reg < 32)
            {
                value->value.uint32 = m_state.context.vfp.__r[reg];
                return true;
            }
            else if (reg == 32)
            {
                value->value.uint32 = m_state.context.vfp.__fpscr;
                return true;
            }
            break;

        case e_regSetEXC:
            if (reg < k_num_exc_registers)
            {
                value->value.uint32 = (&m_state.context.exc.__exception)[reg];
                return true;
            }
            break;
        }
    }
    return false;
}

bool
DNBArchMachARM::SetRegisterValue(int set, int reg, const DNBRegisterValue *value)
{
    if (set == REGISTER_SET_GENERIC)
    {
        switch (reg)
        {
        case GENERIC_REGNUM_PC:     // Program Counter
            set = e_regSetGPR;
            reg = gpr_pc;
            break;

        case GENERIC_REGNUM_SP:     // Stack Pointer
            set = e_regSetGPR;
            reg = gpr_sp;
            break;

        case GENERIC_REGNUM_FP:     // Frame Pointer
            set = e_regSetGPR;
            reg = gpr_r7;
            break;

        case GENERIC_REGNUM_RA:     // Return Address
            set = e_regSetGPR;
            reg = gpr_lr;
            break;

        case GENERIC_REGNUM_FLAGS:  // Processor flags register
            set = e_regSetGPR;
            reg = gpr_cpsr;
            break;

        default:
            return false;
        }
    }

    if (GetRegisterState(set, false) != KERN_SUCCESS)
        return false;

    bool success = false;
    const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
    if (regInfo)
    {
        switch (set)
        {
        case e_regSetGPR:
            if (reg < k_num_gpr_registers)
            {
                m_state.context.gpr.__r[reg] = value->value.uint32;
                success = true;
            }
            break;

        case e_regSetVFP:
            if (reg < 32)
            {
                m_state.context.vfp.__r[reg] = value->value.float64;
                success = true;
            }
            else if (reg == 32)
            {
                m_state.context.vfp.__fpscr = value->value.uint32;
                success = true;
            }
            break;

        case e_regSetEXC:
            if (reg < k_num_exc_registers)
            {
                (&m_state.context.exc.__exception)[reg] = value->value.uint32;
                success = true;
            }
            break;
        }

    }
    if (success)
        return SetRegisterState(set) == KERN_SUCCESS;
    return false;
}

kern_return_t
DNBArchMachARM::GetRegisterState(int set, bool force)
{
    switch (set)
    {
    case e_regSetALL:   return GetGPRState(force) |
                               GetVFPState(force) |
                               GetEXCState(force) |
                               GetDBGState(force);
    case e_regSetGPR:   return GetGPRState(force);
    case e_regSetVFP:   return GetVFPState(force);
    case e_regSetEXC:   return GetEXCState(force);
    case e_regSetDBG:   return GetDBGState(force);
    default: break;
    }
    return KERN_INVALID_ARGUMENT;
}

kern_return_t
DNBArchMachARM::SetRegisterState(int set)
{
    // Make sure we have a valid context to set.
    kern_return_t err = GetRegisterState(set, false);
    if (err != KERN_SUCCESS)
        return err;

    switch (set)
    {
    case e_regSetALL:   return SetGPRState() |
                               SetVFPState() |
                               SetEXCState() |
                               SetDBGState();
    case e_regSetGPR:   return SetGPRState();
    case e_regSetVFP:   return SetVFPState();
    case e_regSetEXC:   return SetEXCState();
    case e_regSetDBG:   return SetDBGState();
    default: break;
    }
    return KERN_INVALID_ARGUMENT;
}

bool
DNBArchMachARM::RegisterSetStateIsValid (int set) const
{
    return m_state.RegsAreValid(set);
}


nub_size_t
DNBArchMachARM::GetRegisterContext (void *buf, nub_size_t buf_len)
{
    nub_size_t size = sizeof (m_state.context);
    
    if (buf && buf_len)
    {
        if (size > buf_len)
            size = buf_len;

        bool force = false;
        if (GetGPRState(force) | GetVFPState(force) | GetEXCState(force))
            return 0;
        ::memcpy (buf, &m_state.context, size);
    }
    DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::GetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size);
    // Return the size of the register context even if NULL was passed in
    return size;
}

nub_size_t
DNBArchMachARM::SetRegisterContext (const void *buf, nub_size_t buf_len)
{
    nub_size_t size = sizeof (m_state.context);
    if (buf == NULL || buf_len == 0)
        size = 0;
    
    if (size)
    {
        if (size > buf_len)
            size = buf_len;

        ::memcpy (&m_state.context, buf, size);
        SetGPRState();
        SetVFPState();
        SetEXCState();
    }
    DNBLogThreadedIf (LOG_THREAD, "DNBArchMachARM::SetRegisterContext (buf = %p, len = %zu) => %zu", buf, buf_len, size);
    return size;
}


#endif    // #if defined (__arm__)

