@@ -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:
@@ -73,6 +73,12 @@ MOV_rxri .... 000 1101 . 0000 .... ..... .. 0 .... @s_rxr_shi
BIC_rrri .... 000 1110 . .... .... ..... .. 0 .... @s_rrr_shi
MVN_rxri .... 000 1111 . 0000 .... ..... .. 0 .... @s_rxr_shi
+%imm16 16:4 0:12
+@mov16 ---- .... .... .... rd:4 ............ &ri imm=%imm16
+
+MOVW .... 0011 0000 .... .... ............ @mov16
+MOVT .... 0011 0100 .... .... ............ @mov16
+
# Data-processing (register-shifted register)
@s_rrr_shr ---- ... .... s:1 rn:4 rd:4 rs:4 . shty:2 . rm:4 \
@@ -150,6 +150,15 @@ RSB_rri 1111 0.0 1110 . .... 0 ... .... ........ @s_rri_rot
SUB_rri 1111 0.1 0101 0 .... 0 ... .... ........ @s0_rri_12
}
+# Move Wide
+
+%imm16_26_16_12_0 16:4 26:1 12:3 0:8
+@mov16 .... .... .... .... .... rd:4 .... .... \
+ &ri imm=%imm16_26_16_12_0
+
+MOVW 1111 0.10 0100 .... 0 ... .... ........ @mov16
+MOVT 1111 0.10 1100 .... 0 ... .... ........ @mov16
+
# Saturate, bitfield
@sat .... .... .. sh:1 . rn:4 . ... rd:4 .. . satimm:5 \