From: Thiemo S. <th...@us...> - 2005-09-12 12:06:12
|
Update of /cvsroot/sbcl/sbcl/src/runtime In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9254/src/runtime Modified Files: mips-arch.c mips-linux-os.c Log Message: 0.9.4.64: Handle also for branch delay slot of newer mips instructions, reduce copy&pasteage, remove SIGILL handler which was only good for debugging. Index: mips-arch.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/mips-arch.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- mips-arch.c 7 Sep 2005 23:03:17 -0000 1.14 +++ mips-arch.c 12 Sep 2005 12:05:49 -0000 1.15 @@ -23,6 +23,8 @@ #include "genesis/constants.h" +#define INSN_LEN 4 + void arch_init() { @@ -54,11 +56,63 @@ os_context_insn(os_context_t *context) { if (os_context_bd_cause(context)) - return *(unsigned int *)(os_context_pc(context) + 4); + return *(unsigned int *)(os_context_pc(context) + INSN_LEN); else return *(unsigned int *)(os_context_pc(context)); } +boolean +arch_insn_with_bdelay_p(unsigned int insn) +{ + switch (insn >> 26) { + case 0x0: + switch (insn & 0x3f) { + /* register jumps */ + case 0x08: + case 0x09: + return 1; + } + break; + /* branches and immediate jumps */ + case 0x1: + switch ((insn >> 16) & 0x1f) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + return 1; + } + break; + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + return 1; + case 0x10: + case 0x11: + case 0x12: + switch ((insn >> 21) & 0x1f) { + /* CP0/CP1/CP2 branches */ + case 0x08: + return 1; + } + break; + /* branch likely (MIPS II) */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + return 1; + } + return 0; +} + /* This function is somewhat misnamed, it actually just jumps to the correct target address without attempting to execute the delay slot. For other instructions it just increments the returned PC value. */ @@ -82,10 +136,10 @@ case 0x09: /* jalr */ tgt = os_context_register(context, r1); *os_context_register_addr(context, r3) - = os_context_pc(context) + 4; + = os_context_pc(context) + INSN_LEN; break; default: - tgt += 4; + tgt += INSN_LEN; break; } break; @@ -103,13 +157,13 @@ if(os_context_register(context, r1) < 0) tgt += disp; *os_context_register_addr(context, 31) - = os_context_pc(context) + 4; + = os_context_pc(context) + INSN_LEN; break; case 0x11: /* bgezal */ if(os_context_register(context, r1) >= 0) tgt += disp; *os_context_register_addr(context, 31) - = os_context_pc(context) + 4; + = os_context_pc(context) + INSN_LEN; break; default: /* conditional branches/traps for > MIPS I, ignore for now. */ break; @@ -141,7 +195,7 @@ case 0x3: /* jal */ tgt = jtgt; *os_context_register_addr(context, 31) - = os_context_pc(context) + 4; + = os_context_pc(context) + INSN_LEN; break; default: tgt += 4; @@ -156,18 +210,18 @@ /* Skip the offending instruction. Don't use os_context_insn here, since in case of a branch we want the branch insn, not the delay slot. */ - *os_context_pc_addr(context) - = emulate_branch(context, - *(unsigned int *)(os_context_pc(context))); + *os_context_pc_addr(context) + = emulate_branch(context, + *(unsigned int *)(os_context_pc(context))); } unsigned char * arch_internal_error_arguments(os_context_t *context) { if (os_context_bd_cause(context)) - return (unsigned char *)(os_context_pc(context) + 8); + return (unsigned char *)(os_context_pc(context) + (INSN_LEN * 2)); else - return (unsigned char *)(os_context_pc(context) + 4); + return (unsigned char *)(os_context_pc(context) + INSN_LEN); } boolean @@ -186,31 +240,16 @@ arch_install_breakpoint(void *pc) { unsigned int *ptr = (unsigned int *)pc; + unsigned int insn = *ptr; unsigned long result; - /* Don't install over a branch/jump. */ - switch (*ptr >> 26) { - case 0x0: /* immediate jumps */ - switch (*ptr & 0x3f) { - case 0x08: - case 0x09: + /* Don't install over a branch/jump with delay slot. */ + if (arch_insn_with_bdelay_p(insn)) ptr++; - } - break; - /* branches and register jumps */ - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - ptr++; - } - result = (unsigned long) *ptr; + result = (unsigned long)insn; *ptr = (trap_Breakpoint << 16) | 0xd; - os_flush_icache((os_vm_address_t)ptr, sizeof(unsigned int)); + os_flush_icache((os_vm_address_t)ptr, INSN_LEN); return result; } @@ -221,7 +260,7 @@ unsigned int *ptr = (unsigned int *)pc; *ptr = (unsigned int) orig_inst; - os_flush_icache((os_vm_address_t)ptr, sizeof(unsigned int)); + os_flush_icache((os_vm_address_t)ptr, INSN_LEN); } static unsigned int *skipped_break_addr, displaced_after_inst; @@ -257,15 +296,6 @@ } static void -sigill_handler(int signal, siginfo_t *info, void *void_context) -{ - os_context_t *context = arch_os_get_context(&void_context); - - fake_foreign_function_call(context); - monitor_or_something(); -} - -static void sigtrap_handler(int signal, siginfo_t *info, void *void_context) { os_context_t *context = arch_os_get_context(&void_context); @@ -379,7 +409,6 @@ void arch_install_interrupt_handlers() { - undoably_install_low_level_interrupt_handler(SIGILL,sigill_handler); undoably_install_low_level_interrupt_handler(SIGTRAP,sigtrap_handler); undoably_install_low_level_interrupt_handler(SIGFPE,sigfpe_handler); } Index: mips-linux-os.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/mips-linux-os.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- mips-linux-os.c 7 Sep 2005 22:53:19 -0000 1.9 +++ mips-linux-os.c 12 Sep 2005 12:05:49 -0000 1.10 @@ -15,24 +15,7 @@ */ #include <stdio.h> -#include <sys/param.h> -#include <sys/file.h> -#include "sbcl.h" -#include "./signal.h" -#include "os.h" -#include "arch.h" -#include "globals.h" -#include "interrupt.h" -#include "interr.h" -#include "lispregs.h" -#include <sys/socket.h> -#include <sys/utsname.h> - -#include <sys/types.h> #include <signal.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <unistd.h> /* for cacheflush() */ #include <sys/cachectl.h> @@ -40,7 +23,9 @@ /* for BD_CAUSE */ #include <asm/mipsregs.h> -#include "validate.h" +#include "sbcl.h" +#include "os.h" +#include "arch.h" size_t os_vm_page_size; @@ -119,26 +104,15 @@ os_context_bd_cause is also used to find out if a branch emulation is needed. We work around that by checking if the current instruction is a jump or a branch. */ - unsigned int inst = *((unsigned int *)(unsigned int)(*os_context_pc_addr(context))); + extern boolean arch_insn_with_bdelay_p(unsigned int insn); - switch (inst >> 26) { - case 0x0: /* immediate jumps */ - switch (inst & 0x3f) { - case 0x08: - case 0x09: - return CAUSEF_BD; - } - break; - /* branches and register jumps */ - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: + os_vm_address_t addr + = (os_vm_address_t)(unsigned int)*os_context_pc_addr(context); + unsigned int insn = *(unsigned int *)addr; + + if (arch_insn_with_bdelay_p(insn)) return CAUSEF_BD; - } + return 0; } |