summaryrefslogtreecommitdiff
path: root/target/arm/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r--target/arm/translate.c89
1 files changed, 33 insertions, 56 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 5b9b303467..b7d26f7cc8 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -7870,6 +7870,34 @@ static bool trans_ADR(DisasContext *s, arg_ri *a)
return true;
}
+static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
+{
+ TCGv_i32 tmp;
+
+ if (!ENABLE_ARCH_6T2) {
+ return false;
+ }
+
+ tmp = tcg_const_i32(a->imm);
+ store_reg(s, a->rd, tmp);
+ return true;
+}
+
+static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
+{
+ TCGv_i32 tmp;
+
+ if (!ENABLE_ARCH_6T2) {
+ return false;
+ }
+
+ tmp = load_reg(s, a->rd);
+ tcg_gen_ext16u_i32(tmp, tmp);
+ tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
+ store_reg(s, a->rd, tmp);
+ return true;
+}
+
/*
* Multiply and multiply accumulate
*/
@@ -9762,7 +9790,7 @@ static bool trans_UDIV(DisasContext *s, arg_rrr *a)
static void disas_arm_insn(DisasContext *s, unsigned int insn)
{
- unsigned int cond, val, op1, i, rn, rd;
+ unsigned int cond, val, op1, i, rn;
TCGv_i32 tmp;
TCGv_i32 tmp2;
TCGv_i32 addr;
@@ -10011,26 +10039,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
/* fall back to legacy decoder */
if ((insn & 0x0f900000) == 0x03000000) {
- if ((insn & (1 << 21)) == 0) {
- ARCH(6T2);
- rd = (insn >> 12) & 0xf;
- val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
- if ((insn & (1 << 22)) == 0) {
- /* MOVW */
- tmp = tcg_temp_new_i32();
- tcg_gen_movi_i32(tmp, val);
- } else {
- /* MOVT */
- tmp = load_reg(s, rd);
- tcg_gen_ext16u_i32(tmp, tmp);
- tcg_gen_ori_i32(tmp, tmp, val << 16);
- }
- store_reg(s, rd, tmp);
- } else {
- /* MSR (immediate) and hints */
- /* All done in decodetree. Illegal ops already signalled. */
- g_assert_not_reached();
- }
+ /* All done in decodetree. Illegal ops reach here. */
+ goto illegal_op;
} else if ((insn & 0x0f900000) == 0x01000000
&& (insn & 0x00000090) != 0x00000090) {
/* miscellaneous instructions */
@@ -10765,42 +10775,9 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
/*
* 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
* - Data-processing (modified immediate, plain binary immediate)
+ * All in decodetree.
*/
- if (insn & (1 << 25)) {
- /*
- * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
- * - Data-processing (plain binary immediate)
- */
- if (insn & (1 << 24)) {
- /* Bitfield/Saturate, in decodetree */
- goto illegal_op;
- } else {
- imm = ((insn & 0x04000000) >> 15)
- | ((insn & 0x7000) >> 4) | (insn & 0xff);
- if (insn & (1 << 22)) {
- /* 16-bit immediate. */
- imm |= (insn >> 4) & 0xf000;
- if (insn & (1 << 23)) {
- /* movt */
- tmp = load_reg(s, rd);
- tcg_gen_ext16u_i32(tmp, tmp);
- tcg_gen_ori_i32(tmp, tmp, imm << 16);
- } else {
- /* movw */
- tmp = tcg_temp_new_i32();
- tcg_gen_movi_i32(tmp, imm);
- }
- store_reg(s, rd, tmp);
- } else {
- /* Add/sub 12-bit immediate, in decodetree */
- goto illegal_op;
- }
- }
- } else {
- /* Data-processing (modified immediate) */
- /* All done in decodetree. Reach here for illegal ops. */
- goto illegal_op;
- }
+ goto illegal_op;
}
break;
case 12: