diff options
Diffstat (limited to 'libc/gnu_i386/mksyscall')
-rw-r--r-- | libc/gnu_i386/mksyscall | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/libc/gnu_i386/mksyscall b/libc/gnu_i386/mksyscall new file mode 100644 index 0000000..b655e9e --- /dev/null +++ b/libc/gnu_i386/mksyscall @@ -0,0 +1,123 @@ +# Copyright (C) 1995-1997 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 for the 386 +# +# 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 + +rm -f syscall.c syscall.mak + +tr '[A-Z]' '[a-z]' < syscall.dat | \ +awk 'BEGIN{ + print "# Copyright (C) 1995-1997 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-1997 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_32__\n"); + printf(" .text\n"); + printf(" .align 16\n"); + + COMPACT=0; +} +/^[ ]*#/ { next; } +/^[ ]*$/ { next; } +{ + if( $2 > max_call ) max_call = $2; + + if( $3 == "x" || $3 == "" ) next; + else if( $4 == "-" ) next; + else if( $4 == "*" ) funcname="__" $1; + else funcname=$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(".globl %s\n", funcname); + printf(".type %s,@function\n", funcname); + printf("%s:\n", funcname); + + # Inline assembler max to 5 args (20 bytes) + if( $3 != 4 && $3 != 5 && ( COMPACT || $3 > 5 )) + { + printf(" mov %%eax,#%d\n", $2); + printf(" br sys_call%d\n", $3); + } + else + { + printf(" pushl %%ebp\n"); + printf(" movl %%esp,%%ebp\n"); + printf(" pushl %%ebx\n"); + if( $3 >= 1 ) printf(" mov 8(%%ebp),%%ebx\n"); + if( $3 >= 2 ) printf(" mov 12(%%ebp),%%ecx\n"); + if( $3 >= 3 ) printf(" mov 16(%%ebp),%%edx\n"); + if( $3 >= 4 ) printf(" push %%esi\n"); + if( $3 >= 4 ) printf(" mov 20(%%ebp),%%esi\n"); + if( $3 >= 5 ) printf(" push %%edi\n"); + if( $3 >= 5 ) printf(" mov 24(%%ebp),%%edi\n"); + printf(" mov $%d,%%eax\n", $2); + printf(" int $0x80\n"); + + if( $3 >= 5 ) printf(" pop %%edi\n"); + if( $3 >= 4 ) printf(" pop %%esi\n"); + printf(" pop %%ebx\n"); + + printf(" test %%eax,%%eax\n"); + printf(" jge syscall_ok\n"); + printf(" neg %%eax\n"); + printf(" mov %%eax,errno\n"); + printf(" mov $-1,%%eax\n"); + printf("syscall_ok:\n"); + printf(" movl %%ebp,%%esp\n"); + printf(" popl %%ebp\n"); + printf(" ret\n"); + } + printf(".endif\n\n"); +} +END{ + + printf("#endif /* __AS386_32__ */\n\n"); + printf("#endif /* __MSDOS__ */\n\n"); + printf("%s\n", obj) > "syscall.mak"; + printf "\n" > "syscall.mak"; + +}' > syscall.s + +cat >> syscall.mak <<\! + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC)($(OBJ)) + @$(RM) $(OBJ) + +$(LIBC)($(OBJ)): syscall.dat mksyscall + $(AS) --defsym L_$*=0 syscall.s -o $*.o + $(AR) $(ARFLAGS) $@ $*.o +! + +exit $? |