aboutsummaryrefslogtreecommitdiff
path: root/linux-user/loongarch64/cpu_loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user/loongarch64/cpu_loop.c')
-rw-r--r--linux-user/loongarch64/cpu_loop.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c
index 73d7b67..ec8a06c 100644
--- a/linux-user/loongarch64/cpu_loop.c
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -8,9 +8,15 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "user-internals.h"
-#include "cpu_loop-common.h"
+#include "user/cpu_loop.h"
#include "signal-common.h"
+/* Break codes */
+enum {
+ BRK_OVERFLOW = 6,
+ BRK_DIVZERO = 7
+};
+
void cpu_loop(CPULoongArchState *env)
{
CPUState *cs = env_cpu(env);
@@ -66,9 +72,26 @@ void cpu_loop(CPULoongArchState *env)
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
break;
case EXCP_DEBUG:
- case EXCCODE_BRK:
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
break;
+ case EXCCODE_BRK:
+ {
+ unsigned int opcode;
+
+ get_user_u32(opcode, env->pc);
+
+ switch (opcode & 0x7fff) {
+ case BRK_OVERFLOW:
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTOVF, env->pc);
+ break;
+ case BRK_DIVZERO:
+ force_sig_fault(TARGET_SIGFPE, TARGET_FPE_INTDIV, env->pc);
+ break;
+ default:
+ force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
+ }
+ }
+ break;
case EXCCODE_BCE:
force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
break;
@@ -97,7 +120,7 @@ void cpu_loop(CPULoongArchState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
+void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
{
int i;