From e669e995072212c8916f2eec04ba499c956ad542 Mon Sep 17 00:00:00 2001 From: ch <ch> Date: Sat, 26 May 1990 01:23:30 +0000 Subject: [PATCH] Added the SIGFPE handler for handling FIXNUM overflows. This took some frobbing to make it work. Also moved the SIGSEGV handler (which isn't currently used) into this file. --- ldb/test.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/ldb/test.c b/ldb/test.c index 4edb0590c..08e0b3368 100644 --- a/ldb/test.c +++ b/ldb/test.c @@ -1,4 +1,4 @@ -/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/test.c,v 1.4 1990/05/24 17:46:28 wlott Exp $ */ +/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/test.c,v 1.5 1990/05/26 01:23:30 ch Exp $ */ /* Extra random routines for testing stuff. */ #include <signal.h> @@ -74,6 +74,95 @@ struct sigcontext *context; sigsetmask(mask); } + + +#define FIXNUM_VALUE(lispobj) (((int)lispobj)>>2) + +static sigfpe_handler(signal, code, context) +int signal, code; +struct sigcontext *context; +{ + unsigned long bad_inst; + unsigned int op, rs, rt, rd, funct, dest; + int immed; + long result; + + if (context->sc_cause & CAUSE_BD) + bad_inst = *(unsigned long *)(context->sc_pc + 4); + else + bad_inst = *(unsigned long *)(context->sc_pc); + + op = (bad_inst >> 26) & 0x3f; + rs = (bad_inst >> 21) & 0x1f; + rt = (bad_inst >> 16) & 0x1f; + rd = (bad_inst >> 11) & 0x1f; + funct = bad_inst & 0x3f; + immed = (((int)(bad_inst & 0xffff)) << 16) >> 16; + + switch (op) { + case 0x0: /* SPECIAL */ + switch (funct) { + case 0x20: /* ADD */ + result = FIXNUM_VALUE(context->sc_regs[rs]) + FIXNUM_VALUE(context->sc_regs[rt]); + dest = rd; + break; + + case 0x22: /* SUB */ + result = FIXNUM_VALUE(context->sc_regs[rs]) - FIXNUM_VALUE(context->sc_regs[rt]); + dest = rd; + break; + + default: + signal_handler(signal, code, context); + return; + } + break; + + case 0x8: /* ADDI */ + result = FIXNUM_VALUE(context->sc_regs[rs]) + (immed>>2); + dest = rt; + break; + + default: + signal_handler(signal, code, context); + return; + } + + context->sc_regs[dest] = alloc_number(result); + + /* Skip the offending instruction */ + if (context->sc_cause & CAUSE_BD) + emulate_branch(context, *(unsigned long *)context->sc_pc); + else + context->sc_pc += 4; +} + + + +static sigsegv_handler(signal, code, context) +int signal, code; +struct sigcontext *context; +{ +#if 0 + if (bogus_page == guard_page) { + unprotext(guard_page); + if ((!foreign_function_call_active) && + (context->sc_regs[FLAGS] & (1<<flag_Atomic))) { + pending_signal = signal; + pending_code = code; + pending_mask = context->sc_mask; + context->sc_mask |= BLOCKABLE; + context->sc_regs[FLAGS] |= (1<<flag_Interrupted); + } + /* ### Fix this */ + SetSymbolValue(GC_TRIGGER_HIT, T); + } + else +#endif +} + + + test_init() { extern int throw_to_top(), throw_to_monitor(); @@ -81,7 +170,7 @@ test_init() install_handler(SIGINT, signal_handler); install_handler(SIGQUIT, throw_to_top); install_handler(SIGTRAP, signal_handler); - install_handler(SIGFPE, signal_handler); + install_handler(SIGFPE, sigfpe_handler); } -- GitLab