1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * QEMU LoongArch user cpu_loop.
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
8 #include "qemu/osdep.h"
10 #include "user-internals.h"
11 #include "cpu_loop-common.h"
12 #include "signal-common.h"
14 void cpu_loop(CPULoongArchState
*env
)
16 CPUState
*cs
= env_cpu(env
);
22 trapnr
= cpu_exec(cs
);
24 process_queued_cpu_work(cs
);
28 /* just indicate that signals should be handled asap */
32 ret
= do_syscall(env
, env
->gpr
[11],
33 env
->gpr
[4], env
->gpr
[5],
34 env
->gpr
[6], env
->gpr
[7],
35 env
->gpr
[8], env
->gpr
[9],
37 if (ret
== -QEMU_ERESTARTSYS
) {
41 if (ret
== -QEMU_ESIGRETURN
) {
43 * Returning from a successful sigreturn syscall.
44 * Avoid clobbering register state.
51 force_sig_fault(TARGET_SIGILL
, 0, env
->pc
);
54 si_code
= TARGET_FPE_FLTUNK
;
55 if (GET_FP_CAUSE(env
->fcsr0
) & FP_INVALID
) {
56 si_code
= TARGET_FPE_FLTINV
;
57 } else if (GET_FP_CAUSE(env
->fcsr0
) & FP_DIV0
) {
58 si_code
= TARGET_FPE_FLTDIV
;
59 } else if (GET_FP_CAUSE(env
->fcsr0
) & FP_OVERFLOW
) {
60 si_code
= TARGET_FPE_FLTOVF
;
61 } else if (GET_FP_CAUSE(env
->fcsr0
) & FP_UNDERFLOW
) {
62 si_code
= TARGET_FPE_FLTUND
;
63 } else if (GET_FP_CAUSE(env
->fcsr0
) & FP_INEXACT
) {
64 si_code
= TARGET_FPE_FLTRES
;
66 force_sig_fault(TARGET_SIGFPE
, si_code
, env
->pc
);
70 force_sig_fault(TARGET_SIGTRAP
, TARGET_TRAP_BRKPT
, env
->pc
);
73 force_sig_fault(TARGET_SIGSYS
, TARGET_SI_KERNEL
, env
->pc
);
76 cpu_exec_step_atomic(cs
);
79 EXCP_DUMP(env
, "qemu: unhandled CPU exception 0x%x - aborting\n",
83 process_pending_signals(env
);
87 void target_cpu_copy_regs(CPUArchState
*env
, struct target_pt_regs
*regs
)
91 for (i
= 0; i
< 32; i
++) {
92 env
->gpr
[i
] = regs
->regs
[i
];
94 env
->pc
= regs
->csr
.era
;