FS#8961 - Anti-Aliased Fonts.
[kugel-rb.git] / apps / codecs / lib / setjmp_arm.S
blob4bb2a46a7af13837af37d753feb88360038bf3be
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
11 #endif
13 #define SYM(x) CONCAT (__USER_LABEL_PREFIX__, x)
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
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 
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.
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.
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.
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.  */
58 #ifdef __APCS_26__
59 #define RET     movs            pc, lr
60 #elif defined(__thumb2__)
61 #define RET     bx lr
62 #else
63 #define RET     tst             lr, #1; \
64                 moveq           pc, lr ; \
65 .word           0xe12fff1e      /* bx lr */
66 #endif
68 #ifdef __thumb2__
69 .macro COND where when 
70         i\where \when
71 .endm
72 #else
73 .macro COND where when 
74 .endm
75 #endif
77 #if defined(__thumb2__)
78 .syntax unified
79 .macro MODE
80         .thumb
81         .thumb_func
82 .endm
83 .macro PROLOGUE name
84 .endm
86 #elif defined(__thumb__)
87 #define MODE            .thumb_func
88 .macro PROLOGUE name
89         .code 16
90         bx      pc
91         nop     
92         .code 32
93 SYM (.arm_start_of.\name):
94 .endm
95 #else /* Arm */
96 #define MODE            .code 32
97 .macro PROLOGUE name
98 .endm
99 #endif
100         
101 .macro FUNC_START name
102         .text
103         .align 2
104         MODE
105         .globl SYM (\name)
106         TYPE (\name)
107 SYM (\name):
108         PROLOGUE \name
109 .endm
111 .macro FUNC_END name
112         RET
113         SIZE (\name)
114 .endm
115         
116 /* --------------------------------------------------------------------
117                  int setjmp (jmp_buf); 
118    -------------------------------------------------------------------- */
119         
120         FUNC_START setjmp
122         /* Save all the callee-preserved registers into the jump buffer.  */
123 #ifdef __thumb2__
124         stmea           a1!, { v1-v7, fp, ip, lr }
125         str             sp, [a1],#+4
126 #else
127         stmea           a1!, { v1-v7, fp, ip, sp, lr }
128 #endif
129         
130 #if 0   /* Simulator does not cope with FP instructions yet.  */
131 #ifndef __SOFTFP__
132         /* Save the floating point registers.  */
133         sfmea           f4, 4, [a1]
134 #endif
135 #endif          
136         /* When setting up the jump buffer return 0.  */
137         mov             a1, #0
139         FUNC_END setjmp
140         
141 /* --------------------------------------------------------------------
142                 volatile void longjmp (jmp_buf, int);
143    -------------------------------------------------------------------- */
144         
145         FUNC_START longjmp
147         /* If we have stack extension code it ought to be handled here.  */
148         
149         /* Restore the registers, retrieving the state when setjmp() was called.  */
150 #ifdef __thumb2__
151         ldmfd           a1!, { v1-v7, fp, ip, lr }
152         ldr             sp, [a1],#+4
153 #else
154         ldmfd           a1!, { v1-v7, fp, ip, sp, lr }
155 #endif
156         
157 #if 0   /* Simulator does not cope with FP instructions yet.  */
158 #ifndef __SOFTFP__
159         /* Restore floating point registers as well.  */
160         lfmfd           f4, 4, [a1]
161 #endif
162 #endif  
163         /* Put the return value into the integer result register.
164            But if it is zero then return 1 instead.  */ 
165         movs            a1, a2
166 #ifdef __thumb2__
167         it              eq
168 #endif
169         moveq           a1, #1
171         FUNC_END longjmp