mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
target/arm: Implement MVE logical immediate insns
Implement the MVE logical-immediate insns (VMOV, VMVN, VORR and VBIC). These have essentially the same encoding as their Neon equivalents, and we implement the decode in the same way. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20210628135835.6690-7-peter.maydell@linaro.org
This commit is contained in:
parent
e4667a5b5e
commit
eab8413985
4 changed files with 95 additions and 0 deletions
|
@ -34,6 +34,7 @@ typedef void MVEGenTwoOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_ptr);
|
|||
typedef void MVEGenTwoOpScalarFn(TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i32);
|
||||
typedef void MVEGenDualAccOpFn(TCGv_i64, TCGv_ptr, TCGv_ptr, TCGv_ptr, TCGv_i64);
|
||||
typedef void MVEGenVADDVFn(TCGv_i32, TCGv_ptr, TCGv_ptr, TCGv_i32);
|
||||
typedef void MVEGenOneOpImmFn(TCGv_ptr, TCGv_ptr, TCGv_i64);
|
||||
|
||||
/* Return the offset of a Qn register (same semantics as aa32_vfp_qreg()) */
|
||||
static inline long mve_qreg_offset(unsigned reg)
|
||||
|
@ -787,3 +788,52 @@ static bool trans_VADDV(DisasContext *s, arg_VADDV *a)
|
|||
mve_update_eci(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_1imm(DisasContext *s, arg_1imm *a, MVEGenOneOpImmFn *fn)
|
||||
{
|
||||
TCGv_ptr qd;
|
||||
uint64_t imm;
|
||||
|
||||
if (!dc_isar_feature(aa32_mve, s) ||
|
||||
!mve_check_qreg_bank(s, a->qd) ||
|
||||
!fn) {
|
||||
return false;
|
||||
}
|
||||
if (!mve_eci_check(s) || !vfp_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
imm = asimd_imm_const(a->imm, a->cmode, a->op);
|
||||
|
||||
qd = mve_qreg_ptr(a->qd);
|
||||
fn(cpu_env, qd, tcg_constant_i64(imm));
|
||||
tcg_temp_free_ptr(qd);
|
||||
mve_update_eci(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_Vimm_1r(DisasContext *s, arg_1imm *a)
|
||||
{
|
||||
/* Handle decode of cmode/op here between VORR/VBIC/VMOV */
|
||||
MVEGenOneOpImmFn *fn;
|
||||
|
||||
if ((a->cmode & 1) && a->cmode < 12) {
|
||||
if (a->op) {
|
||||
/*
|
||||
* For op=1, the immediate will be inverted by asimd_imm_const(),
|
||||
* so the VBIC becomes a logical AND operation.
|
||||
*/
|
||||
fn = gen_helper_mve_vandi;
|
||||
} else {
|
||||
fn = gen_helper_mve_vorri;
|
||||
}
|
||||
} else {
|
||||
/* There is one unallocated cmode/op combination in this space */
|
||||
if (a->cmode == 15 && a->op == 1) {
|
||||
return false;
|
||||
}
|
||||
/* asimd_imm_const() sorts out VMVNI vs VMOVI for us */
|
||||
fn = gen_helper_mve_vmovi;
|
||||
}
|
||||
return do_1imm(s, a, fn);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue