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

target/arm: Convert BX, BXJ, BLX (register)



Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20190904193059.26202-16-richard.henderson@linaro.org
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 6c35d53f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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
}
+38 −40
Original line number Diff line number Diff line
@@ -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)) {
                    case 4: /* bxj, in decodetree */
                        goto illegal_op;
                        }
                        tmp = load_reg(s, rn);
                        gen_bx(s, tmp);
                        break;
                    case 5: /* Exception return.  */
                        if (IS_USER(s)) {
                            goto illegal_op;