OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgcc/] [config/] [xtensa/] [lib2funcs.S] - Blame information for rev 849

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.