# Copyright (C) 1995,1996 Robert de Bath # 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 syscall.dat if [ -r ${ELKSSRC}/arch/i86/kernel/syscall.dat \ -a ! -r ${TOPDIR}/libc/kinclude/Used ] then echo Using syscalls from ${ELKSSRC} cp -p ${ELKSSRC}/arch/i86/kernel/syscall.dat syscall.dat else echo Using syscalls from syscall.dev86 cp -p syscall.dev86 syscall.dat fi tr '[A-Z]' '[a-z]' < syscall.dat | \ awk -v COMPACT=$COMPACT 'BEGIN{ print "# Copyright (C) 1995,1996 Robert de Bath " > "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 "; 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; } { callno = 0+$2; if( !(callno in calltab) ) callwas[callno] = " /* " $1 " */"; if( $3 == "x" || $3 == "" ) next; else if( $4 == "@" || $4 == "-" ) next; else if( $4 == "*" ) funcname="__" $1; else funcname=$1; if( callno > max_call ) max_call = callno; calltab[callno] = $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", callno); } else { printf("#if __FIRST_ARG_IN_AX__\n"); printf(" mov dx,#%d\n", callno); printf("#else\n"); printf(" mov ax,#%d\n", callno); 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", callno); 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 <<\! all: $(LIBC)($(OBJ)) @$(RM) $(OBJ) $(LIBC)($(OBJ)): syscall.dat $(CC) $(CFLAGS) -DL_$* syscall.c -c -o $*.o $(AR) $(ARFLAGS) $@ $*.o ! exit $?