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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [config/] [xtensa/] [lib2funcs.S] - Blame information for rev 856

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

Line No. Rev Author Line
1 38 julius
/* Assembly functions for libgcc2.
2
   Copyright (C) 2001 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 2, or (at your option) any later
10
version.
11
 
12
In addition to the permissions in the GNU General Public License, the
13
Free Software Foundation gives you unlimited permission to link the
14
compiled version of this file into combinations with other programs,
15
and to distribute those combinations without any restriction coming
16
from the use of this file.  (The General Public License restrictions
17
do apply in other respects; for example, they cover modification of
18
the file, and distribution when not linked into a combine
19
executable.)
20
 
21
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
22
WARRANTY; without even the implied warranty of MERCHANTABILITY or
23
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
for more details.
25
 
26
You should have received a copy of the GNU General Public License
27
along with GCC; see the file COPYING.  If not, write to the Free
28
Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
29
02110-1301, USA.  */
30
 
31
#include "xtensa-config.h"
32
 
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
35
   arbitrary frames can be accessed.  */
36
 
37
        .align  4
38
        .global __xtensa_libgcc_window_spill
39
        .type   __xtensa_libgcc_window_spill,@function
40
__xtensa_libgcc_window_spill:
41
        entry   sp, 32
42
        movi    a2, 0
43
        syscall
44
        retw
45
        .size   __xtensa_libgcc_window_spill,.-__xtensa_libgcc_window_spill
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 */
66
        mov     a5, a2
67
        movi    a2, 0
68
        syscall
69
        mov     a2, a5
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
94
           saved _two_ frames below the current frame.  */
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
115
           already been flushed.  */
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
128
           from the return address two frames below the target.  */
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
152
   fetch buffer.  */
153
 
154
#define TRAMPOLINE_SIZE 60
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
162
#if XCHAL_DCACHE_SIZE > 0
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

powered by: WebSVN 2.1.0

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