about summary refs log tree commit diff
path: root/sysdeps/unix
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix')
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/syscall.S14
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h30
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/syscall.S12
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h30
4 files changed, 71 insertions, 15 deletions
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S b/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S
index f4f0beb31b..5455ec832d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/syscall.S
@@ -37,15 +37,19 @@ ENTRY (syscall)
 	lr     %r4,%r5             /* third parameter  */
 	lr     %r5,%r6             /* fourth parameter */
 	l      %r6,192(%r15)       /* fifth parameter  */
-	basr   %r7,0
-.L0:    ex     %r1,.L1-.L0(%r7)    /* lsb of R1 is subsituted as SVC number */
 
-	l       %r15,0(0,%r15)     /* load back chain */
-	lm      %r6,15,24(%r15)    /* load registers */
+	basr   %r7,0
+0:	cl     %r1,4f-0b(%r7)      /* svc number < 256? */
+	jl     2f
+1:	svc    0
+	j      3f
+2:	ex     %r1,1b-0b(%r7)      /* lsb of R1 is subsituted as SVC number */
+3:	l      %r15,0(%r15)        /* load back chain */
+	lm     %r6,15,24(%r15)     /* load registers */
 
 	lhi    %r0,-4095
 	clr    %r2,%r0             /* check R2 for error */
 	jnl    SYSCALL_ERROR_LABEL
 	br     %r14                /* return to caller */
-.L1:    .word  0x0A00              /* opcode for SVC 0 */
+4:	.long  256
 PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
index f7bfb8dac1..af8515b195 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
@@ -133,7 +133,12 @@
  */
 
 #define DO_CALL(syscall, args)						      \
-    svc     SYS_ify (syscall)
+  .if SYS_ify (syscall) < 256;						      \
+    svc SYS_ify (syscall);						      \
+  .else;								      \
+    lhi %r1,SYS_ify (syscall);						      \
+    svc 0;								      \
+  .endif
 
 #define ret                                                                   \
     br      14
@@ -154,8 +159,8 @@
 #undef INTERNAL_SYSCALL_DECL
 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
 
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...)			      \
+#undef INTERNAL_SYSCALL_DIRECT
+#define INTERNAL_SYSCALL_DIRECT(name, err, nr, args...)			      \
   ({									      \
     DECLARGS_##nr(args)							      \
     register int _ret asm("2");						      \
@@ -166,6 +171,25 @@
     : "memory" );							      \
     _ret; })
 
+#undef INTERNAL_SYSCALL_SVC0
+#define INTERNAL_SYSCALL_SVC0(name, err, nr, args...)			      \
+  ({									      \
+    DECLARGS_##nr(args)							      \
+    register unsigned long _nr asm("1") = (unsigned long)(__NR_##name);	      \
+    register int _ret asm("2");						      \
+    asm volatile (							      \
+    "svc    0\n\t"							      \
+    : "=d" (_ret)							      \
+    : "d" (_nr), "i" (__NR_##name) ASMFMT_##nr				      \
+    : "memory" );							      \
+    _ret; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...)			      \
+  (((__NR_##name) < 256) ?						      \
+    INTERNAL_SYSCALL_DIRECT(name, err, nr, args) :			      \
+    INTERNAL_SYSCALL_SVC0(name, err,nr, args))
+
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val, err)				      \
   ((unsigned int) (val) >= 0xfffff001u)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S b/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
index 718d559c3b..5a6bcfc90d 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
@@ -37,16 +37,20 @@ ENTRY (syscall)
 	lgr    %r4,%r5		   /* Third parameter.	*/
 	lgr    %r5,%r6		   /* Fourth parameter.	 */
 	lg     %r6,320(%r15)	   /* Fifth parameter.	*/
-	basr   %r7,0
-.L0:	ex     %r1,.L1-.L0(%r7)	   /* Lsb of R1 is subsituted as SVC number.  */
 
-	lg	%r15,0(%r15)	   /* Load back chain.	*/
+	basr   %r7,0
+0:	clg    %r1,4f-0b(%r7)      /* svc number < 256? */
+	jl     2f
+1:	svc    0
+	j      3f
+2:	ex     %r1,1b-0b(%r7)      /* lsb of R1 is subsituted as SVC number */
+3:	lg     %r15,0(%r15)        /* load back chain */
 	lmg	%r6,15,48(%r15)	   /* Load registers.  */
 
 	lghi   %r0,-4095
 	clgr   %r2,%r0		   /* Check R2 for error.  */
 	jgnl   SYSCALL_ERROR_LABEL
 	br     %r14		   /* Return to caller.	 */
-.L1:	.word  0x0A00		   /* Opcode for SVC 0.	 */
+4:	.quad  256
 PSEUDO_END (syscall)
 
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
index 976fd26f50..6de2dae288 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
@@ -122,7 +122,12 @@
  */
 
 #define DO_CALL(syscall, args)						      \
-    svc	    SYS_ify (syscall)
+  .if SYS_ify (syscall) < 256;						      \
+    svc SYS_ify (syscall);						      \
+  .else;								      \
+    lghi %r1,SYS_ify (syscall);						      \
+    svc 0;								      \
+  .endif
 
 #define ret								      \
     br	    14
@@ -143,8 +148,8 @@
 #undef INTERNAL_SYSCALL_DECL
 #define INTERNAL_SYSCALL_DECL(err) do { } while (0)
 
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...)			      \
+#undef INTERNAL_SYSCALL_DIRECT
+#define INTERNAL_SYSCALL_DIRECT(name, err, nr, args...)			      \
   ({									      \
     DECLARGS_##nr(args)							      \
     register int _ret asm("2");						      \
@@ -155,6 +160,25 @@
     : "memory" );							      \
     _ret; })
 
+#undef INTERNAL_SYSCALL_SVC0
+#define INTERNAL_SYSCALL_SVC0(name, err, nr, args...)			      \
+  ({									      \
+    DECLARGS_##nr(args)							      \
+    register unsigned long _nr asm("1") = (unsigned long)(__NR_##name);	      \
+    register int _ret asm("2");						      \
+    asm volatile (							      \
+    "svc    0\n\t"							      \
+    : "=d" (_ret)							      \
+    : "d" (_nr), "i" (__NR_##name) ASMFMT_##nr				      \
+    : "memory" );							      \
+    _ret; })
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...)			      \
+  (((__NR_##name) < 256) ?						      \
+    INTERNAL_SYSCALL_DIRECT(name, err, nr, args) :			      \
+    INTERNAL_SYSCALL_SVC0(name, err,nr, args))
+
 #undef INTERNAL_SYSCALL_ERROR_P
 #define INTERNAL_SYSCALL_ERROR_P(val, err)				      \
   ((unsigned int) (val) >= 0xfffff001u)