Commit 63130596 authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Convert MSR (immediate) and hints



Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-13-richard.henderson@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 485b607d
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -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
+17 −0
Original line number Diff line number Diff line
@@ -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 ---- ----
}
+42 −18
Original line number Diff line number Diff line
@@ -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.
 */
@@ -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;