target/riscv: rvv-1.0: allow load element with sign-extended
For some vector instructions (e.g. vmv.s.x), the element is loaded with sign-extended. Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20211210075704.23951-35-frank.chang@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
f4f47e04de
commit
308ee80578
|
@ -2825,17 +2825,29 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
|
||||||
/* Integer Extract Instruction */
|
/* Integer Extract Instruction */
|
||||||
|
|
||||||
static void load_element(TCGv_i64 dest, TCGv_ptr base,
|
static void load_element(TCGv_i64 dest, TCGv_ptr base,
|
||||||
int ofs, int sew)
|
int ofs, int sew, bool sign)
|
||||||
{
|
{
|
||||||
switch (sew) {
|
switch (sew) {
|
||||||
case MO_8:
|
case MO_8:
|
||||||
tcg_gen_ld8u_i64(dest, base, ofs);
|
if (!sign) {
|
||||||
|
tcg_gen_ld8u_i64(dest, base, ofs);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ld8s_i64(dest, base, ofs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MO_16:
|
case MO_16:
|
||||||
tcg_gen_ld16u_i64(dest, base, ofs);
|
if (!sign) {
|
||||||
|
tcg_gen_ld16u_i64(dest, base, ofs);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ld16s_i64(dest, base, ofs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MO_32:
|
case MO_32:
|
||||||
tcg_gen_ld32u_i64(dest, base, ofs);
|
if (!sign) {
|
||||||
|
tcg_gen_ld32u_i64(dest, base, ofs);
|
||||||
|
} else {
|
||||||
|
tcg_gen_ld32s_i64(dest, base, ofs);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MO_64:
|
case MO_64:
|
||||||
tcg_gen_ld_i64(dest, base, ofs);
|
tcg_gen_ld_i64(dest, base, ofs);
|
||||||
|
@ -2890,7 +2902,7 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
|
||||||
|
|
||||||
/* Perform the load. */
|
/* Perform the load. */
|
||||||
load_element(dest, base,
|
load_element(dest, base,
|
||||||
vreg_ofs(s, vreg), s->sew);
|
vreg_ofs(s, vreg), s->sew, false);
|
||||||
tcg_temp_free_ptr(base);
|
tcg_temp_free_ptr(base);
|
||||||
tcg_temp_free_i32(ofs);
|
tcg_temp_free_i32(ofs);
|
||||||
|
|
||||||
|
@ -2906,9 +2918,9 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
|
static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
|
||||||
int vreg, int idx)
|
int vreg, int idx, bool sign)
|
||||||
{
|
{
|
||||||
load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew);
|
load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_vext_x_v(DisasContext *s, arg_r *a)
|
static bool trans_vext_x_v(DisasContext *s, arg_r *a)
|
||||||
|
@ -2918,7 +2930,7 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
|
||||||
|
|
||||||
if (a->rs1 == 0) {
|
if (a->rs1 == 0) {
|
||||||
/* Special case vmv.x.s rd, vs2. */
|
/* Special case vmv.x.s rd, vs2. */
|
||||||
vec_element_loadi(s, tmp, a->rs2, 0);
|
vec_element_loadi(s, tmp, a->rs2, 0, false);
|
||||||
} else {
|
} else {
|
||||||
/* This instruction ignores LMUL and vector register groups */
|
/* This instruction ignores LMUL and vector register groups */
|
||||||
int vlmax = s->vlen >> (3 + s->sew);
|
int vlmax = s->vlen >> (3 + s->sew);
|
||||||
|
@ -3000,7 +3012,7 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
|
||||||
(s->mstatus_fs != 0) && (s->sew != 0)) {
|
(s->mstatus_fs != 0) && (s->sew != 0)) {
|
||||||
unsigned int len = 8 << s->sew;
|
unsigned int len = 8 << s->sew;
|
||||||
|
|
||||||
vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0);
|
vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false);
|
||||||
if (len < 64) {
|
if (len < 64) {
|
||||||
tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
|
tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
|
||||||
MAKE_64BIT_MASK(len, 64 - len));
|
MAKE_64BIT_MASK(len, 64 - len));
|
||||||
|
@ -3102,7 +3114,7 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
|
||||||
TCGv_i64 dest = tcg_temp_new_i64();
|
TCGv_i64 dest = tcg_temp_new_i64();
|
||||||
|
|
||||||
if (a->rs1 == 0) {
|
if (a->rs1 == 0) {
|
||||||
vec_element_loadi(s, dest, a->rs2, 0);
|
vec_element_loadi(s, dest, a->rs2, 0, false);
|
||||||
} else {
|
} else {
|
||||||
vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
|
vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue