target/arm: Split trans_WHILE to lt and gt
Use TRANS_FEAT to select the correct predicate. Pass the helper and a boolean to do_WHILE. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704142112.1018902-77-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
f96fd13c6e
commit
54e260bbfc
2 changed files with 12 additions and 15 deletions
|
|
@ -789,7 +789,9 @@ SINCDECP_z 00100101 .. 1010 d:1 u:1 10000 00 .... ..... @incdec2_pred
|
|||
CTERM 00100101 1 sf:1 1 rm:5 001000 rn:5 ne:1 0000
|
||||
|
||||
# SVE integer compare scalar count and limit
|
||||
WHILE 00100101 esz:2 1 rm:5 000 sf:1 u:1 lt:1 rn:5 eq:1 rd:4
|
||||
&while esz rd rn rm sf u eq
|
||||
WHILE_lt 00100101 esz:2 1 rm:5 000 sf:1 u:1 1 rn:5 eq:1 rd:4 &while
|
||||
WHILE_gt 00100101 esz:2 1 rm:5 000 sf:1 u:1 0 rn:5 eq:1 rd:4 &while
|
||||
|
||||
# SVE2 pointer conflict compare
|
||||
WHILE_ptr 00100101 esz:2 1 rm:5 001 100 rn:5 rw:1 rd:4
|
||||
|
|
|
|||
|
|
@ -3108,7 +3108,8 @@ static bool trans_CTERM(DisasContext *s, arg_CTERM *a)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
|
||||
typedef void gen_while_fn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
|
||||
static bool do_WHILE(DisasContext *s, arg_while *a, bool lt, gen_while_fn *fn)
|
||||
{
|
||||
TCGv_i64 op0, op1, t0, t1, tmax;
|
||||
TCGv_i32 t2;
|
||||
|
|
@ -3118,14 +3119,8 @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
|
|||
TCGCond cond;
|
||||
uint64_t maxval;
|
||||
/* Note that GE/HS has a->eq == 0 and GT/HI has a->eq == 1. */
|
||||
bool eq = a->eq == a->lt;
|
||||
bool eq = a->eq == lt;
|
||||
|
||||
/* The greater-than conditions are all SVE2. */
|
||||
if (a->lt
|
||||
? !dc_isar_feature(aa64_sve, s)
|
||||
: !dc_isar_feature(aa64_sve2, s)) {
|
||||
return false;
|
||||
}
|
||||
if (!sve_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3149,7 +3144,7 @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
|
|||
t0 = tcg_temp_new_i64();
|
||||
t1 = tcg_temp_new_i64();
|
||||
|
||||
if (a->lt) {
|
||||
if (lt) {
|
||||
tcg_gen_sub_i64(t0, op1, op0);
|
||||
if (a->u) {
|
||||
maxval = a->sf ? UINT64_MAX : UINT32_MAX;
|
||||
|
|
@ -3204,15 +3199,15 @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
|
|||
ptr = tcg_temp_new_ptr();
|
||||
tcg_gen_addi_ptr(ptr, tcg_env, pred_full_reg_offset(s, a->rd));
|
||||
|
||||
if (a->lt) {
|
||||
gen_helper_sve_whilel(t2, ptr, t2, tcg_constant_i32(desc));
|
||||
} else {
|
||||
gen_helper_sve_whileg(t2, ptr, t2, tcg_constant_i32(desc));
|
||||
}
|
||||
fn(t2, ptr, t2, tcg_constant_i32(desc));
|
||||
|
||||
do_pred_flags(t2);
|
||||
return true;
|
||||
}
|
||||
|
||||
TRANS_FEAT(WHILE_lt, aa64_sve, do_WHILE, a, true, gen_helper_sve_whilel)
|
||||
TRANS_FEAT(WHILE_gt, aa64_sve2, do_WHILE, a, false, gen_helper_sve_whileg)
|
||||
|
||||
static bool trans_WHILE_ptr(DisasContext *s, arg_WHILE_ptr *a)
|
||||
{
|
||||
TCGv_i64 op0, op1, diff, t1, tmax;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue