mirror of https://gitee.com/openkylin/qemu.git
target/arm: Implement MVE WLSTP insn
Implement the MVE WLSTP insn; this is like the existing WLS insn, except that it specifies a size value which is used to set FPSCR.LTPSIZE. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210614151007.4545-8-peter.maydell@linaro.org
This commit is contained in:
parent
76c32d721d
commit
6822abfdf8
|
@ -672,8 +672,12 @@ BL 1111 0. .......... 11.1 ............ @branch24
|
||||||
%lob_imm 1:10 11:1 !function=times_2
|
%lob_imm 1:10 11:1 !function=times_2
|
||||||
|
|
||||||
DLS 1111 0 0000 100 rn:4 1110 0000 0000 0001
|
DLS 1111 0 0000 100 rn:4 1110 0000 0000 0001
|
||||||
WLS 1111 0 0000 100 rn:4 1100 . .......... 1 imm=%lob_imm
|
WLS 1111 0 0000 100 rn:4 1100 . .......... 1 imm=%lob_imm size=4
|
||||||
|
{
|
||||||
LE 1111 0 0000 0 f:1 0 1111 1100 . .......... 1 imm=%lob_imm
|
LE 1111 0 0000 0 f:1 0 1111 1100 . .......... 1 imm=%lob_imm
|
||||||
|
# This is WLSTP
|
||||||
|
WLS 1111 0 0000 0 size:2 rn:4 1100 . .......... 1 imm=%lob_imm
|
||||||
|
}
|
||||||
|
|
||||||
LCTP 1111 0 0000 000 1111 1110 0000 0000 0001
|
LCTP 1111 0 0000 000 1111 1110 0000 0000 0001
|
||||||
]
|
]
|
||||||
|
|
|
@ -8134,7 +8134,11 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (a->rn == 13 || a->rn == 15) {
|
if (a->rn == 13 || a->rn == 15) {
|
||||||
/* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
|
/*
|
||||||
|
* For WLSTP rn == 15 is a related encoding (LE); the
|
||||||
|
* other cases caught by this condition are all
|
||||||
|
* CONSTRAINED UNPREDICTABLE: we choose to UNDEF
|
||||||
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (s->condexec_mask) {
|
if (s->condexec_mask) {
|
||||||
|
@ -8147,10 +8151,41 @@ static bool trans_WLS(DisasContext *s, arg_WLS *a)
|
||||||
*/
|
*/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (a->size != 4) {
|
||||||
|
/* WLSTP */
|
||||||
|
if (!dc_isar_feature(aa32_mve, s)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We need to check that the FPU is enabled here, but mustn't
|
||||||
|
* call vfp_access_check() to do that because we don't want to
|
||||||
|
* do the lazy state preservation in the "loop count is zero" case.
|
||||||
|
* Do the check-and-raise-exception by hand.
|
||||||
|
*/
|
||||||
|
if (s->fp_excp_el) {
|
||||||
|
gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
|
||||||
|
syn_uncategorized(), s->fp_excp_el);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nextlabel = gen_new_label();
|
nextlabel = gen_new_label();
|
||||||
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
|
tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
|
||||||
tmp = load_reg(s, a->rn);
|
tmp = load_reg(s, a->rn);
|
||||||
store_reg(s, 14, tmp);
|
store_reg(s, 14, tmp);
|
||||||
|
if (a->size != 4) {
|
||||||
|
/*
|
||||||
|
* WLSTP: set FPSCR.LTPSIZE. This requires that we do the
|
||||||
|
* lazy state preservation, new FP context creation, etc,
|
||||||
|
* that vfp_access_check() does. We know that the actual
|
||||||
|
* access check will succeed (ie it won't generate code that
|
||||||
|
* throws an exception) because we did that check by hand earlier.
|
||||||
|
*/
|
||||||
|
bool ok = vfp_access_check(s);
|
||||||
|
assert(ok);
|
||||||
|
tmp = tcg_const_i32(a->size);
|
||||||
|
store_cpu_field(tmp, v7m.ltpsize);
|
||||||
|
}
|
||||||
gen_jmp_tb(s, s->base.pc_next, 1);
|
gen_jmp_tb(s, s->base.pc_next, 1);
|
||||||
|
|
||||||
gen_set_label(nextlabel);
|
gen_set_label(nextlabel);
|
||||||
|
|
Loading…
Reference in New Issue