1/* MIPS support code for fibers and multithreading.
2   Copyright (C) 2019-2020 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14for more details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23<http://www.gnu.org/licenses/>.  */
24
25#include "../common/threadasm.S"
26
27#if _MIPS_SIM == _ABIO32
28
29/**
30 * Performs a context switch.
31 *
32 * $a0 - void** - ptr to old stack pointer
33 * $a1 - void*  - new stack pointer
34 *
35 */
36    .text
37    .globl fiber_switchContext
38    .align 2
39    .ent fiber_switchContext,0
40fiber_switchContext:
41    .cfi_startproc
42    addiu $sp, $sp, -(10 * 4)
43
44    // fp regs and return address are stored below the stack
45    // because we don't want the GC to scan them.
46
47#ifdef __mips_hard_float
48#define ALIGN8(val) (val + (-val & 7))
49#define BELOW (ALIGN8(6 * 8 + 4))
50    s.d $f20, (0 * 8 - BELOW)($sp)
51    s.d $f22, (1 * 8 - BELOW)($sp)
52    s.d $f24, (2 * 8 - BELOW)($sp)
53    s.d $f26, (3 * 8 - BELOW)($sp)
54    s.d $f28, (4 * 8 - BELOW)($sp)
55    s.d $f30, (5 * 8 - BELOW)($sp)
56#endif
57    sw $ra, -4($sp)
58
59    sw $s0, (0 * 4)($sp)
60    sw $s1, (1 * 4)($sp)
61    sw $s2, (2 * 4)($sp)
62    sw $s3, (3 * 4)($sp)
63    sw $s4, (4 * 4)($sp)
64    sw $s5, (5 * 4)($sp)
65    sw $s6, (6 * 4)($sp)
66    sw $s7, (7 * 4)($sp)
67    sw $s8, (8 * 4)($sp)
68    sw $gp, (9 * 4)($sp)
69
70    // swap stack pointer
71    sw $sp, 0($a0)
72    move $sp, $a1
73
74#ifdef __mips_hard_float
75    l.d $f20, (0 * 8 - BELOW)($sp)
76    l.d $f22, (1 * 8 - BELOW)($sp)
77    l.d $f24, (2 * 8 - BELOW)($sp)
78    l.d $f26, (3 * 8 - BELOW)($sp)
79    l.d $f28, (4 * 8 - BELOW)($sp)
80    l.d $f30, (5 * 8 - BELOW)($sp)
81#endif
82    lw $ra, -4($sp)
83
84    lw $s0, (0 * 4)($sp)
85    lw $s1, (1 * 4)($sp)
86    lw $s2, (2 * 4)($sp)
87    lw $s3, (3 * 4)($sp)
88    lw $s4, (4 * 4)($sp)
89    lw $s5, (5 * 4)($sp)
90    lw $s6, (6 * 4)($sp)
91    lw $s7, (7 * 4)($sp)
92    lw $s8, (8 * 4)($sp)
93    lw $gp, (9 * 4)($sp)
94
95    addiu $sp, $sp, (10 * 4)
96
97    jr $ra // return
98    .cfi_endproc
99    .end fiber_switchContext
100    .size fiber_switchContext,.-fiber_switchContext
101
102#endif
103