aboutsummaryrefslogtreecommitdiff
path: root/target/loongarch/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/loongarch/translate.c')
-rw-r--r--target/loongarch/translate.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 21d8607..ae53f5e 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -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"
@@ -21,7 +23,6 @@
/* Global register indices */
TCGv cpu_gpr[32], cpu_pc;
static TCGv cpu_lladdr, cpu_llval;
-TCGv_i64 cpu_fpr[32];
#include "exec/gen-icount.h"
@@ -29,16 +30,43 @@ 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;
}
+static inline int shl_1(DisasContext *ctx, int x)
+{
+ return x << 1;
+}
+
static inline int shl_2(DisasContext *ctx, int x)
{
return x << 2;
}
+static inline int shl_3(DisasContext *ctx, int x)
+{
+ return x << 3;
+}
+
/*
* LoongArch the upper 32 bits are undefined ("can be any value").
* QEMU chooses to nanbox, because it is most likely to show guest bugs early.
@@ -71,6 +99,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 +114,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);
}
@@ -157,6 +190,20 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext)
}
}
+static TCGv get_fpr(DisasContext *ctx, int reg_num)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_ld_i64(t, cpu_env,
+ offsetof(CPULoongArchState, fpr[reg_num].vreg.D(0)));
+ return t;
+}
+
+static void set_fpr(int reg_num, TCGv val)
+{
+ tcg_gen_st_i64(val, cpu_env,
+ offsetof(CPULoongArchState, fpr[reg_num].vreg.D(0)));
+}
+
#include "decode-insns.c.inc"
#include "insn_trans/trans_arith.c.inc"
#include "insn_trans/trans_shift.c.inc"
@@ -171,6 +218,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend dst_ext)
#include "insn_trans/trans_fmemory.c.inc"
#include "insn_trans/trans_branch.c.inc"
#include "insn_trans/trans_privileged.c.inc"
+#include "insn_trans/trans_lsx.c.inc"
static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{
@@ -250,11 +298,6 @@ void loongarch_translate_init(void)
regnames[i]);
}
- for (i = 0; i < 32; i++) {
- int off = offsetof(CPULoongArchState, fpr[i]);
- cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
- }
-
cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPULoongArchState, pc), "pc");
cpu_lladdr = tcg_global_mem_new(cpu_env,
offsetof(CPULoongArchState, lladdr), "lladdr");