source: trunk/libs/newlib/src/newlib/libc/machine/arm/setjmp.S @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.3 KB
Line 
1/* This is a simple version of setjmp and longjmp.
2
3   Nick Clifton, Cygnus Solutions, 13 June 1997.  */
4
5#include "acle-compat.h"
6
7/* ANSI concatenation macros.  */
8#define CONCAT(a, b)  CONCAT2(a, b)
9#define CONCAT2(a, b) a##b
10
11#ifndef __USER_LABEL_PREFIX__
12#error  __USER_LABEL_PREFIX__ not defined
13#endif
14
15#define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
16
17#ifdef __ELF__
18#define TYPE(x) .type SYM(x),function
19#define SIZE(x) .size SYM(x), . - SYM(x)
20#else
21#define TYPE(x)
22#define SIZE(x)
23#endif
24
25/* Arm/Thumb interworking support:
26
27   The interworking scheme expects functions to use a BX instruction
28   to return control to their parent.  Since we need this code to work
29   in both interworked and non-interworked environments as well as with
30   older processors which do not have the BX instruction we do the
31   following:
32        Test the return address.
33        If the bottom bit is clear perform an "old style" function exit.
34        (We know that we are in ARM mode and returning to an ARM mode caller).
35        Otherwise use the BX instruction to perform the function exit.
36
37   We know that we will never attempt to perform the BX instruction on
38   an older processor, because that kind of processor will never be
39   interworked, and a return address with the bottom bit set will never
40   be generated.
41
42   In addition, we do not actually assemble the BX instruction as this would
43   require us to tell the assembler that the processor is an ARM7TDMI and
44   it would store this information in the binary.  We want this binary to be
45   able to be linked with binaries compiled for older processors however, so
46   we do not want such information stored there. 
47
48   If we are running using the APCS-26 convention however, then we never
49   test the bottom bit, because this is part of the processor status. 
50   Instead we just do a normal return, since we know that we cannot be
51   returning to a Thumb caller - the Thumb does not support APCS-26.
52       
53   Function entry is much simpler.  If we are compiling for the Thumb we
54   just switch into ARM mode and then drop through into the rest of the
55   function.  The function exit code will take care of the restore to
56   Thumb mode.
57   
58   For Thumb-2 do everything in Thumb mode.  */
59
60#if __ARM_ARCH_ISA_THUMB == 1 && !__ARM_ARCH_ISA_ARM
61/* ARMv6-M-like has to be implemented in Thumb mode.  */
62
63.thumb
64.thumb_func
65        .globl SYM (setjmp)
66        TYPE (setjmp)
67SYM (setjmp):
68        /* Save registers in jump buffer.  */
69        stmia   r0!, {r4, r5, r6, r7}
70        mov     r1, r8
71        mov     r2, r9
72        mov     r3, r10
73        mov     r4, fp
74        mov     r5, sp
75        mov     r6, lr
76        stmia   r0!, {r1, r2, r3, r4, r5, r6}
77        sub     r0, r0, #40
78        /* Restore callee-saved low regs.  */
79        ldmia   r0!, {r4, r5, r6, r7}
80        /* Return zero.  */
81        mov     r0, #0
82        bx lr
83
84.thumb_func
85        .globl SYM (longjmp)
86        TYPE (longjmp)
87SYM (longjmp):
88        /* Restore High regs.  */
89        add     r0, r0, #16
90        ldmia   r0!, {r2, r3, r4, r5, r6}
91        mov     r8, r2
92        mov     r9, r3
93        mov     r10, r4
94        mov     fp, r5
95        mov     sp, r6
96        ldmia   r0!, {r3} /* lr */
97        /* Restore low regs.  */
98        sub     r0, r0, #40
99        ldmia   r0!, {r4, r5, r6, r7}
100        /* Return the result argument, or 1 if it is zero.  */
101        mov     r0, r1
102        bne     1f
103        mov     r0, #1
1041:
105        bx      r3
106
107#else
108
109#ifdef __APCS_26__
110#define RET     movs            pc, lr
111#elif defined(__thumb2__)
112#define RET     bx lr
113#else
114#define RET     tst             lr, #1; \
115                moveq           pc, lr ; \
116.word           0xe12fff1e      /* bx lr */
117#endif
118
119#ifdef __thumb2__
120.macro COND where when
121        i\where \when
122.endm
123#else
124.macro COND where when
125.endm
126#endif
127
128#if defined(__thumb2__)
129.syntax unified
130.macro MODE
131        .thumb
132        .thumb_func
133.endm
134.macro PROLOGUE name
135.endm
136
137#elif defined(__thumb__)
138#define MODE            .thumb_func
139.macro PROLOGUE name
140        .code 16
141        bx      pc
142        nop     
143        .code 32
144SYM (.arm_start_of.\name):
145.endm
146#else /* Arm */
147#define MODE            .code 32
148.macro PROLOGUE name
149.endm
150#endif
151       
152.macro FUNC_START name
153        .text
154        .align 2
155        MODE
156        .globl SYM (\name)
157        TYPE (\name)
158SYM (\name):
159        PROLOGUE \name
160.endm
161
162.macro FUNC_END name
163        RET
164        SIZE (\name)
165.endm
166       
167/* --------------------------------------------------------------------
168                 int setjmp (jmp_buf);
169   -------------------------------------------------------------------- */
170       
171        FUNC_START setjmp
172
173        /* Save all the callee-preserved registers into the jump buffer.  */
174#ifdef __thumb2__
175        mov             ip, sp
176        stmea           a1!, { v1-v7, fp, ip, lr }
177#else
178        stmea           a1!, { v1-v7, fp, ip, sp, lr }
179#endif
180       
181#if 0   /* Simulator does not cope with FP instructions yet.  */
182#ifndef __SOFTFP__
183        /* Save the floating point registers.  */
184        sfmea           f4, 4, [a1]
185#endif
186#endif         
187        /* When setting up the jump buffer return 0.  */
188        mov             a1, #0
189
190        FUNC_END setjmp
191       
192/* --------------------------------------------------------------------
193                volatile void longjmp (jmp_buf, int);
194   -------------------------------------------------------------------- */
195       
196        FUNC_START longjmp
197
198        /* If we have stack extension code it ought to be handled here.  */
199       
200        /* Restore the registers, retrieving the state when setjmp() was called.  */
201#ifdef __thumb2__
202        ldmfd           a1!, { v1-v7, fp, ip, lr }
203        mov             sp, ip
204#else
205        ldmfd           a1!, { v1-v7, fp, ip, sp, lr }
206#endif
207       
208#if 0   /* Simulator does not cope with FP instructions yet.  */
209#ifndef __SOFTFP__
210        /* Restore floating point registers as well.  */
211        lfmfd           f4, 4, [a1]
212#endif
213#endif 
214        /* Put the return value into the integer result register.
215           But if it is zero then return 1 instead.  */
216        movs            a1, a2
217#ifdef __thumb2__
218        it              eq
219#endif
220        moveq           a1, #1
221
222        FUNC_END longjmp
223#endif
Note: See TracBrowser for help on using the repository browser.