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

target/arm: Convert the rest of A32 Miscelaneous instructions



Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-19-richard.henderson@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent ef11bc3c
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
&rrr             rd rn rm
&rr              rd rm
&r               rm
&i               imm
&msr_reg         rn r mask
&mrs_reg         rd r
&msr_bank        rn r sysm
@@ -196,9 +197,11 @@ CRC32CW .... 0001 0100 .... .... 0010 0100 .... @rndm
# Miscellaneous instructions

%sysm            8:1 16:4
%imm16_8_0       8:12 0:4

@rm              ---- .... .... .... .... .... .... rm:4      &r
@rdm             ---- .... .... .... rd:4 .... .... rm:4      &rr
@i16             ---- .... .... .... .... .... .... ....      &i imm=%imm16_8_0

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
@@ -213,3 +216,8 @@ BLX_r .... 0001 0010 1111 1111 1111 0011 .... @rm
CLZ              .... 0001 0110 1111 .... 1111 0001 ....      @rdm

ERET             ---- 0001 0110 0000 0000 0000 0110 1110

HLT              .... 0001 0000 .... .... .... 0111 ....      @i16
BKPT             .... 0001 0010 .... .... .... 0111 ....      @i16
HVC              .... 0001 0100 .... .... .... 0111 ....      @i16
SMC              ---- 0001 0110 0000 0000 0000 0111 imm:4     &i
+5 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
&rrr             !extern rd rn rm
&rr              !extern rd rm
&r               !extern rm
&i               !extern imm
&msr_reg         !extern rn r mask
&mrs_reg         !extern rd r
&msr_bank        !extern rn r sysm
@@ -189,6 +190,7 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm

%msr_sysm        4:1 8:4
%mrs_sysm        4:1 16:4
%imm16_16_0      16:4 0:12

{
  {
@@ -226,4 +228,7 @@ CLZ 1111 1010 1011 ---- 1111 .... 1000 .... @rdm
    SUB_rri      1111 0011 1101 1110 1000 1111 imm:8 \
                 &s_rri_rot rot=0 s=1 rd=15 rn=14
  }
  SMC            1111 0111 1111 imm:4 1000 0000 0000 0000     &i
  HVC            1111 0111 1110 ....  1000 .... .... ....     \
                 &i imm=%imm16_16_0
}
+45 −82
Original line number Diff line number Diff line
@@ -8524,6 +8524,47 @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
    return true;
}

static bool trans_HLT(DisasContext *s, arg_HLT *a)
{
    gen_hlt(s, a->imm);
    return true;
}

static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
{
    if (!ENABLE_ARCH_5) {
        return false;
    }
    gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
    return true;
}

static bool trans_HVC(DisasContext *s, arg_HVC *a)
{
    if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        unallocated_encoding(s);
    } else {
        gen_hvc(s, a->imm);
    }
    return true;
}

static bool trans_SMC(DisasContext *s, arg_SMC *a)
{
    if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
        return false;
    }
    if (IS_USER(s)) {
        unallocated_encoding(s);
    } else {
        gen_smc(s);
    }
    return true;
}

/*
 * Legacy decoder.
 */
@@ -8804,68 +8845,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
    } else if ((insn & 0x0f900000) == 0x01000000
               && (insn & 0x00000090) != 0x00000090) {
        /* miscellaneous instructions */
        op1 = (insn >> 21) & 3;
        sh = (insn >> 4) & 0xf;
        rm = insn & 0xf;
        switch (sh) {
        case 0x0:
            /* MSR/MRS (banked/register) */
            /* All done in decodetree.  Illegal ops already signalled.  */
            g_assert_not_reached();
        case 0x1: /* bx, clz */
        case 0x2: /* bxj */
        case 0x3: /* blx */
        case 0x4: /* crc32 */
        /* All done in decodetree.  Illegal ops reach here.  */
        goto illegal_op;
        case 0x5: /* Saturating addition and subtraction.  */
        case 0x6: /* ERET */
            /* All done in decodetree.  Reach here for illegal ops.  */
            goto illegal_op;
        case 7:
        {
            int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
            switch (op1) {
            case 0:
                /* HLT */
                gen_hlt(s, imm16);
                break;
            case 1:
                /* bkpt */
                ARCH(5);
                gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
                break;
            case 2:
                /* Hypervisor call (v7) */
                ARCH(7);
                if (IS_USER(s)) {
                    goto illegal_op;
                }
                gen_hvc(s, imm16);
                break;
            case 3:
                /* Secure monitor call (v6+) */
                ARCH(6K);
                if (IS_USER(s)) {
                    goto illegal_op;
                }
                gen_smc(s);
                break;
            default:
                g_assert_not_reached();
            }
            break;
        }
        case 0x8:
        case 0xa:
        case 0xc:
        case 0xe:
            /* Halfword multiply and multiply accumulate.  */
            /* All done in decodetree.  Reach here for illegal ops.  */
            goto illegal_op;
        default:
            goto illegal_op;
        }
    } else if (((insn & 0x0e000000) == 0 &&
                (insn & 0x00000090) != 0x90) ||
               ((insn & 0x0e000000) == (1 << 25))) {
@@ -10539,26 +10520,8 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
                    goto illegal_op;

                if (insn & (1 << 26)) {
                    if (arm_dc_feature(s, ARM_FEATURE_M)) {
                        goto illegal_op;
                    }
                    if (!(insn & (1 << 20))) {
                        /* Hypervisor call (v7) */
                        int imm16 = extract32(insn, 16, 4) << 12
                            | extract32(insn, 0, 12);
                        ARCH(7);
                        if (IS_USER(s)) {
                    /* hvc, smc, in decodetree */
                    goto illegal_op;
                        }
                        gen_hvc(s, imm16);
                    } else {
                        /* Secure monitor call (v6+) */
                        ARCH(6K);
                        if (IS_USER(s)) {
                            goto illegal_op;
                        }
                        gen_smc(s);
                    }
                } else {
                    op = (insn >> 20) & 7;
                    switch (op) {