yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame^] | 1 | /******************************************************************************* |
| 2 | * |
| 3 | * Copyright (c) 1993 Intel Corporation |
| 4 | * |
| 5 | * Intel hereby grants you permission to copy, modify, and distribute this |
| 6 | * software and its documentation. Intel grants this permission provided |
| 7 | * that the above copyright notice appears in all copies and that both the |
| 8 | * copyright notice and this permission notice appear in supporting |
| 9 | * documentation. In addition, Intel grants this permission provided that |
| 10 | * you prominently mark as "not part of the original" any modifications |
| 11 | * made to this software or documentation, and that the name of Intel |
| 12 | * Corporation not be used in advertising or publicity pertaining to |
| 13 | * distribution of the software or the documentation without specific, |
| 14 | * written prior permission. |
| 15 | * |
| 16 | * Intel Corporation provides this AS IS, WITHOUT ANY WARRANTY, EXPRESS OR |
| 17 | * IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY |
| 18 | * OR FITNESS FOR A PARTICULAR PURPOSE. Intel makes no guarantee or |
| 19 | * representations regarding the use of, or the results of the use of, |
| 20 | * the software and documentation in terms of correctness, accuracy, |
| 21 | * reliability, currentness, or otherwise; and you rely on the software, |
| 22 | * documentation and results solely at your own risk. |
| 23 | * |
| 24 | * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS, |
| 25 | * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES |
| 26 | * OF ANY KIND. IN NO EVENT SHALL INTEL'S TOTAL LIABILITY EXCEED THE SUM |
| 27 | * PAID TO INTEL FOR THE PRODUCT LICENSED HEREUNDER. |
| 28 | * |
| 29 | ******************************************************************************/ |
| 30 | |
| 31 | /*************************************************************************** |
| 32 | * |
| 33 | * Modified from the original in order to fit with |
| 34 | * uClibc's setjmp, _setjmp, __sigsetjmp and ___sigjmp_save. |
| 35 | * |
| 36 | * |
| 37 | * int setjmp (jmp_buf __env) is the BSD style setjmp function. |
| 38 | * It simply calls __sigsetjmp(env, 1) |
| 39 | * |
| 40 | * int _setjmp (jmp_buf __env) is the posix style setjmp function. |
| 41 | * It simply calls __sigsetjmp(env, 0) |
| 42 | * This is the one normally used. |
| 43 | * |
| 44 | ***************************************************************************/ |
| 45 | |
| 46 | .text |
| 47 | .align 4 |
| 48 | .globl _setjmp |
| 49 | .globl __setjmp |
| 50 | |
| 51 | _setjmp: |
| 52 | mov 1, g1 /* __sigsetjmp(env, 1) */ |
| 53 | bx __sigsetjmp |
| 54 | |
| 55 | __setjmp: |
| 56 | mov 0, g1 /* __sigsetjmp(env, 0) */ |
| 57 | bx __sigsetjmp |
| 58 | |
| 59 | |
| 60 | /******************************************************************************/ |
| 61 | /* */ |
| 62 | /* setjmp(), longjmp() */ |
| 63 | /* */ |
| 64 | /******************************************************************************/ |
| 65 | .file "setjmp.S" |
| 66 | .text |
| 67 | /* .link_pix */ |
| 68 | |
| 69 | .align 4 |
| 70 | .globl __sigsetjmp |
| 71 | __sigsetjmp: |
| 72 | flushreg |
| 73 | andnot 0xf,pfp,g2 /* get pfp, mask out return status bits */ |
| 74 | st g2, 0x58(g0) /* save fp of caller*/ |
| 75 | /* save globals not killed by the calling convention */ |
| 76 | stq g8, 0x40(g0) /* save g8-g11*/ |
| 77 | st g12, 0x50(g0) /* save g12*/ |
| 78 | st g14, 0x54(g0) /* save g14*/ |
| 79 | /* save previous frame local registers */ |
| 80 | ldq (g2), g4 /* get previous frame pfp, sp, rip, r3 */ |
| 81 | stq g4, (g0) /* save pfp, sp, rip, r3 */ |
| 82 | ldq 0x10(g2), g4 /* get previous frame r4-r7 */ |
| 83 | stq g4, 0x10(g0) /* save r4-r7 */ |
| 84 | ldq 0x20(g2), g4 /* get previous frame r8-r11 */ |
| 85 | stq g4, 0x20(g0) /* save r8-r11 */ |
| 86 | ldq 0x30(g2), g4 /* get previous frame r12-r15 */ |
| 87 | stq g4, 0x30(g0) /* save r12-r15 */ |
| 88 | |
| 89 | bx ___sigjmp_save |
| 90 | |
| 91 | /* |
| 92 | * fake a return to the place that called the corresponding __sigsetjmp |
| 93 | */ |
| 94 | .align 4 |
| 95 | .globl ___longjmp |
| 96 | ___longjmp: |
| 97 | call 0f /* ensure there is at least one stack frame */ |
| 98 | |
| 99 | 0: |
| 100 | flushreg /* do this before swapping stack */ |
| 101 | ld 0x58(g0), pfp /* get fp of caller of setjmp */ |
| 102 | /* restore local registers |
| 103 | * the following code modifies the frame of the function which originally |
| 104 | * called setjmp. |
| 105 | */ |
| 106 | ldq (g0), g4 /* get pfp, sp, rip, r3 */ |
| 107 | stq g4, (pfp) /* restore pfp, sp, rip, r3 */ |
| 108 | ldq 0x10(g0), g4 /* get r4-r7 */ |
| 109 | stq g4, 0x10(pfp) /* restore r4-r7 */ |
| 110 | ldq 0x20(g0), g4 /* get r8-r11 */ |
| 111 | stq g4, 0x20(pfp) /* restore r8-r11 */ |
| 112 | ldq 0x30(g0), g4 /* get r12-r15 */ |
| 113 | stq g4, 0x30(pfp) /* restore r12-r15 */ |
| 114 | /* restore global registers */ |
| 115 | ldq 0x40(g0), g8 /* get old g8-g11 values */ |
| 116 | ld 0x50(g0), g12 /* get old g12 value */ |
| 117 | ld 0x54(g0), g14 /* get old g14 value */ |
| 118 | |
| 119 | mov g1, g0 /* get return value */ |
| 120 | cmpo g0, 0 /* make sure it is not zero */ |
| 121 | bne 0f |
| 122 | mov 1, g0 /* return 1 by default */ |
| 123 | 0: |
| 124 | ret /* return to caller of __sigsetjmp */ |