Skip to content

Commit

Permalink
target/arm: Convert MSR (immediate) and hints
Browse files Browse the repository at this point in the history
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-13-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
rth7680 authored and pm215 committed Sep 5, 2019
1 parent 485b607 commit 6313059
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 18 deletions.
25 changes: 25 additions & 0 deletions target/arm/a32.decode
Expand Up @@ -22,6 +22,7 @@
# All insns that have 0xf in insn[31:28] are in a32-uncond.decode.
#

&empty
&s_rrr_shi s rd rn rm shim shty
&s_rrr_shr s rn rd rm rs shty
&s_rri_rot s rn rd imm rot
Expand Down Expand Up @@ -152,3 +153,27 @@ SMULBB .... 0001 0110 .... 0000 .... 1000 .... @rd0mn
SMULBT .... 0001 0110 .... 0000 .... 1100 .... @rd0mn
SMULTB .... 0001 0110 .... 0000 .... 1010 .... @rd0mn
SMULTT .... 0001 0110 .... 0000 .... 1110 .... @rd0mn

# MSR (immediate) and hints

&msr_i r mask rot imm
@msr_i ---- .... .... mask:4 .... rot:4 imm:8 &msr_i

{
{
YIELD ---- 0011 0010 0000 1111 ---- 0000 0001
WFE ---- 0011 0010 0000 1111 ---- 0000 0010
WFI ---- 0011 0010 0000 1111 ---- 0000 0011

# TODO: Implement SEV, SEVL; may help SMP performance.
# SEV ---- 0011 0010 0000 1111 ---- 0000 0100
# SEVL ---- 0011 0010 0000 1111 ---- 0000 0101

# The canonical nop ends in 00000000, but the whole of the
# rest of the space executes as nop if otherwise unsupported.
NOP ---- 0011 0010 0000 1111 ---- ---- ----
}
# Note mask = 0 is covered by NOP
MSR_imm .... 0011 0010 .... 1111 .... .... .... @msr_i r=0
}
MSR_imm .... 0011 0110 .... 1111 .... .... .... @msr_i r=1
17 changes: 17 additions & 0 deletions target/arm/t32.decode
Expand Up @@ -19,6 +19,7 @@
# This file is processed by scripts/decodetree.py
#

&empty !extern
&s_rrr_shi !extern s rd rn rm shim shty
&s_rrr_shr !extern s rn rd rm rs shty
&s_rri_rot !extern s rn rd imm rot
Expand Down Expand Up @@ -166,3 +167,19 @@ QADD 1111 1010 1000 .... 1111 .... 1000 .... @rndm
QSUB 1111 1010 1000 .... 1111 .... 1010 .... @rndm
QDADD 1111 1010 1000 .... 1111 .... 1001 .... @rndm
QDSUB 1111 1010 1000 .... 1111 .... 1011 .... @rndm

# Branches and miscellaneous control

{
YIELD 1111 0011 1010 1111 1000 0000 0000 0001
WFE 1111 0011 1010 1111 1000 0000 0000 0010
WFI 1111 0011 1010 1111 1000 0000 0000 0011

# TODO: Implement SEV, SEVL; may help SMP performance.
# SEV 1111 0011 1010 1111 1000 0000 0000 0100
# SEVL 1111 0011 1010 1111 1000 0000 0000 0101

# The canonical nop ends in 0000 0000, but the whole rest
# of the space is "reserved hint, behaves as nop".
NOP 1111 0011 1010 1111 1000 0000 ---- ----
}
60 changes: 42 additions & 18 deletions target/arm/translate.c
Expand Up @@ -8282,6 +8282,44 @@ DO_SMLAWX(SMLAWT, 1, 1)

#undef DO_SMLAWX

/*
* MSR (immediate) and hints
*/

static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
{
gen_nop_hint(s, 1);
return true;
}

static bool trans_WFE(DisasContext *s, arg_WFE *a)
{
gen_nop_hint(s, 2);
return true;
}

static bool trans_WFI(DisasContext *s, arg_WFI *a)
{
gen_nop_hint(s, 3);
return true;
}

static bool trans_NOP(DisasContext *s, arg_NOP *a)
{
return true;
}

static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
{
uint32_t val = ror32(a->imm, a->rot * 2);
uint32_t mask = msr_mask(s, a->mask, a->r);

if (gen_set_psr_im(s, mask, a->r, val)) {
unallocated_encoding(s);
}
return true;
}

/*
* Legacy decoder.
*/
Expand Down Expand Up @@ -8555,21 +8593,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
}
store_reg(s, rd, tmp);
} else {
if (((insn >> 12) & 0xf) != 0xf)
goto illegal_op;
if (((insn >> 16) & 0xf) == 0) {
gen_nop_hint(s, insn & 0xff);
} else {
/* CPSR = immediate */
val = insn & 0xff;
shift = ((insn >> 8) & 0xf) * 2;
val = ror32(val, shift);
i = ((insn & (1 << 22)) != 0);
if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
i, val)) {
goto illegal_op;
}
}
/* MSR (immediate) and hints */
/* All done in decodetree. Illegal ops already signalled. */
g_assert_not_reached();
}
} else if ((insn & 0x0f900000) == 0x01000000
&& (insn & 0x00000090) != 0x00000090) {
Expand Down Expand Up @@ -10522,9 +10548,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
goto illegal_op;
break;
case 2: /* cps, nop-hint. */
if (((insn >> 8) & 7) == 0) {
gen_nop_hint(s, insn & 0xff);
}
/* nop hints in decodetree */
/* Implemented as NOP in user mode. */
if (IS_USER(s))
break;
Expand Down

0 comments on commit 6313059

Please sign in to comment.