libunwind-arm.S revision 169689
1169689Skan/* Support functions for the unwinder. 2169689Skan Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. 3169689Skan Contributed by Paul Brook 4169689Skan 5169689Skan This file is free software; you can redistribute it and/or modify it 6169689Skan under the terms of the GNU General Public License as published by the 7169689Skan Free Software Foundation; either version 2, or (at your option) any 8169689Skan later version. 9169689Skan 10169689Skan In addition to the permissions in the GNU General Public License, the 11169689Skan Free Software Foundation gives you unlimited permission to link the 12169689Skan compiled version of this file into combinations with other programs, 13169689Skan and to distribute those combinations without any restriction coming 14169689Skan from the use of this file. (The General Public License restrictions 15169689Skan do apply in other respects; for example, they cover modification of 16169689Skan the file, and distribution when not linked into a combine 17169689Skan executable.) 18169689Skan 19169689Skan This file is distributed in the hope that it will be useful, but 20169689Skan WITHOUT ANY WARRANTY; without even the implied warranty of 21169689Skan MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22169689Skan General Public License for more details. 23169689Skan 24169689Skan You should have received a copy of the GNU General Public License 25169689Skan along with this program; see the file COPYING. If not, write to 26169689Skan the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27169689Skan Boston, MA 02110-1301, USA. */ 28169689Skan 29169689Skan#ifndef __symbian__ 30169689Skan 31169689Skan#include "lib1funcs.asm" 32169689Skan 33169689Skan.macro UNPREFIX name 34169689Skan .global SYM (\name) 35169689Skan EQUIV SYM (\name), SYM (__\name) 36169689Skan.endm 37169689Skan 38169689Skan/* r0 points to a 16-word block. Upload these values to the actual core 39169689Skan state. */ 40169689SkanARM_FUNC_START restore_core_regs 41169689Skan /* We must use sp as the base register when restoring sp. Push the 42169689Skan last 3 registers onto the top of the current stack to achieve 43169689Skan this. */ 44169689Skan add r1, r0, #52 45169689Skan ldmia r1, {r3, r4, r5} /* {sp, lr, pc}. */ 46169689Skan#ifdef __INTERWORKING__ 47169689Skan /* Restore pc into ip. */ 48169689Skan mov r2, r5 49169689Skan stmfd sp!, {r2, r3, r4} 50169689Skan#else 51169689Skan stmfd sp!, {r3, r4, r5} 52169689Skan#endif 53169689Skan /* Don't bother restoring ip. */ 54169689Skan ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp} 55169689Skan /* Pop the three registers we pushed earlier. */ 56169689Skan#ifdef __INTERWORKING__ 57169689Skan ldmfd sp, {ip, sp, lr} 58169689Skan bx ip 59169689Skan#else 60169689Skan ldmfd sp, {sp, lr, pc} 61169689Skan#endif 62169689Skan FUNC_END restore_core_regs 63169689Skan UNPREFIX restore_core_regs 64169689Skan 65169689Skan/* Load VFP registers d0-d15 from the address in r0. */ 66169689SkanARM_FUNC_START gnu_Unwind_Restore_VFP 67169689Skan /* Use the generic coprocessor form so that gas doesn't complain 68169689Skan on soft-float targets. */ 69169689Skan ldc p11,cr0,[r0],{0x21} /* fldmiax r0, {d0-d15} */ 70169689Skan RET 71169689Skan 72169689Skan/* Store VFR regsters d0-d15 to the address in r0. */ 73169689SkanARM_FUNC_START gnu_Unwind_Save_VFP 74169689Skan /* Use the generic coprocessor form so that gas doesn't complain 75169689Skan on soft-float targets. */ 76169689Skan stc p11,cr0,[r0],{0x21} /* fstmiax r0, {d0-d15} */ 77169689Skan RET 78169689Skan 79169689Skan/* Wrappers to save core registers, then call the real routine. */ 80169689Skan 81169689Skan.macro UNWIND_WRAPPER name nargs 82169689Skan ARM_FUNC_START \name 83169689Skan /* Create a phase2_vrs structure. */ 84169689Skan /* Split reg push in two to ensure the correct value for sp. */ 85169689Skan stmfd sp!, {sp, lr, pc} 86169689Skan stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} 87169689Skan 88169689Skan /* Demand-save flags, plus an extra word for alignment. */ 89169689Skan mov r3, #0 90169689Skan stmfd sp!, {r2, r3} 91169689Skan 92169689Skan /* Point r1 at the block. Pass r[0..nargs) unchanged. */ 93169689Skan add r\nargs, sp, #4 94169689Skan#if defined(__thumb__) 95169689Skan /* Switch back to thumb mode to avoid interworking hassle. */ 96169689Skan adr ip, .L1_\name 97169689Skan orr ip, ip, #1 98169689Skan bx ip 99169689Skan .thumb 100169689Skan.L1_\name: 101169689Skan bl SYM (__gnu\name) __PLT__ 102169689Skan ldr r3, [sp, #64] 103169689Skan add sp, #72 104169689Skan bx r3 105169689Skan#else 106169689Skan bl SYM (__gnu\name) __PLT__ 107169689Skan ldr lr, [sp, #64] 108169689Skan add sp, sp, #72 109169689Skan RET 110169689Skan#endif 111169689Skan FUNC_END \name 112169689Skan UNPREFIX \name 113169689Skan.endm 114169689Skan 115169689SkanUNWIND_WRAPPER _Unwind_RaiseException 1 116169689SkanUNWIND_WRAPPER _Unwind_Resume 1 117169689SkanUNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1 118169689SkanUNWIND_WRAPPER _Unwind_ForcedUnwind 3 119169689Skan 120169689Skan#endif /* __symbian__ */ 121