1/* 2 3Copyright (c) 2005 Red Hat Incorporated. 4All rights reserved. 5 6Redistribution and use in source and binary forms, with or without 7modification, are permitted provided that the following conditions are met: 8 9 Redistributions of source code must retain the above copyright 10 notice, this list of conditions and the following disclaimer. 11 12 Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 The name of Red Hat Incorporated may not be used to endorse 17 or promote products derived from this software without specific 18 prior written permission. 19 20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY 24DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31*/ 32 33#include <picolibc.h> 34 35#if defined(__r8c_cpu__) || defined(__m16c_cpu__) 36#define A16 1 37#endif 38 39/* We implement setjmp/longjmp much like the way gcc implements 40 exceptions - we create new stack frames, then switch to them and 41 return. Thus, the two setjmp's below each push all the relevent 42 registers, then copy the whole frame into the buffer (first $sp is 43 moved, then smovf copies the frame itself), and the two longjmps 44 restore $sp, copy the frame back into place, and issue the same 45 return as the setjmp would have used. 46 47 Since the sizes of registers differs between the 16 and 24 bit 48 models, we provide separate implementations for each rather than 49 trying to parameterize them. 50 51 Jump buffer sizes: 21 bytes for 16 bit, 34 bytes for 24 bit. 52*/ 53 54 .text 55 56#ifdef A16 /* 16 bit versions */ 57 58 .global _setjmp 59_setjmp: 60 enter #0 61 pushm r1,r2,r3,a0,a1,sb,fb 62 63; At this point, the stack looks like this: 64; ... [pc:3] [oldfb:2] <fb> [r1:2] [r2:2] [r3:2] [a0:2] [a1:2] [sb:2] [fb:2] <sp> */ 65 66 mov.w r1,a1 ; a1 is the destination of smovf 67 mov.b #0,r1h 68 stc sp,a0 ; r1h:a0 is the source of smovf 69 mov.w a0,[a1] 70 add.w #2,a1 71 mov.w #19,r3 ; plus two for sp later 72 smovf.b 73 74 ; Return 0 to caller. 75 mov.w #0,r0 76 popm r1,r2,r3,a0,a1,sb,fb 77 exitd 78 79 .global _longjmp 80_longjmp: 81 enter #0 82 mov.w r1,a0 ; pointer to jump buf 83 mov.w r2,r0 ; setjmp's "new" return value 84 85 mov.b #0,r1h ; r1h: a0 is the source, now jmpbuf 86 mov.w [a0],a1 ; dest is new stack 87 ldc a1,sp 88 add.w #2,a0 89 mov.w #19,r3 90 smovf.b 91 92 ;; now return to our caller with this newly restored frame 93 popm r1,r2,r3,a0,a1,sb,fb 94 exitd 95 96#else /* 24 bit versions */ 97 98 .global _setjmp 99_setjmp: 100 enter #0 101 pushm r1,r2,r3,a0,a1,sb,fb 102 103; At this point, the stack looks like this: 104; ... [jbuf:4] [pc:4] [oldfb:4] <fb> [r1:2] [r2:2] [r3:2] [a0:4] [a1:4] [sb:4] [fb:4] <sp> */ 105 106 mov.l 8[fb],a1 ; a1 is the destination of smovf 107 stc sp,a0 ; r1h:a0 is the source of smovf 108 mov.l a0,[a1] 109 add.l #4,a1 110 mov.w #30,r3 ; plus two for sp later 111 smovf.b 112 113 ; Return 0 to caller. 114 mov.w #0,r0 115 popm r1,r2,r3,a0,a1,sb,fb 116 exitd 117 118 .global _longjmp 119_longjmp: 120 enter #0 121; ... [rv:2] [jbuf:4] [pc:4] [oldfb:4] <fb> 122 mov.l 8[fb],a0 ; pointer to jump buf 123 mov.w 12[fb],r0 ; setjmp's "new" return value 124 125 mov.l [a0],a1 ; dest is new stack 126 ldc a1,sp 127 add.l #4,a0 128 mov.w #30,r3 129 smovf.b 130 131 ;; now return to our caller with this newly restored frame 132 popm r1,r2,r3,a0,a1,sb,fb 133 exitd 134#endif 135 136