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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [sparc/] [reg_win/] [window.S] - Blame information for rev 507

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

Line No. Rev Author Line
1 30 unneback
/*
2
 *  window.s
3
 *
4
 *  This file contains the register window management routines for the
5
 *  SPARC architecture.  Trap handlers for the following capabilities
6
 *  are included in this file:
7
 *
8
 *    + Window Overflow
9
 *    + Window Underflow
10
 *    + Flushing All Windows
11
 *
12
 *  COPYRIGHT:
13
 *
14
 *  This file includes the window overflow and underflow handlers from
15
 *  the file srt0.s provided with the binary distribution of the SPARC
16
 *  Instruction Simulator (SIS) found at
17
 *  ftp://ftp.estec.esa.nl/pub/ws/wsd/erc32.
18
 *
19
 *  COPYRIGHT (c) 1995. European Space Agency.
20
 *
21
 *  This terms of the RTEMS license apply to this file.
22
 *
23
 *  $Id: window.S,v 1.2 2001-09-27 12:01:39 chris Exp $
24
 */
25
 
26
#include 
27
 
28
        .seg    "text"
29
        /*
30
         *  Window overflow trap handler.
31
         *
32
         *  On entry:
33
         *
34
         *    l0 = psr (from trap table)
35
         *    l1 = pc
36
         *    l2 = npc
37
         */
38
 
39
        PUBLIC(window_overflow_trap_handler)
40
 
41
SYM(window_overflow_trap_handler):
42
 
43
        /*
44
         *  Calculate new WIM by "rotating" the valid bits in the WIM right
45
         *  by one position.  The following shows how the bits move for a SPARC
46
         *  cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8.
47
         *
48
         *    OLD WIM = 76543210
49
         *    NEW WIM = 07654321
50
         *
51
         *  NOTE: New WIM must be stored in a global register since the
52
         *        "save" instruction just prior to the load of the wim
53
         *        register will result in the local register set changing.
54
         */
55
 
56
        mov  %wim, %l3                   ! l3 = WIM
57
        mov  %g1, %l7                    ! save g1
58
        srl  %l3, 1, %g1                 ! g1 = WIM >> 1
59
        sll  %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1 , %l4
60
                                         ! l4 = WIM << (Number Windows - 1)
61
        or   %l4, %g1, %g1               ! g1 = (WIM >> 1) |
62
                                         !      (WIM << (Number Windows - 1))
63
 
64
        save                             ! Get into window to be saved.
65
        mov  %g1, %wim                   ! load new WIM
66
        nop; nop; nop                    ! 3 slot delay
67
        std  %l0, [%sp + 0x00]           ! save local register set
68
        std  %l2, [%sp + 0x08]
69
        std  %l4, [%sp + 0x10]
70
        std  %l6, [%sp + 0x18]
71
        std  %i0, [%sp + 0x20]           ! save input register set
72
        std  %i2, [%sp + 0x28]
73
        std  %i4, [%sp + 0x30]
74
        std  %i6, [%sp + 0x38]
75
        restore                          ! Go back to trap window.
76
        mov  %l7, %g1                    ! restore g1
77
        jmp  %l1                         ! Re-execute save.
78
        rett %l2
79
 
80
        /*
81
         *  Window underflow trap handler.
82
         *
83
         *  On entry:
84
         *
85
         *    l0 = psr (from trap table)
86
         *    l1 = pc
87
         *    l2 = npc
88
         */
89
 
90
        PUBLIC(window_underflow_trap_handler)
91
 
92
SYM(window_underflow_trap_handler):
93
 
94
        /*
95
         *  Calculate new WIM by "rotating" the valid bits in the WIM left
96
         *  by one position.  The following shows how the bits move for a SPARC
97
         *  cpu implementation where SPARC_NUMBER_OF_REGISTER_WINDOWS is 8.
98
         *
99
         *    OLD WIM = 76543210
100
         *    NEW WIM = 07654321
101
         *
102
         *  NOTE: New WIM must be stored in a global register since the
103
         *        "save" instruction just prior to the load of the wim
104
         *        register will result in the local register set changing.
105
         */
106
 
107
        mov  %wim, %l3                  ! Calculate new WIM
108
        sll  %l3, 1, %l4                ! l4 = WIM << 1
109
        srl  %l3, SPARC_NUMBER_OF_REGISTER_WINDOWS-1, %l5
110
                                        ! l5 = WIM >> (Number Windows-1)
111
        or   %l5, %l4, %l5              ! l5 = (WIM << 1) |
112
                                        !      (WIM >> (Number Windows-1))
113
        mov  %l5, %wim                  ! load the new WIM
114
        nop; nop; nop
115
        restore                         ! Two restores to get into the
116
        restore                         ! window to restore
117
        ldd  [%sp + 0x00], %l0          ! First the local register set
118
        ldd  [%sp + 0x08], %l2
119
        ldd  [%sp + 0x10], %l4
120
        ldd  [%sp + 0x18], %l6
121
        ldd  [%sp + 0x20], %i0          ! Then the input registers
122
        ldd  [%sp + 0x28], %i2
123
        ldd  [%sp + 0x30], %i4
124
        ldd  [%sp + 0x38], %i6
125
        save                            ! Get back to the trap window.
126
        save
127
        jmp  %l1                        ! Re-execute restore.
128
        rett  %l2
129
 
130
        /*
131
         *  Flush All Windows trap handler.
132
         *
133
         *  Flush all windows with valid contents except the current one
134
         *  and the one we will be returning to.
135
         *
136
         *  In examining the set register windows, one may logically divide
137
         *  the windows into sets (some of which may be empty) based on their
138
         *  current status:
139
         *
140
         *    + current (i.e. in use),
141
         *    + used (i.e. a restore would not trap)
142
         *    + invalid (i.e. 1 in corresponding bit in WIM)
143
         *    + unused
144
         *
145
         *  Either the used or unused set of windows may be empty.
146
         *
147
         *  NOTE: We assume only one bit is set in the WIM at a time.
148
         *
149
         *  Given a CWP of 5 and a WIM of 0x1, the registers are divided
150
         *  into sets as follows:
151
         *
152
         *    + 0   - invalid
153
         *    + 1-4 - unused
154
         *    + 5   - current
155
         *    + 6-7 - used
156
         *
157
         *  In this case, we only would save the used windows which we
158
         *  will not be returning to -- 6.
159
         *
160
         *    Register Usage while saving the windows:
161
         *      g1 = current PSR
162
         *      g2 = current wim
163
         *      g3 = CWP
164
         *      g4 = wim scratch
165
         *      g5 = scratch
166
         *
167
         *  On entry:
168
         *
169
         *    l0 = psr (from trap table)
170
         *    l1 = pc
171
         *    l2 = npc
172
         */
173
 
174
        PUBLIC(window_flush_trap_handler)
175
 
176
SYM(window_flush_trap_handler):
177
        /*
178
         *  Save the global registers we will be using
179
         */
180
 
181
        mov     %g1, %l3
182
        mov     %g2, %l4
183
        mov     %g3, %l5
184
        mov     %g4, %l6
185
        mov     %g5, %l7
186
 
187
        mov     %l0, %g1                      ! g1 = psr
188
        mov     %wim, %g2                     ! g2 = wim
189
        and     %l0, SPARC_PSR_CWP_MASK, %g3  ! g3 = CWP
190
 
191
        add     %g3, 1, %g5                   ! g5 = CWP + 1
192
        and     %g5, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g5
193
 
194
        mov     1, %g4
195
        sll     %g4, %g5, %g4                 ! g4 = WIM mask for CWP+1 invalid
196
 
197
        restore                               ! go back one register window
198
 
199
save_frame_loop:
200
        sll     %g4, 1, %g5                   ! rotate the "wim" left 1
201
        srl     %g4, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g4
202
        or      %g4, %g5, %g4                 ! g4 = wim if we do one restore
203
 
204
        /*
205
         *  If a restore would not underflow, then continue.
206
         */
207
 
208
        andcc   %g4, %g2, %g0                 ! Any windows to flush?
209
        bnz     done_flushing                 ! No, then continue
210
        nop
211
 
212
        restore                               ! back one window
213
 
214
        /*
215
         *  Now save the window just as if we overflowed to it.
216
         */
217
 
218
        std     %l0, [%sp + CPU_STACK_FRAME_L0_OFFSET]
219
        std     %l2, [%sp + CPU_STACK_FRAME_L2_OFFSET]
220
        std     %l4, [%sp + CPU_STACK_FRAME_L4_OFFSET]
221
        std     %l6, [%sp + CPU_STACK_FRAME_L6_OFFSET]
222
 
223
        std     %i0, [%sp + CPU_STACK_FRAME_I0_OFFSET]
224
        std     %i2, [%sp + CPU_STACK_FRAME_I2_OFFSET]
225
        std     %i4, [%sp + CPU_STACK_FRAME_I4_OFFSET]
226
        std     %i6, [%sp + CPU_STACK_FRAME_I6_FP_OFFSET]
227
 
228
        ba      save_frame_loop
229
        nop
230
 
231
done_flushing:
232
 
233
        add     %g3, 2, %g3                   ! calculate desired WIM
234
        and     %g3, SPARC_NUMBER_OF_REGISTER_WINDOWS - 1, %g3
235
        mov     1, %g4
236
        sll     %g4, %g3, %g4                 ! g4 = new WIM
237
        mov     %g4, %wim
238
 
239
        mov     %g1, %psr                     ! restore PSR
240
        nop
241
        nop
242
        nop
243
 
244
        /*
245
         *  Restore the global registers we used
246
         */
247
 
248
        mov     %l3, %g1
249
        mov     %l4, %g2
250
        mov     %l5, %g3
251
        mov     %l6, %g4
252
        mov     %l7, %g5
253
 
254
        jmpl    %l2, %g0
255
        rett    %l2 + 4
256
 
257
/* end of file */

powered by: WebSVN 2.1.0

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