3 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
6 * LEON2/3 LIBIO low-level routines
7 * Written by Jiri Gaisler.
8 * Copyright (C) 2004 Gaisler Research AB
10 * SPDX-License-Identifier: GPL-2.0+
13 #ifndef __SPARC_WINMACRO_H__
14 #define __SPARC_WINMACRO_H__
16 #include <asm/asmmacro.h>
17 #include <asm/stack.h>
19 /* Store the register window onto the 8-byte aligned area starting
20 * at %reg. It might be %sp, it might not, we don't care.
22 #define RW_STORE(reg) \
23 std %l0, [%reg + RW_L0]; \
24 std %l2, [%reg + RW_L2]; \
25 std %l4, [%reg + RW_L4]; \
26 std %l6, [%reg + RW_L6]; \
27 std %i0, [%reg + RW_I0]; \
28 std %i2, [%reg + RW_I2]; \
29 std %i4, [%reg + RW_I4]; \
30 std %i6, [%reg + RW_I6];
32 /* Load a register window from the area beginning at %reg. */
33 #define RW_LOAD(reg) \
34 ldd [%reg + RW_L0], %l0; \
35 ldd [%reg + RW_L2], %l2; \
36 ldd [%reg + RW_L4], %l4; \
37 ldd [%reg + RW_L6], %l6; \
38 ldd [%reg + RW_I0], %i0; \
39 ldd [%reg + RW_I2], %i2; \
40 ldd [%reg + RW_I4], %i4; \
41 ldd [%reg + RW_I6], %i6;
43 /* Loading and storing struct pt_reg trap frames. */
44 #define PT_LOAD_INS(base_reg) \
45 ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
46 ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
47 ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
48 ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
50 #define PT_LOAD_GLOBALS(base_reg) \
51 ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
52 ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
53 ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
54 ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
56 #define PT_LOAD_YREG(base_reg, scratch) \
57 ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
60 #define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
61 ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
62 ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
63 ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
65 #define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
66 PT_LOAD_YREG(base_reg, scratch) \
67 PT_LOAD_INS(base_reg) \
68 PT_LOAD_GLOBALS(base_reg) \
69 PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
71 #define PT_STORE_INS(base_reg) \
72 std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
73 std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
74 std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
75 std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
77 #define PT_STORE_GLOBALS(base_reg) \
78 st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
79 std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
80 std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
81 std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
83 #define PT_STORE_YREG(base_reg, scratch) \
85 st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
87 #define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
88 st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
89 st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
90 st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
92 #define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
93 PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
94 PT_STORE_GLOBALS(base_reg) \
95 PT_STORE_YREG(base_reg, g_scratch) \
96 PT_STORE_INS(base_reg)
98 /* Store the fpu register window*/
99 #define FW_STORE(reg) \
100 std %f0, [reg + FW_F0]; \
101 std %f2, [reg + FW_F2]; \
102 std %f4, [reg + FW_F4]; \
103 std %f6, [reg + FW_F6]; \
104 std %f8, [reg + FW_F8]; \
105 std %f10, [reg + FW_F10]; \
106 std %f12, [reg + FW_F12]; \
107 std %f14, [reg + FW_F14]; \
108 std %f16, [reg + FW_F16]; \
109 std %f18, [reg + FW_F18]; \
110 std %f20, [reg + FW_F20]; \
111 std %f22, [reg + FW_F22]; \
112 std %f24, [reg + FW_F24]; \
113 std %f26, [reg + FW_F26]; \
114 std %f28, [reg + FW_F28]; \
115 std %f30, [reg + FW_F30]; \
116 st %fsr, [reg + FW_FSR];
118 /* Load a fpu register window from the area beginning at reg. */
119 #define FW_LOAD(reg) \
120 ldd [reg + FW_F0], %f0; \
121 ldd [reg + FW_F2], %f2; \
122 ldd [reg + FW_F4], %f4; \
123 ldd [reg + FW_F6], %f6; \
124 ldd [reg + FW_F8], %f8; \
125 ldd [reg + FW_F10], %f10; \
126 ldd [reg + FW_F12], %f12; \
127 ldd [reg + FW_F14], %f14; \
128 ldd [reg + FW_F16], %f16; \
129 ldd [reg + FW_F18], %f18; \
130 ldd [reg + FW_F20], %f20; \
131 ldd [reg + FW_F22], %f22; \
132 ldd [reg + FW_F24], %f24; \
133 ldd [reg + FW_F26], %f26; \
134 ldd [reg + FW_F28], %f28; \
135 ldd [reg + FW_F30], %f30; \
136 ld [reg + FW_FSR], %fsr;
140 #ifndef __SPARC_WINMACRO_H__
141 #define __SPARC_WINMACRO_H__
143 #include <asm/asmmacro.h>
144 #include <asm/stack.h>
146 /* Store the register window onto the 8-byte aligned area starting
147 * at %reg. It might be %sp, it might not, we don't care.
149 #define RW_STORE(reg) \
150 std %l0, [%reg + RW_L0]; \
151 std %l2, [%reg + RW_L2]; \
152 std %l4, [%reg + RW_L4]; \
153 std %l6, [%reg + RW_L6]; \
154 std %i0, [%reg + RW_I0]; \
155 std %i2, [%reg + RW_I2]; \
156 std %i4, [%reg + RW_I4]; \
157 std %i6, [%reg + RW_I6];
159 /* Load a register window from the area beginning at %reg. */
160 #define RW_LOAD(reg) \
161 ldd [%reg + RW_L0], %l0; \
162 ldd [%reg + RW_L2], %l2; \
163 ldd [%reg + RW_L4], %l4; \
164 ldd [%reg + RW_L6], %l6; \
165 ldd [%reg + RW_I0], %i0; \
166 ldd [%reg + RW_I2], %i2; \
167 ldd [%reg + RW_I4], %i4; \
168 ldd [%reg + RW_I6], %i6;
170 /* Loading and storing struct pt_reg trap frames. */
171 #define PT_LOAD_INS(base_reg) \
172 ldd [%base_reg + SF_REGS_SZ + PT_I0], %i0; \
173 ldd [%base_reg + SF_REGS_SZ + PT_I2], %i2; \
174 ldd [%base_reg + SF_REGS_SZ + PT_I4], %i4; \
175 ldd [%base_reg + SF_REGS_SZ + PT_I6], %i6;
177 #define PT_LOAD_GLOBALS(base_reg) \
178 ld [%base_reg + SF_REGS_SZ + PT_G1], %g1; \
179 ldd [%base_reg + SF_REGS_SZ + PT_G2], %g2; \
180 ldd [%base_reg + SF_REGS_SZ + PT_G4], %g4; \
181 ldd [%base_reg + SF_REGS_SZ + PT_G6], %g6;
183 #define PT_LOAD_YREG(base_reg, scratch) \
184 ld [%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
185 wr %scratch, 0x0, %y;
187 #define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
188 ld [%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
189 ld [%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
190 ld [%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
192 #define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
193 PT_LOAD_YREG(base_reg, scratch) \
194 PT_LOAD_INS(base_reg) \
195 PT_LOAD_GLOBALS(base_reg) \
196 PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
198 #define PT_STORE_INS(base_reg) \
199 std %i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
200 std %i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
201 std %i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
202 std %i6, [%base_reg + SF_REGS_SZ + PT_I6];
204 #define PT_STORE_GLOBALS(base_reg) \
205 st %g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
206 std %g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
207 std %g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
208 std %g6, [%base_reg + SF_REGS_SZ + PT_G6];
210 #define PT_STORE_YREG(base_reg, scratch) \
212 st %scratch, [%base_reg + SF_REGS_SZ + PT_Y];
214 #define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
215 st %pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
216 st %pt_pc, [%base_reg + SF_REGS_SZ + PT_PC]; \
217 st %pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
219 #define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
220 PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
221 PT_STORE_GLOBALS(base_reg) \
222 PT_STORE_YREG(base_reg, g_scratch) \
223 PT_STORE_INS(base_reg)
225 /* Store the fpu register window*/
226 #define FW_STORE(reg) \
227 std %f0, [reg + FW_F0]; \
228 std %f2, [reg + FW_F2]; \
229 std %f4, [reg + FW_F4]; \
230 std %f6, [reg + FW_F6]; \
231 std %f8, [reg + FW_F8]; \
232 std %f10, [reg + FW_F10]; \
233 std %f12, [reg + FW_F12]; \
234 std %f14, [reg + FW_F14]; \
235 std %f16, [reg + FW_F16]; \
236 std %f18, [reg + FW_F18]; \
237 std %f20, [reg + FW_F20]; \
238 std %f22, [reg + FW_F22]; \
239 std %f24, [reg + FW_F24]; \
240 std %f26, [reg + FW_F26]; \
241 std %f28, [reg + FW_F28]; \
242 std %f30, [reg + FW_F30]; \
243 st %fsr, [reg + FW_FSR];
245 /* Load a fpu register window from the area beginning at reg. */
246 #define FW_LOAD(reg) \
247 ldd [reg + FW_F0], %f0; \
248 ldd [reg + FW_F2], %f2; \
249 ldd [reg + FW_F4], %f4; \
250 ldd [reg + FW_F6], %f6; \
251 ldd [reg + FW_F8], %f8; \
252 ldd [reg + FW_F10], %f10; \
253 ldd [reg + FW_F12], %f12; \
254 ldd [reg + FW_F14], %f14; \
255 ldd [reg + FW_F16], %f16; \
256 ldd [reg + FW_F18], %f18; \
257 ldd [reg + FW_F20], %f20; \
258 ldd [reg + FW_F22], %f22; \
259 ldd [reg + FW_F24], %f24; \
260 ldd [reg + FW_F26], %f26; \
261 ldd [reg + FW_F28], %f28; \
262 ldd [reg + FW_F30], %f30; \
263 ld [reg + FW_FSR], %fsr;