mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 06:45:35 +00:00
Merge pull request #7 from lioncash/flags
Backport several feature flags from qemu
This commit is contained in:
commit
c25f059530
|
@ -139,6 +139,10 @@ static void arm_cpu_reset(CPUState *s)
|
||||||
uint32_t initial_msp; /* Loaded from 0x0 */
|
uint32_t initial_msp; /* Loaded from 0x0 */
|
||||||
uint32_t initial_pc; /* Loaded from 0x4 */
|
uint32_t initial_pc; /* Loaded from 0x4 */
|
||||||
|
|
||||||
|
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
|
||||||
|
env->v7m.secure = true;
|
||||||
|
}
|
||||||
|
|
||||||
env->daif &= ~PSTATE_I;
|
env->daif &= ~PSTATE_I;
|
||||||
#if 0
|
#if 0
|
||||||
uint8_t *rom;
|
uint8_t *rom;
|
||||||
|
@ -348,6 +352,11 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
||||||
} else {
|
} else {
|
||||||
set_feature(env, ARM_FEATURE_V6);
|
set_feature(env, ARM_FEATURE_V6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Always define VBAR for V7 CPUs even if it doesn't exist in
|
||||||
|
* non-EL3 configs. This is needed by some legacy boards.
|
||||||
|
*/
|
||||||
|
set_feature(env, ARM_FEATURE_VBAR);
|
||||||
}
|
}
|
||||||
if (arm_feature(env, ARM_FEATURE_V6K)) {
|
if (arm_feature(env, ARM_FEATURE_V6K)) {
|
||||||
set_feature(env, ARM_FEATURE_V6);
|
set_feature(env, ARM_FEATURE_V6);
|
||||||
|
@ -355,6 +364,7 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
||||||
}
|
}
|
||||||
if (arm_feature(env, ARM_FEATURE_V6)) {
|
if (arm_feature(env, ARM_FEATURE_V6)) {
|
||||||
set_feature(env, ARM_FEATURE_V5);
|
set_feature(env, ARM_FEATURE_V5);
|
||||||
|
set_feature(env, ARM_FEATURE_JAZELLE);
|
||||||
if (!arm_feature(env, ARM_FEATURE_M)) {
|
if (!arm_feature(env, ARM_FEATURE_M)) {
|
||||||
set_feature(env, ARM_FEATURE_AUXCR);
|
set_feature(env, ARM_FEATURE_AUXCR);
|
||||||
}
|
}
|
||||||
|
@ -382,11 +392,19 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
||||||
if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
|
if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
|
||||||
set_feature(env, ARM_FEATURE_CBAR);
|
set_feature(env, ARM_FEATURE_CBAR);
|
||||||
}
|
}
|
||||||
|
if (arm_feature(env, ARM_FEATURE_THUMB2) &&
|
||||||
|
!arm_feature(env, ARM_FEATURE_M)) {
|
||||||
|
set_feature(env, ARM_FEATURE_THUMB_DSP);
|
||||||
|
}
|
||||||
|
|
||||||
if (cpu->reset_hivecs) {
|
if (cpu->reset_hivecs) {
|
||||||
cpu->reset_sctlr |= (1 << 13);
|
cpu->reset_sctlr |= (1 << 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arm_feature(env, ARM_FEATURE_EL3)) {
|
||||||
|
set_feature(env, ARM_FEATURE_VBAR);
|
||||||
|
}
|
||||||
|
|
||||||
register_cp_regs_for_features(cpu);
|
register_cp_regs_for_features(cpu);
|
||||||
arm_cpu_register_gdb_regs_for_features(cpu);
|
arm_cpu_register_gdb_regs_for_features(cpu);
|
||||||
|
|
||||||
|
@ -431,6 +449,7 @@ static void arm926_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||||
set_feature(&cpu->env, ARM_FEATURE_VFP);
|
set_feature(&cpu->env, ARM_FEATURE_VFP);
|
||||||
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
|
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
|
||||||
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
|
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
|
||||||
|
set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
|
||||||
cpu->midr = 0x41069265;
|
cpu->midr = 0x41069265;
|
||||||
cpu->reset_fpsid = 0x41011090;
|
cpu->reset_fpsid = 0x41011090;
|
||||||
cpu->ctr = 0x1dd20d2;
|
cpu->ctr = 0x1dd20d2;
|
||||||
|
@ -460,6 +479,7 @@ static void arm1026_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||||
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
|
set_feature(&cpu->env, ARM_FEATURE_AUXCR);
|
||||||
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
|
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
|
||||||
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
|
set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
|
||||||
|
set_feature(&cpu->env, ARM_FEATURE_JAZELLE);
|
||||||
cpu->midr = 0x4106a262;
|
cpu->midr = 0x4106a262;
|
||||||
cpu->reset_fpsid = 0x410110a0;
|
cpu->reset_fpsid = 0x410110a0;
|
||||||
cpu->ctr = 0x1dd20d2;
|
cpu->ctr = 0x1dd20d2;
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#define ARMV7M_EXCP_MEM 4
|
#define ARMV7M_EXCP_MEM 4
|
||||||
#define ARMV7M_EXCP_BUS 5
|
#define ARMV7M_EXCP_BUS 5
|
||||||
#define ARMV7M_EXCP_USAGE 6
|
#define ARMV7M_EXCP_USAGE 6
|
||||||
|
#define ARMV7M_EXCP_SECURE 7
|
||||||
#define ARMV7M_EXCP_SVC 11
|
#define ARMV7M_EXCP_SVC 11
|
||||||
#define ARMV7M_EXCP_DEBUG 12
|
#define ARMV7M_EXCP_DEBUG 12
|
||||||
#define ARMV7M_EXCP_PENDSV 14
|
#define ARMV7M_EXCP_PENDSV 14
|
||||||
|
@ -246,6 +247,7 @@ typedef struct CPUARMState {
|
||||||
int current_sp;
|
int current_sp;
|
||||||
int exception;
|
int exception;
|
||||||
int pending_exception;
|
int pending_exception;
|
||||||
|
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
|
||||||
} v7m;
|
} v7m;
|
||||||
|
|
||||||
/* Information associated with an exception about to be taken:
|
/* Information associated with an exception about to be taken:
|
||||||
|
@ -749,6 +751,12 @@ enum arm_features {
|
||||||
ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */
|
ARM_FEATURE_V8_SHA1, /* implements SHA1 part of v8 Crypto Extensions */
|
||||||
ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
|
ARM_FEATURE_V8_SHA256, /* implements SHA256 part of v8 Crypto Extensions */
|
||||||
ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
|
ARM_FEATURE_V8_PMULL, /* implements PMULL part of v8 Crypto Extensions */
|
||||||
|
ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
|
||||||
|
ARM_FEATURE_PMU, /* has PMU support */
|
||||||
|
ARM_FEATURE_VBAR, /* has cp15 VBAR */
|
||||||
|
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
|
||||||
|
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
|
||||||
|
ARM_FEATURE_SVE, /* has Scalable Vector Extension */
|
||||||
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
|
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,7 @@ static void aarch64_a57_initfn(struct uc_struct *uc, Object *obj, void *opaque)
|
||||||
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
|
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
|
||||||
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
|
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
|
||||||
set_feature(&cpu->env, ARM_FEATURE_CRC);
|
set_feature(&cpu->env, ARM_FEATURE_CRC);
|
||||||
|
set_feature(&cpu->env, ARM_FEATURE_PMU);
|
||||||
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
|
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
|
||||||
cpu->midr = 0x411fd070;
|
cpu->midr = 0x411fd070;
|
||||||
cpu->reset_fpsid = 0x41034070;
|
cpu->reset_fpsid = 0x41034070;
|
||||||
|
|
|
@ -751,9 +751,6 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
|
||||||
{ "PMINTENCLR", 15,9,14, 0,0,2, 0,
|
{ "PMINTENCLR", 15,9,14, 0,0,2, 0,
|
||||||
ARM_CP_NO_MIGRATE, PL1_RW, NULL, 0, offsetof(CPUARMState, cp15.c9_pminten),
|
ARM_CP_NO_MIGRATE, PL1_RW, NULL, 0, offsetof(CPUARMState, cp15.c9_pminten),
|
||||||
NULL, NULL, pmintenclr_write, },
|
NULL, NULL, pmintenclr_write, },
|
||||||
{ "VBAR", 0,12,0, 3,0,0, ARM_CP_STATE_BOTH,
|
|
||||||
0, PL1_RW, NULL, 0, offsetof(CPUARMState, cp15.vbar_el[1]),
|
|
||||||
NULL, NULL, vbar_write, },
|
|
||||||
{ "SCR", 15,1,1, 0,0,0, 0,
|
{ "SCR", 15,1,1, 0,0,0, 0,
|
||||||
0, PL1_RW, NULL, 0, offsetoflow32(CPUARMState, cp15.scr_el3),
|
0, PL1_RW, NULL, 0, offsetoflow32(CPUARMState, cp15.scr_el3),
|
||||||
NULL, NULL, scr_write },
|
NULL, NULL, scr_write },
|
||||||
|
@ -2708,6 +2705,16 @@ void register_cp_regs_for_features(ARMCPU *cpu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arm_feature(env, ARM_FEATURE_VBAR)) {
|
||||||
|
ARMCPRegInfo vbar_cp_reginfo[] = {
|
||||||
|
{ "VBAR", 0,12,0, 3,0,0, ARM_CP_STATE_BOTH,
|
||||||
|
0, PL1_RW, NULL, 0, offsetof(CPUARMState, cp15.vbar_el[1]),
|
||||||
|
NULL, NULL, vbar_write, },
|
||||||
|
REGINFO_SENTINEL
|
||||||
|
};
|
||||||
|
define_arm_cp_regs(cpu, vbar_cp_reginfo);
|
||||||
|
}
|
||||||
|
|
||||||
/* Generic registers whose values depend on the implementation */
|
/* Generic registers whose values depend on the implementation */
|
||||||
{
|
{
|
||||||
ARMCPRegInfo sctlr = {
|
ARMCPRegInfo sctlr = {
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
|
#define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
|
||||||
/* currently all emulated v5 cores are also v5TE, so don't bother */
|
/* currently all emulated v5 cores are also v5TE, so don't bother */
|
||||||
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
|
#define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
|
||||||
#define ENABLE_ARCH_5J 0
|
#define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
|
||||||
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
|
#define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
|
||||||
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
|
#define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
|
||||||
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
|
#define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
|
||||||
|
@ -9529,6 +9529,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
|
|
||||||
op = (insn >> 21) & 0xf;
|
op = (insn >> 21) & 0xf;
|
||||||
if (op == 6) {
|
if (op == 6) {
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
/* Halfword pack. */
|
/* Halfword pack. */
|
||||||
tmp = load_reg(s, rn);
|
tmp = load_reg(s, rn);
|
||||||
tmp2 = load_reg(s, rm);
|
tmp2 = load_reg(s, rm);
|
||||||
|
@ -9593,6 +9596,27 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
store_reg_bx(s, rd, tmp);
|
store_reg_bx(s, rd, tmp);
|
||||||
break;
|
break;
|
||||||
case 1: /* Sign/zero extend. */
|
case 1: /* Sign/zero extend. */
|
||||||
|
op = (insn >> 20) & 7;
|
||||||
|
switch (op) {
|
||||||
|
case 0: /* SXTAH, SXTH */
|
||||||
|
case 1: /* UXTAH, UXTH */
|
||||||
|
case 4: /* SXTAB, SXTB */
|
||||||
|
case 5: /* UXTAB, UXTB */
|
||||||
|
break;
|
||||||
|
case 2: /* SXTAB16, SXTB16 */
|
||||||
|
case 3: /* UXTAB16, UXTB16 */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
if (rn != 15) {
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
}
|
||||||
tmp = load_reg(s, rm);
|
tmp = load_reg(s, rm);
|
||||||
shift = (insn >> 4) & 3;
|
shift = (insn >> 4) & 3;
|
||||||
/* ??? In many cases it's not necessary to do a
|
/* ??? In many cases it's not necessary to do a
|
||||||
|
@ -9607,7 +9631,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
case 3: gen_uxtb16(tmp); break;
|
case 3: gen_uxtb16(tmp); break;
|
||||||
case 4: gen_sxtb(tmp); break;
|
case 4: gen_sxtb(tmp); break;
|
||||||
case 5: gen_uxtb(tmp); break;
|
case 5: gen_uxtb(tmp); break;
|
||||||
default: goto illegal_op;
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
if (rn != 15) {
|
if (rn != 15) {
|
||||||
tmp2 = load_reg(s, rn);
|
tmp2 = load_reg(s, rn);
|
||||||
|
@ -9621,6 +9646,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
store_reg(s, rd, tmp);
|
store_reg(s, rd, tmp);
|
||||||
break;
|
break;
|
||||||
case 2: /* SIMD add/subtract. */
|
case 2: /* SIMD add/subtract. */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
op = (insn >> 20) & 7;
|
op = (insn >> 20) & 7;
|
||||||
shift = (insn >> 4) & 7;
|
shift = (insn >> 4) & 7;
|
||||||
if ((op & 3) == 3 || (shift & 3) == 3)
|
if ((op & 3) == 3 || (shift & 3) == 3)
|
||||||
|
@ -9635,6 +9663,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
|
op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
|
||||||
if (op < 4) {
|
if (op < 4) {
|
||||||
/* Saturating add/subtract. */
|
/* Saturating add/subtract. */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
tmp = load_reg(s, rn);
|
tmp = load_reg(s, rn);
|
||||||
tmp2 = load_reg(s, rm);
|
tmp2 = load_reg(s, rm);
|
||||||
if (op & 1)
|
if (op & 1)
|
||||||
|
@ -9645,6 +9676,31 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
gen_helper_add_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
gen_helper_add_saturate(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
} else {
|
} else {
|
||||||
|
switch (op) {
|
||||||
|
case 0x0a: /* rbit */
|
||||||
|
case 0x08: /* rev */
|
||||||
|
case 0x09: /* rev16 */
|
||||||
|
case 0x0b: /* revsh */
|
||||||
|
case 0x18: /* clz */
|
||||||
|
break;
|
||||||
|
case 0x10: /* sel */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x20: /* crc32/crc32c */
|
||||||
|
case 0x21:
|
||||||
|
case 0x22:
|
||||||
|
case 0x28:
|
||||||
|
case 0x29:
|
||||||
|
case 0x2a:
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
tmp = load_reg(s, rn);
|
tmp = load_reg(s, rn);
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 0x0a: /* rbit */
|
case 0x0a: /* rbit */
|
||||||
|
@ -9681,10 +9737,6 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
uint32_t sz = op & 0x3;
|
uint32_t sz = op & 0x3;
|
||||||
uint32_t c = op & 0x8;
|
uint32_t c = op & 0x8;
|
||||||
|
|
||||||
if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
|
|
||||||
goto illegal_op;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp2 = load_reg(s, rm);
|
tmp2 = load_reg(s, rm);
|
||||||
if (sz == 0) {
|
if (sz == 0) {
|
||||||
tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xff);
|
tcg_gen_andi_i32(tcg_ctx, tmp2, tmp2, 0xff);
|
||||||
|
@ -9702,12 +9754,26 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
goto illegal_op;
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
store_reg(s, rd, tmp);
|
store_reg(s, rd, tmp);
|
||||||
break;
|
break;
|
||||||
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
|
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
|
||||||
|
switch ((insn >> 20) & 7) {
|
||||||
|
case 0: /* 32 x 32 -> 32 */
|
||||||
|
case 7: /* Unsigned sum of absolute differences. */
|
||||||
|
break;
|
||||||
|
case 1: /* 16 x 16 -> 32 */
|
||||||
|
case 2: /* Dual multiply add. */
|
||||||
|
case 3: /* 32 * 16 -> 32msb */
|
||||||
|
case 4: /* Dual multiply subtract. */
|
||||||
|
case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
op = (insn >> 4) & 0xf;
|
op = (insn >> 4) & 0xf;
|
||||||
tmp = load_reg(s, rn);
|
tmp = load_reg(s, rn);
|
||||||
tmp2 = load_reg(s, rm);
|
tmp2 = load_reg(s, rm);
|
||||||
|
@ -9820,6 +9886,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
store_reg(s, rd, tmp);
|
store_reg(s, rd, tmp);
|
||||||
} else if ((op & 0xe) == 0xc) {
|
} else if ((op & 0xe) == 0xc) {
|
||||||
/* Dual multiply accumulate long. */
|
/* Dual multiply accumulate long. */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
if (op & 1)
|
if (op & 1)
|
||||||
gen_swap_half(s, tmp2);
|
gen_swap_half(s, tmp2);
|
||||||
gen_smul_dual(s, tmp, tmp2);
|
gen_smul_dual(s, tmp, tmp2);
|
||||||
|
@ -9843,6 +9914,11 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
} else {
|
} else {
|
||||||
if (op & 8) {
|
if (op & 8) {
|
||||||
/* smlalxy */
|
/* smlalxy */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
gen_mulxy(s, tmp, tmp2, op & 2, op & 1);
|
gen_mulxy(s, tmp, tmp2, op & 2, op & 1);
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
tmp64 = tcg_temp_new_i64(tcg_ctx);
|
tmp64 = tcg_temp_new_i64(tcg_ctx);
|
||||||
|
@ -9855,6 +9931,10 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
}
|
}
|
||||||
if (op & 4) {
|
if (op & 4) {
|
||||||
/* umaal */
|
/* umaal */
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
tcg_temp_free_i64(tcg_ctx, tmp64);
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
gen_addq_lo(s, tmp64, rs);
|
gen_addq_lo(s, tmp64, rs);
|
||||||
gen_addq_lo(s, tmp64, rd);
|
gen_addq_lo(s, tmp64, rd);
|
||||||
} else if (op & 0x40) {
|
} else if (op & 0x40) {
|
||||||
|
@ -10119,16 +10199,28 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
||||||
tmp2 = tcg_const_i32(tcg_ctx, imm);
|
tmp2 = tcg_const_i32(tcg_ctx, imm);
|
||||||
if (op & 4) {
|
if (op & 4) {
|
||||||
/* Unsigned. */
|
/* Unsigned. */
|
||||||
if ((op & 1) && shift == 0)
|
if ((op & 1) && shift == 0) {
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
gen_helper_usat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
gen_helper_usat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||||
else
|
} else {
|
||||||
gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Signed. */
|
/* Signed. */
|
||||||
if ((op & 1) && shift == 0)
|
if ((op & 1) && shift == 0) {
|
||||||
|
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp);
|
||||||
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
|
goto illegal_op;
|
||||||
|
}
|
||||||
gen_helper_ssat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
gen_helper_ssat16(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||||
else
|
} else {
|
||||||
gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||||
break;
|
break;
|
||||||
|
@ -11567,7 +11659,6 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
ARMCPU *cpu = ARM_CPU(cs);
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
int i;
|
int i;
|
||||||
uint32_t psr;
|
|
||||||
|
|
||||||
if (is_a64(env)) {
|
if (is_a64(env)) {
|
||||||
aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
|
aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
|
||||||
|
@ -11581,15 +11672,53 @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
|
||||||
else
|
else
|
||||||
cpu_fprintf(f, " ");
|
cpu_fprintf(f, " ");
|
||||||
}
|
}
|
||||||
psr = cpsr_read(env);
|
|
||||||
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
|
if (arm_feature(env, ARM_FEATURE_M)) {
|
||||||
psr,
|
uint32_t xpsr = xpsr_read(env);
|
||||||
psr & (1 << 31) ? 'N' : '-',
|
const char *mode;
|
||||||
psr & (1 << 30) ? 'Z' : '-',
|
const char *ns_status = "";
|
||||||
psr & (1 << 29) ? 'C' : '-',
|
|
||||||
psr & (1 << 28) ? 'V' : '-',
|
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
|
||||||
psr & CPSR_T ? 'T' : 'A',
|
ns_status = env->v7m.secure ? "S " : "NS ";
|
||||||
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
|
}
|
||||||
|
|
||||||
|
if (xpsr & XPSR_EXCP) {
|
||||||
|
mode = "handler";
|
||||||
|
} else {
|
||||||
|
if (env->v7m.control & R_V7M_CONTROL_NPRIV_MASK) {
|
||||||
|
mode = "unpriv-thread";
|
||||||
|
} else {
|
||||||
|
mode = "priv-thread";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
|
||||||
|
xpsr,
|
||||||
|
xpsr & XPSR_N ? 'N' : '-',
|
||||||
|
xpsr & XPSR_Z ? 'Z' : '-',
|
||||||
|
xpsr & XPSR_C ? 'C' : '-',
|
||||||
|
xpsr & XPSR_V ? 'V' : '-',
|
||||||
|
xpsr & XPSR_T ? 'T' : 'A',
|
||||||
|
ns_status,
|
||||||
|
mode);
|
||||||
|
} else {
|
||||||
|
uint32_t psr = cpsr_read(env);
|
||||||
|
const char *ns_status = "";
|
||||||
|
|
||||||
|
if (arm_feature(env, ARM_FEATURE_EL3) &&
|
||||||
|
(psr & CPSR_M) != ARM_CPU_MODE_MON) {
|
||||||
|
ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
|
||||||
|
psr,
|
||||||
|
psr & (1 << 31) ? 'N' : '-',
|
||||||
|
psr & (1 << 30) ? 'Z' : '-',
|
||||||
|
psr & (1 << 29) ? 'C' : '-',
|
||||||
|
psr & (1 << 28) ? 'V' : '-',
|
||||||
|
psr & CPSR_T ? 'T' : 'A',
|
||||||
|
cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & CPU_DUMP_FPU) {
|
if (flags & CPU_DUMP_FPU) {
|
||||||
int numvfpregs = 0;
|
int numvfpregs = 0;
|
||||||
|
|
Loading…
Reference in a new issue