libunwind-arm.S revision 318714
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 29275380Sandrew#include <machine/acle-compat.h> 30275380Sandrew 31275380Sandrew/* Allow the use of VFP instructions */ 32275380Sandrew#if __ARM_ARCH >= 7 33275380Sandrew.fpu vfp 34275380Sandrew#endif 35275380Sandrew 36169689Skan#ifndef __symbian__ 37169689Skan 38169689Skan#include "lib1funcs.asm" 39169689Skan 40169689Skan.macro UNPREFIX name 41169689Skan .global SYM (\name) 42169689Skan EQUIV SYM (\name), SYM (__\name) 43169689Skan.endm 44169689Skan 45169689Skan/* r0 points to a 16-word block. Upload these values to the actual core 46169689Skan state. */ 47169689SkanARM_FUNC_START restore_core_regs 48169689Skan /* We must use sp as the base register when restoring sp. Push the 49169689Skan last 3 registers onto the top of the current stack to achieve 50169689Skan this. */ 51169689Skan add r1, r0, #52 52169689Skan ldmia r1, {r3, r4, r5} /* {sp, lr, pc}. */ 53169689Skan#ifdef __INTERWORKING__ 54169689Skan /* Restore pc into ip. */ 55169689Skan mov r2, r5 56169689Skan stmfd sp!, {r2, r3, r4} 57169689Skan#else 58169689Skan stmfd sp!, {r3, r4, r5} 59169689Skan#endif 60169689Skan /* Don't bother restoring ip. */ 61169689Skan ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp} 62169689Skan /* Pop the three registers we pushed earlier. */ 63169689Skan#ifdef __INTERWORKING__ 64169689Skan ldmfd sp, {ip, sp, lr} 65169689Skan bx ip 66169689Skan#else 67169689Skan ldmfd sp, {sp, lr, pc} 68169689Skan#endif 69169689Skan FUNC_END restore_core_regs 70169689Skan UNPREFIX restore_core_regs 71169689Skan 72169689Skan/* Load VFP registers d0-d15 from the address in r0. */ 73169689SkanARM_FUNC_START gnu_Unwind_Restore_VFP 74169689Skan /* Use the generic coprocessor form so that gas doesn't complain 75169689Skan on soft-float targets. */ 76275380Sandrew#if __ARM_ARCH >= 7 77275380Sandrew fldmiax r0, {d0-d15} 78275380Sandrew#else 79169689Skan ldc p11,cr0,[r0],{0x21} /* fldmiax r0, {d0-d15} */ 80275380Sandrew#endif 81169689Skan RET 82169689Skan 83169689Skan/* Store VFR regsters d0-d15 to the address in r0. */ 84169689SkanARM_FUNC_START gnu_Unwind_Save_VFP 85169689Skan /* Use the generic coprocessor form so that gas doesn't complain 86169689Skan on soft-float targets. */ 87275380Sandrew#if __ARM_ARCH >= 7 88275380Sandrew fstmiax r0, {d0-d15} 89275380Sandrew#else 90169689Skan stc p11,cr0,[r0],{0x21} /* fstmiax r0, {d0-d15} */ 91275380Sandrew#endif 92169689Skan RET 93169689Skan 94169689Skan/* Wrappers to save core registers, then call the real routine. */ 95169689Skan 96169689Skan.macro UNWIND_WRAPPER name nargs 97169689Skan ARM_FUNC_START \name 98169689Skan /* Create a phase2_vrs structure. */ 99169689Skan /* Split reg push in two to ensure the correct value for sp. */ 100169689Skan stmfd sp!, {sp, lr, pc} 101169689Skan stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} 102169689Skan 103169689Skan /* Demand-save flags, plus an extra word for alignment. */ 104169689Skan mov r3, #0 105169689Skan stmfd sp!, {r2, r3} 106169689Skan 107169689Skan /* Point r1 at the block. Pass r[0..nargs) unchanged. */ 108169689Skan add r\nargs, sp, #4 109169689Skan#if defined(__thumb__) 110169689Skan /* Switch back to thumb mode to avoid interworking hassle. */ 111169689Skan adr ip, .L1_\name 112169689Skan orr ip, ip, #1 113169689Skan bx ip 114169689Skan .thumb 115169689Skan.L1_\name: 116169689Skan bl SYM (__gnu\name) __PLT__ 117169689Skan ldr r3, [sp, #64] 118169689Skan add sp, #72 119169689Skan bx r3 120169689Skan#else 121169689Skan bl SYM (__gnu\name) __PLT__ 122169689Skan ldr lr, [sp, #64] 123169689Skan add sp, sp, #72 124169689Skan RET 125169689Skan#endif 126169689Skan FUNC_END \name 127169689Skan UNPREFIX \name 128169689Skan.endm 129169689Skan 130169689SkanUNWIND_WRAPPER _Unwind_RaiseException 1 131169689SkanUNWIND_WRAPPER _Unwind_Resume 1 132169689SkanUNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1 133169689SkanUNWIND_WRAPPER _Unwind_ForcedUnwind 3 134255095SandrewUNWIND_WRAPPER _Unwind_Backtrace 2 135169689Skan 136318714Smmel/* 137318714Smmel * Originally, we incorrectly export _Unwind_Backtrace symbol 138318714Smmel * with GCC_3.3 version, but real GCC libgcc export it as GCC_4.3.0. 139318714Smmel * To maintain backward compatibility, export it with both versions where 140318714Smmel * GCC_4.3.0 is default one. 141318714Smmel * 142318714Smmel * The workaround is complicated by next two issues: 143318714Smmel * - old GNU ld cannot handle two (or more) symbol versions 144318714Smmel * targeting same function. 145318714Smmel * - the .weakref crashes clang 4.0 146318714Smmel */ 147318714Smmel .globl SYM(_Unwind_Backtrace33) 148318714Smmel TYPE(_Unwind_Backtrace33) 149318714SmmelSYM(_Unwind_Backtrace33): 150318714Smmel b _Unwind_Backtrace 151318714Smmel 152318714Smmel .symver SYM(_Unwind_Backtrace33),_Unwind_Backtrace@GCC_3.3 153318714Smmel 154255095Sandrew#endif /* ndef __symbian__ */ 155