more minor fixes
* tccgen: re-allow long double constants for x87 cross
  sizeof (long double) may be 12 or 16 depending on host platform
  (i386/x86_64 on unix/windows).
  Except that it's 8 if the host is on windows and not gcc
  was used to compile tcc.
* win64: fix builtin_va_start after VT_REF removal
  See also a8b83ce43a
* tcctest.c: remove outdated limitation for ll-bitfield test
  It always worked, there is no reason why it should not work
  in future.
* libtcc1.c: exclude long double conversion on ARM
* Makefile: remove CFLAGS from link recipes
* lib/Makefile: use target DEFINES as passed from main Makefile
* lib/armflush.c lib/va_list.c: factor out from libtcc1.c
* arm-gen.c: disable "depreciated" warnings for now
			
			
This commit is contained in:
		
							parent
							
								
									94ac9f2b49
								
							
						
					
					
						commit
						44abffe33a
					
				
					 9 changed files with 195 additions and 167 deletions
				
			
		
							
								
								
									
										14
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -195,14 +195,14 @@ $(X)arm-gen.o : arm-asm.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Host Tiny C Compiler
 | 
					# Host Tiny C Compiler
 | 
				
			||||||
tcc$(EXESUF): tcc.o $(LIBTCC)
 | 
					tcc$(EXESUF): tcc.o $(LIBTCC)
 | 
				
			||||||
	$(CC) -o $@ $^ $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
 | 
						$(CC) -o $@ $^ $(LIBS) $(LDFLAGS) $(LINK_LIBTCC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Cross Tiny C Compilers
 | 
					# Cross Tiny C Compilers
 | 
				
			||||||
%-tcc$(EXESUF): FORCE
 | 
					%-tcc$(EXESUF): FORCE
 | 
				
			||||||
	@$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
 | 
						@$(MAKE) --no-print-directory $@ CROSS_TARGET=$* ONE_SOURCE=$(or $(ONE_SOURCE),yes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
 | 
					$(CROSS_TARGET)-tcc$(EXESUF): $(TCC_FILES)
 | 
				
			||||||
	$(CC) -o $@ $^ $(DEFINES) $(CFLAGS) $(LIBS) $(LDFLAGS)
 | 
						$(CC) -o $@ $^ $(LIBS) $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# profiling version
 | 
					# profiling version
 | 
				
			||||||
tcc_p$(EXESUF): $($T_FILES)
 | 
					tcc_p$(EXESUF): $($T_FILES)
 | 
				
			||||||
| 
						 | 
					@ -214,13 +214,14 @@ libtcc.a: $(LIBTCC_OBJ)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# dynamic libtcc library
 | 
					# dynamic libtcc library
 | 
				
			||||||
libtcc.so: $(LIBTCC_OBJ)
 | 
					libtcc.so: $(LIBTCC_OBJ)
 | 
				
			||||||
	$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(CFLAGS) $(LDFLAGS)
 | 
						$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libtcc.so: CFLAGS+=-fPIC
 | 
					libtcc.so: CFLAGS+=-fPIC
 | 
				
			||||||
 | 
					libtcc.so: LDFLAGS+=-fPIC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# windows dynamic libtcc library
 | 
					# windows dynamic libtcc library
 | 
				
			||||||
libtcc.dll : $(LIBTCC_OBJ)
 | 
					libtcc.dll : $(LIBTCC_OBJ)
 | 
				
			||||||
	$(CC) -shared -o $@ $^ $(CFLAGS) $(LDFLAGS)
 | 
						$(CC) -shared -o $@ $^ $(LDFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
libtcc.def : libtcc.dll tcc$(EXESUF)
 | 
					libtcc.def : libtcc.dll tcc$(EXESUF)
 | 
				
			||||||
	./tcc$(EXESUF) -impdef $< -o $@
 | 
						./tcc$(EXESUF) -impdef $< -o $@
 | 
				
			||||||
| 
						 | 
					@ -229,12 +230,13 @@ libtcc.dll : DEFINES += -DLIBTCC_AS_DLL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# TinyCC runtime libraries
 | 
					# TinyCC runtime libraries
 | 
				
			||||||
libtcc1.a : tcc$(EXESUF) FORCE
 | 
					libtcc1.a : tcc$(EXESUF) FORCE
 | 
				
			||||||
	@$(MAKE) -C lib
 | 
						@$(MAKE) -C lib DEFINES="$(DEF-$T)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Cross libtcc1.a
 | 
					# Cross libtcc1.a
 | 
				
			||||||
libtcc1-%.a : %-tcc$(EXESUF) FORCE
 | 
					libtcc1-%.a : %-tcc$(EXESUF) FORCE
 | 
				
			||||||
	@$(MAKE) -C lib CROSS_TARGET=$*
 | 
						@$(MAKE) -C lib DEFINES="$(DEF-$*)" CROSS_TARGET=$*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PRECIOUS: libtcc1-%.a
 | 
				
			||||||
FORCE:
 | 
					FORCE:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# --------------------------------------------------------------------------
 | 
					# --------------------------------------------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -179,6 +179,7 @@ ST_FUNC void arm_init(struct TCCState *s)
 | 
				
			||||||
#define func_ldouble_type func_old_type
 | 
					#define func_ldouble_type func_old_type
 | 
				
			||||||
ST_FUNC void arm_init(struct TCCState *s)
 | 
					ST_FUNC void arm_init(struct TCCState *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
#if !defined (TCC_ARM_VFP)
 | 
					#if !defined (TCC_ARM_VFP)
 | 
				
			||||||
    tcc_warning("Support for FPA is deprecated and will be removed in next"
 | 
					    tcc_warning("Support for FPA is deprecated and will be removed in next"
 | 
				
			||||||
                " release");
 | 
					                " release");
 | 
				
			||||||
| 
						 | 
					@ -187,6 +188,7 @@ ST_FUNC void arm_init(struct TCCState *s)
 | 
				
			||||||
    tcc_warning("Support for OABI is deprecated and will be removed in next"
 | 
					    tcc_warning("Support for OABI is deprecated and will be removed in next"
 | 
				
			||||||
                " release");
 | 
					                " release");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										53
									
								
								lib/Makefile
									
										
									
									
									
								
							
							
						
						
									
										53
									
								
								lib/Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -17,61 +17,54 @@ XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include
 | 
				
			||||||
XFLAGS = $(XFLAGS$(XCFG))
 | 
					XFLAGS = $(XFLAGS$(XCFG))
 | 
				
			||||||
XCFG = $(or $(findstring -win,$T),-unx)
 | 
					XCFG = $(or $(findstring -win,$T),-unx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(X),)
 | 
					# using gcc ("make armlib-usegcc=no" to use tcc)
 | 
				
			||||||
 BCHECK_O = bcheck.o
 | 
					armlib-usegcc ?= no
 | 
				
			||||||
 ifeq "$T" "arm"
 | 
					
 | 
				
			||||||
 | 
					ifeq "$($(X)$(T)lib-usegcc)" "yes"
 | 
				
			||||||
 XCC = $(CC)
 | 
					 XCC = $(CC)
 | 
				
			||||||
 XAR = $(AR)
 | 
					 XAR = $(AR)
 | 
				
			||||||
 XFLAGS = $(CFLAGS) -fPIC
 | 
					 XFLAGS = $(CFLAGS) -fPIC
 | 
				
			||||||
 endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# only for native compiler
 | 
				
			||||||
 | 
					$(X)BCHECK_O = bcheck.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ifeq ($(CONFIG_musl),yes)
 | 
				
			||||||
 | 
					 BCHECK_O =
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifdef CONFIG_OSX
 | 
					ifdef CONFIG_OSX
 | 
				
			||||||
 XFLAGS += -D_ANSI_SOURCE
 | 
					 XFLAGS += -D_ANSI_SOURCE
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(CONFIG_musl),yes)
 | 
					 | 
				
			||||||
 BCHECK_O =
 | 
					 | 
				
			||||||
endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
I386_O = libtcc1.o alloca86.o alloca86-bt.o
 | 
					I386_O = libtcc1.o alloca86.o alloca86-bt.o
 | 
				
			||||||
X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
 | 
					X86_64_O = libtcc1.o alloca86_64.o alloca86_64-bt.o
 | 
				
			||||||
ARM_O = libtcc1.o armeabi.o alloca-arm.o
 | 
					ARM_O = libtcc1.o armeabi.o alloca-arm.o armflush.o
 | 
				
			||||||
ARM64_O = lib-arm64.o
 | 
					ARM64_O = lib-arm64.o
 | 
				
			||||||
WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
 | 
					WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OBJ-i386 = $(I386_O) $(BCHECK_O)
 | 
					OBJ-i386 = $(I386_O) $(BCHECK_O)
 | 
				
			||||||
TGT-i386 = -DTCC_TARGET_I386
 | 
					OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O)
 | 
				
			||||||
 | 
					OBJ-x86_64-osx = $(X86_64_O) va_list.o
 | 
				
			||||||
OBJ-x86_64 = $(X86_64_O) $(BCHECK_O)
 | 
					 | 
				
			||||||
TGT-x86_64 = -DTCC_TARGET_X86_64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OBJ-x86_64-osx = $(X86_64_O)
 | 
					 | 
				
			||||||
TGT-x86_64-osx = -DTCC_TARGET_X86_64 -DTCC_TARGET_MACHO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OBJ-arm = $(ARM_O)
 | 
					 | 
				
			||||||
TGT-arm = -DTCC_TARGET_ARM
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OBJ-arm64 = $(ARM64_O)
 | 
					 | 
				
			||||||
TGT-arm64 = -DTCC_TARGET_ARM64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
 | 
					OBJ-i386-win32 = $(I386_O) chkstk.o bcheck.o $(WIN_O)
 | 
				
			||||||
TGT-i386-win32 = -DTCC_TARGET_I386 -DTCC_TARGET_PE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
 | 
					OBJ-x86_64-win32 = $(X86_64_O) chkstk.o bcheck.o $(WIN_O)
 | 
				
			||||||
TGT-x86_64-win32 = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
 | 
					OBJ-arm64 = $(ARM64_O)
 | 
				
			||||||
 | 
					OBJ-arm = $(ARM_O)
 | 
				
			||||||
 | 
					OBJ-arm-fpa = $(ARM_O)
 | 
				
			||||||
 | 
					OBJ-arm-fpa-ld = $(ARM_O)
 | 
				
			||||||
 | 
					OBJ-arm-vfp = $(ARM_O)
 | 
				
			||||||
 | 
					OBJ-arm-eabi = $(ARM_O)
 | 
				
			||||||
 | 
					OBJ-arm-eabihf = $(ARM_O)
 | 
				
			||||||
OBJ-arm-wince = $(ARM_O) $(WIN_O)
 | 
					OBJ-arm-wince = $(ARM_O) $(WIN_O)
 | 
				
			||||||
TGT-arm-wince = -DTCC_TARGET_ARM -DTCC_TARGET_PE
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
 | 
					$(BIN) : $(patsubst %.o,$(X)%.o,$(OBJ-$T))
 | 
				
			||||||
	$(XAR) rcs $@ $^
 | 
						$(XAR) rcs $@ $^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(X)%.o : %.c
 | 
					$(X)%.o : %.c
 | 
				
			||||||
	$(XCC) -c $< -o $@ $(TGT-$T) $(XFLAGS)
 | 
						$(XCC) -c $< -o $@ $(DEFINES) $(XFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(X)%.o : %.S
 | 
					$(X)%.o : %.S
 | 
				
			||||||
	$(XCC) -c $< -o $@ $(TGT-$T) $(XFLAGS)
 | 
						$(XCC) -c $< -o $@ $(DEFINES) $(XFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(X)crt1w.o : crt1.c
 | 
					$(X)crt1w.o : crt1.c
 | 
				
			||||||
$(X)wincrt1w.o : wincrt1.c
 | 
					$(X)wincrt1w.o : wincrt1.c
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								lib/armflush.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								lib/armflush.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					/* armflush.c - flush the instruction cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   __clear_cache is used in tccrun.c,  It is a built-in
 | 
				
			||||||
 | 
					   intrinsic with gcc.  However tcc in order to compile
 | 
				
			||||||
 | 
					   itself needs this function */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __TINYC__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* syscall wrapper */
 | 
				
			||||||
 | 
					unsigned syscall(unsigned syscall_nr, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* arm-tcc supports only fake asm currently */
 | 
				
			||||||
 | 
					__asm__(
 | 
				
			||||||
 | 
					    ".global syscall\n"
 | 
				
			||||||
 | 
					    "syscall:\n"
 | 
				
			||||||
 | 
					    ".int 0xe92d4080\n"  // push    {r7, lr}
 | 
				
			||||||
 | 
					    ".int 0xe1a07000\n"  // mov     r7, r0
 | 
				
			||||||
 | 
					    ".int 0xe1a00001\n"  // mov     r0, r1
 | 
				
			||||||
 | 
					    ".int 0xe1a01002\n"  // mov     r1, r2
 | 
				
			||||||
 | 
					    ".int 0xe1a02003\n"  // mov     r2, r3
 | 
				
			||||||
 | 
					    ".int 0xef000000\n"  // svc     0x00000000
 | 
				
			||||||
 | 
					    ".int 0xe8bd8080\n"  // pop     {r7, pc}
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* from unistd.h: */
 | 
				
			||||||
 | 
					#if defined(__thumb__) || defined(__ARM_EABI__)
 | 
				
			||||||
 | 
					# define __NR_SYSCALL_BASE      0x0
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define __NR_SYSCALL_BASE      0x900000
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#define __ARM_NR_BASE           (__NR_SYSCALL_BASE+0x0f0000)
 | 
				
			||||||
 | 
					#define __ARM_NR_cacheflush     (__ARM_NR_BASE+2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _GNU_SOURCE
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Flushing for tccrun */
 | 
				
			||||||
 | 
					void __clear_cache(void *beginning, void *end)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
 | 
				
			||||||
 | 
					 * However, there is no ARM asm parser in tcc so we use it for now */
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
 | 
					    syscall(__ARM_NR_cacheflush, beginning, end, 0);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    __asm__ ("push {r7}\n\t"
 | 
				
			||||||
 | 
					             "mov r7, #0xf0002\n\t"
 | 
				
			||||||
 | 
					             "mov r2, #0\n\t"
 | 
				
			||||||
 | 
					             "swi 0\n\t"
 | 
				
			||||||
 | 
					             "pop {r7}\n\t"
 | 
				
			||||||
 | 
					             "ret");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										128
									
								
								lib/libtcc1.c
									
										
									
									
									
								
							
							
						
						
									
										128
									
								
								lib/libtcc1.c
									
										
									
									
									
								
							| 
						 | 
					@ -550,6 +550,13 @@ unsigned long long __fixunssfdi (float a1)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long long __fixsfdi (float a1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    long long ret; int s;
 | 
				
			||||||
 | 
					    ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
 | 
				
			||||||
 | 
					    return s ? ret : -ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned long long __fixunsdfdi (double a1)
 | 
					unsigned long long __fixunsdfdi (double a1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    register union double_long dl1;
 | 
					    register union double_long dl1;
 | 
				
			||||||
| 
						 | 
					@ -575,6 +582,14 @@ unsigned long long __fixunsdfdi (double a1)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					long long __fixdfdi (double a1)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    long long ret; int s;
 | 
				
			||||||
 | 
					    ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
 | 
				
			||||||
 | 
					    return s ? ret : -ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef TCC_TARGET_ARM
 | 
				
			||||||
unsigned long long __fixunsxfdi (long double a1)
 | 
					unsigned long long __fixunsxfdi (long double a1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    register union ldouble_long dl1;
 | 
					    register union ldouble_long dl1;
 | 
				
			||||||
| 
						 | 
					@ -598,121 +613,10 @@ unsigned long long __fixunsxfdi (long double a1)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
long long __fixsfdi (float a1)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    long long ret; int s;
 | 
					 | 
				
			||||||
    ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1);
 | 
					 | 
				
			||||||
    return s ? ret : -ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long long __fixdfdi (double a1)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    long long ret; int s;
 | 
					 | 
				
			||||||
    ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1);
 | 
					 | 
				
			||||||
    return s ? ret : -ret;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
long long __fixxfdi (long double a1)
 | 
					long long __fixxfdi (long double a1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    long long ret; int s;
 | 
					    long long ret; int s;
 | 
				
			||||||
    ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
 | 
					    ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1);
 | 
				
			||||||
    return s ? ret : -ret;
 | 
					    return s ? ret : -ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif /* !ARM */
 | 
				
			||||||
#if defined(TCC_TARGET_X86_64) && !defined(_WIN64)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef __TINYC__
 | 
					 | 
				
			||||||
# include <stdlib.h>
 | 
					 | 
				
			||||||
# include <stdio.h>
 | 
					 | 
				
			||||||
# include <string.h>
 | 
					 | 
				
			||||||
# undef __va_start
 | 
					 | 
				
			||||||
# undef __va_arg
 | 
					 | 
				
			||||||
# undef __va_copy
 | 
					 | 
				
			||||||
# undef __va_end
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
/* Avoid include files, they may not be available when cross compiling */
 | 
					 | 
				
			||||||
extern void *memset(void *s, int c, __SIZE_TYPE__ n);
 | 
					 | 
				
			||||||
extern void abort(void);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* This should be in sync with our include/stdarg.h */
 | 
					 | 
				
			||||||
enum __va_arg_type {
 | 
					 | 
				
			||||||
    __va_gen_reg, __va_float_reg, __va_stack
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* GCC compatible definition of va_list. */
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    unsigned int gp_offset;
 | 
					 | 
				
			||||||
    unsigned int fp_offset;
 | 
					 | 
				
			||||||
    union {
 | 
					 | 
				
			||||||
        unsigned int overflow_offset;
 | 
					 | 
				
			||||||
        char *overflow_arg_area;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    char *reg_save_area;
 | 
					 | 
				
			||||||
} __va_list_struct;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void __va_start(__va_list_struct *ap, void *fp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    memset(ap, 0, sizeof(__va_list_struct));
 | 
					 | 
				
			||||||
    *ap = *(__va_list_struct *)((char *)fp - 16);
 | 
					 | 
				
			||||||
    ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
 | 
					 | 
				
			||||||
    ap->reg_save_area = (char *)fp - 176 - 16;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void *__va_arg(__va_list_struct *ap,
 | 
					 | 
				
			||||||
               enum __va_arg_type arg_type,
 | 
					 | 
				
			||||||
               int size, int align)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    size = (size + 7) & ~7;
 | 
					 | 
				
			||||||
    align = (align + 7) & ~7;
 | 
					 | 
				
			||||||
    switch (arg_type) {
 | 
					 | 
				
			||||||
    case __va_gen_reg:
 | 
					 | 
				
			||||||
        if (ap->gp_offset + size <= 48) {
 | 
					 | 
				
			||||||
            ap->gp_offset += size;
 | 
					 | 
				
			||||||
            return ap->reg_save_area + ap->gp_offset - size;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        goto use_overflow_area;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case __va_float_reg:
 | 
					 | 
				
			||||||
        if (ap->fp_offset < 128 + 48) {
 | 
					 | 
				
			||||||
            ap->fp_offset += 16;
 | 
					 | 
				
			||||||
            return ap->reg_save_area + ap->fp_offset - 16;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        size = 8;
 | 
					 | 
				
			||||||
        goto use_overflow_area;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    case __va_stack:
 | 
					 | 
				
			||||||
    use_overflow_area:
 | 
					 | 
				
			||||||
        ap->overflow_arg_area += size;
 | 
					 | 
				
			||||||
        ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
 | 
					 | 
				
			||||||
        return ap->overflow_arg_area - size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    default: /* should never happen */
 | 
					 | 
				
			||||||
        abort();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif /* __x86_64__ */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined TCC_TARGET_ARM && !defined __TINYC__
 | 
					 | 
				
			||||||
#define _GNU_SOURCE
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <sys/syscall.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Flushing for tccrun */
 | 
					 | 
				
			||||||
void __clear_cache(void *beginning, void *end)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
/* __ARM_NR_cacheflush is kernel private and should not be used in user space.
 | 
					 | 
				
			||||||
 * However, there is no ARM asm parser in tcc so we use it for now */
 | 
					 | 
				
			||||||
#if 1
 | 
					 | 
				
			||||||
    syscall(__ARM_NR_cacheflush, beginning, end, 0);
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    __asm__ ("push {r7}\n\t"
 | 
					 | 
				
			||||||
             "mov r7, #0xf0002\n\t"
 | 
					 | 
				
			||||||
             "mov r2, #0\n\t"
 | 
					 | 
				
			||||||
             "swi 0\n\t"
 | 
					 | 
				
			||||||
             "pop {r7}\n\t"
 | 
					 | 
				
			||||||
             "ret");
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif /* arm */
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										65
									
								
								lib/va_list.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								lib/va_list.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					/* va_list.c - tinycc support for va_list on X86_64 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined TCC_TARGET_X86_64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Avoid include files, they may not be available when cross compiling */
 | 
				
			||||||
 | 
					extern void *memset(void *s, int c, __SIZE_TYPE__ n);
 | 
				
			||||||
 | 
					extern void abort(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* This should be in sync with our include/stdarg.h */
 | 
				
			||||||
 | 
					enum __va_arg_type {
 | 
				
			||||||
 | 
					    __va_gen_reg, __va_float_reg, __va_stack
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GCC compatible definition of va_list. */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    unsigned int gp_offset;
 | 
				
			||||||
 | 
					    unsigned int fp_offset;
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        unsigned int overflow_offset;
 | 
				
			||||||
 | 
					        char *overflow_arg_area;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    char *reg_save_area;
 | 
				
			||||||
 | 
					} __va_list_struct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void __va_start(__va_list_struct *ap, void *fp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    memset(ap, 0, sizeof(__va_list_struct));
 | 
				
			||||||
 | 
					    *ap = *(__va_list_struct *)((char *)fp - 16);
 | 
				
			||||||
 | 
					    ap->overflow_arg_area = (char *)fp + ap->overflow_offset;
 | 
				
			||||||
 | 
					    ap->reg_save_area = (char *)fp - 176 - 16;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void *__va_arg(__va_list_struct *ap,
 | 
				
			||||||
 | 
					               enum __va_arg_type arg_type,
 | 
				
			||||||
 | 
					               int size, int align)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size = (size + 7) & ~7;
 | 
				
			||||||
 | 
					    align = (align + 7) & ~7;
 | 
				
			||||||
 | 
					    switch (arg_type) {
 | 
				
			||||||
 | 
					    case __va_gen_reg:
 | 
				
			||||||
 | 
					        if (ap->gp_offset + size <= 48) {
 | 
				
			||||||
 | 
					            ap->gp_offset += size;
 | 
				
			||||||
 | 
					            return ap->reg_save_area + ap->gp_offset - size;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        goto use_overflow_area;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case __va_float_reg:
 | 
				
			||||||
 | 
					        if (ap->fp_offset < 128 + 48) {
 | 
				
			||||||
 | 
					            ap->fp_offset += 16;
 | 
				
			||||||
 | 
					            return ap->reg_save_area + ap->fp_offset - 16;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        size = 8;
 | 
				
			||||||
 | 
					        goto use_overflow_area;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case __va_stack:
 | 
				
			||||||
 | 
					    use_overflow_area:
 | 
				
			||||||
 | 
					        ap->overflow_arg_area += size;
 | 
				
			||||||
 | 
					        ap->overflow_arg_area = (char*)((long long)(ap->overflow_arg_area + align - 1) & -align);
 | 
				
			||||||
 | 
					        return ap->overflow_arg_area - size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default: /* should never happen */
 | 
				
			||||||
 | 
					        abort();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										13
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								tccgen.c
									
										
									
									
									
								
							| 
						 | 
					@ -4578,9 +4578,12 @@ ST_FUNC void unary(void)
 | 
				
			||||||
#ifdef TCC_TARGET_PE
 | 
					#ifdef TCC_TARGET_PE
 | 
				
			||||||
    case TOK_builtin_va_start:
 | 
					    case TOK_builtin_va_start:
 | 
				
			||||||
	parse_builtin_params(0, "ee");
 | 
						parse_builtin_params(0, "ee");
 | 
				
			||||||
	if ((vtop->r & VT_VALMASK) != VT_LOCAL)
 | 
					        r = vtop->r & VT_VALMASK;
 | 
				
			||||||
 | 
					        if (r == VT_LLOCAL)
 | 
				
			||||||
 | 
					            r = VT_LOCAL;
 | 
				
			||||||
 | 
					        if (r != VT_LOCAL)
 | 
				
			||||||
            tcc_error("__builtin_va_start expects a local variable");
 | 
					            tcc_error("__builtin_va_start expects a local variable");
 | 
				
			||||||
	vtop->r &= ~VT_LVAL;
 | 
					        vtop->r = r;
 | 
				
			||||||
	vtop->type = char_pointer_type;
 | 
						vtop->type = char_pointer_type;
 | 
				
			||||||
	vtop->c.i += 8;
 | 
						vtop->c.i += 8;
 | 
				
			||||||
	vstore();
 | 
						vstore();
 | 
				
			||||||
| 
						 | 
					@ -6169,7 +6172,11 @@ static void init_putv(CType *type, Section *sec, unsigned long c)
 | 
				
			||||||
                if (sizeof(long double) == LDOUBLE_SIZE)
 | 
					                if (sizeof(long double) == LDOUBLE_SIZE)
 | 
				
			||||||
		    *(long double *)ptr = vtop->c.ld;
 | 
							    *(long double *)ptr = vtop->c.ld;
 | 
				
			||||||
		else if (sizeof(double) == LDOUBLE_SIZE)
 | 
							else if (sizeof(double) == LDOUBLE_SIZE)
 | 
				
			||||||
		    *(double *)ptr = vtop->c.ld;
 | 
							    *(double *)ptr = (double)vtop->c.ld;
 | 
				
			||||||
 | 
					#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
 | 
				
			||||||
 | 
					                else if (sizeof (long double) >= 10)
 | 
				
			||||||
 | 
					                    memcpy(memset(ptr, 0, LDOUBLE_SIZE), &vtop->c.ld, 10);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
                    tcc_error("can't cross compile long double constants");
 | 
					                    tcc_error("can't cross compile long double constants");
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -637,10 +637,13 @@ int main(int argc, char **argv) {
 | 
				
			||||||
  RUN_TEST(ret_longdouble_test);
 | 
					  RUN_TEST(ret_longdouble_test);
 | 
				
			||||||
  RUN_TEST(ret_2float_test);
 | 
					  RUN_TEST(ret_2float_test);
 | 
				
			||||||
  RUN_TEST(ret_2double_test);
 | 
					  RUN_TEST(ret_2double_test);
 | 
				
			||||||
  /* RUN_TEST(ret_8plus2double_test); currently broken on x86_64 */
 | 
					#if !defined __x86_64__ || defined _WIN32
 | 
				
			||||||
  /* RUN_TEST(ret_6plus2longlong_test); currently broken on x86_64 */
 | 
					  /* currently broken on x86_64 linux */
 | 
				
			||||||
  /* RUN_TEST(ret_mixed_test); currently broken on x86_64 */
 | 
					  RUN_TEST(ret_8plus2double_test);
 | 
				
			||||||
  /* RUN_TEST(ret_mixed2_test); currently broken on x86_64 */
 | 
					  RUN_TEST(ret_6plus2longlong_test);
 | 
				
			||||||
 | 
					  RUN_TEST(ret_mixed_test);
 | 
				
			||||||
 | 
					  RUN_TEST(ret_mixed2_test);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
  RUN_TEST(ret_mixed3_test);
 | 
					  RUN_TEST(ret_mixed3_test);
 | 
				
			||||||
  RUN_TEST(reg_pack_test);
 | 
					  RUN_TEST(reg_pack_test);
 | 
				
			||||||
  RUN_TEST(reg_pack_longlong_test);
 | 
					  RUN_TEST(reg_pack_longlong_test);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2044,13 +2044,6 @@ void bitfield_test(void)
 | 
				
			||||||
    else 
 | 
					    else 
 | 
				
			||||||
        printf("st1.f2 != -1\n");
 | 
					        printf("st1.f2 != -1\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __i386__
 | 
					 | 
				
			||||||
    /* on i386 we don't correctly support long long bit-fields.
 | 
					 | 
				
			||||||
       The bitfields can straddle long long boundaries (at least with
 | 
					 | 
				
			||||||
       GCC bitfield layout) and code generation isn't prepared for this
 | 
					 | 
				
			||||||
       (would have to work with two words in that case).  */
 | 
					 | 
				
			||||||
    /* bit sizes below must be bigger than 32 since GCC doesn't allow
 | 
					 | 
				
			||||||
       long-long bitfields whose size is not bigger than int */
 | 
					 | 
				
			||||||
    struct sbf2 {
 | 
					    struct sbf2 {
 | 
				
			||||||
        long long f1 : 45;
 | 
					        long long f1 : 45;
 | 
				
			||||||
        long long : 2;
 | 
					        long long : 2;
 | 
				
			||||||
| 
						 | 
					@ -2063,7 +2056,7 @@ void bitfield_test(void)
 | 
				
			||||||
    st2.f3 = a;
 | 
					    st2.f3 = a;
 | 
				
			||||||
    st2.f2++;
 | 
					    st2.f2++;
 | 
				
			||||||
    printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
 | 
					    printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3);
 | 
				
			||||||
#endif
 | 
					
 | 
				
			||||||
#if 0
 | 
					#if 0
 | 
				
			||||||
    Disabled for now until further clarification re GCC compatibility
 | 
					    Disabled for now until further clarification re GCC compatibility
 | 
				
			||||||
    struct sbf3 {
 | 
					    struct sbf3 {
 | 
				
			||||||
| 
						 | 
					@ -2076,6 +2069,7 @@ void bitfield_test(void)
 | 
				
			||||||
    } st3;
 | 
					    } st3;
 | 
				
			||||||
    printf("sizeof(st3) = %d\n", sizeof(st3));
 | 
					    printf("sizeof(st3) = %d\n", sizeof(st3));
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct sbf4 {
 | 
					    struct sbf4 {
 | 
				
			||||||
	int x : 31;
 | 
						int x : 31;
 | 
				
			||||||
	char y : 2;
 | 
						char y : 2;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue