Initial cut of the open ath9k htc firmware.
[open-ath9k-htc-firmware.git] / target_firmware / magpie_fw_dev / build / magpie_1_1 / sboot / athos / src / xtos / window-vectors.S
1 // window-vectors.S - Register Window Overflow/Underflow Handlers
2 // $Id: //depot/rel/Cottonwood/Xtensa/OS/xtos/window-vectors.S#3 $
3
4 // Copyright (c) 1999-2010 Tensilica Inc.
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the
8 // "Software"), to deal in the Software without restriction, including
9 // without limitation the rights to use, copy, modify, merge, publish,
10 // distribute, sublicense, and/or sell copies of the Software, and to
11 // permit persons to whom the Software is furnished to do so, subject to
12 // the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included
15 // in all copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 #include <xtensa/coreasm.h>
26
27 #if XCHAL_HAVE_WINDOWED && !defined(__XTENSA_CALL0_ABI__)
28
29 # ifndef NO_SECTION_DIRECTIVES
30 // Exports
31 .global _WindowOverflow4
32 .global _WindowUnderflow4
33 .global _WindowOverflow8
34 .global _WindowUnderflow8
35 .global _WindowOverflow12
36 .global _WindowUnderflow12
37
38         //  Note:  the current window exception vectors do not generate any
39         //  literals.  Hence the literal_prefix directive is not necessary.
40         //  Specifying it "just in case" creates an empty section (named
41         //  ".WindowVectors.literal") which can in some cases cause linking
42         //  problems (the linker scripts don't place it anywhere).
43         //  So leave it commented out:
44         //
45         //.begin        literal_prefix  .WindowVectors
46
47         .section                .WindowVectors.text, "ax"
48 # endif
49
50
51 //
52 // GENERAL NOTES:
53 //
54 // These window exception handlers need not be modified.
55 // They are specific to the windowed call ABI only.
56 //
57 // Underflow Handlers:
58 //
59 // The underflow handler for returning from call[i+1] to call[i]
60 // must preserve all the registers from call[i+1]'s window.
61 // In particular, a0 and a1 must be preserved because the RETW instruction
62 // will be reexecuted (and may even underflow again if an intervening
63 // exception has flushed call[i]'s registers).
64 // Registers a2 and up may contain return values.
65 //
66 // The caller could also potentially assume that the callee's a0 and a1
67 // (its own a4&a5 if call4, a8&a9 if call8, a12&a13 if call12)
68 // are correct for whatever reason (not a clean thing to do in general,
69 // but if it's possible, unless the ABI explicitly prohibits it,
70 // it will eventually be done :) -- whether the the ABI needs to
71 // prohibit this is a different question).
72 //
73 // Timing of Handlers:
74 //
75 // Here is an overview of the overhead of taking a window exception,
76 // ie. the number of additional cycles taken relative to case where
77 // an exception is not taken.
78 // NOTE:  these numbers do not take into account any cache misses,
79 // write buffer stalls, or other external stalls, if they occur.
80 // The totals consist of 5 cycles to enter the handler (or 6 or 7
81 // for optional longer pipelines in Xtensa LX), the number of instructions
82 // and interlocks (2nd and 3rd columns below), and 2 cycles jump delay
83 // on return (3 cycles for optional longer I-side pipeline in Xtensa LX):
84 //
85 //                      Instruction+bubbles     Totals (5-stage)
86 //                      XEA1    XEA2            XEA1    XEA2
87 //      Overflow-4      7       5               14      12
88 //      Overflow-8      14      10              21      17
89 //      Overflow-12     18      14              25      21
90 //      Underflow-4     6       5               13      12
91 //      Underflow-8     14      10              21      17
92 //      Underflow-12    18      14              25      21
93 //
94 //      Underflow-8     15      12              25      22      (7-stage; could be made 1 less)
95 //      Underflow-12    19      16              29      26      (7-stage; could be made 1 less)
96
97 #ifndef WINDOW_BASE_VECOFS
98 #define WINDOW_BASE_VECOFS      XCHAL_WINDOW_OF4_VECOFS
99 #endif
100
101
102 // 4-Register Window Overflow Vector (Handler)
103 //
104 // Invoked if a call[i] referenced a register (a4-a15)
105 // that contains data from ancestor call[j];
106 // call[j] had done a call4 to call[j+1].
107 // On entry here:
108 //      window rotated to call[j] start point;
109 //      a0-a3 are registers to be saved;
110 //      a4-a15 must be preserved;
111 //      a5 is call[j+1]'s stack pointer.
112
113         .org    XCHAL_WINDOW_OF4_VECOFS - WINDOW_BASE_VECOFS
114 _WindowOverflow4:
115 #if XCHAL_HAVE_XEA1
116         addi    a5, a5, -16     // to make store offsets positive
117         s32i    a0, a5,   0     // save a0 to call[j+1]'s stack frame
118         s32i    a1, a5,   4     // save a1 to call[j+1]'s stack frame
119         s32i    a2, a5,   8     // save a2 to call[j+1]'s stack frame
120         s32i    a3, a5,  12     // save a3 to call[j+1]'s stack frame
121         addi    a5, a5,  16     // restore a5
122 #else
123         s32e    a0, a5, -16     // save a0 to call[j+1]'s stack frame
124         s32e    a1, a5, -12     // save a1 to call[j+1]'s stack frame
125         s32e    a2, a5,  -8     // save a2 to call[j+1]'s stack frame
126         s32e    a3, a5,  -4     // save a3 to call[j+1]'s stack frame
127 #endif
128         rfwo                    // rotates back to call[i] position
129
130         .size   _WindowOverflow4, . - _WindowOverflow4
131
132
133 // 4-Register Window Underflow Vector (Handler)
134 //
135 // Invoked by RETW returning from call[i+1] to call[i]
136 // where call[i]'s registers must be reloaded (not live in ARs);
137 // call[i] had done a call4 to call[i+1].
138 // On entry here:
139 //      window rotated to call[i] start point;
140 //      a0-a3 are undefined, must be reloaded with call[i].reg[0..3];
141 //      a4-a15 must be preserved (they are call[i+1].reg[0..11]);
142 //      a5 is call[i+1]'s stack pointer.
143
144         .org    XCHAL_WINDOW_UF4_VECOFS - WINDOW_BASE_VECOFS
145 _WindowUnderflow4:
146 #if XCHAL_HAVE_XEA1
147         addi    a3, a5, -16     // to make load offsets positive
148         l32i    a0, a3,   0     // restore a0 from call[i+1]'s stack frame
149         l32i    a1, a3,   4     // restore a1 from call[i+1]'s stack frame
150         l32i    a2, a3,   8     // restore a2 from call[i+1]'s stack frame
151         l32i    a3, a3,  12     // restore a3 from call[i+1]'s stack frame
152 #else
153         l32e    a0, a5, -16     // restore a0 from call[i+1]'s stack frame
154         l32e    a1, a5, -12     // restore a1 from call[i+1]'s stack frame
155         l32e    a2, a5,  -8     // restore a2 from call[i+1]'s stack frame
156         l32e    a3, a5,  -4     // restore a3 from call[i+1]'s stack frame
157 #endif
158         rfwu
159
160         .size   _WindowUnderflow4, . - _WindowUnderflow4
161
162
163 // 8-Register Window Overflow Vector (Handler)
164 //
165 // Invoked if a call[i] referenced a register (a4-a15)
166 // that contains data from ancestor call[j];
167 // call[j] had done a call8 to call[j+1].
168 // On entry here:
169 //      window rotated to call[j] start point;
170 //      a0-a7 are registers to be saved;
171 //      a8-a15 must be preserved;
172 //      a9 is call[j+1]'s stack pointer.
173
174         .org    XCHAL_WINDOW_OF8_VECOFS - WINDOW_BASE_VECOFS
175 _WindowOverflow8:
176 #if XCHAL_HAVE_XEA1
177         addi    a9, a9, -16     // to make store offsets positive
178         s32i    a0, a9,   0     // save a0 to call[j+1]'s stack frame
179         addi    a0, a1, -16     // a0 <- call[j-1]'s sp
180         s32i    a1, a9,   4     // save a1 to call[j+1]'s stack frame
181         l32i    a0, a0,   4     // (used to find end of call[j]'s frame)
182         s32i    a2, a9,   8     // save a2 to call[j+1]'s stack frame
183         s32i    a3, a9,  12     // save a3 to call[j+1]'s stack frame
184         addi    a9, a9,  16     // restore a9
185         addi    a0, a0, -32     // to make load offsets positive
186         s32i    a4, a0,   0     // save a4 to call[j]'s stack frame
187         s32i    a5, a0,   4     // save a5 to call[j]'s stack frame
188         s32i    a6, a0,   8     // save a6 to call[j]'s stack frame
189         s32i    a7, a0,  12     // save a7 to call[j]'s stack frame
190 #else
191         s32e    a0, a9, -16     // save a0 to call[j+1]'s stack frame
192         l32e    a0, a1, -12     // a0 <- call[j-1]'s sp (used to find end of call[j]'s frame)
193         s32e    a1, a9, -12     // save a1 to call[j+1]'s stack frame
194         s32e    a2, a9,  -8     // save a2 to call[j+1]'s stack frame
195         s32e    a3, a9,  -4     // save a3 to call[j+1]'s stack frame
196         s32e    a4, a0, -32     // save a4 to call[j]'s stack frame
197         s32e    a5, a0, -28     // save a5 to call[j]'s stack frame
198         s32e    a6, a0, -24     // save a6 to call[j]'s stack frame
199         s32e    a7, a0, -20     // save a7 to call[j]'s stack frame
200 #endif
201         rfwo                    // rotates back to call[i] position
202
203         .size   _WindowOverflow8, . - _WindowOverflow8
204
205
206 // 8-Register Window Underflow Vector (Handler)
207 //
208 // Invoked by RETW returning from call[i+1] to call[i]
209 // where call[i]'s registers must be reloaded (not live in ARs);
210 // call[i] had done a call8 to call[i+1].
211 // On entry here:
212 //      window rotated to call[i] start point;
213 //      a0-a7 are undefined, must be reloaded with call[i].reg[0..7];
214 //      a8-a15 must be preserved (they are call[i+1].reg[0..7]);
215 //      a9 is call[i+1]'s stack pointer.
216
217         .org    XCHAL_WINDOW_UF8_VECOFS - WINDOW_BASE_VECOFS
218 _WindowUnderflow8:
219 #if XCHAL_HAVE_XEA1
220         addi    a9, a9, -16     // to make load offsets positive
221         l32i    a0, a9,   0     // restore a0 from call[i+1]'s stack frame
222         l32i    a1, a9,   4     // restore a1 from call[i+1]'s stack frame
223         l32i    a2, a9,   8     // restore a2 from call[i+1]'s stack frame
224         addi    a7, a1, -16     // a7 <- call[i-1]'s sp
225         l32i    a7, a7,   4     // (used to find end of call[i]'s frame)
226         l32i    a3, a9,  12     // restore a3 from call[i+1]'s stack frame
227         addi    a9, a9,  16     // restore a9
228         addi    a7, a7, -32     // to make load offsets positive
229         l32i    a4, a7,   0     // restore a4 from call[i]'s stack frame
230         l32i    a5, a7,   4     // restore a5 from call[i]'s stack frame
231         l32i    a6, a7,   8     // restore a6 from call[i]'s stack frame
232         l32i    a7, a7,  12     // restore a7 from call[i]'s stack frame
233 #else
234         l32e    a0, a9, -16     // restore a0 from call[i+1]'s stack frame
235         l32e    a1, a9, -12     // restore a1 from call[i+1]'s stack frame
236         l32e    a2, a9,  -8     // restore a2 from call[i+1]'s stack frame
237         l32e    a7, a1, -12     // a7 <- call[i-1]'s sp (used to find end of call[i]'s frame)
238         l32e    a3, a9,  -4     // restore a3 from call[i+1]'s stack frame
239         l32e    a4, a7, -32     // restore a4 from call[i]'s stack frame
240         l32e    a5, a7, -28     // restore a5 from call[i]'s stack frame
241         l32e    a6, a7, -24     // restore a6 from call[i]'s stack frame
242         l32e    a7, a7, -20     // restore a7 from call[i]'s stack frame
243 #endif
244         rfwu
245
246         .size   _WindowUnderflow8, . - _WindowUnderflow8
247
248
249 // 12-Register Window Overflow Vector (Handler)
250 //
251 // Invoked if a call[i] referenced a register (a4-a15)
252 // that contains data from ancestor call[j];
253 // call[j] had done a call12 to call[j+1].
254 // On entry here:
255 //      window rotated to call[j] start point;
256 //      a0-a11 are registers to be saved;
257 //      a12-a15 must be preserved;
258 //      a13 is call[j+1]'s stack pointer.
259
260         .org    XCHAL_WINDOW_OF12_VECOFS - WINDOW_BASE_VECOFS
261 _WindowOverflow12:
262 #if XCHAL_HAVE_XEA1
263         addi    a13, a13, -16   // to make store offsets positive
264         s32i    a0,  a13,   0   // save a0 to call[j+1]'s stack frame
265         addi    a0,  a1,  -16   // a0 <- call[j-1]'s sp
266         s32i    a1,  a13,   4   // save a1 to call[j+1]'s stack frame
267         l32i    a0,  a0,    4   // (used to find end of call[j]'s frame)
268         s32i    a2,  a13,   8   // save a2 to call[j+1]'s stack frame
269         s32i    a3,  a13,  12   // save a3 to call[j+1]'s stack frame
270         addi    a13, a13,  16   // restore a13
271         addi    a0,  a0,  -48   // to make load offsets positive
272         s32i    a4,  a0,    0   // save a4 to end of call[j]'s stack frame
273         s32i    a5,  a0,    4   // save a5 to end of call[j]'s stack frame
274         s32i    a6,  a0,    8   // save a6 to end of call[j]'s stack frame
275         s32i    a7,  a0,   12   // save a7 to end of call[j]'s stack frame
276         s32i    a8,  a0,   16   // save a8 to end of call[j]'s stack frame
277         s32i    a9,  a0,   20   // save a9 to end of call[j]'s stack frame
278         s32i    a10, a0,   24   // save a10 to end of call[j]'s stack frame
279         s32i    a11, a0,   28   // save a11 to end of call[j]'s stack frame
280 #else
281         s32e    a0,  a13, -16   // save a0 to call[j+1]'s stack frame
282         l32e    a0,  a1,  -12   // a0 <- call[j-1]'s sp (used to find end of call[j]'s frame)
283         s32e    a1,  a13, -12   // save a1 to call[j+1]'s stack frame
284         s32e    a2,  a13,  -8   // save a2 to call[j+1]'s stack frame
285         s32e    a3,  a13,  -4   // save a3 to call[j+1]'s stack frame
286         s32e    a4,  a0,  -48   // save a4 to end of call[j]'s stack frame
287         s32e    a5,  a0,  -44   // save a5 to end of call[j]'s stack frame
288         s32e    a6,  a0,  -40   // save a6 to end of call[j]'s stack frame
289         s32e    a7,  a0,  -36   // save a7 to end of call[j]'s stack frame
290         s32e    a8,  a0,  -32   // save a8 to end of call[j]'s stack frame
291         s32e    a9,  a0,  -28   // save a9 to end of call[j]'s stack frame
292         s32e    a10, a0,  -24   // save a10 to end of call[j]'s stack frame
293         s32e    a11, a0,  -20   // save a11 to end of call[j]'s stack frame
294 #endif
295         rfwo                    // rotates back to call[i] position
296
297         .size   _WindowOverflow12, . - _WindowOverflow12
298
299
300 // 12-Register Window Underflow Vector (Handler)
301 //
302 // Invoked by RETW returning from call[i+1] to call[i]
303 // where call[i]'s registers must be reloaded (not live in ARs);
304 // call[i] had done a call12 to call[i+1].
305 // On entry here:
306 //      window rotated to call[i] start point;
307 //      a0-a11 are undefined, must be reloaded with call[i].reg[0..11];
308 //      a12-a15 must be preserved (they are call[i+1].reg[0..3]);
309 //      a13 is call[i+1]'s stack pointer.
310
311         .org    XCHAL_WINDOW_UF12_VECOFS - WINDOW_BASE_VECOFS
312 _WindowUnderflow12:
313 #if XCHAL_HAVE_XEA1
314         addi    a13, a13, -16   // to make load offsets positive
315         l32i    a0,  a13,   0   // restore a0 from call[i+1]'s stack frame
316         l32i    a1,  a13,   4   // restore a1 from call[i+1]'s stack frame
317         l32i    a2,  a13,   8   // restore a2 from call[i+1]'s stack frame
318         addi    a11, a1,  -16   // a11 <- call[i-1]'s sp
319         l32i    a11, a11,   4   // (used to find end of call[i]'s frame)
320         l32i    a3,  a13,  12   // restore a3 from call[i+1]'s stack frame
321         addi    a13, a13,  16   // restore a13
322         addi    a11, a11, -48   // to make load offsets positive
323         l32i    a4,  a11,   0   // restore a4 from end of call[i]'s stack frame
324         l32i    a5,  a11,   4   // restore a5 from end of call[i]'s stack frame
325         l32i    a6,  a11,   8   // restore a6 from end of call[i]'s stack frame
326         l32i    a7,  a11,  12   // restore a7 from end of call[i]'s stack frame
327         l32i    a8,  a11,  16   // restore a8 from end of call[i]'s stack frame
328         l32i    a9,  a11,  20   // restore a9 from end of call[i]'s stack frame
329         l32i    a10, a11,  24   // restore a10 from end of call[i]'s stack frame
330         l32i    a11, a11,  28   // restore a11 from end of call[i]'s stack frame
331 #else
332         l32e    a0,  a13, -16   // restore a0 from call[i+1]'s stack frame
333         l32e    a1,  a13, -12   // restore a1 from call[i+1]'s stack frame
334         l32e    a2,  a13,  -8   // restore a2 from call[i+1]'s stack frame
335         l32e    a11, a1,  -12   // a11 <- call[i-1]'s sp (used to find end of call[i]'s frame)
336         l32e    a3,  a13,  -4   // restore a3 from call[i+1]'s stack frame
337         l32e    a4,  a11, -48   // restore a4 from end of call[i]'s stack frame
338         l32e    a5,  a11, -44   // restore a5 from end of call[i]'s stack frame
339         l32e    a6,  a11, -40   // restore a6 from end of call[i]'s stack frame
340         l32e    a7,  a11, -36   // restore a7 from end of call[i]'s stack frame
341         l32e    a8,  a11, -32   // restore a8 from end of call[i]'s stack frame
342         l32e    a9,  a11, -28   // restore a9 from end of call[i]'s stack frame
343         l32e    a10, a11, -24   // restore a10 from end of call[i]'s stack frame
344         l32e    a11, a11, -20   // restore a11 from end of call[i]'s stack frame
345 #endif
346         rfwu
347
348         .size   _WindowUnderflow12, . - _WindowUnderflow12
349
350
351 # ifndef NO_SECTION_DIRECTIVES
352         //.end  literal_prefix
353         .text
354 # endif
355
356
357 #endif /* XCHAL_HAVE_WINDOWED && !defined(__XTENSA_CALL0_ABI__) */
358