Skip to content

Commit

Permalink
[libc] Implement regparmcall calling convention for most libc
Browse files Browse the repository at this point in the history
routines (except execl...)
  • Loading branch information
tkchia committed Nov 26, 2022
1 parent cfe17a6 commit 42fea4c
Show file tree
Hide file tree
Showing 13 changed files with 200 additions and 15 deletions.
5 changes: 0 additions & 5 deletions libc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,6 @@ endif

MAINMULTISUBDIR=$(firstword $(subst ;, ,$(MAINMULTI)))

# For now do not build multilibs for the regparmcall calling convention, as
# the assembly code in elks-libc does not yet support it. TODO. -- tkchia
BUILDMULTIS:=$(strip \
$(foreach ml,$(BUILDMULTIS), \
$(if $(findstring @mregparmcall@,$(ml)@),,$(ml))))
ifeq "" "$(BUILDMULTIS)"
$(error no multilib variants to build for elks-libc)
endif
Expand Down
22 changes: 22 additions & 0 deletions libc/asm/memcmp-s.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,35 @@ memcmp:

// Save SI DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %es,%dx

mov %ds,%ax
mov %ax,%es

mov %si,%cx
mov %di,%bx
#else
push %es

mov %ds,%bx
mov %bx,%es

push %si
mov %di,%bx
#endif

// Do the copy

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%si // s1
mov 6+FAR_ADJ_(%bp),%di // s2
mov 8+FAR_ADJ_(%bp),%cx // n
#else
mov %ax,%si // s1
mov %dx,%di // s2
// n = CX already
#endif

xor %ax,%ax
cld
Expand All @@ -42,9 +58,15 @@ memcmp:

// Restore SI DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %cx,%si
mov %bx,%di
mov %dx,%es
#else
pop %si
mov %bx,%di
pop %es
#endif

pop %bp
RET_(6)
Expand Down
28 changes: 28 additions & 0 deletions libc/asm/memcpy-s.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,62 @@ memcpy:

// Save SI DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %es,%dx

mov %ds,%ax
mov %ax,%es

mov %si,%ax
mov %di,%bx
#else
push %es

mov %ds,%bx
mov %bx,%es

push %si
push %di
#endif

// Do the copy

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%di // dest
mov 6+FAR_ADJ_(%bp),%si // src
mov 8+FAR_ADJ_(%bp),%cx // n
#else
mov %ax,%di // dest
mov %ax,%bx
mov %dx,%si // src
// n = CX already
#endif

cld
rep
movsb

// Restore SI DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %ax,%si
mov %bx,%di

mov %dx,%es
#else
pop %di
pop %si

pop %es
#endif

// Return value is destination

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%ax
#else
mov %bx,%ax
#endif

pop %bp
RET_(6)
Expand Down
24 changes: 24 additions & 0 deletions libc/asm/memset-s.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,55 @@ memset:

// Save DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %es,%dx

mov %ds,%ax
mov %ax,%es

mov %di,%bx
#else
push %es
push %di

mov %ds,%bx
mov %bx,%es
#endif

// Do the setup

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%di // s
mov 6+FAR_ADJ_(%bp),%ax // c
mov 8+FAR_ADJ_(%bp),%cx // n
#else
mov %ax,%di // s
mov %ax,%bx
mov %dx,%ax // c
// n = CX already
#endif

cld
rep
stosb

// Restore DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %bx,%di
mov %dx,%es
#else
pop %di
pop %es
#endif

// Return value is destination

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%ax
#else
mov %bx,%ax
#endif

pop %bp
RET_(6)
Expand Down
19 changes: 19 additions & 0 deletions libc/asm/strcmp-s.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,27 @@ strcmp:
push %bp
mov %sp,%bp

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %si,%dx // save SI DI ES -> DX BX CX
mov %di,%bx
mov %es,%cx
mov %ds,%ax
mov %ax,%es
#else
push %si
mov %di,%bx
mov %es,%cx
mov %ds,%si
mov %si,%es
#endif

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%di // s1
mov 6+FAR_ADJ_(%bp),%si // s2
#else
mov %ax,%di // s1
mov %dx,%si // s2
#endif
cld
1:
lodsb
Expand All @@ -35,9 +48,15 @@ strcmp:
sbb %ax,%ax // return correct val (-1,1)
orb $1,%al
3:
#ifndef __IA16_CALLCVT_REGPARMCALL
mov %dx,%si // restore SI DI ES
mov %bx,%di
mov %cx,%es
#else
pop %si
mov %bx,%di
mov %cx,%es
#endif

pop %bp
RET_(2)
Expand Down
27 changes: 27 additions & 0 deletions libc/asm/strcpy-s.S
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,34 @@ strcpy:

// Save SI DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %es,%dx

mov %ds,%ax
mov %ax,%es

mov %si,%bx
mov %di,%cx
#else
push %es

mov %ds,%bx
mov %bx,%es

push %si
mov %di,%cx
#endif

// Do the copy

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%di // dest
mov 6+FAR_ADJ_(%bp),%si // src
#else
mov %ax,%di // dest
mov %ax,%bx
mov %dx,%si // src
#endif
cld

_loop:
Expand All @@ -39,14 +55,25 @@ _loop:

// Restore SI DI ES

#ifndef __IA16_CALLCVT_REGPARMCALL
mov %bx,%si
mov %cx,%di

mov %dx,%es
#else
pop %si
mov %cx,%di

pop %es
#endif

// Return value is destination

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%ax
#else
mov %bx,%ax
#endif

pop %bp
RET_(4)
Expand Down
8 changes: 6 additions & 2 deletions libc/asm/strlen-s.S
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ strlen:

mov %es,%dx

mov %ds,%ax
mov %ax,%es
mov %ds,%bx
mov %bx,%es

mov %di,%bx

// Do the scan

#ifndef __IA16_CALLCVT_REGPARMCALL
mov 4+FAR_ADJ_(%bp),%di // s
#else
mov %ax,%di
#endif
mov $-1,%cx
xor %ax,%ax

Expand Down
7 changes: 6 additions & 1 deletion libc/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ _start:
shl $1,%ax
add %bx,%ax // envp [0]
mov %ax,environ
#ifndef __IA16_CALLCVT_REGPARMCALL
push %ax
push %bx
push %cx
#else
xchg %ax,%cx // ax := argc, cx := envp
mov %bx,%dx // dx := argv
#endif
mov (%bx),%bx
mov %bx,_program_filename
push %cx
CALL_(main)
#ifdef __IA16_CALLCVT_CDECL
add $6,%sp
Expand Down
12 changes: 9 additions & 3 deletions libc/include/libc-private/call-cvt.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
/* Adjustment to stack frame offsets to account for far return addresses */
# define FAR_ADJ_ 2
/* How to return from a subroutine with N bytes of arguments */
# ifdef __IA16_CALLCVT_STDCALL
# if defined __IA16_CALLCVT_STDCALL
# define RET_(n) .if (n); lret $(n); .else; lret; .endif
# elif defined __IA16_CALLCVT_CDECL
# define RET_(n) lret
# elif defined __IA16_CALLCVT_REGPARMCALL
# define RET_(n) .if (n)>6; lret $(n)-6; .else; lret; .endif
# else
# error "unknown calling convention!"
# endif
Expand All @@ -29,10 +31,14 @@
# endif
#else
# define FAR_ADJ_ 0
# ifdef __IA16_CALLCVT_STDCALL
# if defined __IA16_CALLCVT_STDCALL
# define RET_(n) .if (n); ret $(n); .else; ret; .endif
# else
# elif defined __IA16_CALLCVT_CDECL
# define RET_(n) ret
# elif defined __IA16_CALLCVT_REGPARMCALL
# define RET_(n) .if (n)>6; ret $(n)-6; .else; ret; .endif
# else
# error "unknown calling convention!"
# endif
# define CALL_N_(s) call s
# define CALL_(s) call s
Expand Down
7 changes: 6 additions & 1 deletion libc/system/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ ifeq "$(VPATH)" ""
else
dir = $(VPATH)/
endif
ifeq "$(filter -mregparmcall,$(CC) $(CFLAGS) $(MULTILIB))" ""
regparmcall = 0
else
regparmcall = 1
endif

all: out.a

out.a: syscall.mk out

syscall.mk: $(SYSCALLDAT) $(dir)syscall.awk
awk -f $(dir)syscall.awk $< > $@
awk -f $(dir)syscall.awk regparmcall=$(regparmcall) $< > $@

out::
$(MAKE) -f $(dir)out.mk
Expand Down
Loading

0 comments on commit 42fea4c

Please sign in to comment.