1 /* This is a simple version of setjmp and longjmp.
3 Nick Clifton, Cygnus Solutions, 13 June 1997. */
5 /* ANSI concatenation macros. */
6 #define CONCAT(a, b) CONCAT2(a, b)
7 #define CONCAT2(a, b) a##b
9 #ifndef __USER_LABEL_PREFIX__
10 #error __USER_LABEL_PREFIX__ not defined
13 #define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
16 #define TYPE(x) .type SYM(x),function
17 #define SIZE(x) .size SYM(x), . - SYM(x)
23 /* Arm/Thumb interworking support:
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
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.
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
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.
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.
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
56 For Thumb-2 do everything in Thumb mode. */
59 #define RET movs pc, lr
60 #elif defined(__thumb2__)
63 #define RET tst lr, #1; \
65 .word 0xe12fff1e /* bx lr */
69 .macro COND where when
73 .macro COND where when
77 #if defined(__thumb2__)
86 #elif defined(__thumb__)
87 #define MODE .thumb_func
93 SYM (.arm_start_of.\name):
101 .macro FUNC_START name
116 /* --------------------------------------------------------------------
117 int setjmp (jmp_buf);
118 -------------------------------------------------------------------- */
122 /* Save all the callee-preserved registers into the jump buffer. */
124 stmea a1!, { v1-v7, fp, ip, lr }
127 stmea a1!, { v1-v7, fp, ip, sp, lr }
130 #if 0 /* Simulator does not cope with FP instructions yet. */
132 /* Save the floating point registers. */
136 /* When setting up the jump buffer return 0. */
141 /* --------------------------------------------------------------------
142 volatile void longjmp (jmp_buf, int);
143 -------------------------------------------------------------------- */
147 /* If we have stack extension code it ought to be handled here. */
149 /* Restore the registers, retrieving the state when setjmp() was called. */
151 ldmfd a1!, { v1-v7, fp, ip, lr }
154 ldmfd a1!, { v1-v7, fp, ip, sp, lr }
157 #if 0 /* Simulator does not cope with FP instructions yet. */
159 /* Restore floating point registers as well. */
163 /* Put the return value into the integer result register.
164 But if it is zero then return 1 instead. */