diff options
Diffstat (limited to 'target/loongarch/cpu.c')
-rw-r--r-- | target/loongarch/cpu.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index 49393d95d8..46b04cbdad 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c @@ -48,6 +48,7 @@ static const char * const excp_names[] = { [EXCCODE_BRK] = "Break", [EXCCODE_INE] = "Instruction Non-Existent", [EXCCODE_IPE] = "Instruction privilege error", + [EXCCODE_FPD] = "Floating Point Disabled", [EXCCODE_FPE] = "Floating Point Exception", [EXCCODE_DBP] = "Debug breakpoint", [EXCCODE_BCE] = "Bound Check Exception", @@ -177,6 +178,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) } QEMU_FALLTHROUGH; case EXCCODE_PIF: + case EXCCODE_ADEF: cause = cs->exception_index; update_badinstr = 0; break; @@ -184,6 +186,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) case EXCCODE_BRK: case EXCCODE_INE: case EXCCODE_IPE: + case EXCCODE_FPD: case EXCCODE_FPE: case EXCCODE_BCE: env->CSR_BADV = env->pc; @@ -220,7 +223,10 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->CSR_TLBRERA = FIELD_DP64(env->CSR_TLBRERA, CSR_TLBRERA, PC, (env->pc >> 2)); } else { - env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, cause); + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ECODE, + EXCODE_MCODE(cause)); + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, ESUBCODE, + EXCODE_SUBCODE(cause)); env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PPLV, FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PLV)); env->CSR_PRMD = FIELD_DP64(env->CSR_PRMD, CSR_PRMD, PIE, @@ -257,7 +263,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs) env->pc = env->CSR_TLBRENTRY; } else { env->pc = env->CSR_EENTRY; - env->pc += cause * vec_size; + env->pc += EXCODE_MCODE(cause) * vec_size; } qemu_log_mask(CPU_LOG_INT, "%s: PC " TARGET_FMT_lx " ERA " TARGET_FMT_lx |