1 /* Copyright (C) 2011-2018 Free Software Foundation, Inc. 2 3 The GNU C Library is free software; you can redistribute it and/or 4 modify it under the terms of the GNU Lesser General Public 5 License as published by the Free Software Foundation; either 6 version 2.1 of the License, or (at your option) any later version. 7 8 The GNU C Library is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 Lesser General Public License for more details. 12 13 You should have received a copy of the GNU Lesser General Public 14 License along with the GNU C Library. If not, see 15 <http://www.gnu.org/licenses/>. */ 16 17 #include <common/sysdep.h> 18 #include <bits/wordsize.h> 19 #include <arch/abi.h> 20 21 #undef SYS_ify 22 #define SYS_ify(syscall_name) __NR_##syscall_name 23 24 #if defined __ASSEMBLER__ 25 26 /* Make use of .size directive. */ 27 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name; 28 29 /* Define an entry point visible from C. */ 30 #define ENTRY(name) \ 31 .globl C_SYMBOL_NAME(name); \ 32 .type C_SYMBOL_NAME(name),@function; \ 33 .align 8; \ 34 C_LABEL(name) \ 35 cfi_startproc; \ 36 37 #undef END 38 #define END(name) \ 39 cfi_endproc; \ 40 ASM_SIZE_DIRECTIVE(name) 41 42 /* Since C identifiers are not normally prefixed with an underscore 43 on this system, the asm identifier `syscall_error' intrudes on the 44 C name space. Make sure we use an innocuous name. */ 45 #define syscall_error __syscall_error 46 47 /* Local label name for asm code. */ 48 #define L(name) .L##name 49 50 /* Specify the size in bytes of a machine register. */ 51 #define REGSIZE 8 52 53 /* Provide "pointer-oriented" instruction variants. These differ not 54 just for tilepro vs tilegx, but also for tilegx -m64 vs -m32. */ 55 #if __WORDSIZE == 32 56 #define ADD_PTR addx 57 #define ADDI_PTR addxi 58 #define ADDLI_PTR addxli 59 #define LD_PTR ld4s 60 #define ST_PTR st4 61 #define SHL_PTR_ADD shl2add 62 #else 63 #define ADD_PTR add 64 #define ADDI_PTR addi 65 #define ADDLI_PTR addli 66 #define LD_PTR LD 67 #define ST_PTR ST 68 #define SHL_PTR_ADD shl3add 69 #endif 70 71 /* The actual implementation of doing a syscall. */ 72 #define DO_CALL(syscall_name, args) \ 73 moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name); \ 74 swint1 75 76 /* TILE Linux returns the result in r0 (or a negative errno). 77 The kernel "owns" the code to decide if a given value is an error, 78 and puts errno in r1 if so, or otherwise zero. */ 79 #define PSEUDO(name, syscall_name, args) \ 80 ENTRY (name); \ 81 DO_CALL(syscall_name, args); \ 82 BNEZ r1, 0f 83 84 #define ret jrp lr 85 86 #ifndef SHARED 87 /* For static code, on error jump to __syscall_error directly. */ 88 # define SYSCALL_ERROR_NAME __syscall_error 89 #elif IS_IN_libc || IS_IN_libpthread 90 /* Use the internal name for libc/libpthread shared objects. */ 91 # define SYSCALL_ERROR_NAME __GI___syscall_error 92 #else 93 /* Otherwise, on error do a full PLT jump. */ 94 # define SYSCALL_ERROR_NAME plt(__syscall_error) 95 #endif 96 97 #undef PSEUDO_END 98 #define PSEUDO_END(name) \ 99 0: \ 100 j SYSCALL_ERROR_NAME; \ 101 END (name) 102 103 #undef PSEUDO_NOERRNO 104 #define PSEUDO_NOERRNO(name, syscall_name, args) \ 105 ENTRY (name); \ 106 DO_CALL(syscall_name, args) 107 108 #define ret_NOERRNO jrp lr 109 110 #undef PSEUDO_END_NOERRNO 111 #define PSEUDO_END_NOERRNO(name) \ 112 END (name) 113 114 /* Convenience wrappers. */ 115 #define SYSCALL__(name, args) PSEUDO (__##name, name, args) 116 #define SYSCALL(name, args) PSEUDO (name, name, args) 117 118 #endif /* __ASSEMBLER__ */ 119