@@ -546,6 +546,8 @@ static void loongarch_cpu_reset_hold(Object *obj)
memset(env->tlb, 0, sizeof(env->tlb));
#endif
+ env->extctx_flags = EXTCTX_FLAGS_FPU;
+
restore_fp_status(env);
cs->exception_index = -1;
}
@@ -295,6 +295,8 @@ typedef struct CPUArchState {
uint64_t lladdr; /* LL virtual address compared against SC */
uint64_t llval;
+ uint64_t extctx_flags; /* Use for user-mode setup extcontext */
+
/* LoongArch CSRs */
uint64_t CSR_CRMD;
uint64_t CSR_PRMD;
@@ -21,6 +21,8 @@
/* Global bit for huge page */
#define LOONGARCH_HGLOBAL_SHIFT 12
+#define EXTCTX_FLAGS_FPU 0b01
+
void loongarch_translate_init(void);
void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
@@ -147,6 +147,8 @@ static void loongarch_tr_init_disas_context(DisasContextBase *dcbase,
ctx->cpucfg1 = env->cpucfg[1];
ctx->cpucfg2 = env->cpucfg[2];
+
+ ctx->extctx_flags = env->extctx_flags;
}
static void loongarch_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
@@ -294,6 +296,7 @@ static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
generate_exception(ctx, EXCCODE_INE);
}
+ env->extctx_flags |= ctx->extctx_flags;
ctx->base.pc_next += 4;
if (ctx->va32) {
@@ -40,6 +40,7 @@ typedef enum {
typedef struct DisasContext {
DisasContextBase base;
target_ulong page_start;
+ uint64_t extctx_flags;
uint32_t opcode;
uint16_t mem_idx;
uint16_t plv;
extctx_flags only for user-mode, and the default value is EXTCTX_FLAGS_FPU, We only need save/restore fpu context, After a LSX or LASX instruction is execed, the value change to EXTCTX_FLAGS_LSX/LASX, and we need save/restore lsx/lasx context. So if the binary no LSX/LASX instruction We only need save/restore fpu context. Signed-off-by: Song Gao <gaosong@loongson.cn> --- target/loongarch/cpu.c | 2 ++ target/loongarch/cpu.h | 2 ++ target/loongarch/internals.h | 2 ++ target/loongarch/translate.c | 3 +++ target/loongarch/translate.h | 1 + 5 files changed, 10 insertions(+)