mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 12:05:30 +00:00
target/arm: Implement SVE MOVPRFX
Backports commit a21035822e67000b4849e31935d0ecc39a96bb9f from qemu
This commit is contained in:
parent
00d3671412
commit
f7847aad46
|
@ -270,6 +270,10 @@ ORV 00000100 .. 011 000 001 ... ..... ..... @rd_pg_rn
|
||||||
EORV 00000100 .. 011 001 001 ... ..... ..... @rd_pg_rn
|
EORV 00000100 .. 011 001 001 ... ..... ..... @rd_pg_rn
|
||||||
ANDV 00000100 .. 011 010 001 ... ..... ..... @rd_pg_rn
|
ANDV 00000100 .. 011 010 001 ... ..... ..... @rd_pg_rn
|
||||||
|
|
||||||
|
# SVE constructive prefix (predicated)
|
||||||
|
MOVPRFX_z 00000100 .. 010 000 001 ... ..... ..... @rd_pg_rn
|
||||||
|
MOVPRFX_m 00000100 .. 010 001 001 ... ..... ..... @rd_pg_rn
|
||||||
|
|
||||||
# SVE integer add reduction (predicated)
|
# SVE integer add reduction (predicated)
|
||||||
# Note that saddv requires size != 3.
|
# Note that saddv requires size != 3.
|
||||||
UADDV 00000100 .. 000 001 001 ... ..... ..... @rd_pg_rn
|
UADDV 00000100 .. 000 001 001 ... ..... ..... @rd_pg_rn
|
||||||
|
@ -428,6 +432,9 @@ ADR_p64 00000100 11 1 ..... 1010 .. ..... ..... @rd_rn_msz_rm
|
||||||
|
|
||||||
### SVE Integer Misc - Unpredicated Group
|
### SVE Integer Misc - Unpredicated Group
|
||||||
|
|
||||||
|
# SVE constructive prefix (unpredicated)
|
||||||
|
MOVPRFX 00000100 00 1 00000 101111 rn:5 rd:5
|
||||||
|
|
||||||
# SVE floating-point exponential accelerator
|
# SVE floating-point exponential accelerator
|
||||||
# Note esz != 0
|
# Note esz != 0
|
||||||
FEXPA 00000100 .. 1 00000 101110 ..... ..... @rd_rn
|
FEXPA 00000100 .. 1 00000 101110 ..... ..... @rd_rn
|
||||||
|
|
|
@ -358,6 +358,24 @@ static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Select active elememnts from Zn and inactive elements from Zm,
|
||||||
|
* storing the result in Zd.
|
||||||
|
*/
|
||||||
|
static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
|
||||||
|
{
|
||||||
|
static gen_helper_gvec_4 * const fns[4] = {
|
||||||
|
gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
|
||||||
|
gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
|
||||||
|
};
|
||||||
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
|
unsigned vsz = vec_full_reg_size(s);
|
||||||
|
tcg_gen_gvec_4_ool(tcg_ctx, vec_full_reg_offset(s, rd),
|
||||||
|
vec_full_reg_offset(s, rn),
|
||||||
|
vec_full_reg_offset(s, rm),
|
||||||
|
pred_full_reg_offset(s, pg),
|
||||||
|
vsz, vsz, 0, fns[esz]);
|
||||||
|
}
|
||||||
|
|
||||||
#define DO_ZPZZ(NAME, name) \
|
#define DO_ZPZZ(NAME, name) \
|
||||||
static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a, \
|
static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a, \
|
||||||
uint32_t insn) \
|
uint32_t insn) \
|
||||||
|
@ -408,7 +426,13 @@ static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
|
||||||
return do_zpzz_ool(s, a, fns[a->esz]);
|
return do_zpzz_ool(s, a, fns[a->esz]);
|
||||||
}
|
}
|
||||||
|
|
||||||
DO_ZPZZ(SEL, sel)
|
static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
|
||||||
|
{
|
||||||
|
if (sve_access_check(s)) {
|
||||||
|
do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#undef DO_ZPZZ
|
#undef DO_ZPZZ
|
||||||
|
|
||||||
|
@ -5211,3 +5235,38 @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
|
||||||
sve_access_check(s);
|
sve_access_check(s);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move Prefix
|
||||||
|
*
|
||||||
|
* TODO: The implementation so far could handle predicated merging movprfx.
|
||||||
|
* The helper functions as written take an extra source register to
|
||||||
|
* use in the operation, but the result is only written when predication
|
||||||
|
* succeeds. For unpredicated movprfx, we need to rearrange the helpers
|
||||||
|
* to allow the final write back to the destination to be unconditional.
|
||||||
|
* For predicated zeroing movprfx, we need to rearrange the helpers to
|
||||||
|
* allow the final write back to zero inactives.
|
||||||
|
*
|
||||||
|
* In the meantime, just emit the moves.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)
|
||||||
|
{
|
||||||
|
return do_mov_z(s, a->rd, a->rn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
|
||||||
|
{
|
||||||
|
if (sve_access_check(s)) {
|
||||||
|
do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
|
||||||
|
{
|
||||||
|
if (sve_access_check(s)) {
|
||||||
|
do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue