source: rtems/cpukit/score/cpu/riscv/riscv-context-validate.S @ 8db3f0e

5
Last change on this file since 8db3f0e was 52352387, checked in by Sebastian Huber <sebastian.huber@…>, on 06/28/18 at 07:32:26

riscv: Add floating-point support

Update #3433.

  • Property mode set to 100644
File size: 8.7 KB
Line 
1/*
2 * Copyright (c) 2018 embedded brains GmbH
3 * Copyright (c) 2015 Hesham Almatary <hesham@alumni.york.ac.uk>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <rtems/asm.h>
32#include <rtems/score/cpu.h>
33
34#define OFFSET(i) ((i) * CPU_SIZEOF_POINTER)
35
36#define RA_OFFSET OFFSET(0)
37#define T0_OFFSET OFFSET(1)
38#define T1_OFFSET OFFSET(2)
39#define T2_OFFSET OFFSET(3)
40#define S0_OFFSET OFFSET(4)
41#define S1_OFFSET OFFSET(5)
42#define A0_OFFSET OFFSET(6)
43#define A1_OFFSET OFFSET(7)
44#define A2_OFFSET OFFSET(8)
45#define A3_OFFSET OFFSET(9)
46#define A4_OFFSET OFFSET(10)
47#define A5_OFFSET OFFSET(11)
48#define A6_OFFSET OFFSET(12)
49#define A7_OFFSET OFFSET(13)
50#define S2_OFFSET OFFSET(14)
51#define S3_OFFSET OFFSET(15)
52#define S4_OFFSET OFFSET(16)
53#define S5_OFFSET OFFSET(17)
54#define S6_OFFSET OFFSET(18)
55#define S7_OFFSET OFFSET(19)
56#define S8_OFFSET OFFSET(20)
57#define S9_OFFSET OFFSET(21)
58#define S10_OFFSET OFFSET(22)
59#define S11_OFFSET OFFSET(23)
60#define T3_OFFSET OFFSET(24)
61#define T4_OFFSET OFFSET(25)
62#define T5_OFFSET OFFSET(26)
63#define T6_OFFSET OFFSET(27)
64#define TMP_OFFSET OFFSET(28)
65
66#if __riscv_flen == 32
67#define FOFFSET(i) (OFFSET(29) + (i) * 4)
68#elif __riscv_flen == 64
69#define FOFFSET(i) (OFFSET(29) + (i) * 8)
70#else
71#define FOFFSET(i) OFFSET(29)
72#endif /* __riscv_flen */
73
74#define FRAME_SIZE \
75  ((FOFFSET(32) + CPU_STACK_ALIGNMENT - 1) & ~(CPU_STACK_ALIGNMENT - 1))
76
77        .section        .text, "ax", @progbits
78        .align  2
79
80PUBLIC(_CPU_Context_validate)
81SYM(_CPU_Context_validate):
82        addi    sp, sp, -FRAME_SIZE
83
84        /* Save */
85
86        SREG    ra, RA_OFFSET(sp)
87        SREG    t0, T0_OFFSET(sp)
88        SREG    t1, T1_OFFSET(sp)
89        SREG    t2, T2_OFFSET(sp)
90        SREG    s0, S0_OFFSET(sp)
91        SREG    s1, S1_OFFSET(sp)
92        SREG    a0, A0_OFFSET(sp)
93        SREG    a1, A1_OFFSET(sp)
94        SREG    a2, A2_OFFSET(sp)
95        SREG    a3, A3_OFFSET(sp)
96        SREG    a4, A4_OFFSET(sp)
97        SREG    a5, A5_OFFSET(sp)
98        SREG    a6, A6_OFFSET(sp)
99        SREG    a7, A7_OFFSET(sp)
100        SREG    s2, S2_OFFSET(sp)
101        SREG    s3, S3_OFFSET(sp)
102        SREG    s4, S4_OFFSET(sp)
103        SREG    s5, S5_OFFSET(sp)
104        SREG    s6, S6_OFFSET(sp)
105        SREG    s7, S7_OFFSET(sp)
106        SREG    s8, S8_OFFSET(sp)
107        SREG    s9, S9_OFFSET(sp)
108        SREG    s10, S10_OFFSET(sp)
109        SREG    s11, S11_OFFSET(sp)
110        SREG    t3, T3_OFFSET(sp)
111        SREG    t4, T4_OFFSET(sp)
112        SREG    t5, T5_OFFSET(sp)
113        SREG    t6, T6_OFFSET(sp)
114
115#if __riscv_flen > 0
116        FSREG   f0, FOFFSET(0)(sp)
117        FSREG   f1, FOFFSET(1)(sp)
118        FSREG   f2, FOFFSET(2)(sp)
119        FSREG   f3, FOFFSET(3)(sp)
120        FSREG   f4, FOFFSET(4)(sp)
121        FSREG   f5, FOFFSET(5)(sp)
122        FSREG   f6, FOFFSET(6)(sp)
123        FSREG   f7, FOFFSET(7)(sp)
124        FSREG   f8, FOFFSET(8)(sp)
125        FSREG   f9, FOFFSET(9)(sp)
126        FSREG   f10, FOFFSET(10)(sp)
127        FSREG   f11, FOFFSET(11)(sp)
128        FSREG   f12, FOFFSET(12)(sp)
129        FSREG   f13, FOFFSET(13)(sp)
130        FSREG   f14, FOFFSET(14)(sp)
131        FSREG   f15, FOFFSET(15)(sp)
132        FSREG   f16, FOFFSET(16)(sp)
133        FSREG   f17, FOFFSET(17)(sp)
134        FSREG   f18, FOFFSET(18)(sp)
135        FSREG   f19, FOFFSET(19)(sp)
136        FSREG   f20, FOFFSET(20)(sp)
137        FSREG   f21, FOFFSET(21)(sp)
138        FSREG   f22, FOFFSET(22)(sp)
139        FSREG   f23, FOFFSET(23)(sp)
140        FSREG   f24, FOFFSET(24)(sp)
141        FSREG   f25, FOFFSET(25)(sp)
142        FSREG   f26, FOFFSET(26)(sp)
143        FSREG   f27, FOFFSET(27)(sp)
144        FSREG   f28, FOFFSET(28)(sp)
145        FSREG   f29, FOFFSET(29)(sp)
146        FSREG   f30, FOFFSET(30)(sp)
147        FSREG   f31, FOFFSET(31)(sp)
148#endif /* __riscv_flen */
149
150        /* Fill */
151
152        addi    ra, a0, 1
153        /* sp must remain as is */
154        /* gp must remain as is */
155        /* tp must remain as is */
156        /* t0 is used for temporary values */
157        addi    t1, a0, 2
158        addi    t2, a0, 3
159        addi    s0, a0, 4
160        addi    s1, a0, 5
161        /* a0 is the pattern */
162        addi    a1, a0, 6
163        addi    a2, a0, 7
164        addi    a3, a0, 8
165        addi    a4, a0, 9
166        addi    a5, a0, 10
167        addi    a6, a0, 11
168        addi    a7, a0, 12
169        addi    s2, a0, 13
170        addi    s3, a0, 14
171        addi    s4, a0, 15
172        addi    s5, a0, 16
173        addi    s6, a0, 17
174        addi    s7, a0, 18
175        addi    s8, a0, 19
176        addi    s9, a0, 20
177        addi    s10, a0, 21
178        addi    s11, a0, 22
179        addi    t3, a0, 23
180
181        xor     t4, sp, a0
182        xor     t5, gp, a0
183        xor     t6, tp, a0
184
185#if __riscv_flen > 0
186        andi    t0, a0, 0x1f
187        fsflags t0
188
189        .macro  fill_f reg, inc
190        addi    t0, a0, 24 + \inc
191        FMVYX   \reg, t0
192        .endm
193
194        fill_f  f0, 0
195        fill_f  f1, 1
196        fill_f  f2, 2
197        fill_f  f3, 3
198        fill_f  f4, 4
199        fill_f  f5, 5
200        fill_f  f6, 6
201        fill_f  f7, 7
202        fill_f  f8, 8
203        fill_f  f9, 9
204        fill_f  f10, 10
205        fill_f  f11, 11
206        fill_f  f12, 12
207        fill_f  f13, 13
208        fill_f  f14, 14
209        fill_f  f15, 15
210        fill_f  f16, 16
211        fill_f  f17, 17
212        fill_f  f18, 18
213        fill_f  f19, 19
214        fill_f  f20, 20
215        fill_f  f21, 21
216        fill_f  f22, 22
217        fill_f  f23, 23
218        fill_f  f24, 24
219        fill_f  f25, 25
220        fill_f  f26, 26
221        fill_f  f27, 27
222        fill_f  f28, 28
223        fill_f  f29, 29
224        fill_f  f30, 30
225        fill_f  f31, 31
226#endif /* __riscv_flen */
227
228        /* Check */
229
230.Lcheck:
231        .macro  check_register reg, inc
232        addi    t0, a0, \inc
233        bne     \reg, t0, .Lrestore
234        .endm
235
236        check_register  ra, 1
237        check_register  t1, 2
238        check_register  t2, 3
239        check_register  s0, 4
240        check_register  s1, 5
241        check_register  a1, 6
242        check_register  a2, 7
243        check_register  a3, 8
244        check_register  a4, 9
245        check_register  a5, 10
246        check_register  a6, 11
247        check_register  a7, 12
248        check_register  s2, 13
249        check_register  s3, 14
250        check_register  s4, 15
251        check_register  s5, 16
252        check_register  s6, 17
253        check_register  s7, 18
254        check_register  s8, 19
255        check_register  s9, 20
256        check_register  s10, 21
257        check_register  s11, 22
258        check_register  t3, 23
259
260        xor     t0, sp, a0
261        bne     t4, t0, .Lrestore
262
263        xor     t0, gp, a0
264        bne     t5, t0, .Lrestore
265
266        xor     t0, tp, a0
267        bne     t6, t0, .Lrestore
268
269#if __riscv_flen > 0
270        SREG    t1, TMP_OFFSET(sp)
271        frflags t0
272        andi    t1, a0, 0x1f
273        xor     t0, t1, t0
274        LREG    t1, TMP_OFFSET(sp)
275        bnez    t0, .Lrestore
276
277
278        .macro  check_f reg, inc
279        FMVXY   t0, \reg
280        addi    t0, t0, -24 - \inc
281        bne     t0, a0, .Lrestore
282        .endm
283
284        check_f f0, 0
285        check_f f1, 1
286        check_f f2, 2
287        check_f f3, 3
288        check_f f4, 4
289        check_f f5, 5
290        check_f f6, 6
291        check_f f7, 7
292        check_f f8, 8
293        check_f f9, 9
294        check_f f10, 10
295        check_f f11, 11
296        check_f f12, 12
297        check_f f13, 13
298        check_f f14, 14
299        check_f f15, 15
300        check_f f16, 16
301        check_f f17, 17
302        check_f f18, 18
303        check_f f19, 19
304        check_f f20, 20
305        check_f f21, 21
306        check_f f22, 22
307        check_f f23, 23
308        check_f f24, 24
309        check_f f25, 25
310        check_f f26, 26
311        check_f f27, 27
312        check_f f28, 28
313        check_f f29, 29
314        check_f f30, 30
315        check_f f31, 31
316#endif /* __riscv_flen */
317
318        j       .Lcheck
319
320        /* Restore */
321
322.Lrestore:
323
324        LREG    ra, RA_OFFSET(sp)
325        LREG    t0, T0_OFFSET(sp)
326        LREG    t1, T1_OFFSET(sp)
327        LREG    t2, T2_OFFSET(sp)
328        LREG    s0, S0_OFFSET(sp)
329        LREG    s1, S1_OFFSET(sp)
330        LREG    a0, A0_OFFSET(sp)
331        LREG    a1, A1_OFFSET(sp)
332        LREG    a2, A2_OFFSET(sp)
333        LREG    a3, A3_OFFSET(sp)
334        LREG    a4, A4_OFFSET(sp)
335        LREG    a5, A5_OFFSET(sp)
336        LREG    a6, A6_OFFSET(sp)
337        LREG    a7, A7_OFFSET(sp)
338        LREG    s2, S2_OFFSET(sp)
339        LREG    s3, S3_OFFSET(sp)
340        LREG    s4, S4_OFFSET(sp)
341        LREG    s5, S5_OFFSET(sp)
342        LREG    s6, S6_OFFSET(sp)
343        LREG    s7, S7_OFFSET(sp)
344        LREG    s8, S8_OFFSET(sp)
345        LREG    s9, S9_OFFSET(sp)
346        LREG    s10, S10_OFFSET(sp)
347        LREG    s11, S11_OFFSET(sp)
348        LREG    t3, T3_OFFSET(sp)
349        LREG    t4, T4_OFFSET(sp)
350        LREG    t5, T5_OFFSET(sp)
351        LREG    t6, T6_OFFSET(sp)
352
353#if __riscv_flen > 0
354        FLREG   f0, FOFFSET(0)(sp)
355        FLREG   f1, FOFFSET(1)(sp)
356        FLREG   f2, FOFFSET(2)(sp)
357        FLREG   f3, FOFFSET(3)(sp)
358        FLREG   f4, FOFFSET(4)(sp)
359        FLREG   f5, FOFFSET(5)(sp)
360        FLREG   f6, FOFFSET(6)(sp)
361        FLREG   f7, FOFFSET(7)(sp)
362        FLREG   f8, FOFFSET(8)(sp)
363        FLREG   f9, FOFFSET(9)(sp)
364        FLREG   f10, FOFFSET(10)(sp)
365        FLREG   f11, FOFFSET(11)(sp)
366        FLREG   f12, FOFFSET(12)(sp)
367        FLREG   f13, FOFFSET(13)(sp)
368        FLREG   f14, FOFFSET(14)(sp)
369        FLREG   f15, FOFFSET(15)(sp)
370        FLREG   f16, FOFFSET(16)(sp)
371        FLREG   f17, FOFFSET(17)(sp)
372        FLREG   f18, FOFFSET(18)(sp)
373        FLREG   f19, FOFFSET(19)(sp)
374        FLREG   f20, FOFFSET(20)(sp)
375        FLREG   f21, FOFFSET(21)(sp)
376        FLREG   f22, FOFFSET(22)(sp)
377        FLREG   f23, FOFFSET(23)(sp)
378        FLREG   f24, FOFFSET(24)(sp)
379        FLREG   f25, FOFFSET(25)(sp)
380        FLREG   f26, FOFFSET(26)(sp)
381        FLREG   f27, FOFFSET(27)(sp)
382        FLREG   f28, FOFFSET(28)(sp)
383        FLREG   f29, FOFFSET(29)(sp)
384        FLREG   f30, FOFFSET(30)(sp)
385        FLREG   f31, FOFFSET(31)(sp)
386#endif /* __riscv_flen */
387
388        addi    sp, sp, FRAME_SIZE
389        ret
Note: See TracBrowser for help on using the repository browser.