From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/config/xtensa/lib2funcs.S | 186 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 gcc/config/xtensa/lib2funcs.S (limited to 'gcc/config/xtensa/lib2funcs.S') diff --git a/gcc/config/xtensa/lib2funcs.S b/gcc/config/xtensa/lib2funcs.S new file mode 100644 index 000000000..65134e24c --- /dev/null +++ b/gcc/config/xtensa/lib2funcs.S @@ -0,0 +1,186 @@ +/* Assembly functions for libgcc2. + Copyright (C) 2001, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#include "xtensa-config.h" + +/* __xtensa_libgcc_window_spill: This function flushes out all but the + current register window. This is used to set up the stack so that + arbitrary frames can be accessed. */ + + .align 4 + .global __xtensa_libgcc_window_spill + .type __xtensa_libgcc_window_spill,@function +__xtensa_libgcc_window_spill: + entry sp, 32 + movi a2, 0 + syscall + retw + .size __xtensa_libgcc_window_spill, .-__xtensa_libgcc_window_spill + + +/* __xtensa_nonlocal_goto: This code does all the hard work of a + nonlocal goto on Xtensa. It is here in the library to avoid the + code size bloat of generating it in-line. There are two + arguments: + + a2 = frame pointer for the procedure containing the label + a3 = goto handler address + + This function never returns to its caller but instead goes directly + to the address of the specified goto handler. */ + + .align 4 + .global __xtensa_nonlocal_goto + .type __xtensa_nonlocal_goto,@function +__xtensa_nonlocal_goto: + entry sp, 32 + + /* Flush registers. */ + mov a5, a2 + movi a2, 0 + syscall + mov a2, a5 + + /* Because the save area for a0-a3 is stored one frame below + the one identified by a2, the only way to restore those + registers is to unwind the stack. If alloca() were never + called, we could just unwind until finding the sp value + matching a2. However, a2 is a frame pointer, not a stack + pointer, and may not be encountered during the unwinding. + The solution is to unwind until going _past_ the value + given by a2. This involves keeping three stack pointer + values during the unwinding: + + next = sp of frame N-1 + cur = sp of frame N + prev = sp of frame N+1 + + When next > a2, the desired save area is stored relative + to prev. At this point, cur will be the same as a2 + except in the alloca() case. + + Besides finding the values to be restored to a0-a3, we also + need to find the current window size for the target + function. This can be extracted from the high bits of the + return address, initially in a0. As the unwinding + proceeds, the window size is taken from the value of a0 + saved _two_ frames below the current frame. */ + + addi a5, sp, -16 /* a5 = prev - save area */ + l32i a6, a5, 4 + addi a6, a6, -16 /* a6 = cur - save area */ + mov a8, a0 /* a8 = return address (for window size) */ + j .Lfirstframe + +.Lnextframe: + l32i a8, a5, 0 /* next return address (for window size) */ + mov a5, a6 /* advance prev */ + addi a6, a7, -16 /* advance cur */ +.Lfirstframe: + l32i a7, a6, 4 /* a7 = next */ + bgeu a2, a7, .Lnextframe + + /* At this point, prev (a5) points to the save area with the saved + values of a0-a3. Copy those values into the save area at the + current sp so they will be reloaded when the return from this + function underflows. We don't have to worry about exceptions + while updating the current save area, because the windows have + already been flushed. */ + + addi a4, sp, -16 /* a4 = save area of this function */ + l32i a6, a5, 0 + l32i a7, a5, 4 + s32i a6, a4, 0 + s32i a7, a4, 4 + l32i a6, a5, 8 + l32i a7, a5, 12 + s32i a6, a4, 8 + s32i a7, a4, 12 + + /* Set return address to goto handler. Use the window size bits + from the return address two frames below the target. */ + extui a8, a8, 30, 2 /* get window size from return addr. */ + slli a3, a3, 2 /* get goto handler addr. << 2 */ + ssai 2 + src a0, a8, a3 /* combine them with a funnel shift */ + + retw + .size __xtensa_nonlocal_goto, .-__xtensa_nonlocal_goto + + +/* __xtensa_sync_caches: This function is called after writing a trampoline + on the stack to force all the data writes to memory and invalidate the + instruction cache. a2 is the address of the new trampoline. + + After the trampoline data is written out, it must be flushed out of + the data cache into memory. We use DHWB in case we have a writeback + cache. At least one DHWB instruction is needed for each data cache + line which may be touched by the trampoline. An ISYNC instruction + must follow the DHWBs. + + We have to flush the i-cache to make sure that the new values get used. + At least one IHI instruction is needed for each i-cache line which may + be touched by the trampoline. An ISYNC instruction is also needed to + make sure that the modified instructions are loaded into the instruction + fetch buffer. */ + +/* Use the maximum trampoline size. Flushing a bit extra is OK. */ +#define TRAMPOLINE_SIZE 60 + + .text + .align 4 + .global __xtensa_sync_caches + .type __xtensa_sync_caches,@function +__xtensa_sync_caches: + entry sp, 32 +#if XCHAL_DCACHE_SIZE > 0 + /* Flush the trampoline from the data cache. */ + extui a4, a2, 0, XCHAL_DCACHE_LINEWIDTH + addi a4, a4, TRAMPOLINE_SIZE + addi a4, a4, (1 << XCHAL_DCACHE_LINEWIDTH) - 1 + srli a4, a4, XCHAL_DCACHE_LINEWIDTH + mov a3, a2 +.Ldcache_loop: + dhwb a3, 0 + addi a3, a3, (1 << XCHAL_DCACHE_LINEWIDTH) + addi a4, a4, -1 + bnez a4, .Ldcache_loop + isync +#endif +#if XCHAL_ICACHE_SIZE > 0 + /* Invalidate the corresponding lines in the instruction cache. */ + extui a4, a2, 0, XCHAL_ICACHE_LINEWIDTH + addi a4, a4, TRAMPOLINE_SIZE + addi a4, a4, (1 << XCHAL_ICACHE_LINEWIDTH) - 1 + srli a4, a4, XCHAL_ICACHE_LINEWIDTH +.Licache_loop: + ihi a2, 0 + addi a2, a2, (1 << XCHAL_ICACHE_LINEWIDTH) + addi a4, a4, -1 + bnez a4, .Licache_loop +#endif + isync + retw + .size __xtensa_sync_caches, .-__xtensa_sync_caches -- cgit v1.2.3