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