]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/xtensa/lib2funcs.S
* gcc_update: Include revision number in LAST_UPDATED.
[thirdparty/gcc.git] / gcc / config / xtensa / lib2funcs.S
CommitLineData
03984308
BW
1/* Assembly functions for libgcc2.
2 Copyright (C) 2001 Free Software Foundation, Inc.
3 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
e2fb85da
BW
12In addition to the permissions in the GNU General Public License, the
13Free Software Foundation gives you unlimited permission to link the
14compiled version of this file into combinations with other programs,
15and to distribute those combinations without any restriction coming
16from the use of this file. (The General Public License restrictions
17do apply in other respects; for example, they cover modification of
18the file, and distribution when not linked into a combine
19executable.)
20
03984308
BW
21GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22WARRANTY; without even the implied warranty of MERCHANTABILITY or
23FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24for more details.
25
26You should have received a copy of the GNU General Public License
27along with GCC; see the file COPYING. If not, write to the Free
39d14dda
KC
28Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2902110-1301, USA. */
03984308 30
e677f70c 31#include "xtensa-config.h"
03984308 32
57174693
BW
33/* __xtensa_libgcc_window_spill: This function flushes out all but the
34 current register window. This is used to set up the stack so that
ff482c8d 35 arbitrary frames can be accessed. */
03984308 36
57174693
BW
37 .align 4
38 .global __xtensa_libgcc_window_spill
39 .type __xtensa_libgcc_window_spill,@function
03984308 40__xtensa_libgcc_window_spill:
57174693
BW
41 entry sp, 32
42 movi a2, 0
43 syscall
03984308 44 retw
57174693 45 .size __xtensa_libgcc_window_spill,.-__xtensa_libgcc_window_spill
03984308
BW
46
47
48/* __xtensa_nonlocal_goto: This code does all the hard work of a
49 nonlocal goto on Xtensa. It is here in the library to avoid the
50 code size bloat of generating it in-line. There are two
51 arguments:
52
53 a2 = frame pointer for the procedure containing the label
54 a3 = goto handler address
55
56 This function never returns to its caller but instead goes directly
57 to the address of the specified goto handler. */
58
59 .align 4
60 .global __xtensa_nonlocal_goto
61 .type __xtensa_nonlocal_goto,@function
62__xtensa_nonlocal_goto:
63 entry sp, 32
64
65 /* flush registers */
57174693
BW
66 mov a5, a2
67 movi a2, 0
68 syscall
69 mov a2, a5
03984308
BW
70
71 /* Because the save area for a0-a3 is stored one frame below
72 the one identified by a2, the only way to restore those
73 registers is to unwind the stack. If alloca() were never
74 called, we could just unwind until finding the sp value
75 matching a2. However, a2 is a frame pointer, not a stack
76 pointer, and may not be encountered during the unwinding.
77 The solution is to unwind until going _past_ the value
78 given by a2. This involves keeping three stack pointer
79 values during the unwinding:
80
81 next = sp of frame N-1
82 cur = sp of frame N
83 prev = sp of frame N+1
84
85 When next > a2, the desired save area is stored relative
86 to prev. At this point, cur will be the same as a2
87 except in the alloca() case.
88
89 Besides finding the values to be restored to a0-a3, we also
90 need to find the current window size for the target
91 function. This can be extracted from the high bits of the
92 return address, initially in a0. As the unwinding
93 proceeds, the window size is taken from the value of a0
ff482c8d 94 saved _two_ frames below the current frame. */
03984308
BW
95
96 addi a5, sp, -16 # a5 = prev - save area
97 l32i a6, a5, 4
98 addi a6, a6, -16 # a6 = cur - save area
99 mov a8, a0 # a8 = return address (for window size)
100 j .Lfirstframe
101
102.Lnextframe:
103 l32i a8, a5, 0 # next return address (for window size)
104 mov a5, a6 # advance prev
105 addi a6, a7, -16 # advance cur
106.Lfirstframe:
107 l32i a7, a6, 4 # a7 = next
108 bge a2, a7, .Lnextframe
109
110 /* At this point, prev (a5) points to the save area with the saved
111 values of a0-a3. Copy those values into the save area at the
112 current sp so they will be reloaded when the return from this
113 function underflows. We don't have to worry about exceptions
114 while updating the current save area, because the windows have
ff482c8d 115 already been flushed. */
03984308
BW
116
117 addi a4, sp, -16 # a4 = save area of this function
118 l32i a6, a5, 0
119 l32i a7, a5, 4
120 s32i a6, a4, 0
121 s32i a7, a4, 4
122 l32i a6, a5, 8
123 l32i a7, a5, 12
124 s32i a6, a4, 8
125 s32i a7, a4, 12
126
127 /* Set return address to goto handler. Use the window size bits
ff482c8d 128 from the return address two frames below the target. */
03984308
BW
129 extui a8, a8, 30, 2 # get window size from return addr.
130 slli a3, a3, 2 # get goto handler addr. << 2
131 ssai 2
132 src a0, a8, a3 # combine them with a funnel shift
133
134 retw
135 .size __xtensa_nonlocal_goto,.-__xtensa_nonlocal_goto
136
137
138/* __xtensa_sync_caches: This function is called after writing a trampoline
139 on the stack to force all the data writes to memory and invalidate the
140 instruction cache. a2 is the address of the new trampoline.
141
142 After the trampoline data is written out, it must be flushed out of
143 the data cache into memory. We use DHWB in case we have a writeback
144 cache. At least one DHWB instruction is needed for each data cache
145 line which may be touched by the trampoline. An ISYNC instruction
146 must follow the DHWBs.
147
148 We have to flush the i-cache to make sure that the new values get used.
149 At least one IHI instruction is needed for each i-cache line which may
150 be touched by the trampoline. An ISYNC instruction is also needed to
151 make sure that the modified instructions are loaded into the instruction
ff482c8d 152 fetch buffer. */
13fb3a61 153
f42f5a1b 154#define TRAMPOLINE_SIZE 59
03984308
BW
155
156 .text
157 .align 4
158 .global __xtensa_sync_caches
159 .type __xtensa_sync_caches,@function
160__xtensa_sync_caches:
161 entry sp, 32
1839841c 162#if XCHAL_DCACHE_SIZE > 0
03984308
BW
163 # Flush the trampoline from the data cache
164 extui a4, a2, 0, XCHAL_DCACHE_LINEWIDTH
165 addi a4, a4, TRAMPOLINE_SIZE
166 addi a4, a4, (1 << XCHAL_DCACHE_LINEWIDTH) - 1
167 srli a4, a4, XCHAL_DCACHE_LINEWIDTH
168 mov a3, a2
169.Ldcache_loop:
170 dhwb a3, 0
171 addi a3, a3, (1 << XCHAL_DCACHE_LINEWIDTH)
172 addi a4, a4, -1
173 bnez a4, .Ldcache_loop
174 isync
175#endif
176#if XCHAL_ICACHE_SIZE > 0
177 # Invalidate the corresponding lines in the instruction cache
178 extui a4, a2, 0, XCHAL_ICACHE_LINEWIDTH
179 addi a4, a4, TRAMPOLINE_SIZE
180 addi a4, a4, (1 << XCHAL_ICACHE_LINEWIDTH) - 1
181 srli a4, a4, XCHAL_ICACHE_LINEWIDTH
182.Licache_loop:
183 ihi a2, 0
184 addi a2, a2, (1 << XCHAL_ICACHE_LINEWIDTH)
185 addi a4, a4, -1
186 bnez a4, .Licache_loop
187 isync
188#endif
189 retw
190 .size __xtensa_sync_caches,.-__xtensa_sync_caches