1*ec02198aSmrg /* Copyright (C) 2005-2020 Free Software Foundation, Inc.
263d1a8abSmrg    Contributed by Jakub Jelinek <jakub@redhat.com>.
363d1a8abSmrg 
463d1a8abSmrg    This file is part of the GNU Offloading and Multi Processing Library
563d1a8abSmrg    (libgomp).
663d1a8abSmrg 
763d1a8abSmrg    Libgomp is free software; you can redistribute it and/or modify it
863d1a8abSmrg    under the terms of the GNU General Public License as published by
963d1a8abSmrg    the Free Software Foundation; either version 3, or (at your option)
1063d1a8abSmrg    any later version.
1163d1a8abSmrg 
1263d1a8abSmrg    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
1363d1a8abSmrg    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1463d1a8abSmrg    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1563d1a8abSmrg    more details.
1663d1a8abSmrg 
1763d1a8abSmrg    Under Section 7 of GPL version 3, you are granted additional
1863d1a8abSmrg    permissions described in the GCC Runtime Library Exception, version
1963d1a8abSmrg    3.1, as published by the Free Software Foundation.
2063d1a8abSmrg 
2163d1a8abSmrg    You should have received a copy of the GNU General Public License and
2263d1a8abSmrg    a copy of the GCC Runtime Library Exception along with this program;
2363d1a8abSmrg    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2463d1a8abSmrg    <http://www.gnu.org/licenses/>.  */
2563d1a8abSmrg 
2663d1a8abSmrg /* Provide target-specific access to the futex system call.  */
2763d1a8abSmrg 
2863d1a8abSmrg #include <sys/syscall.h>
2963d1a8abSmrg 
3063d1a8abSmrg static inline long
sys_futex0(int * addr,int op,int val)3163d1a8abSmrg sys_futex0 (int *addr, int op, int val)
3263d1a8abSmrg {
3363d1a8abSmrg   register long int g1  __asm__ ("g1");
3463d1a8abSmrg   register long int o0  __asm__ ("o0");
3563d1a8abSmrg   register long int o1  __asm__ ("o1");
3663d1a8abSmrg   register long int o2  __asm__ ("o2");
3763d1a8abSmrg   register long int o3  __asm__ ("o3");
3863d1a8abSmrg 
3963d1a8abSmrg   g1 = SYS_futex;
4063d1a8abSmrg   o0 = (long) addr;
4163d1a8abSmrg   o1 = op;
4263d1a8abSmrg   o2 = val;
4363d1a8abSmrg   o3 = 0;
4463d1a8abSmrg 
4563d1a8abSmrg #ifdef __arch64__
4663d1a8abSmrg # define SYSCALL_STRING "ta\t0x6d; bcs,a,pt %%xcc, 1f; sub %%g0, %%o0, %%o0; 1:"
4763d1a8abSmrg #else
4863d1a8abSmrg # define SYSCALL_STRING "ta\t0x10; bcs,a 1f; sub %%g0, %%o0, %%o0; 1:"
4963d1a8abSmrg #endif
5063d1a8abSmrg 
5163d1a8abSmrg   __asm volatile (SYSCALL_STRING
5263d1a8abSmrg 		  : "=r" (g1), "=r" (o0)
5363d1a8abSmrg 		  : "0" (g1), "1" (o0), "r" (o1), "r" (o2), "r" (o3)
5463d1a8abSmrg 		  : "g2", "g3", "g4", "g5", "g6",
5563d1a8abSmrg 		    "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
5663d1a8abSmrg 		    "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
5763d1a8abSmrg 		    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
5863d1a8abSmrg 		    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
5963d1a8abSmrg #ifdef __arch64__
6063d1a8abSmrg 		    "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
6163d1a8abSmrg 		    "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
6263d1a8abSmrg #endif
6363d1a8abSmrg 		    "cc", "memory");
6463d1a8abSmrg   return o0;
6563d1a8abSmrg }
6663d1a8abSmrg 
6763d1a8abSmrg static inline void
futex_wait(int * addr,int val)6863d1a8abSmrg futex_wait (int *addr, int val)
6963d1a8abSmrg {
7063d1a8abSmrg   long err = sys_futex0 (addr, gomp_futex_wait, val);
7163d1a8abSmrg   if (__builtin_expect (err == ENOSYS, 0))
7263d1a8abSmrg     {
7363d1a8abSmrg       gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
7463d1a8abSmrg       gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
7563d1a8abSmrg       sys_futex0 (addr, gomp_futex_wait, val);
7663d1a8abSmrg     }
7763d1a8abSmrg }
7863d1a8abSmrg 
7963d1a8abSmrg static inline void
futex_wake(int * addr,int count)8063d1a8abSmrg futex_wake (int *addr, int count)
8163d1a8abSmrg {
8263d1a8abSmrg   long err = sys_futex0 (addr, gomp_futex_wake, count);
8363d1a8abSmrg   if (__builtin_expect (err == ENOSYS, 0))
8463d1a8abSmrg     {
8563d1a8abSmrg       gomp_futex_wait &= ~FUTEX_PRIVATE_FLAG;
8663d1a8abSmrg       gomp_futex_wake &= ~FUTEX_PRIVATE_FLAG;
8763d1a8abSmrg       sys_futex0 (addr, gomp_futex_wake, count);
8863d1a8abSmrg     }
8963d1a8abSmrg }
9063d1a8abSmrg 
9163d1a8abSmrg static inline void
cpu_relax(void)9263d1a8abSmrg cpu_relax (void)
9363d1a8abSmrg {
9463d1a8abSmrg   __asm volatile ("rd %%ccr, %%g0" : : : "memory");
9563d1a8abSmrg }
96