mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-08 23:05:30 +00:00
Backport the THUMB_DSP feature flag
Backports commit 62b44f059a84d1ac580a653fc4110dfabaef6b83 in qemu to unicorn.
This commit is contained in:
parent
9ff703fd60
commit
291b5753eb
|
@ -382,6 +382,10 @@ static int arm_cpu_realizefn(struct uc_struct *uc, DeviceState *dev, Error **err
|
|||
if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
|
||||
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) {
|
||||
cpu->reset_sctlr |= (1 << 13);
|
||||
|
|
|
@ -749,6 +749,7 @@ enum arm_features {
|
|||
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_PMULL, /* implements PMULL part of v8 Crypto Extensions */
|
||||
ARM_FEATURE_THUMB_DSP, /* DSP insns supported in the Thumb encodings */
|
||||
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
|
||||
};
|
||||
|
||||
|
|
|
@ -9529,6 +9529,9 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
|
|||
|
||||
op = (insn >> 21) & 0xf;
|
||||
if (op == 6) {
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
/* Halfword pack. */
|
||||
tmp = load_reg(s, rn);
|
||||
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);
|
||||
break;
|
||||
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);
|
||||
shift = (insn >> 4) & 3;
|
||||
/* ??? 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 4: gen_sxtb(tmp); break;
|
||||
case 5: gen_uxtb(tmp); break;
|
||||
default: goto illegal_op;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
if (rn != 15) {
|
||||
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);
|
||||
break;
|
||||
case 2: /* SIMD add/subtract. */
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
op = (insn >> 20) & 7;
|
||||
shift = (insn >> 4) & 7;
|
||||
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);
|
||||
if (op < 4) {
|
||||
/* Saturating add/subtract. */
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
tmp = load_reg(s, rn);
|
||||
tmp2 = load_reg(s, rm);
|
||||
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);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
} 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);
|
||||
switch (op) {
|
||||
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 c = op & 0x8;
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
|
||||
tmp2 = load_reg(s, rm);
|
||||
if (sz == 0) {
|
||||
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;
|
||||
}
|
||||
default:
|
||||
goto illegal_op;
|
||||
g_assert_not_reached();
|
||||
}
|
||||
}
|
||||
store_reg(s, rd, tmp);
|
||||
break;
|
||||
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;
|
||||
tmp = load_reg(s, rn);
|
||||
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);
|
||||
} else if ((op & 0xe) == 0xc) {
|
||||
/* 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)
|
||||
gen_swap_half(s, 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 {
|
||||
if (op & 8) {
|
||||
/* 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);
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
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) {
|
||||
/* 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, rd);
|
||||
} 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);
|
||||
if (op & 4) {
|
||||
/* 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);
|
||||
else
|
||||
} else {
|
||||
gen_helper_usat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||
}
|
||||
} else {
|
||||
/* 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);
|
||||
else
|
||||
} else {
|
||||
gen_helper_ssat(tcg_ctx, tmp, tcg_ctx->cpu_env, tmp, tmp2);
|
||||
}
|
||||
}
|
||||
tcg_temp_free_i32(tcg_ctx, tmp2);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue