OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libc/] [machine/] [arm/] [setjmp.S] - Blame information for rev 307

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.