target/arm: Implement v8.1M conditional-select insns

v8.1M brings four new insns to M-profile:
* CSEL : Rd = cond ? Rn : Rm
* CSINC : Rd = cond ? Rn : Rm+1
* CSINV : Rd = cond ? Rn : ~Rm
* CSNEG : Rd = cond ? Rn : -Rm

Implement these.

Backports cc73bbded0dfb5612b0e416f7eda13a66950542a
This commit is contained in:
Peter Maydell 2021-03-01 20:19:31 -05:00 committed by Lioncash
parent 2dae268fcb
commit 666fe17025
2 changed files with 64 additions and 0 deletions

View file

@ -90,6 +90,9 @@ SBC_rrri 1110101 1011 . .... 0 ... .... .... .... @s_rrr_shi
}
RSB_rrri 1110101 1110 . .... 0 ... .... .... .... @s_rrr_shi
# v8.1M CSEL and friends
CSEL 1110101 0010 1 rn:4 10 op:2 rd:4 fcond:4 rm:4
# Data-processing (register-shifted register)
MOV_rxrr 1111 1010 0 shty:2 s:1 rm:4 1111 rd:4 0000 rs:4 \

View file

@ -8511,6 +8511,67 @@ static bool trans_IT(DisasContext *s, arg_IT *a)
return true;
}
/* v8.1M CSEL/CSINC/CSNEG/CSINV */
static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
{
TCGv_i32 rn, rm, zero;
DisasCompare c;
TCGContext *tcg_ctx = s->uc->tcg_ctx;
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
return false;
}
if (a->rm == 13) {
/* SEE "Related encodings" (MVE shifts) */
return false;
}
if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
/* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
return false;
}
/* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
if (a->rn == 15) {
rn = tcg_const_i32(tcg_ctx, 0);
} else {
rn = load_reg(s, a->rn);
}
if (a->rm == 15) {
rm = tcg_const_i32(tcg_ctx, 0);
} else {
rm = load_reg(s, a->rm);
}
switch (a->op) {
case 0: /* CSEL */
break;
case 1: /* CSINC */
tcg_gen_addi_i32(tcg_ctx, rm, rm, 1);
break;
case 2: /* CSINV */
tcg_gen_not_i32(tcg_ctx, rm, rm);
break;
case 3: /* CSNEG */
tcg_gen_neg_i32(tcg_ctx, rm, rm);
break;
default:
g_assert_not_reached();
}
arm_test_cc(s, &c, a->fcond);
zero = tcg_const_i32(tcg_ctx, 0);
tcg_gen_movcond_i32(tcg_ctx, c.cond, rn, c.value, zero, rn, rm);
arm_free_cc(s, &c);
tcg_temp_free_i32(tcg_ctx, zero);
store_reg(s, a->rd, rn);
tcg_temp_free_i32(tcg_ctx, rm);
return true;
}
/*
* Legacy decoder.
*/