target/arm: Convert MOVW, MOVT

Backports commit 8f4451274b7010c1f50e0baa5bb608f19f02b90f from qemu
This commit is contained in:
Richard Henderson 2019-11-20 11:14:03 -05:00 committed by Lioncash
parent b35749e239
commit e4ca88f9d6
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 50 additions and 56 deletions

View file

@ -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 \

View file

@ -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 \

View file

@ -8153,6 +8153,36 @@ static bool trans_ADR(DisasContext *s, arg_ri *a)
return true;
}
static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tmp;
if (!ENABLE_ARCH_6T2) {
return false;
}
tmp = tcg_const_i32(tcg_ctx, a->imm);
store_reg(s, a->rd, tmp);
return true;
}
static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tmp;
if (!ENABLE_ARCH_6T2) {
return false;
}
tmp = load_reg(s, a->rd);
tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
tcg_gen_ori_i32(tcg_ctx, tmp, tmp, a->imm << 16);
store_reg(s, a->rd, tmp);
return true;
}
/*
* Multiply and multiply accumulate
*/
@ -10090,7 +10120,7 @@ static bool trans_UDIV(DisasContext *s, arg_rrr *a)
static void disas_arm_insn(DisasContext *s, unsigned int insn)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
unsigned int cond, val, op1, i, rn, rd;
unsigned int cond, val, op1, i, rn;
TCGv_i32 tmp;
TCGv_i32 tmp2;
TCGv_i32 addr;
@ -10347,26 +10377,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_ctx);
tcg_gen_movi_i32(tcg_ctx, tmp, val);
} else {
/* MOVT */
tmp = load_reg(s, rd);
tcg_gen_ext16u_i32(tcg_ctx, tmp, tmp);
tcg_gen_ori_i32(tcg_ctx, 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 */
@ -11102,42 +11114,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(tcg_ctx, tmp, tmp);
tcg_gen_ori_i32(tcg_ctx, tmp, tmp, imm << 16);
} else {
/* movw */
tmp = tcg_temp_new_i32(tcg_ctx);
tcg_gen_movi_i32(tcg_ctx, 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: