target/arm: Convert BX, BXJ, BLX (register)
Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190904193059.26202-16-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
6c35d53f1b
commit
4ed95abd70
@ -29,6 +29,7 @@
|
||||
&s_rrrr s rd rn rm ra
|
||||
&rrrr rd rn rm ra
|
||||
&rrr rd rn rm
|
||||
&r rm
|
||||
&msr_reg rn r mask
|
||||
&mrs_reg rd r
|
||||
&msr_bank rn r sysm
|
||||
@ -195,8 +196,14 @@ CRC32CW .... 0001 0100 .... .... 0010 0100 .... @rndm
|
||||
|
||||
%sysm 8:1 16:4
|
||||
|
||||
@rm ---- .... .... .... .... .... .... rm:4 &r
|
||||
|
||||
MRS_bank ---- 0001 0 r:1 00 .... rd:4 001. 0000 0000 &mrs_bank %sysm
|
||||
MSR_bank ---- 0001 0 r:1 10 .... 1111 001. 0000 rn:4 &msr_bank %sysm
|
||||
|
||||
MRS_reg ---- 0001 0 r:1 00 1111 rd:4 0000 0000 0000 &mrs_reg
|
||||
MSR_reg ---- 0001 0 r:1 10 mask:4 1111 0000 0000 rn:4 &msr_reg
|
||||
|
||||
BX .... 0001 0010 1111 1111 1111 0001 .... @rm
|
||||
BXJ .... 0001 0010 1111 1111 1111 0010 .... @rm
|
||||
BLX_r .... 0001 0010 1111 1111 1111 0011 .... @rm
|
||||
|
@ -26,6 +26,7 @@
|
||||
&s_rrrr !extern s rd rn rm ra
|
||||
&rrrr !extern rd rn rm ra
|
||||
&rrr !extern rd rn rm
|
||||
&r !extern rm
|
||||
&msr_reg !extern rn r mask
|
||||
&mrs_reg !extern rd r
|
||||
&msr_bank !extern rn r sysm
|
||||
@ -211,4 +212,5 @@ CRC32CW 1111 1010 1101 .... 1111 .... 1010 .... @rndm
|
||||
MSR_reg 1111 0011 100 r:1 rn:4 1000 mask:4 0000 0000 &msr_reg
|
||||
MSR_v7m 1111 0011 100 0 rn:4 1000 mask:2 00 sysm:8
|
||||
}
|
||||
BXJ 1111 0011 1100 rm:4 1000 1111 0000 0000 &r
|
||||
}
|
||||
|
@ -8458,6 +8458,38 @@ static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_BX(DisasContext *s, arg_BX *a)
|
||||
{
|
||||
if (!ENABLE_ARCH_4T) {
|
||||
return false;
|
||||
}
|
||||
gen_bx(s, load_reg(s, a->rm));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
|
||||
{
|
||||
if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
return false;
|
||||
}
|
||||
/* Trivial implementation equivalent to bx. */
|
||||
gen_bx(s, load_reg(s, a->rm));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
|
||||
{
|
||||
TCGv_i32 tmp;
|
||||
|
||||
if (!ENABLE_ARCH_5) {
|
||||
return false;
|
||||
}
|
||||
tmp = load_reg(s, a->rm);
|
||||
tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
|
||||
gen_bx(s, tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Legacy decoder.
|
||||
*/
|
||||
@ -8747,12 +8779,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
|
||||
/* All done in decodetree. Illegal ops already signalled. */
|
||||
g_assert_not_reached();
|
||||
case 0x1:
|
||||
if (op1 == 1) {
|
||||
/* branch/exchange thumb (bx). */
|
||||
ARCH(4T);
|
||||
tmp = load_reg(s, rm);
|
||||
gen_bx(s, tmp);
|
||||
} else if (op1 == 3) {
|
||||
if (op1 == 3) {
|
||||
/* clz */
|
||||
ARCH(5);
|
||||
rd = (insn >> 12) & 0xf;
|
||||
@ -8763,30 +8790,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
|
||||
goto illegal_op;
|
||||
}
|
||||
break;
|
||||
case 0x2:
|
||||
if (op1 == 1) {
|
||||
ARCH(5J); /* bxj */
|
||||
/* Trivial implementation equivalent to bx. */
|
||||
tmp = load_reg(s, rm);
|
||||
gen_bx(s, tmp);
|
||||
} else {
|
||||
goto illegal_op;
|
||||
}
|
||||
break;
|
||||
case 0x3:
|
||||
if (op1 != 1)
|
||||
goto illegal_op;
|
||||
|
||||
ARCH(5);
|
||||
/* branch link/exchange thumb (blx) */
|
||||
tmp = load_reg(s, rm);
|
||||
tmp2 = tcg_temp_new_i32();
|
||||
tcg_gen_movi_i32(tmp2, s->base.pc_next);
|
||||
store_reg(s, 14, tmp2);
|
||||
gen_bx(s, tmp);
|
||||
break;
|
||||
case 0x4:
|
||||
/* crc32 */
|
||||
case 0x2: /* bxj */
|
||||
case 0x3: /* blx */
|
||||
case 0x4: /* crc32 */
|
||||
/* All done in decodetree. Illegal ops reach here. */
|
||||
goto illegal_op;
|
||||
case 0x5:
|
||||
@ -10620,16 +10626,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
|
||||
goto illegal_op;
|
||||
}
|
||||
break;
|
||||
case 4: /* bxj */
|
||||
/* Trivial implementation equivalent to bx.
|
||||
* This instruction doesn't exist at all for M-profile.
|
||||
*/
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
goto illegal_op;
|
||||
}
|
||||
tmp = load_reg(s, rn);
|
||||
gen_bx(s, tmp);
|
||||
break;
|
||||
case 4: /* bxj, in decodetree */
|
||||
goto illegal_op;
|
||||
case 5: /* Exception return. */
|
||||
if (IS_USER(s)) {
|
||||
goto illegal_op;
|
||||
|
Loading…
Reference in New Issue
Block a user