aboutsummaryrefslogtreecommitdiff
path: root/target/loongarch/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/loongarch/cpu.c')
-rw-r--r--target/loongarch/cpu.c10
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