/* MIPS support code for fibers and multithreading. Copyright (C) 2019-2020 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 . */ #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)) s.d $f20, (0 * 8 - BELOW)($sp) s.d $f22, (1 * 8 - BELOW)($sp) s.d $f24, (2 * 8 - BELOW)($sp) s.d $f26, (3 * 8 - BELOW)($sp) s.d $f28, (4 * 8 - BELOW)($sp) s.d $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 l.d $f20, (0 * 8 - BELOW)($sp) l.d $f22, (1 * 8 - BELOW)($sp) l.d $f24, (2 * 8 - BELOW)($sp) l.d $f26, (3 * 8 - BELOW)($sp) l.d $f28, (4 * 8 - BELOW)($sp) l.d $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