diff options
author | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
---|---|---|
committer | Ranjith Kumaran <ranjith@cygnus.com> | 2000-03-17 22:48:54 +0000 |
commit | 03261851a10dd2d6900a0a00a7515a0a46fb5d76 (patch) | |
tree | 7c22ac6cbbc99fd5cd1b5426853be8d4fd7bfcf1 /libgloss/m68k/mvme162lx-asm.S | |
parent | fae4c299f14fc23e2829c8656992eba21f79242a (diff) | |
download | cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.gz cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.tar.bz2 cygnal-03261851a10dd2d6900a0a00a7515a0a46fb5d76.zip |
20000317 sourceware import
Diffstat (limited to 'libgloss/m68k/mvme162lx-asm.S')
-rw-r--r-- | libgloss/m68k/mvme162lx-asm.S | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/libgloss/m68k/mvme162lx-asm.S b/libgloss/m68k/mvme162lx-asm.S new file mode 100644 index 000000000..8b83621d6 --- /dev/null +++ b/libgloss/m68k/mvme162lx-asm.S @@ -0,0 +1,292 @@ +/* + * mvme162lx-asm.S -- assembler routines for the MVME stub. + * + * This code was pulled out of mvme162lx-stub.c by Ian Taylor so that I + * could handle different register and label prefixes in a sensible + * way. + */ + +/**************************************************************************** + + THIS SOFTWARE IS NOT COPYRIGHTED + + HP offers the following for use in the public domain. HP makes no + warranty with regard to the software or it's performance and the + user accepts the software "AS IS" with all faults. + + HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD + TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +****************************************************************************/ + +#include "asm.h" + + .title "mvme162lx-asm.S for m68k" + + .globl SYM (registers) + .globl SYM (lastFrame) + .globl SYM (superStack) + .globl SYM (exceptionHook) + .globl SYM (_returnFromException) + .globl SYM (stackPtr) + .globl SYM (handle_exception) + .globl SYM (exceptionSize) + +.text +.globl SYM (return_to_super) +SYM (return_to_super): + movel SYM (registers)+60,sp /* get new stack pointer */ + movel SYM (lastFrame),a0 /* get last frame info */ + bra return_to_any + +.globl SYM (return_to_user) +SYM (return_to_user): + movel SYM (registers)+60,a0 /* get usp */ + movel a0,usp /* set usp */ + movel SYM (superStack),sp /* get original stack pointer */ + +return_to_any: + movel SYM (lastFrame),a0 /* get last frame info */ + movel a0@+,SYM (lastFrame) /* link in previous frame */ + addql IMM (8),a0 /* skip over pc, vector#*/ + movew a0@+,d0 /* get # of words in cpu frame */ + addw d0,a0 /* point to end of data */ + addw d0,a0 /* point to end of data */ + movel a0,a1 +/* copy the stack frame */ + subql IMM (1),d0 +copyUserLoop: + movew a1@-,sp@- + dbf d0,copyUserLoop + +#ifdef __HAVE_68881__ + fmoveml SYM (registers)+168,fpcr/fpsr/fpi + fmovemx SYM (registers)+72,fp0-fp7 + cmpl IMM (-1),a0@ /* skip frestore flag set ? */ + beq skip_frestore + frestore a0@+ +skip_frestore: +#endif + + moveml SYM (registers),d0-d7/a0-a6 + rte /* pop and go! */ + + +/* this function is called immediately when a level 7 interrupt occurs */ +/* if the previous interrupt level was 7 then we're already servicing */ +/* this interrupt and an rte is in order to return to the debugger. */ +/* For the 68000, the offset for sr is 6 due to the jsr return address */ +.text +.globl SYM (_debug_level7) +SYM (_debug_level7): + movew d0,sp@- +#ifdef mc68020 + movew sp@(2),d0 +#else + movew sp@(6),d0 +#endif + andiw IMM (0x700),d0 + cmpiw IMM (0x700),d0 + beq _already7 + movew sp@+,d0 + bra SYM (_catchException) +_already7: + movew sp@+,d0 +#ifndef mc68020 + lea sp@(4),sp /* pull off 68000 return address */ +#endif + rte + +#ifdef mc68020 +/* This function is called when a 68020 exception occurs. It saves + * all the cpu and fpcp regs in the _registers array, creates a frame on a + * linked list of frames which has the cpu and fpcp stack frames needed + * to properly restore the context of these processors, and invokes + * an exception handler (remcom_handler). + * + * stack on entry: stack on exit: + * N bytes of junk exception # MSWord + * Exception Format Word exception # MSWord + * Program counter LSWord + * Program counter MSWord + * Status Register + * + * + */ + +.text +.globl SYM (_catchException) +SYM (_catchException): + + oriw IMM (0x0700),sr /* Disable interrupts */ + + moveml d0-d7/a0-a6,SYM (registers) /* save registers */ + movel SYM (lastFrame),a0 /* last frame pointer */ + +#ifdef __HAVE_68881__ + /* do an fsave, then remember the address to begin a restore from */ + fsave a0@- + fmovemx fp0-fp7, SYM (registers)+72 + fmoveml fpcr/fpsr/fpi, SYM (registers)+168 +#endif + + lea SYM (registers),a5 /* get address of registers */ + movew sp@,d1 /* get status register */ + movew d1,a5@(66) /* save sr */ + movel sp@(2),a4 /* save pc in a4 for later use */ + movel a4,a5@(68) /* save pc in _regisers[] */ + +/* figure out how many bytes in the stack frame */ + movew sp@(6),d0 /* get '020 exception format */ + movew d0,d2 /* make a copy of format word */ + andiw IMM (0xf000),d0 /* mask off format type */ + rolw IMM (5),d0 /* rotate into the low byte *2 */ + lea SYM (exceptionSize),a1 + addw d0,a1 /* index into the table */ + movew a1@,d0 /* get number of words in frame */ + movew d0,d3 /* save it */ + subw d0,a0 /* adjust save pointer */ + subw d0,a0 /* adjust save pointer(bytes) */ + movel a0,a1 /* copy save pointer */ + subql IMM (1),d0 /* predecrement loop counter */ + +/* copy the frame */ + +saveFrameLoop: + movew sp@+,a1@+ + dbf d0,saveFrameLoop + +/* now that the stack has been clenaed, + * save the a7 in use at time of exception + */ + movel sp,SYM (superStack) /* save supervisor sp */ + andiw IMM (0x2000),d1 /* were we in supervisor mode ? */ + beq userMode + movel a7,a5@(60) /* save a7 */ + bra a7saveDone +userMode: + movel usp,a1 + movel a1,a5@(60) /* save user stack pointer */ +a7saveDone: + + +/* save size of frame */ + movew d3,a0@- + +/* compute exception number */ + andl IMM (0xfff),d2 /* mask off vector offset */ + lsrw IMM (2),d2 /* divide by 4 to get vect num */ + movel d2,a0@- /* save it */ + +/* save pc causing exception */ + movel a4,a0@- + +/* save old frame link and set the new value*/ + movel SYM (lastFrame),a1 /* last frame pointer */ + movel a1,a0@- /* save pointer to prev frame */ + movel a0,SYM (lastFrame) + + movel d2,sp@- /* push exception num */ +#ifdef TMP_HACK + movel SYM (exceptionHook),a0 /* get address of handler */ + jbsr a0@ /* and call it */ +#else + jbsr SYM (remcomHandler) +#endif + clrl sp@ /* replace exception num parm with frame ptr */ + jbsr SYM (_returnFromException) /* jbsr, but never returns */ + +#else /* mc68000 */ + +/* This function is called when an exception occurs. It translates the + * return address found on the stack into an exception vector # which + * is then handled by either handle_exception or a system handler. + * _catchException provides a front end for both. + * + * stack on entry: stack on exit: + * Program counter MSWord exception # MSWord + * Program counter LSWord exception # MSWord + * Status Register + * Return Address MSWord + * Return Address LSWord + */ +.text +.globl SYM (_catchException) +SYM (_catchException): + + oriw IMM (0x0700),sr /* Disable interrupts */ + + moveml d0-d7/a0-a6,SYM (registers) /* save registers */ + movel SYM (lastFrame),a0 /* last frame pointer */ + +#ifdef __HAVE_68881__ + /* do an fsave, then remember the address to begin a restore from */ + fsave a0@- + fmovemx fp0-fp7, SYM (registers)+72 + fmoveml fpcr/fpsr/fpi, SYM (registers)+168 +#endif + + lea SYM (registers),a5 /* get address of registers */ + movel sp@+,d2 /* pop return address */ + addl IMM (1530),d2 /* convert return addr to */ + divs IMM (6),d2 /* exception number */ + extl d2 + + moveql IMM (3),d3 /* assume a three word frame */ + + cmpiw IMM (3),d2 /* bus error or address error ? */ + bgt normal /* if >3 then normal error */ + movel sp@+,a0@- /* copy error info to frame buff*/ + movel sp@+,a0@- /* these are never used */ + moveql IMM (7),d3 /* this is a 7 word frame */ + +normal: + movew sp@+,d1 /* pop status register */ + movel sp@+,a4 /* pop program counter */ + movew d1,a5@(66) /* save sr */ + movel a4,a5@(68) /* save pc in _regisers[] */ + movel a4,a0@- /* copy pc to frame buffer */ + movew d1,a0@- /* copy sr to frame buffer */ + + movel sp,SYM (superStack) /* save supervisor sp */ + + andiw IMM (0x2000),d1 /* were we in supervisor mode ? */ + beq userMode + movel a7,a5@(60) /* save a7 */ + bra saveDone +userMode: + movel usp,a1 /* save user stack pointer */ + movel a1,a5@(60) /* save user stack pointer */ +saveDone: + + movew d3,a0@- /* push frame size in words */ + movel d2,a0@- /* push vector number */ + movel a4,a0@- /* push exception pc */ + +/* save old frame link and set the new value */ + movel SYM (lastFrame),a1 /* last frame pointer */ + movel a1,a0@- /* save pointer to prev frame */ + movel a0,SYM (lastFrame) + + movel d2,sp@- /* push exception num */ + movel SYM (exceptionHook),a0 /* get address of handler */ + jbsr a0@ /* and call it */ + clrl sp@ /* replace exception num parm with frame ptr */ + jbsr SYM (_returnFromException) /* jbsr, but never returns */ + +#endif /* m68000 */ + +/* + * remcomHandler is a front end for handle_exception. It moves the + * stack pointer into an area reserved for debugger use in case the + * breakpoint happened in supervisor mode. + */ +.globl SYM (remcomHandler) +SYM (remcomHandler): + addl IMM (4),sp /* pop off return address */ + movel sp@+,d0 /* get the exception number */ + movel SYM (stackPtr),sp /* move to remcom stack area */ + movel d0,sp@- /* push exception onto stack */ + jbsr SYM (handle_exception) /* this never returns */ + rts /* return */ |