/* Copyright (C) 2011-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library.  If not, see
   <http://www.gnu.org/licenses/>.  */

#include <sysdep.h>
#include <arch/abi.h>

#include "ucontext_i.h"

/* int getcontext (ucontext_t *ucp) */

	.text
ENTRY (__getcontext)
	FEEDBACK_ENTER(__getcontext)

	/* Save the callee-saved GPRs.  There's no need to save the
	   caller-saved GPRs since the eventual setcontext() or
	   swapcontext() will assume those registers are all dead.
	   Save value "1" to uc_flags to later recognize getcontext().  */
	{ movei r11, 1; ADDI_PTR r10, r0, UC_FLAGS_OFFSET }
	{ ST_PTR r10, r11; addli r10, r0, UC_REG(30) }
	{ st r10, r30; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r31; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r32; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r33; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r34; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r35; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r36; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r37; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r38; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r39; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r40; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r41; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r42; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r43; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r44; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r45; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r46; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r47; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r48; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r49; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r50; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r51; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, r52; ADDI_PTR r10, r10, REGSIZE }
	{ st r10, tp;  ADDI_PTR r10, r10, REGSIZE }
	{ st r10, sp;  ADDI_PTR r10, r10, REGSIZE }
	{ st r10, lr;  ADDI_PTR r10, r10, REGSIZE }
	lnk r11   /* Point PC at the "jrp lr" instruction.  */
	addli r11, r11, .Lreturn - .
	{ st r10, r11; ADDI_PTR r10, r10, REGSIZE }
	mfspr r11, INTERRUPT_CRITICAL_SECTION
	{
	 st r10, r11
	 movei r1, 0
	}

	/* rt_sigprocmask (SIG_BLOCK, NULL, &ucp->uc_sigmask, _NSIG / 8) */
	{
	 movei r3, _NSIG / 8
	 addli r2, r0, UC_SIGMASK_OFFSET
	}
	{
	 movei r0, SIG_BLOCK
	 moveli TREG_SYSCALL_NR_NAME, __NR_rt_sigprocmask
	}
	swint1
	bnez r1, .Lsyscall_error

.Lreturn:
	{
	 movei r0, 0
	 jrp lr
	}

.Lsyscall_error:
	j SYSCALL_ERROR_NAME

END (__getcontext)
.hidden __getcontext

weak_alias (__getcontext, getcontext)
