summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2019-09-04 12:30:02 -0700
committerPeter Maydell <peter.maydell@linaro.org>2019-09-05 13:23:03 +0100
commit6313059623dc512308681ba160ed862ac387e2fb (patch)
tree718bf82b8843553dc6a90aba9034cbcd69e1c008
parent485b607d4f393e0de92c922806a68aef22340c98 (diff)
downloadqemu-6313059623dc512308681ba160ed862ac387e2fb.zip
target/arm: Convert MSR (immediate) and hints
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>
-rw-r--r--target/arm/a32.decode25
-rw-r--r--target/arm/t32.decode17
-rw-r--r--target/arm/translate.c60
3 files changed, 84 insertions, 18 deletions
diff --git a/target/arm/a32.decode b/target/arm/a32.decode
index 19d12e726b..3d5c5408f9 100644
--- a/target/arm/a32.decode
+++ b/target/arm/a32.decode
@@ -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
@@ -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
diff --git a/target/arm/t32.decode b/target/arm/t32.decode
index 122a0537ed..ccb7cdd4ef 100644
--- a/target/arm/t32.decode
+++ b/target/arm/t32.decode
@@ -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
@@ -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 ---- ----
+}
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 71cc96b70e..58bfbb8ed9 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -8283,6 +8283,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.
*/
@@ -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) {
@@ -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;