URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [xtensa/] [lib2funcs.S] - Rev 734
Compare with Previous | Blame | View Log
/* 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 underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 3, or (at your option) any laterversion.GCC is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public Licensefor more details.Under Section 7 of GPL version 3, you are granted additionalpermissions described in the GCC Runtime Library Exception, version3.1, as published by the Free Software Foundation.You should have received a copy of the GNU General Public License anda copy of the GCC Runtime Library Exception along with this program;see the files COPYING3 and COPYING.RUNTIME respectively. If not, see<http://www.gnu.org/licenses/>. */#include "xtensa-config.h"/* __xtensa_libgcc_window_spill: This function flushes out all but thecurrent register window. This is used to set up the stack so thatarbitrary frames can be accessed. */.align 4.global __xtensa_libgcc_window_spill.type __xtensa_libgcc_window_spill,@function__xtensa_libgcc_window_spill:entry sp, 32movi a2, 0syscallretw.size __xtensa_libgcc_window_spill, .-__xtensa_libgcc_window_spill/* __xtensa_nonlocal_goto: This code does all the hard work of anonlocal goto on Xtensa. It is here in the library to avoid thecode size bloat of generating it in-line. There are twoarguments:a2 = frame pointer for the procedure containing the labela3 = goto handler addressThis function never returns to its caller but instead goes directlyto 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, a2movi a2, 0syscallmov a2, a5/* Because the save area for a0-a3 is stored one frame belowthe one identified by a2, the only way to restore thoseregisters is to unwind the stack. If alloca() were nevercalled, we could just unwind until finding the sp valuematching a2. However, a2 is a frame pointer, not a stackpointer, and may not be encountered during the unwinding.The solution is to unwind until going _past_ the valuegiven by a2. This involves keeping three stack pointervalues during the unwinding:next = sp of frame N-1cur = sp of frame Nprev = sp of frame N+1When next > a2, the desired save area is stored relativeto prev. At this point, cur will be the same as a2except in the alloca() case.Besides finding the values to be restored to a0-a3, we alsoneed to find the current window size for the targetfunction. This can be extracted from the high bits of thereturn address, initially in a0. As the unwindingproceeds, the window size is taken from the value of a0saved _two_ frames below the current frame. */addi a5, sp, -16 /* a5 = prev - save area */l32i a6, a5, 4addi 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 savedvalues of a0-a3. Copy those values into the save area at thecurrent sp so they will be reloaded when the return from thisfunction underflows. We don't have to worry about exceptionswhile updating the current save area, because the windows havealready been flushed. */addi a4, sp, -16 /* a4 = save area of this function */l32i a6, a5, 0l32i a7, a5, 4s32i a6, a4, 0s32i a7, a4, 4l32i a6, a5, 8l32i a7, a5, 12s32i a6, a4, 8s32i a7, a4, 12/* Set return address to goto handler. Use the window size bitsfrom 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 2src 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 trampolineon the stack to force all the data writes to memory and invalidate theinstruction cache. a2 is the address of the new trampoline.After the trampoline data is written out, it must be flushed out ofthe data cache into memory. We use DHWB in case we have a writebackcache. At least one DHWB instruction is needed for each data cacheline which may be touched by the trampoline. An ISYNC instructionmust 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 maybe touched by the trampoline. An ISYNC instruction is also needed tomake sure that the modified instructions are loaded into the instructionfetch 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_LINEWIDTHaddi a4, a4, TRAMPOLINE_SIZEaddi a4, a4, (1 << XCHAL_DCACHE_LINEWIDTH) - 1srli a4, a4, XCHAL_DCACHE_LINEWIDTHmov a3, a2.Ldcache_loop:dhwb a3, 0addi a3, a3, (1 << XCHAL_DCACHE_LINEWIDTH)addi a4, a4, -1bnez a4, .Ldcache_loopisync#endif#if XCHAL_ICACHE_SIZE > 0/* Invalidate the corresponding lines in the instruction cache. */extui a4, a2, 0, XCHAL_ICACHE_LINEWIDTHaddi a4, a4, TRAMPOLINE_SIZEaddi a4, a4, (1 << XCHAL_ICACHE_LINEWIDTH) - 1srli a4, a4, XCHAL_ICACHE_LINEWIDTH.Licache_loop:ihi a2, 0addi a2, a2, (1 << XCHAL_ICACHE_LINEWIDTH)addi a4, a4, -1bnez a4, .Licache_loop#endifisyncretw.size __xtensa_sync_caches, .-__xtensa_sync_caches
