diff options
Diffstat (limited to 'libc/syscall/mksyscall')
-rw-r--r-- | libc/syscall/mksyscall | 300 |
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 |