[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V2] Target-arm: Add the THUMB_DSP feature
From: |
Aurelio C. Remonda |
Subject: |
[Qemu-devel] [PATCH V2] Target-arm: Add the THUMB_DSP feature |
Date: |
Sun, 14 Jun 2015 16:49:15 -0300 |
Created an ARM_FEATURE_THUMB_DSP to be added to any non-M
thumb2-compatible CPU that uses DSP instructions. There are 85 DSP
instructions (all of them thumb2). On disas_thumb2_insn the DSP feature is
tested before the instruction is generated; if it's not enabled then its an
illegal op.
Signed-off-by: Aurelio C. Remonda <address@hidden>
---
* Changes in V2: Add the ARM_FEATURE_THUMB_DSP to non-M thumb2-compatible
CPUs to this patch, and fixed some syntax errors. Also added extra switches
so there's no need to do temp_free in some places.
target-arm/cpu.c | 4 +++
target-arm/cpu.h | 1 +
target-arm/translate.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 94 insertions(+), 5 deletions(-)
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 4a888ab..ad381e2 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -533,6 +533,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error
**errp)
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);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 21b5b8e..7fedf3f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -890,6 +890,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 */
};
static inline int arm_feature(CPUARMState *env, int feature)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 39692d7..8d438f8 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9444,6 +9444,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);
@@ -9508,6 +9511,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
@@ -9522,8 +9546,10 @@ 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();
}
+ /*-sxtab->-sxtab16->*/
if (rn != 15) {
tmp2 = load_reg(s, rn);
if ((op >> 1) == 1) {
@@ -9537,6 +9563,9 @@ static int disas_thumb2_insn(CPUARMState *env,
DisasContext *s, uint16_t insn_hw
break;
case 2: /* SIMD add/subtract. */
op = (insn >> 20) & 7;
+ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
+ goto illegal_op;
+ }
shift = (insn >> 4) & 7;
if ((op & 3) == 3 || (shift & 3) == 3)
goto illegal_op;
@@ -9550,6 +9579,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)
@@ -9560,6 +9592,18 @@ static int disas_thumb2_insn(CPUARMState *env,
DisasContext *s, uint16_t insn_hw
gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
tcg_temp_free_i32(tmp2);
} else {
+ switch (op) {
+ case 0x0a: /* rbit */
+ case 0x08: /* rev */
+ case 0x09: /* rev16 */
+ case 0x0b: /* revsh */
+ break;
+ case 0x10: /* sel */
+ if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
+ goto illegal_op;
+ }
+ break;
+ }
tmp = load_reg(s, rn);
switch (op) {
case 0x0a: /* rbit */
@@ -9624,6 +9668,20 @@ static int disas_thumb2_insn(CPUARMState *env,
DisasContext *s, uint16_t insn_hw
break;
case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
op = (insn >> 4) & 0xf;
+ 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;
+ }
tmp = load_reg(s, rn);
tmp2 = load_reg(s, rm);
switch ((insn >> 20) & 7) {
@@ -9735,6 +9793,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(tmp);
+ tcg_temp_free_i32(tmp2);
+ goto illegal_op;
+ }
if (op & 1)
gen_swap_half(tmp2);
gen_smul_dual(tmp, tmp2);
@@ -9758,6 +9821,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(tmp2);
+ tcg_temp_free_i32(tmp);
+ goto illegal_op;
+ }
gen_mulxy(tmp, tmp2, op & 2, op & 1);
tcg_temp_free_i32(tmp2);
tmp64 = tcg_temp_new_i64();
@@ -9770,6 +9838,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(tmp64);
+ goto illegal_op;
+ }
gen_addq_lo(s, tmp64, rs);
gen_addq_lo(s, tmp64, rd);
} else if (op & 0x40) {
@@ -10034,16 +10106,28 @@ static int disas_thumb2_insn(CPUARMState *env,
DisasContext *s, uint16_t insn_hw
tmp2 = tcg_const_i32(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(tmp);
+ tcg_temp_free_i32(tmp2);
+ goto illegal_op;
+ }
gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
- else
+ } else {
gen_helper_usat(tmp, 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(tmp);
+ tcg_temp_free_i32(tmp2);
+ goto illegal_op;
+ }
gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
- else
+ } else {
gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
+ }
}
tcg_temp_free_i32(tmp2);
break;
--
1.9.1
- [Qemu-devel] [PATCH V2] Target-arm: Add the THUMB_DSP feature,
Aurelio C. Remonda <=