/*******************************************************************************
 * Copyright (c) 2013, 2015 Stanislav Yakovlev and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Eclipse Distribution License v1.0 which accompany this distribution.
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 * You may elect to redistribute this code under either of these licenses.
 *
 * Contributors:
 *     Stanislav Yakovlev           - initial API and implementation
 *     Emmanuel Touron (Wind River) - initial ARM stepping emulation
 *     Stanislav Yakovlev           - [404627] Add support for ARM VFP registers
 *******************************************************************************/

#include <tcf/config.h>

#if ENABLE_DebugContext && !ENABLE_ContextProxy

#ifndef USE_getauxval
#  include <features.h>
#  define USE_getauxval (defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)))
#endif

#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include <signal.h>
#if USE_getauxval
#  include <sys/auxv.h>
#  include <asm/hwcap.h>
#endif
#include <tcf/framework/errors.h>
#include <tcf/framework/cpudefs.h>
#include <tcf/framework/context.h>
#include <tcf/framework/myalloc.h>
#include <tcf/framework/trace.h>
#include <tcf/services/symbols.h>
#include <tcf/services/runctrl.h>
#include <machine/arm/tcf/disassembler-arm.h>
#include <machine/arm/tcf/stack-crawl-arm.h>
#include <tcf/cpudefs-mdep.h>

#define REG_OFFSET(name) offsetof(REG_SET, name)

RegisterDefinition regs_def[] = {
#   define REG_FP user.regs.uregs[11]
#   define REG_IP user.regs.uregs[12]
#   define REG_SP user.regs.uregs[13]
#   define REG_LR user.regs.uregs[14]
#   define REG_PC user.regs.uregs[15]
#   define REG_CPSR user.regs.uregs[16]
    { "r0",      REG_OFFSET(user.regs.uregs[0]),      4, 0, 0},
    { "r1",      REG_OFFSET(user.regs.uregs[1]),      4, 1, 1},
    { "r2",      REG_OFFSET(user.regs.uregs[2]),      4, 2, 2},
    { "r3",      REG_OFFSET(user.regs.uregs[3]),      4, 3, 3},
    { "r4",      REG_OFFSET(user.regs.uregs[4]),      4, 4, 4},
    { "r5",      REG_OFFSET(user.regs.uregs[5]),      4, 5, 5},
    { "r6",      REG_OFFSET(user.regs.uregs[6]),      4, 6, 6},
    { "r7",      REG_OFFSET(user.regs.uregs[7]),      4, 7, 7},
    { "r8",      REG_OFFSET(user.regs.uregs[8]),      4, 8, 8},
    { "r9",      REG_OFFSET(user.regs.uregs[9]),      4, 9, 9},
    { "r10",     REG_OFFSET(user.regs.uregs[10]),     4, 10, 10},
    { "fp",      REG_OFFSET(user.regs.uregs[11]),     4, 11, 11},
    { "ip",      REG_OFFSET(user.regs.uregs[12]),     4, 12, 12},
    { "sp",      REG_OFFSET(user.regs.uregs[13]),     4, 13, 13},
    { "lr",      REG_OFFSET(user.regs.uregs[14]),     4, 14, 14},
    { "pc",      REG_OFFSET(user.regs.uregs[15]),     4, 15, 15},
    { "cpsr",    REG_OFFSET(user.regs.uregs[16]),     4, 128, 128},
    { "orig_r0", REG_OFFSET(user.regs.uregs[17]),     4, -1, -1},
    { "vfp",     0, 0, -1, -1, 0, 0, 1, 1 },
    { NULL,      0, 0,  0,  0},
};

RegisterDefinition * regs_index = NULL;
static unsigned regs_cnt = 0;
static unsigned regs_max = 0;

unsigned char BREAK_INST[] = { 0xf0, 0x01, 0xf0, 0xe7 };

static RegisterDefinition * pc_def = NULL;
static RegisterDefinition * lr_def = NULL;
static RegisterDefinition * cpsr_def = NULL;

#include <sys/ptrace.h>

#if !defined(PTRACE_GETHBPREGS)
#define PTRACE_GETHBPREGS 29
#endif
#if !defined(PTRACE_SETHBPREGS)
#define PTRACE_SETHBPREGS 30
#endif

#define ARM_DEBUG_ARCH_V6       1
#define ARM_DEBUG_ARCH_V6_1     2
#define ARM_DEBUG_ARCH_V7_ECP14 3
#define ARM_DEBUG_ARCH_V7_MM    4
#define ARM_DEBUG_ARCH_V7_1     5
#define ARM_DEBUG_ARCH_V8       6

typedef struct ContextExtensionARM {
    int sw_stepping;
    char opcode[sizeof(BREAK_INST)];
    ContextAddress addr;

#if ENABLE_HardwareBreakpoints
#define MAX_HBP 16
#define MAX_HWP 16
#define MAX_HW_BPS (MAX_HBP + MAX_HWP)
    uint8_t arch;
    uint8_t wp_size;
    uint8_t wp_cnt;
    uint8_t bp_cnt;
    int8_t info_ok;
    int hw_stepping;

    ContextBreakpoint * triggered_hw_bps[MAX_HW_BPS + 1];
    unsigned hw_bps_regs_generation;

    ContextBreakpoint * hw_bps[MAX_HW_BPS];
    unsigned hw_bps_generation;

    unsigned armed;
#endif
} ContextExtensionARM;

static size_t context_extension_offset = 0;

#define EXT(ctx) ((ContextExtensionARM *)((char *)(ctx) + context_extension_offset))

static int arm_get_next_address(Context * ctx, ContextAddress * next_addr);

RegisterDefinition * get_PC_definition(Context * ctx) {
    if (!context_has_state(ctx)) return NULL;
    return pc_def;
}

int crawl_stack_frame(StackFrame * frame, StackFrame * down) {
    return crawl_stack_frame_arm(frame, down);
}

#if defined(ENABLE_add_cpudefs_disassembler) && ENABLE_add_cpudefs_disassembler
void add_cpudefs_disassembler(Context * cpu_ctx) {
    add_disassembler(cpu_ctx, "ARM", disassemble_arm);
    add_disassembler(cpu_ctx, "Thumb", disassemble_thumb);
}
#endif

static int read_reg(Context *ctx, RegisterDefinition * def, size_t size, ContextAddress * addr) {
    size_t i;
    uint8_t buf[8];
    uint64_t n = 0;
    *addr = 0;
    assert(!def->big_endian);
    assert(size <= def->size);
    assert(size <= sizeof(buf));
    if (context_read_reg(ctx, def, 0, size, buf) < 0) return -1;
    for (i = 0; i < size; i++) n |= (uint64_t)buf[i] << (i * 8);
    *addr = (ContextAddress)n;
    return 0;
}

#if ENABLE_HardwareBreakpoints

static void clear_bp(ContextBreakpoint * bp) {
    unsigned i;
    Context * ctx = bp->ctx;
    ContextExtensionARM * bps = EXT(ctx);
    for (i = 0; i < MAX_HW_BPS; i++) {
        if (bps->hw_bps[i] == bp) bps->hw_bps[i] = NULL;
    }
}

static int get_bp_info(Context * ctx) {
    uint32_t buf = 0;
    ContextExtensionARM * bps = EXT(ctx);
    if (bps->info_ok) return 0;
    if (ptrace(PTRACE_GETHBPREGS, id2pid(ctx->id, NULL), 0, &buf) < 0) {
        /* Kernel does not support hardware breakpoints */
        bps->arch = 0;
        bps->wp_size = 0;
        bps->wp_cnt = 0;
        bps->bp_cnt = 0;
        bps->info_ok = 1;
        return 0;
    }
    bps->arch = (uint8_t)(buf >> 24);
    bps->wp_size = (uint8_t)(buf >> 16);
    bps->wp_cnt = (uint8_t)(buf >> 8);
    bps->bp_cnt = (uint8_t)buf;
    if (bps->wp_cnt > MAX_HWP) bps->wp_cnt = MAX_HWP;
    if (bps->bp_cnt > MAX_HBP) bps->bp_cnt = MAX_HBP;
    bps->info_ok = 1;
    return 0;
}

static int is_triggered(Context * ctx, ContextBreakpoint * cb) {
    if (ctx->stopped_by_cb != NULL) {
        unsigned i = 0;
        while (ctx->stopped_by_cb[i] != NULL) {
            if (ctx->stopped_by_cb[i] == cb) return 1;
            i++;
        }
    }
    return 0;
}

static int set_debug_regs(Context * ctx, int * step_over_hw_bp) {
    int i, j;
    ContextAddress pc = 0;
    Context * grp = context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT);
    ContextExtensionARM * ext = EXT(ctx);
    ContextExtensionARM * bps = EXT(grp);
    pid_t pid = id2pid(ctx->id, NULL);

    assert(bps->info_ok);

    ext->armed = 0;
    *step_over_hw_bp = 0;
    if (read_reg(ctx, pc_def, pc_def->size, &pc) < 0) return -1;

    for (i = 0; i < bps->bp_cnt + bps->wp_cnt; i++) {
        uint32_t cr = 0;
        ContextBreakpoint * cb = bps->hw_bps[i];
        if (i == 0 && ext->hw_stepping) {
            uint32_t vr = 0;
            if (ext->hw_stepping == 1) {
                vr = (uint32_t)ext->addr;
            }
            else {
                vr = (uint32_t)pc;
                cr |= 1u << 22;
            }
            cr |= 0xfu << 5;
            cr |= 0x7u;
            if (ptrace(PTRACE_SETHBPREGS, pid, 1, &vr) < 0) return -1;
        }
        else if (cb != NULL) {
            if (i < bps->bp_cnt && cb->address == pc) {
                /* Skipping the breakpoint */
                *step_over_hw_bp = 1;
            }
            else if (bps->arch >= ARM_DEBUG_ARCH_V7_ECP14 && i >= bps->bp_cnt && is_triggered(ctx, cb)) {
                /* Skipping the watchpoint */
                *step_over_hw_bp = 1;
            }
            else {
                uint32_t vr = (uint32_t)(cb->address & ~3);
                if (i < bps->bp_cnt) {
                    cr |= 0xfu << 5;
                }
                else {
                    for (j = 0; j < 4; j++) {
                        if (vr + j < cb->address) continue;
                        if (vr + j >= cb->address + cb->length) continue;
                        cr |= 1 << (5 + j);
                    }
                    if (cb->access_types & CTX_BP_ACCESS_DATA_READ) cr |= 1 << 3;
                    if (cb->access_types & CTX_BP_ACCESS_DATA_WRITE) cr |= 1 << 4;
                }
                cr |= 0x7u;
                if (i < bps->bp_cnt) {
                    if (ptrace(PTRACE_SETHBPREGS, pid, i * 2 + 1, &vr) < 0) return -1;
                }
                else {
                    if (ptrace(PTRACE_SETHBPREGS, pid, -(i * 2 + 1), &vr) < 0) return -1;
                }
                ext->armed |= 1u << i;
            }
        }
        if (cr == 0) {
            /* Linux kernel does not allow 0 as Control Register value */
            cr |= 0x3u << 1;
            cr |= 0xfu << 5;
            if (i >= bps->bp_cnt) {
                cr |= 1u << 4;
            }
        }
        if (i < bps->bp_cnt) {
            if (ptrace(PTRACE_SETHBPREGS, pid, i * 2 + 2, &cr) < 0) return -1;
        }
        else {
            if (ptrace(PTRACE_SETHBPREGS, pid, -(i * 2 + 2), &cr) < 0) return -1;
        }
    }

    ext->hw_bps_regs_generation = bps->hw_bps_generation;
    return 0;
}

static int enable_hw_stepping_mode(Context * ctx, int mode) {
    int step = 0;
    ContextExtensionARM * ext = EXT(ctx);
    if (mode == 1 && arm_get_next_address(ctx, &ext->addr) < 0) return -1;
    ext->hw_stepping = mode;
    return set_debug_regs(ctx, &step);
}

static int disable_hw_stepping_mode(Context * ctx) {
    ContextExtensionARM * ext = EXT(ctx);
    ext->hw_stepping = 0;
    ext->hw_bps_regs_generation--;
    return 0;
}

int cpu_bp_get_capabilities(Context * ctx) {
    int res = 0;
    ContextExtensionARM * bps = EXT(ctx);
    if (ctx != context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT)) return 0;
    if (get_bp_info(ctx) < 0) return 0;
    if (bps->bp_cnt > 0) {
        res |= CTX_BP_ACCESS_INSTRUCTION;
    }
    if (bps->wp_cnt > 0) {
        res |= CTX_BP_ACCESS_DATA_READ;
        res |= CTX_BP_ACCESS_DATA_WRITE;
    }
    res |= CTX_BP_ACCESS_VIRTUAL;
    return res;
}

int cpu_bp_plant(ContextBreakpoint * bp) {
    Context * ctx = bp->ctx;
    ContextExtensionARM * bps = EXT(ctx);
    assert(bp->access_types);
    assert(ctx == context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT));
    if (get_bp_info(ctx) < 0) return -1;
    if (bp->access_types & CTX_BP_ACCESS_VIRTUAL) {
        if (bp->access_types & CTX_BP_ACCESS_INSTRUCTION) {
            unsigned i;
            unsigned n = 0;
            for (i = 0; i < bps->bp_cnt; i++) {
                assert(bps->hw_bps[i] != bp);
                if (bps->hw_bps[i] == NULL) {
                    bps->hw_bps[i] = bp;
                    bps->hw_bps_generation++;
                    n++;
                    break;
                }
            }
            if (n == 0) {
                clear_bp(bp);
                errno = ERR_UNSUPPORTED;
                return -1;
            }
        }
        if (bp->access_types & (CTX_BP_ACCESS_DATA_READ | CTX_BP_ACCESS_DATA_WRITE)) {
            unsigned n = 0;
            if (bp->length <= bps->wp_size) {
                unsigned i;
                for (i = bps->bp_cnt; i < bps->bp_cnt + bps->wp_cnt; i++) {
                    assert(bps->hw_bps[i] != bp);
                    if (bps->hw_bps[i] == NULL) {
                        bps->hw_bps[i] = bp;
                        bps->hw_bps_generation++;
                        n++;
                        break;
                    }
                }
            }
            if (n == 0) {
                clear_bp(bp);
                errno = ERR_UNSUPPORTED;
                return -1;
            }
        }
        return 0;
    }
    errno = ERR_UNSUPPORTED;
    return -1;
}

int cpu_bp_remove(ContextBreakpoint * bp) {
    ContextExtensionARM * bps = EXT(bp->ctx);
    clear_bp(bp);
    bps->hw_bps_generation++;
    return 0;
}

int cpu_bp_on_resume(Context * ctx, int * single_step) {
    ContextExtensionARM * ext = EXT(ctx);
    ContextExtensionARM * bps = EXT(context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT));
    if (ctx->stopped_by_cb != NULL || ext->hw_bps_regs_generation != bps->hw_bps_generation) {
        if (set_debug_regs(ctx, single_step) < 0) return -1;
    }
    return 0;
}

int cpu_bp_on_suspend(Context * ctx, int * triggered) {
    unsigned cb_cnt = 0;
    ContextExtensionARM * ext = EXT(ctx);
    ContextExtensionARM * bps = EXT(context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT));
    int i;

    if (ctx->exiting) return 0;

    if (bps->bp_cnt > 0) {
        ContextAddress pc = 0;
        if (read_reg(ctx, pc_def, pc_def->size, &pc) < 0) return -1;
        for (i = 0; i < bps->bp_cnt; i++) {
            ContextBreakpoint * cb = bps->hw_bps[i];
            if (cb != NULL && cb->address == pc && (ext->armed & (1u << i))) {
                ext->triggered_hw_bps[cb_cnt++] = cb;
            }
        }
    }

    if (bps->wp_cnt > 0) {
        siginfo_t siginfo;
        pid_t pid = id2pid(ctx->id, NULL);
        if (ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo) < 0) return -1;
        if (siginfo.si_signo == SIGTRAP && (siginfo.si_code & 0xffff) == 0x0004 && siginfo.si_errno < 0) {
            /* Watchpoint */
            for (i = bps->bp_cnt; i < bps->bp_cnt + bps->wp_cnt; i++) {
                ContextBreakpoint * cb = bps->hw_bps[i];
                if (cb != NULL && (ext->armed & (1u << i))) {
                    if (bps->wp_cnt > 1) {
                        ContextAddress addr = (ContextAddress)siginfo.si_addr;
                        if (addr < cb->address || addr >= cb->address + cb->length) continue;
                    }
                    ext->triggered_hw_bps[cb_cnt++] = cb;
                }
            }
        }
    }

    *triggered = cb_cnt > 0;
    if (cb_cnt > 0) {
        ctx->stopped_by_cb = ext->triggered_hw_bps;
        ctx->stopped_by_cb[cb_cnt] = NULL;
    }
    return 0;
}

#endif /* ENABLE_HardwareBreakpoints */

static Context * arm_ctx;
static uint32_t arm_pc;
static uint32_t arm_instr;
static uint32_t arm_cpsr;
static uint32_t arm_next;

static int arm_evaluate_condition(void) {
    int N = ( arm_cpsr >> 31 ) & 1;
    int Z = ( arm_cpsr >> 30 ) & 1;
    int C = ( arm_cpsr >> 29 ) & 1;
    int V = ( arm_cpsr >> 28 ) & 1;

    switch (arm_instr >> 28) {
    case 0 : return Z;
    case 1 : return Z == 0;
    case 2 : return C;
    case 3 : return C == 0;
    case 4 : return N;
    case 5 : return N == 0;
    case 6 : return V;
    case 7 : return V == 0;
    case 8 : return C == 0 && Z == 0;
    case 9 : return C == 0 || Z == 1;
    case 10: return N == V;
    case 11: return N != V;
    case 12: return Z == 0 && N == V;
    case 13: return Z == 1 || N != V;
    case 15: return 0;
    }

    return 1;
}

static uint32_t arm_calc_shift(uint32_t shift_type, uint32_t shift_imm, uint32_t val) {
    switch (shift_type) {
    case 0: /* logical left */
        val = val << shift_imm;
        break;
    case 1: /* logical right */
        if (shift_imm == 0) val = 0;
        else val = val >> shift_imm;
        break;
    case 2: /* arithmetic right */
        if (shift_imm == 0) shift_imm = 32;
        if (val & 0x80000000) {
            if (shift_imm > 32) {
                val = 0xffffffff;
            }
            else {
                val = val >> shift_imm;
                val |= 0xffffffff << (32 - shift_imm);
            }
        }
        else {
            val = val >> shift_imm;
        }
        break;
    case 3: /* rotate right */
        if (shift_imm == 0) {
            /* Rotate right with extend */
            val = val >> 1;
            if (arm_cpsr & (1 << 29)) val |= 0x80000000;
        }
        else {
            shift_imm &= 0x1f;
            val = (val >> shift_imm) | (val << (32 - shift_imm));
        }
        break;
    }
    return val;
}

static int arm_get_next_bx(void) {
    uint32_t Rm = arm_instr & 0xf;
    return context_read_reg(arm_ctx, regs_index + Rm, 0, 4, &arm_next);
}

static int arm_get_next_data_processing(void) {
    int I = (arm_instr & 0x02000000) != 0;
    int S = (arm_instr & 0x00100000) != 0;
    uint32_t opcode = (arm_instr & 0x01e00000) >> 21;
    uint32_t Rn = (arm_instr & 0x000f0000) >> 16;
    uint32_t Rd = (arm_instr & 0x0000f000) >> 12;
    uint32_t operand2 = (arm_instr & 0x00000fff);
    uint32_t op2val = 0;
    uint32_t nval = 0;

    if (!S && opcode >= 8 && opcode <= 11) return 0;
    if (Rd != 15) return 0;

    /* Decode operand 2 */
    if (I) {
        uint8_t shift_dist  = (operand2 & 0x0f00) >> 8;
        uint8_t shift_const = (operand2 & 0x00ff);

        /* rotate const right by 2 * shift_dist */
        shift_dist *= 2;
        op2val = (shift_const >> shift_dist) | (shift_const << (32 - shift_dist));
    }
    else {
        /* Register and shift */
        uint8_t Rm = (operand2 & 0x000f);
        uint8_t reg_shift = (operand2 & 0x0010) != 0;
        uint8_t shift_type = (operand2 & 0x0060) >> 5;
        uint32_t shift_dist = 0;
        uint32_t mval = 0;

        /* Get the shift distance */
        if (reg_shift) {
            uint8_t Rs = (operand2 & 0x0f00) >> 8;
            if (operand2 & 0x00800) {
                return 0;
            }
            else {
                if (context_read_reg(arm_ctx, regs_index + Rs, 0, 4, &shift_dist) < 0) return -1;
            }
        }
        else {
            shift_dist  = (operand2 & 0x0f80) >> 7;
        }

        if (context_read_reg(arm_ctx, regs_index + Rm, 0, 4, &mval) < 0) return -1;

        if (shift_type == 0 && shift_dist == 0 && opcode == 13) {
            /* MOV Rd,Rm */
            op2val = mval;
        }
        else {
            /* Apply the shift type to the source register */
            switch (shift_type) {
            case 0: /* logical left */
                op2val = mval << shift_dist;
                break;
            case 1: /* logical right */
                if (!reg_shift && shift_dist == 0) shift_dist = 32;
                op2val = mval >> shift_dist;
                break;
            case 2: /* arithmetic right */
                if (!reg_shift && shift_dist == 0) shift_dist = 32;
                if (mval & 0x80000000) {
                    /* Register shifts maybe greater than 32 */
                    if (shift_dist >= 32) {
                        op2val = 0xffffffff;
                    }
                    else {
                        op2val = mval >> shift_dist;
                        op2val |= 0xffffffff << (32 - shift_dist);
                    }
                }
                else {
                    op2val = mval >> shift_dist;
                }
                break;
            case 3: /* rotate right */
                if (!reg_shift && shift_dist == 0) {
                    op2val = mval >> 1;
                    if (arm_cpsr & (1 << 29)) op2val |= 0x80000000;
                }
                else {
                    /* Limit shift distance to 0-31 in case of register shift */
                    shift_dist &= 0x1f;
                    op2val = (mval >> shift_dist) | (mval << (32 - shift_dist));
                }
                break;
            }
        }
    }

    if (context_read_reg(arm_ctx, regs_index + Rn, 0, 4, &nval) < 0) return -1;
    /* Account for pre-fetch by adjusting PC */
    if (Rn == 15) {
        /* If the shift amount is specified in the instruction,
         *  the PC will be 8 bytes ahead. If a register is used
         *  to specify the shift amount the PC will be 12 bytes
         *  ahead.
         */
        if (!I && (operand2 & 0x0010))
            nval += 12;
        else
            nval += 8;
    }

    /* Compute values */
    switch (opcode) {
    case  0: /* AND: Rd:= Op1 AND Op2 */
        arm_next = nval & op2val;
        break;
    case  1: /* EOR: Rd:= Op1 EOR Op2 */
        arm_next = nval ^ op2val;
        break;
    case  2: /* SUB: Rd:= Op1 - Op2 */
        arm_next = nval - op2val;
        break;
    case  3: /* RSB: Rd:= Op2 - Op1 */
        arm_next = op2val - nval;
        break;
    case  4: /* ADD: Rd:= Op1 + Op2 */
        arm_next = nval + op2val;
        break;
    case  5: /* ADC: Rd:= Op1 + Op2 + C */
        arm_next = nval + op2val;
        if (arm_cpsr & (1 << 29)) arm_next++;
        break;
    case  6: /* SBC: Rd:= Op1 - Op2 + C */
        arm_next = nval - op2val;
        if (arm_cpsr & (1 << 29)) arm_next++;
        break;
    case  7: /* RSC: Rd:= Op2 - Op1 + C */
        arm_next = op2val - nval;
        if (arm_cpsr & (1 << 29)) arm_next++;
        break;
    case  8: /* TST: set condition codes on Op1 AND Op2 */
    case  9: /* TEQ: set condition codes on Op1 EOR Op2 */
    case 10: /* CMP: set condition codes on Op1 - Op2 */
    case 11: /* CMN: set condition codes on Op1 + Op2 */
        break;
    case 12: /* ORR: Rd:= Op1 OR Op2 */
        arm_next = nval | op2val;
        break;
    case 13: /* MOV: Rd:= Op2 */
        arm_next = op2val;
        break;
    case 14: /* BIC: Rd:= Op1 AND NOT Op2 */
        arm_next = nval & (~op2val);
        break;
    case 15: /* MVN: Rd:= NOT Op2 */
        arm_next = ~op2val;
        break;
    }

    return 0;
}

static int arm_get_next_ldr(void) {
    int I = (arm_instr & (1 << 25)) != 0;
    int P = (arm_instr & (1 << 24)) != 0;
    int U = (arm_instr & (1 << 23)) != 0;
    int B = (arm_instr & (1 << 22)) != 0;
    int W = (arm_instr & (1 << 21)) != 0;
    int L = (arm_instr & (1 << 20)) != 0;
    uint32_t Rn = (arm_instr >> 16) & 0xf;
    uint32_t Rd = (arm_instr >> 12) & 0xf;
    ContextAddress addr = 0;
    unsigned size = B ? 1 : 4;
    uint8_t bt = 0;

    if (!L || Rd != 15) return 0;

    if (read_reg(arm_ctx, regs_index + Rn, 4, &addr) < 0) return -1;
    if (Rn == 15) addr += 8;

    if (!I && P) {
        uint32_t offs = arm_instr & 0xfff;
        addr = U ? addr + offs : addr - offs;
    }
    else if (I && P) {
        uint8_t Rm = arm_instr & 0xf;
        uint32_t offs = 0;
        if (context_read_reg(arm_ctx, regs_index + Rm, 0, 4, &offs) < 0) return -1;
        if ((arm_instr & 0x00000ff0) == 0x00000000) {
            addr = U ? addr + offs : addr - offs;
        }
        else {
            uint32_t shift_imm = (arm_instr & 0x00000f80) >> 7;
            uint32_t shift_type = (arm_instr & 0x00000060) >> 5;
            uint32_t val = arm_calc_shift(shift_type, shift_imm, offs);
            addr = U ? addr + val : addr - val;
        }
    }
    else if (P || W) {
        size = 0;
    }

    switch (size) {
    case 1:
        if (context_read_mem(arm_ctx, addr, &bt, 1) < 0) return -1;
        arm_next = bt;
        break;
    case 4:
        if (context_read_mem(arm_ctx, addr, &arm_next, 4) < 0) return -1;
        break;
    }
    return 0;
}

static int arm_get_next_ldm(void) {
    int P = (arm_instr & (1 << 24)) != 0;
    int U = (arm_instr & (1 << 23)) != 0;
    int S = (arm_instr & (1 << 22)) != 0;
    int L = (arm_instr & (1 << 20)) != 0;
    uint32_t Rn = (arm_instr >> 16) & 0xf;
    ContextAddress addr = 0;

    if (!L || S || Rn == 15) return 0;
    if ((arm_instr & (1 << 15)) == 0) return 0;

    if (read_reg(arm_ctx, regs_index + Rn, 4, &addr) < 0) return -1;
    if (U) {
        int i;
        for (i = 0; i < 15; i++) {
            if (arm_instr & (1 << i)) addr += 4;
        }
    }
    if (P) addr = U ? addr + 4 : addr - 4;
    return context_read_mem(arm_ctx, addr, &arm_next, 4);
}

static int arm_get_next_branch(void) {
    int32_t imm = arm_instr & 0x00FFFFFF;
    if (imm & 0x00800000) imm |= 0xFF000000;
    imm = imm << 2;
    arm_next = ((int)arm_pc + imm + 8);
    return 0;
}

static int arm_get_next_address(Context * ctx, ContextAddress * next_addr) {
    ContextAddress addr = 0;
    ContextAddress cpsr = 0;

    /* read opcode at PC */
    if (read_reg(ctx, pc_def, pc_def->size, &addr) < 0) return -1;
    if (read_reg(ctx, cpsr_def, cpsr_def->size, &cpsr) < 0) return -1;
    if (context_read_mem(ctx, addr, &arm_instr, 4) < 0) return -1;

    arm_ctx = ctx;
    arm_pc = (uint32_t)addr;
    arm_cpsr = (uint32_t)cpsr;
    trace(LOG_CONTEXT, "pc 0x%x, opcode 0x%x", arm_pc, arm_instr);

    /* decode opcode */
    arm_next = arm_pc + 4;
    if (arm_evaluate_condition()) {
        switch ((arm_instr >> 25) & 7) {
        case 0:
        case 1:
            if ((arm_instr & 0x0ffffff0) == 0x012fff10) {
                /* Branch and Exchange */
                if (arm_get_next_bx() < 0) return -1;
                break;
            }
            if (arm_get_next_data_processing() < 0) return -1;
            break;
        case 2:
        case 3: /* Load */
            if (arm_get_next_ldr() < 0) return -1;
            break;
        case 4: /* Load/store multiple */
            if (arm_get_next_ldm() < 0) return -1;
            break;
        case 5: /* Branch and branch with link */
            if (arm_get_next_branch() < 0) return -1;
            break;
        }
    }

    addr = arm_next;
    if (addr >= 0xffff0000) {
        /* Linux kernel user-mode helpers space - run to return address */
        if (read_reg(ctx, lr_def, lr_def->size, &addr) < 0) return -1;
    }
    *next_addr = addr;
    return 0;
}

static int enable_sw_stepping_mode(Context * ctx) {
    Context * grp = context_get_group(ctx, CONTEXT_GROUP_PROCESS);
    ContextExtensionARM * ext = EXT(grp);
    assert(!grp->exited);
    assert(!ext->sw_stepping);
    if (arm_get_next_address(ctx, &ext->addr) < 0) return -1;
    trace(LOG_CONTEXT, "enable_sw_stepping_mode %s 0x%x", ctx->id, (unsigned)ext->addr);
    if (context_read_mem(grp, ext->addr, ext->opcode, sizeof(BREAK_INST)) < 0) return -1;
    if (context_write_mem(grp, ext->addr, BREAK_INST, sizeof(BREAK_INST)) < 0) return -1;
    ext->sw_stepping = 1;
    run_ctrl_lock();
    return 0;
}

static int disable_sw_stepping_mode(Context * ctx) {
    Context * grp = context_get_group(ctx, CONTEXT_GROUP_PROCESS);
    ContextExtensionARM * ext = EXT(grp);
    if (ext->sw_stepping) {
        trace(LOG_CONTEXT, "disable_sw_stepping_mode %s", ctx->id);
        run_ctrl_unlock();
        ext->sw_stepping = 0;
        if (grp->exited) return 0;
        return context_write_mem(grp, ext->addr, ext->opcode, sizeof(BREAK_INST));
    }
    return 0;
}

int cpu_enable_stepping_mode(Context * ctx, uint32_t * is_cont) {
    *is_cont = 1;
#if ENABLE_HardwareBreakpoints
    {
        int mode = 1;
        ContextExtensionARM * bps = EXT(context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT));
        if (get_bp_info(ctx) < 0) return -1;
#if defined(ENABLE_MismatchBreakpoints) && ENABLE_MismatchBreakpoints
        if (bps->arch >= ARM_DEBUG_ARCH_V7_ECP14) mode = 2;
#endif
        if (bps->bp_cnt > 0) return enable_hw_stepping_mode(ctx, mode);
    }
#endif /* ENABLE_HardwareBreakpoints */
    return enable_sw_stepping_mode(ctx);
}

int cpu_disable_stepping_mode(Context * ctx) {
#if ENABLE_HardwareBreakpoints
    {
        ContextExtensionARM * bps = EXT(context_get_group(ctx, CONTEXT_GROUP_BREAKPOINT));
        if (bps->bp_cnt > 0) return disable_hw_stepping_mode(ctx);
    }
#endif /* ENABLE_HardwareBreakpoints */
    return disable_sw_stepping_mode(ctx);
}

static RegisterDefinition * alloc_reg(void) {
    RegisterDefinition * r = regs_index + regs_cnt++;
    assert(regs_cnt <= regs_max);
    r->dwarf_id = -1;
    r->eh_frame_id = -1;
    r->big_endian = big_endian_host();
    return r;
}

#if !USE_getauxval
#  if defined(ENABLE_arch_armv7l)
#    define read_fpsid(X) *(X) = 0
#    define read_mvfr0(X) *(X) = 0x222
#  else
#    define read_fpsid(X) \
       __asm __volatile("mrc p10, 7, %0, c0, c0, 0" \
            : "=r" (*(X)) : : "memory")
#    define read_mvfr0(X) \
       __asm __volatile("mrc p10, 7, %0, c7, c0, 0" \
            : "=r" (*(X)) : : "memory")
#  endif
#endif

static void ini_reg_defs(void) {
    int i;
    RegisterDefinition * d;
    regs_cnt = 0;
    regs_max = 800;
    regs_index = (RegisterDefinition *)loc_alloc_zero(sizeof(RegisterDefinition) * regs_max);
    for (d = regs_def; d->name != NULL; d++) {
        RegisterDefinition * r = alloc_reg();
        assert(d->parent == NULL);
        *r = *d;
        if (r->offset == offsetof(REG_SET, REG_FP)) {
            r->role = "FP";
        }
        else if (r->offset == offsetof(REG_SET, REG_SP)) {
            r->role = "SP";
        }
        else if (r->offset == offsetof(REG_SET, REG_PC)) {
            r->role = "PC";
            pc_def = r;
        }
        else if (r->offset == offsetof(REG_SET, REG_LR)) {
            r->role = "LR";
            lr_def = r;
        }
        else if (r->offset == offsetof(REG_SET, REG_CPSR)) {
            cpsr_def = r;
        }
        if (strcmp(r->name, "vfp") == 0) {
            uint32_t fpsid = 0;
#if USE_getauxval
            unsigned long hwcap = getauxval(AT_HWCAP);
            if ((hwcap & HWCAP_ARM_VFP) == 0) fpsid = 1 << 23;
#else
            read_fpsid(&fpsid);
#endif
            if ((fpsid & (1 << 23)) == 0) {
                int n;
                RegisterDefinition * x = NULL;
                uint32_t mvfr0 = 0;
#if USE_getauxval
                if (hwcap & HWCAP_ARM_VFPv3D16) mvfr0 = 0x221;
                else if (hwcap & HWCAP_ARM_VFPv3) mvfr0 = 0x222;
                else mvfr0 = 0x110;
#else
                read_mvfr0(&mvfr0);
#endif
                for (n = 0; n < 3; n++) {
                    RegisterDefinition * w = NULL;
                    switch (n) {
                    case 0:
                        if (((mvfr0 >> 4) & 0xf) == 0) continue;
                        break;
                    case 1:
                        if (((mvfr0 >> 8) & 0xf) == 0) continue;
                        break;
                    case 2:
                        if ((mvfr0 & 0xf) == 0) continue;
                        break;
                    }
                    w = alloc_reg();
                    w->no_read = 1;
                    w->no_write = 1;
                    w->parent = r;
                    switch (n) {
                    case 0:
                        w->name = "32-bit";
                        for (i = 0; i < 32; i++) {
                            char nm[32];
                            x = alloc_reg();
                            snprintf(nm, sizeof(nm), "s%d", i);
                            x->name = loc_strdup(nm);
                            x->offset = REG_OFFSET(fp.fpregs[i / 2]);
                            if (r->big_endian) {
                                if ((i & 1) == 0) x->offset += 4;
                            }
                            else {
                                if ((i & 1) != 0) x->offset += 4;
                            }
                            x->size = 4;
                            x->dwarf_id = 64 + i;
                            x->eh_frame_id = 64 + i;
                            x->fp_value = 1;
                            x->parent = w;
                        }
                        break;
                    case 1:
                        w->name = "64-bit";
                        for (i = 0; i < 32; i++) {
                            char nm[32];
                            if (i >= 16 && ((mvfr0 >> 8) & 0xf) < 2) continue;
                            x = alloc_reg();
                            snprintf(nm, sizeof(nm), "d%d", i);
                            x->name = loc_strdup(nm);
                            x->offset = REG_OFFSET(fp.fpregs[i]);
                            x->size = 8;
                            x->dwarf_id = 256 + i;
                            x->eh_frame_id = 256 + i;
                            x->fp_value = 1;
                            x->parent = w;
                        }
                        break;
                    case 2:
                        w->name = "128-bit";
                        for (i = 0; i < 16; i++) {
                            char nm[32];
                            if (i >= 8 && (mvfr0 & 0xf) < 2) continue;
                            x = alloc_reg();
                            snprintf(nm, sizeof(nm), "q%d", i);
                            x->name = loc_strdup(nm);
                            x->offset = REG_OFFSET(fp.fpregs[i * 2]);
                            x->size = 16;
                            x->fp_value = 1;
                            x->parent = w;
                        }
                        break;
                    }
                }
                x = alloc_reg();
                x->name = "fpscr";
                x->offset = REG_OFFSET(fp.fpscr);
                x->size = 4;
                x->parent = r;
            }
        }
    }
}

void ini_cpudefs_mdep(void) {
    ini_reg_defs();
    context_extension_offset = context_extension(sizeof(ContextExtensionARM));
}

#endif
