diff options
author | jake <jake@FreeBSD.org> | 2002-04-27 21:56:28 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2002-04-27 21:56:28 +0000 |
commit | a1a94cce5c09be6d56eb4c83034f03ab93077bbe (patch) | |
tree | ef5f4b8e186ab8b15487aae5d54638610a6e672b /lib/libc/sparc64/sys/__sparc_utrap.c | |
parent | 60ee831d3e0478dd494c5dd9b27f019f1700ea71 (diff) | |
download | FreeBSD-src-a1a94cce5c09be6d56eb4c83034f03ab93077bbe.zip FreeBSD-src-a1a94cce5c09be6d56eb4c83034f03ab93077bbe.tar.gz |
Emulate ldq and stq (load/store long double) instructions. GCC has started
using these to load long doubles, but they aren't implemented in hardware
on (at least) UltraSPARC I and II machines.
Emulate popc in the user trap handler as well.
Re-arrange slightly to make support functions more accessible.
Reviewed by: tmm
Diffstat (limited to 'lib/libc/sparc64/sys/__sparc_utrap.c')
-rw-r--r-- | lib/libc/sparc64/sys/__sparc_utrap.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/lib/libc/sparc64/sys/__sparc_utrap.c b/lib/libc/sparc64/sys/__sparc_utrap.c index f56c019..d51d89a 100644 --- a/lib/libc/sparc64/sys/__sparc_utrap.c +++ b/lib/libc/sparc64/sys/__sparc_utrap.c @@ -32,8 +32,11 @@ __FBSDID("$FreeBSD$"); #include <machine/utrap.h> #include <machine/sysarch.h> +#include <errno.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include "__sparc_utrap_private.h" @@ -77,23 +80,55 @@ static const char *utrap_msg[] = { void __sparc_utrap(struct utrapframe *uf) { + int sig; switch (uf->uf_type) { case UT_FP_EXCEPTION_IEEE_754: case UT_FP_EXCEPTION_OTHER: - __fpu_exception(uf); - UF_DONE(uf); - return; + sig = __fpu_exception(uf); + break; case UT_ILLEGAL_INSTRUCTION: + sig = __emul_insn(uf); + break; case UT_MEM_ADDRESS_NOT_ALIGNED: break; - case UT_TRAP_INSTRUCTION_16: - UF_DONE(uf); - return; default: break; } - printf("__sparc_utrap: type=%s pc=%#lx npc=%#lx\n", - utrap_msg[uf->uf_type], uf->uf_pc, uf->uf_npc); - abort(); + if (sig) { + __utrap_write("__sparc_utrap: fatal "); + __utrap_write(utrap_msg[uf->uf_type]); + __utrap_write("\n"); + __utrap_kill_self(sig); + } + UF_DONE(uf); +} + +void +__utrap_write(const char *str) +{ + int berrno; + + berrno = errno; + __sys_write(STDERR_FILENO, str, strlen(str)); + errno = berrno; +} + +void +__utrap_kill_self(sig) +{ + int berrno; + + berrno = errno; + __sys_kill(__sys_getpid(), sig); + errno = berrno; +} + +void +__utrap_panic(const char *msg) +{ + + __utrap_write(msg); + __utrap_write("\n"); + __utrap_kill_self(SIGKILL); } |