summaryrefslogtreecommitdiff
path: root/libc/syscall/mksyscall
diff options
context:
space:
mode:
Diffstat (limited to 'libc/syscall/mksyscall')
-rw-r--r--libc/syscall/mksyscall300
1 files changed, 300 insertions, 0 deletions
diff --git a/libc/syscall/mksyscall b/libc/syscall/mksyscall
new file mode 100644
index 0000000..1e98836
--- /dev/null
+++ b/libc/syscall/mksyscall
@@ -0,0 +1,300 @@
+# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
+# This file is part of the Linux-8086 C library and is distributed
+# under the GNU Library General Public License.
+#
+# This script generates the 'simple' system calls.
+#
+# Each call is put into it's own object file, if the semantics of the
+# call are not correct UNIX then the 4th field in the dat file has a
+# marker and the function is generated with a __ prefix.
+#
+#
+# Different levels of squeeze
+# 0 = each is complete
+# 1 = Short codes calling common function
+
+COMPACT=1
+
+rm -f syscall.c syscall.mak call_tab.v defn_tab.v
+
+tr '[A-Z]' '[a-z]' < syscall.dat | \
+awk -v COMPACT=$COMPACT 'BEGIN{
+ print "# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>" > "syscall.mak";
+ print "# This file is part of the Linux-8086 C library and is distributed" > "syscall.mak";
+ print "# under the GNU Library General Public License." > "syscall.mak";
+ print "# " > "syscall.mak";
+ print "# This file is automatically generated\n" > "syscall.mak"
+
+ print "/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>";
+ print " * This file is part of the Linux-8086 C library and is distributed";
+ print " * under the GNU Library General Public License.";
+ print " * ";
+ print " * This file is automatically generated */\n"
+ obj="OBJ=";
+
+ print "/* Standard start */\n\n"
+ printf("#ifndef __MSDOS__\n");
+ printf("#ifdef __AS386_16__\n");
+ printf("#asm\n");
+ printf(" .text\n");
+ printf(" .even\n");
+ printf("#endasm\n\n");
+
+ {
+ obj=obj "__syscall.o __syscall4.o ";
+ print "/* Shared system call code */\n"
+ printf("#ifdef L___syscall\n", funcname);
+ printf("#asm\n");
+ printf("#if __FIRST_ARG_IN_AX__\n");
+
+ printf("export sys_call3\nsys_call3:\n");
+ printf(" mov bx,sp\n");
+ printf(" mov cx,[bx+2]\n");
+ printf(" mov bx,[bx+4]\n");
+ # ax=arg1 bx=arg3 cx=arg2 dx=arg0
+ printf(" xchg ax,bx\n");
+ # ax=arg3 bx=arg1 cx=arg2 dx=arg0
+ printf(" xchg ax,dx\n");
+ # ax=arg0 bx=arg1 cx=arg2 dx=arg3
+ printf(" jmp sys_call0\n\n");
+
+ printf("export sys_call2\nsys_call2:\n");
+ printf(" mov bx,sp\n");
+ printf(" mov cx,[bx+2]\n");
+ printf(" mov bx,ax\n");
+ printf(" mov ax,dx\n");
+ printf(" jmp sys_call0\n\n");
+
+ printf("export sys_call1\nsys_call1:\n");
+ printf(" mov bx,ax\n");
+ printf(" mov ax,dx\n");
+ printf("#else\n");
+ printf("export sys_call3\nsys_call3:\n");
+ printf(" mov bx,sp\n");
+ printf(" mov dx,[bx+6]\n");
+ printf(" mov cx,[bx+4]\n");
+ printf(" mov bx,[bx+2]\n");
+ printf(" jmp sys_call0\n\n");
+
+ printf("export sys_call2\nsys_call2:\n");
+ printf(" mov bx,sp\n");
+ printf(" mov cx,[bx+4]\n");
+ printf(" mov bx,[bx+2]\n");
+ printf(" jmp sys_call0\n\n");
+
+ printf("export sys_call1\nsys_call1:\n");
+ printf(" mov bx,sp\n");
+ printf(" mov bx,[bx+2]\n");
+ printf("#endif\n\n");
+
+ printf("export sys_call0\nsys_call0:\n");
+ printf(" int $80\n");
+ printf(" test ax,ax\n");
+ printf(" jge syscall_ok\n");
+ printf(" neg ax\n");
+ printf(" mov [_errno],ax\n");
+ printf(" mov ax,#-1\n");
+ printf("syscall_ok:\n");
+ printf(" ret\n");
+ printf("#endasm\n");
+ printf("#endif\n\n");
+
+ print "/* Shared system call code, syscalls with 4/5 args */\n"
+ printf("#ifdef L___syscall4\n", funcname);
+ printf("#asm\n");
+ printf("#if __FIRST_ARG_IN_AX__\n");
+
+ printf("export sys_call4\nsys_call4:\n");
+ printf("export sys_call5\nsys_call5:\n");
+ printf(" mov bx,sp\n");
+ printf(" push si\n");
+ printf(" mov si,[bx+8]\n");
+ printf(" push di\n");
+ printf(" mov di,[bx+6]\n");
+ printf(" mov cx,[bx+2]\n");
+ printf(" mov bx,[bx+4]\n");
+ # ax=arg1 bx=arg3 cx=arg2 dx=arg0
+ printf(" xchg ax,bx\n");
+ # ax=arg3 bx=arg1 cx=arg2 dx=arg0
+ printf(" xchg ax,dx\n");
+ # ax=arg0 bx=arg1 cx=arg2 dx=arg3
+ printf("#else\n");
+ printf("export sys_call4\nsys_call4:\n");
+ printf("export sys_call5\nsys_call5:\n");
+ printf(" mov bx,sp\n");
+ printf(" push si\n");
+ printf(" mov si,[bx+10]\n");
+ printf(" push di\n");
+ printf(" mov di,[bx+8]\n");
+ printf(" mov dx,[bx+6]\n");
+ printf(" mov cx,[bx+4]\n");
+ printf(" mov bx,[bx+2]\n");
+ printf("#endif\n\n");
+
+ printf(" int $80\n");
+ printf(" pop di\n");
+ printf(" pop si\n");
+ printf(" test ax,ax\n");
+ printf(" jge syscall_ok\n");
+ printf(" neg ax\n");
+ printf(" mov [_errno],ax\n");
+ printf(" mov ax,#-1\n");
+ printf("syscall_ok:\n");
+ printf(" ret\n");
+ printf("#endasm\n");
+ printf("#endif\n\n");
+ }
+}
+/^[ ]*#/ { next; }
+/^[ ]*$/ { next; }
+{
+ if( $2 > max_call ) max_call = $2;
+ if( !($2 in calltab) )
+ callwas[$2] = " /* " $1 " */";
+
+ if( $3 == "x" || $3 == "" ) next;
+ else if( $4 == "-" ) next;
+ else if( $4 == "*" ) funcname="__" $1;
+ else funcname=$1;
+
+ calltab[$2] = $1;
+
+ if( length(obj) > 60 )
+ {
+ printf("%s\t\\\n", obj) > "syscall.mak";
+ obj=" ";
+ }
+ obj=obj funcname ".o ";
+
+ printf "/* CALL %s */\n\n", $0;
+
+ printf("#ifdef L_%s\n", funcname);
+ printf("#asm\n", funcname);
+ printf("export _%s\n", funcname);
+ printf("_%s:\n", funcname);
+
+ # Inline assembler max to 5 args (10 bytes)
+ if( $3 != 4 && $3 != 5 && ( COMPACT || $3 > 5 ))
+ {
+ if( $3 == 0 )
+ {
+ printf(" mov ax,#%d\n", $2);
+ }
+ else
+ {
+ printf("#if __FIRST_ARG_IN_AX__\n");
+ printf(" mov dx,#%d\n", $2);
+ printf("#else\n");
+ printf(" mov ax,#%d\n", $2);
+ printf("#endif\n");
+ }
+ printf(" br sys_call%d\n", $3);
+ }
+ else
+ {
+ if( $3 >= 1 )
+ printf("#if __FIRST_ARG_IN_AX__\n");
+ if( $3 >= 2 )
+ printf(" mov bx,sp\n");
+ if( $3 >= 5 )
+ printf(" push si\n");
+ if( $3 >= 5 )
+ printf(" mov si,[bx+8]\n");
+ if( $3 >= 4 )
+ printf(" push di\n");
+ if( $3 >= 4 )
+ printf(" mov di,[bx+6]\n");
+ if( $3 >= 3 )
+ printf(" mov dx,[bx+4]\n");
+ if( $3 >= 2 )
+ printf(" mov cx,[bx+2]\n");
+ if( $3 >= 1 )
+ printf(" mov bx,ax\n");
+ if( $3 >= 1 )
+ printf("#else\n");
+ if( $3 >= 1 )
+ printf(" mov bx,sp\n");
+ if( $3 >= 5 )
+ printf(" push si\n");
+ if( $3 >= 5 )
+ printf(" mov si,[bx+10]\n");
+ if( $3 >= 4 )
+ printf(" push di\n");
+ if( $3 >= 4 )
+ printf(" mov di,[bx+8]\n");
+ if( $3 >= 3 )
+ printf(" mov dx,[bx+6]\n");
+ if( $3 >= 2 )
+ printf(" mov cx,[bx+4]\n");
+ if( $3 >= 1 )
+ printf(" mov bx,[bx+2]\n");
+ if( $3 >= 1 )
+ printf("#endif\n");
+
+ printf(" mov ax,#%d\n", $2);
+
+ printf(" int $80\n");
+
+ if( $3 >= 4 )
+ printf(" pop di\n");
+ if( $3 >= 5 )
+ printf(" pop si\n");
+
+ printf(" test ax,ax\n");
+ printf(" jl syscall_err\n");
+ printf(" ret\n");
+ printf("syscall_err:\n");
+ printf(" neg ax\n");
+ printf(" mov [_errno],ax\n");
+ printf(" mov ax,#-1\n");
+ printf(" ret\n");
+ }
+ printf("#endasm\n");
+ printf("#endif\n\n");
+}
+END{
+
+ for(i=0; i<=max_call; i++)
+ if( i in calltab )
+ {
+ printf("#ifndef sys_%s\n", calltab[i]) > "defn_tab.v";
+ printf("#define sys_%s sys_enosys\n", calltab[i]) > "defn_tab.v";
+ printf("#endif\n\n") > "defn_tab.v";
+ }
+
+ for(i=0; i<=max_call; i++)
+ if( i in calltab )
+ printf("/* %3d */ sys_%s,\n", i, calltab[i]) > "call_tab.v";
+ else
+ printf("/* %3d */ sys_enosys,%s\n", i, callwas[i]) > "call_tab.v";
+
+ printf("#endif /* __AS386_16__ */\n\n");
+ printf("#endif /* __MSDOS__ */\n\n");
+ printf("%s\n", obj) > "syscall.mak";
+ printf "\n" > "syscall.mak";
+
+}' > syscall.c
+
+cat >> syscall.mak <<\!
+
+TOP=..
+include $(TOP)/Make.defs
+
+all: $(OBJ)
+
+libc.a: $(OBJ)
+ ar r ../$(LIBC) $(OBJ)
+ @touch libc.a
+
+$(OBJ): syscall.dat mksyscall
+ $(CC) $(CFLAGS) -c -DL_$* -o $@ syscall.c
+!
+
+rv=$?
+if [ "$rv" != 0 ]
+then exit $rv
+fi
+
+export MAKELEVEL
+MAKELEVEL=0
+exec make -f syscall.mak $1