| /* MIPS support code for fibers and multithreading. | |
| Copyright (C) 2019 Free Software Foundation, Inc. | |
| This file is part of GCC. | |
| GCC is free software; you can redistribute it and/or modify it under | |
| the terms of the GNU General Public License as published by the Free | |
| Software Foundation; either version 3, or (at your option) any later | |
| version. | |
| GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
| WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
| for more details. | |
| Under Section 7 of GPL version 3, you are granted additional | |
| permissions described in the GCC Runtime Library Exception, version | |
| 3.1, as published by the Free Software Foundation. | |
| You should have received a copy of the GNU General Public License and | |
| a copy of the GCC Runtime Library Exception along with this program; | |
| see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
| <http://www.gnu.org/licenses/>. */ | |
| #include "../common/threadasm.S" | |
| #if _MIPS_SIM == _ABIO32 | |
| /** | |
| * Performs a context switch. | |
| * | |
| * $a0 - void** - ptr to old stack pointer | |
| * $a1 - void* - new stack pointer | |
| * | |
| */ | |
| .text | |
| .globl fiber_switchContext | |
| .align 2 | |
| .ent fiber_switchContext,0 | |
| fiber_switchContext: | |
| .cfi_startproc | |
| addiu $sp, $sp, -(10 * 4) | |
| // fp regs and return address are stored below the stack | |
| // because we don't want the GC to scan them. | |
| #ifdef __mips_hard_float | |
| #define ALIGN8(val) (val + (-val & 7)) | |
| #define BELOW (ALIGN8(6 * 8 + 4)) | |
| sdc1 $f20, (0 * 8 - BELOW)($sp) | |
| sdc1 $f22, (1 * 8 - BELOW)($sp) | |
| sdc1 $f24, (2 * 8 - BELOW)($sp) | |
| sdc1 $f26, (3 * 8 - BELOW)($sp) | |
| sdc1 $f28, (4 * 8 - BELOW)($sp) | |
| sdc1 $f30, (5 * 8 - BELOW)($sp) | |
| #endif | |
| sw $ra, -4($sp) | |
| sw $s0, (0 * 4)($sp) | |
| sw $s1, (1 * 4)($sp) | |
| sw $s2, (2 * 4)($sp) | |
| sw $s3, (3 * 4)($sp) | |
| sw $s4, (4 * 4)($sp) | |
| sw $s5, (5 * 4)($sp) | |
| sw $s6, (6 * 4)($sp) | |
| sw $s7, (7 * 4)($sp) | |
| sw $s8, (8 * 4)($sp) | |
| sw $gp, (9 * 4)($sp) | |
| // swap stack pointer | |
| sw $sp, 0($a0) | |
| move $sp, $a1 | |
| #ifdef __mips_hard_float | |
| ldc1 $f20, (0 * 8 - BELOW)($sp) | |
| ldc1 $f22, (1 * 8 - BELOW)($sp) | |
| ldc1 $f24, (2 * 8 - BELOW)($sp) | |
| ldc1 $f26, (3 * 8 - BELOW)($sp) | |
| ldc1 $f28, (4 * 8 - BELOW)($sp) | |
| ldc1 $f30, (5 * 8 - BELOW)($sp) | |
| #endif | |
| lw $ra, -4($sp) | |
| lw $s0, (0 * 4)($sp) | |
| lw $s1, (1 * 4)($sp) | |
| lw $s2, (2 * 4)($sp) | |
| lw $s3, (3 * 4)($sp) | |
| lw $s4, (4 * 4)($sp) | |
| lw $s5, (5 * 4)($sp) | |
| lw $s6, (6 * 4)($sp) | |
| lw $s7, (7 * 4)($sp) | |
| lw $s8, (8 * 4)($sp) | |
| lw $gp, (9 * 4)($sp) | |
| addiu $sp, $sp, (10 * 4) | |
| jr $ra // return | |
| .cfi_endproc | |
| .end fiber_switchContext | |
| .size fiber_switchContext,.-fiber_switchContext | |
| #endif |