target/loongarch: Implement vadd/vsub
This patch includes: - VADD.{B/H/W/D/Q}; - VSUB.{B/H/W/D/Q}. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Song Gao <gaosong@loongson.cn> Message-Id: <20230504122810.4094787-5-gaosong@loongson.cn>
This commit is contained in:
parent
a3f3db5cda
commit
57b4f1ac18
@ -784,3 +784,26 @@ PCADD_INSN(pcaddi)
|
||||
PCADD_INSN(pcalau12i)
|
||||
PCADD_INSN(pcaddu12i)
|
||||
PCADD_INSN(pcaddu18i)
|
||||
|
||||
#define INSN_LSX(insn, type) \
|
||||
static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
|
||||
{ \
|
||||
output_##type(ctx, a, #insn); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
static void output_vvv(DisasContext *ctx, arg_vvv *a, const char *mnemonic)
|
||||
{
|
||||
output(ctx, mnemonic, "v%d, v%d, v%d", a->vd, a->vj, a->vk);
|
||||
}
|
||||
|
||||
INSN_LSX(vadd_b, vvv)
|
||||
INSN_LSX(vadd_h, vvv)
|
||||
INSN_LSX(vadd_w, vvv)
|
||||
INSN_LSX(vadd_d, vvv)
|
||||
INSN_LSX(vadd_q, vvv)
|
||||
INSN_LSX(vsub_b, vvv)
|
||||
INSN_LSX(vsub_h, vvv)
|
||||
INSN_LSX(vsub_w, vvv)
|
||||
INSN_LSX(vsub_d, vvv)
|
||||
INSN_LSX(vsub_q, vvv)
|
||||
|
@ -14,3 +14,72 @@
|
||||
#else
|
||||
#define CHECK_SXE
|
||||
#endif
|
||||
|
||||
static bool gen_vvv(DisasContext *ctx, arg_vvv *a,
|
||||
void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32))
|
||||
{
|
||||
TCGv_i32 vd = tcg_constant_i32(a->vd);
|
||||
TCGv_i32 vj = tcg_constant_i32(a->vj);
|
||||
TCGv_i32 vk = tcg_constant_i32(a->vk);
|
||||
|
||||
CHECK_SXE;
|
||||
|
||||
func(cpu_env, vd, vj, vk);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
|
||||
void (*func)(unsigned, uint32_t, uint32_t,
|
||||
uint32_t, uint32_t, uint32_t))
|
||||
{
|
||||
uint32_t vd_ofs, vj_ofs, vk_ofs;
|
||||
|
||||
CHECK_SXE;
|
||||
|
||||
vd_ofs = vec_full_offset(a->vd);
|
||||
vj_ofs = vec_full_offset(a->vj);
|
||||
vk_ofs = vec_full_offset(a->vk);
|
||||
|
||||
func(mop, vd_ofs, vj_ofs, vk_ofs, 16, ctx->vl/8);
|
||||
return true;
|
||||
}
|
||||
|
||||
TRANS(vadd_b, gvec_vvv, MO_8, tcg_gen_gvec_add)
|
||||
TRANS(vadd_h, gvec_vvv, MO_16, tcg_gen_gvec_add)
|
||||
TRANS(vadd_w, gvec_vvv, MO_32, tcg_gen_gvec_add)
|
||||
TRANS(vadd_d, gvec_vvv, MO_64, tcg_gen_gvec_add)
|
||||
|
||||
#define VADDSUB_Q(NAME) \
|
||||
static bool trans_v## NAME ##_q(DisasContext *ctx, arg_vvv *a) \
|
||||
{ \
|
||||
TCGv_i64 rh, rl, ah, al, bh, bl; \
|
||||
\
|
||||
CHECK_SXE; \
|
||||
\
|
||||
rh = tcg_temp_new_i64(); \
|
||||
rl = tcg_temp_new_i64(); \
|
||||
ah = tcg_temp_new_i64(); \
|
||||
al = tcg_temp_new_i64(); \
|
||||
bh = tcg_temp_new_i64(); \
|
||||
bl = tcg_temp_new_i64(); \
|
||||
\
|
||||
get_vreg64(ah, a->vj, 1); \
|
||||
get_vreg64(al, a->vj, 0); \
|
||||
get_vreg64(bh, a->vk, 1); \
|
||||
get_vreg64(bl, a->vk, 0); \
|
||||
\
|
||||
tcg_gen_## NAME ##2_i64(rl, rh, al, ah, bl, bh); \
|
||||
\
|
||||
set_vreg64(rh, a->vd, 1); \
|
||||
set_vreg64(rl, a->vd, 0); \
|
||||
\
|
||||
return true; \
|
||||
}
|
||||
|
||||
VADDSUB_Q(add)
|
||||
VADDSUB_Q(sub)
|
||||
|
||||
TRANS(vsub_b, gvec_vvv, MO_8, tcg_gen_gvec_sub)
|
||||
TRANS(vsub_h, gvec_vvv, MO_16, tcg_gen_gvec_sub)
|
||||
TRANS(vsub_w, gvec_vvv, MO_32, tcg_gen_gvec_sub)
|
||||
TRANS(vsub_d, gvec_vvv, MO_64, tcg_gen_gvec_sub)
|
||||
|
@ -485,3 +485,25 @@ ldpte 0000 01100100 01 ........ ..... 00000 @j_i
|
||||
ertn 0000 01100100 10000 01110 00000 00000 @empty
|
||||
idle 0000 01100100 10001 ............... @i15
|
||||
dbcl 0000 00000010 10101 ............... @i15
|
||||
|
||||
#
|
||||
# LSX Argument sets
|
||||
#
|
||||
|
||||
&vvv vd vj vk
|
||||
|
||||
#
|
||||
# LSX Formats
|
||||
#
|
||||
@vvv .... ........ ..... vk:5 vj:5 vd:5 &vvv
|
||||
|
||||
vadd_b 0111 00000000 10100 ..... ..... ..... @vvv
|
||||
vadd_h 0111 00000000 10101 ..... ..... ..... @vvv
|
||||
vadd_w 0111 00000000 10110 ..... ..... ..... @vvv
|
||||
vadd_d 0111 00000000 10111 ..... ..... ..... @vvv
|
||||
vadd_q 0111 00010010 11010 ..... ..... ..... @vvv
|
||||
vsub_b 0111 00000000 11000 ..... ..... ..... @vvv
|
||||
vsub_h 0111 00000000 11001 ..... ..... ..... @vvv
|
||||
vsub_w 0111 00000000 11010 ..... ..... ..... @vvv
|
||||
vsub_d 0111 00000000 11011 ..... ..... ..... @vvv
|
||||
vsub_q 0111 00010010 11011 ..... ..... ..... @vvv
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "cpu.h"
|
||||
#include "tcg/tcg-op.h"
|
||||
#include "tcg/tcg-op-gvec.h"
|
||||
|
||||
#include "exec/translator.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "exec/helper-gen.h"
|
||||
@ -29,6 +31,23 @@ TCGv_i64 cpu_fpr[32];
|
||||
#define DISAS_EXIT DISAS_TARGET_1
|
||||
#define DISAS_EXIT_UPDATE DISAS_TARGET_2
|
||||
|
||||
static inline int vec_full_offset(int regno)
|
||||
{
|
||||
return offsetof(CPULoongArchState, fpr[regno]);
|
||||
}
|
||||
|
||||
static inline void get_vreg64(TCGv_i64 dest, int regno, int index)
|
||||
{
|
||||
tcg_gen_ld_i64(dest, cpu_env,
|
||||
offsetof(CPULoongArchState, fpr[regno].vreg.D(index)));
|
||||
}
|
||||
|
||||
static inline void set_vreg64(TCGv_i64 src, int regno, int index)
|
||||
{
|
||||
tcg_gen_st_i64(src, cpu_env,
|
||||
offsetof(CPULoongArchState, fpr[regno].vreg.D(index)));
|
||||
}
|
||||
|
||||
static inline int plus_1(DisasContext *ctx, int x)
|
||||
{
|
||||
return x + 1;
|
||||
@ -71,6 +90,7 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
|
||||
CPUState *cs)
|
||||
{
|
||||
int64_t bound;
|
||||
CPULoongArchState *env = cs->env_ptr;
|
||||
DisasContext *ctx = container_of(dcbase, DisasContext, base);
|
||||
|
||||
ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
|
||||
@ -85,6 +105,10 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
|
||||
bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
|
||||
ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
|
||||
|
||||
if (FIELD_EX64(env->cpucfg[2], CPUCFG2, LSX)) {
|
||||
ctx->vl = LSX_LEN;
|
||||
}
|
||||
|
||||
ctx->zero = tcg_constant_tl(0);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,7 @@ typedef struct DisasContext {
|
||||
uint32_t opcode;
|
||||
uint16_t mem_idx;
|
||||
uint16_t plv;
|
||||
int vl; /* Vector length */
|
||||
TCGv zero;
|
||||
} DisasContext;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user