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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [config/] [arm/] [libunwind.S] - Blame information for rev 859

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

Line No. Rev Author Line
1 282 jeremybenn
/* Support functions for the unwinder.
2
   Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009  Free Software Foundation, Inc.
3
   Contributed by Paul Brook
4
 
5
   This file is free software; you can redistribute it and/or modify it
6
   under the terms of the GNU General Public License as published by the
7
   Free Software Foundation; either version 3, or (at your option) any
8
   later version.
9
 
10
   This file is distributed in the hope that it will be useful, but
11
   WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   General Public License for more details.
14
 
15
   Under Section 7 of GPL version 3, you are granted additional
16
   permissions described in the GCC Runtime Library Exception, version
17
   3.1, as published by the Free Software Foundation.
18
 
19
   You should have received a copy of the GNU General Public License and
20
   a copy of the GCC Runtime Library Exception along with this program;
21
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22
   .  */
23
 
24
/* An executable stack is *not* required for these functions.  */
25
#if defined(__ELF__) && defined(__linux__)
26
.section .note.GNU-stack,"",%progbits
27
.previous
28
#endif
29
 
30
#ifndef __symbian__
31
 
32
#include "lib1funcs.asm"
33
 
34
.macro UNPREFIX name
35
        .global SYM (\name)
36
        EQUIV SYM (\name), SYM (__\name)
37
.endm
38
 
39
#if (__ARM_ARCH__ == 4)
40
/* Some coprocessors require armv5.  We know this code will never be run on
41
   other cpus.  Tell gas to allow armv5, but only mark the objects as armv4.
42
 */
43
.arch armv5t
44
#ifdef __ARM_ARCH_4T__
45
.object_arch armv4t
46
#else
47
.object_arch armv4
48
#endif
49
#endif
50
 
51
#ifdef __ARM_ARCH_6M__
52
 
53
/* r0 points to a 16-word block.  Upload these values to the actual core
54
   state.  */
55
FUNC_START restore_core_regs
56
        mov r1, r0
57
        add r1, r1, #52
58
        ldmia r1!, {r3, r4, r5}
59
        sub r3, r3, #4
60
        mov ip, r3
61
        str r5, [r3]
62
        mov lr, r4
63
        /* Restore r8-r11.  */
64
        mov r1, r0
65
        add r1, r1, #32
66
        ldmia r1!, {r2, r3, r4, r5}
67
        mov r8, r2
68
        mov r9, r3
69
        mov sl, r4
70
        mov fp, r5
71
        mov r1, r0
72
        add r1, r1, #8
73
        ldmia r1!, {r2, r3, r4, r5, r6, r7}
74
        ldr r1, [r0, #4]
75
        ldr r0, [r0]
76
        mov sp, ip
77
        pop {pc}
78
        FUNC_END restore_core_regs
79
        UNPREFIX restore_core_regs
80
 
81
/* ARMV6M does not have coprocessors, so these should never be used.  */
82
FUNC_START gnu_Unwind_Restore_VFP
83
        RET
84
 
85
/* Store VFR regsters d0-d15 to the address in r0.  */
86
FUNC_START gnu_Unwind_Save_VFP
87
        RET
88
 
89
/* Load VFP registers d0-d15 from the address in r0.
90
   Use this to load from FSTMD format.  */
91
FUNC_START gnu_Unwind_Restore_VFP_D
92
        RET
93
 
94
/* Store VFP registers d0-d15 to the address in r0.
95
   Use this to store in FLDMD format.  */
96
FUNC_START gnu_Unwind_Save_VFP_D
97
        RET
98
 
99
/* Load VFP registers d16-d31 from the address in r0.
100
   Use this to load from FSTMD (=VSTM) format.  Needs VFPv3.  */
101
FUNC_START gnu_Unwind_Restore_VFP_D_16_to_31
102
        RET
103
 
104
/* Store VFP registers d16-d31 to the address in r0.
105
   Use this to store in FLDMD (=VLDM) format.  Needs VFPv3.  */
106
FUNC_START gnu_Unwind_Save_VFP_D_16_to_31
107
        RET
108
 
109
FUNC_START gnu_Unwind_Restore_WMMXD
110
        RET
111
 
112
FUNC_START gnu_Unwind_Save_WMMXD
113
        RET
114
 
115
FUNC_START gnu_Unwind_Restore_WMMXC
116
        RET
117
 
118
FUNC_START gnu_Unwind_Save_WMMXC
119
        RET
120
 
121
.macro  UNWIND_WRAPPER name nargs
122
        FUNC_START \name
123
        /* Create a phase2_vrs structure.  */
124
        /* Save r0 in the PC slot so we can use it as a scratch register.  */
125
        push {r0}
126
        add r0, sp, #4
127
        push {r0, lr} /* Push original SP and LR.  */
128
        /* Make space for r8-r12.  */
129
        sub sp, sp, #20
130
        /* Save low registers.  */
131
        push {r0, r1, r2, r3, r4, r5, r6, r7}
132
        /* Save high registers.  */
133
        add r0, sp, #32
134
        mov r1, r8
135
        mov r2, r9
136
        mov r3, sl
137
        mov r4, fp
138
        mov r5, ip
139
        stmia r0!, {r1, r2, r3, r4, r5}
140
        /* Restore original low register values.  */
141
        add r0, sp, #4
142
        ldmia r0!, {r1, r2, r3, r4, r5}
143
        /* Restore orginial r0.  */
144
        ldr r0, [sp, #60]
145
        str r0, [sp]
146
        /* Demand-save flags, plus an extra word for alignment.  */
147
        mov r3, #0
148
        push {r2, r3}
149
        /* Point r1 at the block.  Pass r[0..nargs) unchanged.  */
150
        add r\nargs, sp, #4
151
 
152
        bl SYM (__gnu\name)
153
 
154
        ldr r3, [sp, #64]
155
        add sp, sp, #72
156
        bx r3
157
 
158
        FUNC_END \name
159
        UNPREFIX \name
160
.endm
161
 
162
#else /* !__ARM_ARCH_6M__ */
163
 
164
/* r0 points to a 16-word block.  Upload these values to the actual core
165
   state.  */
166
ARM_FUNC_START restore_core_regs
167
        /* We must use sp as the base register when restoring sp.  Push the
168
           last 3 registers onto the top of the current stack to achieve
169
           this.  */
170
        add r1, r0, #52
171
        ldmia r1, {r3, r4, r5}  /* {sp, lr, pc}.  */
172
#if defined(__thumb2__)
173
        /* Thumb-2 doesn't allow sp in a load-multiple instruction, so push
174
           the target address onto the target stack.  This is safe as
175
           we're always returning to somewhere further up the call stack.  */
176
        mov ip, r3
177
        mov lr, r4
178
        str r5, [ip, #-4]!
179
#elif defined(__INTERWORKING__)
180
        /* Restore pc into ip.  */
181
        mov r2, r5
182
        stmfd sp!, {r2, r3, r4}
183
#else
184
        stmfd sp!, {r3, r4, r5}
185
#endif
186
        /* Don't bother restoring ip.  */
187
        ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp}
188
#if defined(__thumb2__)
189
        /* Pop the return address off the target stack.  */
190
        mov sp, ip
191
        pop {pc}
192
#elif defined(__INTERWORKING__)
193
        /* Pop the three registers we pushed earlier.  */
194
        ldmfd sp, {ip, sp, lr}
195
        bx ip
196
#else
197
        ldmfd sp, {sp, lr, pc}
198
#endif
199
        FUNC_END restore_core_regs
200
        UNPREFIX restore_core_regs
201
 
202
/* Load VFP registers d0-d15 from the address in r0.
203
   Use this to load from FSTMX format.  */
204
ARM_FUNC_START gnu_Unwind_Restore_VFP
205
        /* Use the generic coprocessor form so that gas doesn't complain
206
           on soft-float targets.  */
207
        ldc   p11,cr0,[r0],{0x21} /* fldmiax r0, {d0-d15} */
208
        RET
209
 
210
/* Store VFP registers d0-d15 to the address in r0.
211
   Use this to store in FSTMX format.  */
212
ARM_FUNC_START gnu_Unwind_Save_VFP
213
        /* Use the generic coprocessor form so that gas doesn't complain
214
           on soft-float targets.  */
215
        stc   p11,cr0,[r0],{0x21} /* fstmiax r0, {d0-d15} */
216
        RET
217
 
218
/* Load VFP registers d0-d15 from the address in r0.
219
   Use this to load from FSTMD format.  */
220
ARM_FUNC_START gnu_Unwind_Restore_VFP_D
221
        ldc   p11,cr0,[r0],{0x20} /* fldmiad r0, {d0-d15} */
222
        RET
223
 
224
/* Store VFP registers d0-d15 to the address in r0.
225
   Use this to store in FLDMD format.  */
226
ARM_FUNC_START gnu_Unwind_Save_VFP_D
227
        stc   p11,cr0,[r0],{0x20} /* fstmiad r0, {d0-d15} */
228
        RET
229
 
230
/* Load VFP registers d16-d31 from the address in r0.
231
   Use this to load from FSTMD (=VSTM) format.  Needs VFPv3.  */
232
ARM_FUNC_START gnu_Unwind_Restore_VFP_D_16_to_31
233
        ldcl  p11,cr0,[r0],{0x20} /* vldm r0, {d16-d31} */
234
        RET
235
 
236
/* Store VFP registers d16-d31 to the address in r0.
237
   Use this to store in FLDMD (=VLDM) format.  Needs VFPv3.  */
238
ARM_FUNC_START gnu_Unwind_Save_VFP_D_16_to_31
239
        stcl  p11,cr0,[r0],{0x20} /* vstm r0, {d16-d31} */
240
        RET
241
 
242
ARM_FUNC_START gnu_Unwind_Restore_WMMXD
243
        /* Use the generic coprocessor form so that gas doesn't complain
244
           on non-iWMMXt targets.  */
245
        ldcl  p1, cr0, [r0], #8 /* wldrd wr0, [r0], #8 */
246
        ldcl  p1, cr1, [r0], #8 /* wldrd wr1, [r0], #8 */
247
        ldcl  p1, cr2, [r0], #8 /* wldrd wr2, [r0], #8 */
248
        ldcl  p1, cr3, [r0], #8 /* wldrd wr3, [r0], #8 */
249
        ldcl  p1, cr4, [r0], #8 /* wldrd wr4, [r0], #8 */
250
        ldcl  p1, cr5, [r0], #8 /* wldrd wr5, [r0], #8 */
251
        ldcl  p1, cr6, [r0], #8 /* wldrd wr6, [r0], #8 */
252
        ldcl  p1, cr7, [r0], #8 /* wldrd wr7, [r0], #8 */
253
        ldcl  p1, cr8, [r0], #8 /* wldrd wr8, [r0], #8 */
254
        ldcl  p1, cr9, [r0], #8 /* wldrd wr9, [r0], #8 */
255
        ldcl  p1, cr10, [r0], #8 /* wldrd wr10, [r0], #8 */
256
        ldcl  p1, cr11, [r0], #8 /* wldrd wr11, [r0], #8 */
257
        ldcl  p1, cr12, [r0], #8 /* wldrd wr12, [r0], #8 */
258
        ldcl  p1, cr13, [r0], #8 /* wldrd wr13, [r0], #8 */
259
        ldcl  p1, cr14, [r0], #8 /* wldrd wr14, [r0], #8 */
260
        ldcl  p1, cr15, [r0], #8 /* wldrd wr15, [r0], #8 */
261
        RET
262
 
263
ARM_FUNC_START gnu_Unwind_Save_WMMXD
264
        /* Use the generic coprocessor form so that gas doesn't complain
265
           on non-iWMMXt targets.  */
266
        stcl  p1, cr0, [r0], #8 /* wstrd wr0, [r0], #8 */
267
        stcl  p1, cr1, [r0], #8 /* wstrd wr1, [r0], #8 */
268
        stcl  p1, cr2, [r0], #8 /* wstrd wr2, [r0], #8 */
269
        stcl  p1, cr3, [r0], #8 /* wstrd wr3, [r0], #8 */
270
        stcl  p1, cr4, [r0], #8 /* wstrd wr4, [r0], #8 */
271
        stcl  p1, cr5, [r0], #8 /* wstrd wr5, [r0], #8 */
272
        stcl  p1, cr6, [r0], #8 /* wstrd wr6, [r0], #8 */
273
        stcl  p1, cr7, [r0], #8 /* wstrd wr7, [r0], #8 */
274
        stcl  p1, cr8, [r0], #8 /* wstrd wr8, [r0], #8 */
275
        stcl  p1, cr9, [r0], #8 /* wstrd wr9, [r0], #8 */
276
        stcl  p1, cr10, [r0], #8 /* wstrd wr10, [r0], #8 */
277
        stcl  p1, cr11, [r0], #8 /* wstrd wr11, [r0], #8 */
278
        stcl  p1, cr12, [r0], #8 /* wstrd wr12, [r0], #8 */
279
        stcl  p1, cr13, [r0], #8 /* wstrd wr13, [r0], #8 */
280
        stcl  p1, cr14, [r0], #8 /* wstrd wr14, [r0], #8 */
281
        stcl  p1, cr15, [r0], #8 /* wstrd wr15, [r0], #8 */
282
        RET
283
 
284
ARM_FUNC_START gnu_Unwind_Restore_WMMXC
285
        /* Use the generic coprocessor form so that gas doesn't complain
286
           on non-iWMMXt targets.  */
287
        ldc2  p1, cr8, [r0], #4 /* wldrw wcgr0, [r0], #4 */
288
        ldc2  p1, cr9, [r0], #4 /* wldrw wcgr1, [r0], #4 */
289
        ldc2  p1, cr10, [r0], #4 /* wldrw wcgr2, [r0], #4 */
290
        ldc2  p1, cr11, [r0], #4 /* wldrw wcgr3, [r0], #4 */
291
        RET
292
 
293
ARM_FUNC_START gnu_Unwind_Save_WMMXC
294
        /* Use the generic coprocessor form so that gas doesn't complain
295
           on non-iWMMXt targets.  */
296
        stc2  p1, cr8, [r0], #4 /* wstrw wcgr0, [r0], #4 */
297
        stc2  p1, cr9, [r0], #4 /* wstrw wcgr1, [r0], #4 */
298
        stc2  p1, cr10, [r0], #4 /* wstrw wcgr2, [r0], #4 */
299
        stc2  p1, cr11, [r0], #4 /* wstrw wcgr3, [r0], #4 */
300
        RET
301
 
302
/* Wrappers to save core registers, then call the real routine.   */
303
 
304
.macro  UNWIND_WRAPPER name nargs
305
        ARM_FUNC_START \name
306
        /* Create a phase2_vrs structure.  */
307
        /* Split reg push in two to ensure the correct value for sp.  */
308
#if defined(__thumb2__)
309
        mov ip, sp
310
        push {lr} /* PC is ignored.  */
311
        push {ip, lr} /* Push original SP and LR.  */
312
#else
313
        stmfd sp!, {sp, lr, pc}
314
#endif
315
        stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip}
316
 
317
        /* Demand-save flags, plus an extra word for alignment.  */
318
        mov r3, #0
319
        stmfd sp!, {r2, r3}
320
 
321
        /* Point r1 at the block.  Pass r[0..nargs) unchanged.  */
322
        add r\nargs, sp, #4
323
#if defined(__thumb__) && !defined(__thumb2__)
324
        /* Switch back to thumb mode to avoid interworking hassle.  */
325
        adr ip, .L1_\name
326
        orr ip, ip, #1
327
        bx ip
328
        .thumb
329
.L1_\name:
330
        bl SYM (__gnu\name) __PLT__
331
        ldr r3, [sp, #64]
332
        add sp, #72
333
        bx r3
334
#else
335
        bl SYM (__gnu\name) __PLT__
336
        ldr lr, [sp, #64]
337
        add sp, sp, #72
338
        RET
339
#endif
340
        FUNC_END \name
341
        UNPREFIX \name
342
.endm
343
 
344
#endif /* !__ARM_ARCH_6M__ */
345
 
346
UNWIND_WRAPPER _Unwind_RaiseException 1
347
UNWIND_WRAPPER _Unwind_Resume 1
348
UNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1
349
UNWIND_WRAPPER _Unwind_ForcedUnwind 3
350
UNWIND_WRAPPER _Unwind_Backtrace 2
351
 
352
#endif  /* ndef __symbian__ */

powered by: WebSVN 2.1.0

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