mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 09:13:55 -06:00
linux-user/loongarch64: Decode BRK break codes for FPE signals
Handle specific LoongArch BRK break codes in user-mode emulation to deliver accurate floating-point exception signals. Specifically, BRK_OVERFLOW (6) triggers TARGET_FPE_INTOVF, and BRK_DIVZERO (7) triggers TARGET_FPE_INTDIV. Other BRK codes fall back to a generic SIGTRAP. This improves correctness for programs that rely on BRK to signal overflow or divide-by-zero conditions. Signed-off-by: WANG Rui <wangrui@loongson.cn> Acked-by: Song Gao <gaosong@loongson.cn> Message-Id: <20250414074952.6253-1-wangrui@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>
This commit is contained in:
parent
0d4c2e408d
commit
a9d3d1dff6
1 changed files with 24 additions and 1 deletions
|
@ -11,6 +11,12 @@
|
||||||
#include "user/cpu_loop.h"
|
#include "user/cpu_loop.h"
|
||||||
#include "signal-common.h"
|
#include "signal-common.h"
|
||||||
|
|
||||||
|
/* Break codes */
|
||||||
|
enum {
|
||||||
|
BRK_OVERFLOW = 6,
|
||||||
|
BRK_DIVZERO = 7
|
||||||
|
};
|
||||||
|
|
||||||
void cpu_loop(CPULoongArchState *env)
|
void cpu_loop(CPULoongArchState *env)
|
||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
|
@ -66,9 +72,26 @@ void cpu_loop(CPULoongArchState *env)
|
||||||
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
|
force_sig_fault(TARGET_SIGFPE, si_code, env->pc);
|
||||||
break;
|
break;
|
||||||
case EXCP_DEBUG:
|
case EXCP_DEBUG:
|
||||||
case EXCCODE_BRK:
|
|
||||||
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
force_sig_fault(TARGET_SIGTRAP, TARGET_TRAP_BRKPT, env->pc);
|
||||||
break;
|
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:
|
case EXCCODE_BCE:
|
||||||
force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
|
force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue