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 <gaos...@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(+) diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 2bea7ca5d5..32dd1b624b 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -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; } diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h index 40e70a8119..7a94963e5f 100644 --- a/target/loongarch/cpu.h +++ b/target/loongarch/cpu.h @@ -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; diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h index c492863cc5..01d98ac2fc 100644 --- a/target/loongarch/internals.h +++ b/target/loongarch/internals.h @@ -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); diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c index 21f4db6fbd..9b82295542 100644 --- a/target/loongarch/translate.c +++ b/target/loongarch/translate.c @@ -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) { diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h index 195f53573a..3bf1a1df86 100644 --- a/target/loongarch/translate.h +++ b/target/loongarch/translate.h @@ -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; -- 2.25.1