mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-27 06:10:06 +08:00
unsorted adjustments
- configure
* use aarch64 instead of arm64
- Makefile
* rename the custom include file to "config-extra.mak"
* Also avoid "rm -r /*" if $(tccdir) is empty
- pp/Makefile
* fix .expect generation with gcc
- tcc.h
* cleanup #defines for _MSC_VER
- tccgen.c:
* fix const-propagation for &,|
* fix anonymous named struct (ms-extension) and enable
-fms-extension by default
- i386-gen.c
* clear VT_DEFSIGN
- x86_64-gen.c/win64:
* fix passing structs in registers
* fix alloca (need to keep "func_scratch" below each alloca area on stack)
(This allows to compile a working gnu-make on win64)
- tccpp.c
* alternative approach to 37999a4fbf
This is to avoid some slowdown with ## token pasting.
* get_tok_str() : return <eof> for TOK_EOF
* -funsigned-char: apply to "string" literals as well
- tccpe/tools.c: -impdef: support both 32 and 64 bit dlls anyway
This commit is contained in:
parent
6c468c10f7
commit
9f79b62ec4
29
Makefile
29
Makefile
@ -151,8 +151,8 @@ DEF-win += -DCONFIG_TCCDIR="\"$(tccdir)/win32\""
|
||||
endif
|
||||
endif
|
||||
|
||||
# include custom cross-compiler configuration (see make help)
|
||||
-include config-cross.mak
|
||||
# include custom configuration (see make help)
|
||||
-include config-extra.mak
|
||||
|
||||
CORE_FILES = tcc.c tcctools.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
||||
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
||||
@ -318,7 +318,7 @@ install-win : INSTALL = cp
|
||||
|
||||
# uninstall on windows
|
||||
uninstall-win:
|
||||
rm -r "$(tccdir)/"*
|
||||
rm -r "$(tccdir)"
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# other stuff
|
||||
@ -374,19 +374,24 @@ help:
|
||||
@echo " build one specific cross compiler for 'TARGET', as in"
|
||||
@echo " $(TCC_X)"
|
||||
@echo ""
|
||||
@echo "Cross compiler configuration:"
|
||||
@echo " make will read custom configuration for cross compilers from a file"
|
||||
@echo " 'config-cross.mak' if present. For example for a windows->i386-linux"
|
||||
@echo " cross-compiler that expects the linux files in <tccdir>/i386-linux:"
|
||||
@echo "Custom configuration:"
|
||||
@echo " The makefile includes a file 'config-extra.mak' if it is present."
|
||||
@echo " This file may contain some custom configuration. For example:"
|
||||
@echo ""
|
||||
@echo " ROOT-i386 = {B}/i386-linux"
|
||||
@echo " CRT-i386 = {B}/i386-linux/usr/lib"
|
||||
@echo " LIB-i386 = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
|
||||
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
|
||||
@echo " DEF-i386 += -D__linux__"
|
||||
@echo " NATIVE_DEFINES += -D..."
|
||||
@echo ""
|
||||
@echo " Or for example to configure the search paths for a cross-compiler"
|
||||
@echo " that expects the linux files in <tccdir>/i386-linux:"
|
||||
@echo ""
|
||||
@echo " ROOT-i386 = {B}/i386-linux"
|
||||
@echo " CRT-i386 = {B}/i386-linux/usr/lib"
|
||||
@echo " LIB-i386 = {B}/i386-linux/lib:{B}/i386-linux/usr/lib"
|
||||
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
|
||||
@echo " DEF-i386 += -D__linux__"
|
||||
@echo ""
|
||||
@echo "Other supported make targets:"
|
||||
@echo " install install-strip test tags ETAGS tar clean distclean help"
|
||||
@echo ""
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
endif # ($(INCLUDED),no)
|
||||
|
14
configure
vendored
14
configure
vendored
@ -161,7 +161,7 @@ fi
|
||||
|
||||
case "$cpu" in
|
||||
x86|i386|i486|i586|i686|i86pc|BePC|i686-AT386)
|
||||
cpu="x86"
|
||||
cpu="i386"
|
||||
;;
|
||||
x86_64|amd64|x86-64)
|
||||
cpu="x86_64"
|
||||
@ -184,7 +184,7 @@ case "$cpu" in
|
||||
cpu="arm"
|
||||
;;
|
||||
aarch64)
|
||||
cpu="arm64"
|
||||
cpu="aarch64"
|
||||
;;
|
||||
alpha)
|
||||
cpu="alpha"
|
||||
@ -301,7 +301,7 @@ Advanced options (experts only):
|
||||
--disable-static make libtcc.so instead of libtcc.a
|
||||
--enable-static make libtcc.a instead of libtcc.dll (win32)
|
||||
--disable-rpath disable use of -rpath with the above
|
||||
--with-libgcc use libgcc_s.so.1 instead of libtcc1.a in dynamic link
|
||||
--with-libgcc use libgcc_s.so.1 instead of libtcc1.a
|
||||
--enable-mingw32 build windows version on linux with mingw32
|
||||
--enable-cross build cross compilers
|
||||
--with-selinux use mmap for executable memory (with tcc -run)
|
||||
@ -340,7 +340,7 @@ if test -z "$cross_prefix" ; then
|
||||
fi
|
||||
|
||||
if test -z "$triplet"; then
|
||||
if test $cpu = "x86_64" -o $cpu = "arm64" ; then
|
||||
if test $cpu = "x86_64" -o $cpu = "aarch64" ; then
|
||||
if test -f "/usr/lib64/crti.o" ; then
|
||||
tcc_lddir="lib64"
|
||||
fi
|
||||
@ -473,13 +473,11 @@ print_mak_int TCC_CPU_VERSION "$cpuver"
|
||||
|
||||
echo "#define GCC_MAJOR $gcc_major" >> $TMPH
|
||||
echo "#define GCC_MINOR $gcc_minor" >> $TMPH
|
||||
|
||||
if test "$cpu" = "x86" ; then
|
||||
echo "ARCH=i386" >> config.mak
|
||||
if test "$cpu" = "aarch64" ; then
|
||||
echo "ARCH=arm64" >> config.mak
|
||||
else
|
||||
echo "ARCH=$cpu" >> config.mak
|
||||
fi
|
||||
|
||||
echo "TARGETOS=$targetos" >> config.mak
|
||||
|
||||
for v in $confvars ; do
|
||||
|
@ -210,7 +210,7 @@ ST_FUNC void load(int r, SValue *sv)
|
||||
#endif
|
||||
|
||||
fr = sv->r;
|
||||
ft = sv->type.t;
|
||||
ft = sv->type.t & ~VT_DEFSIGN;
|
||||
fc = sv->c.i;
|
||||
|
||||
ft &= ~(VT_VOLATILE | VT_CONSTANT);
|
||||
|
@ -27,10 +27,6 @@ p2:
|
||||
|
||||
sub %rax,%rsp
|
||||
mov %rsp,%rax
|
||||
#ifdef TCC_TARGET_PE
|
||||
add $32,%rax
|
||||
#endif
|
||||
|
||||
p3:
|
||||
push %rdx
|
||||
ret
|
||||
|
14
libtcc.c
14
libtcc.c
@ -264,7 +264,7 @@ struct mem_debug_header {
|
||||
int line_num;
|
||||
char file_name[MEM_DEBUG_FILE_LEN + 1];
|
||||
unsigned magic2;
|
||||
__attribute__((aligned(16))) unsigned magic3;
|
||||
ALIGNED(16) unsigned magic3;
|
||||
};
|
||||
|
||||
typedef struct mem_debug_header mem_debug_header_t;
|
||||
@ -581,10 +581,7 @@ ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
|
||||
bf->buf_end = bf->buffer + initlen;
|
||||
bf->buf_end[0] = CH_EOB; /* put eob symbol */
|
||||
pstrcpy(bf->filename, sizeof(bf->filename), filename);
|
||||
pstrcpy(bf->filename2, sizeof(bf->filename2), filename);
|
||||
#ifdef _WIN32
|
||||
normalize_slashes(bf->filename);
|
||||
#endif
|
||||
bf->true_filename = bf->filename;
|
||||
bf->line_num = 1;
|
||||
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||
bf->fd = -1;
|
||||
@ -599,6 +596,8 @@ ST_FUNC void tcc_close(void)
|
||||
close(bf->fd);
|
||||
total_lines += bf->line_num;
|
||||
}
|
||||
if (bf->true_filename != bf->filename)
|
||||
tcc_free(bf->true_filename);
|
||||
file = bf->prev;
|
||||
tcc_free(bf);
|
||||
}
|
||||
@ -615,8 +614,10 @@ ST_FUNC int tcc_open(TCCState *s1, const char *filename)
|
||||
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
tcc_open_bf(s1, filename, 0);
|
||||
#ifdef _WIN32
|
||||
normalize_slashes(file->filename);
|
||||
#endif
|
||||
file->fd = fd;
|
||||
return fd;
|
||||
}
|
||||
@ -737,6 +738,7 @@ LIBTCCAPI TCCState *tcc_new(void)
|
||||
s->alacarte_link = 1;
|
||||
s->nocommon = 1;
|
||||
s->warn_implicit_function_declaration = 1;
|
||||
s->ms_extensions = 1;
|
||||
|
||||
#ifdef CHAR_IS_UNSIGNED
|
||||
s->char_is_unsigned = 1;
|
||||
|
22
tcc.h
22
tcc.h
@ -41,10 +41,11 @@
|
||||
# include <dlfcn.h>
|
||||
# endif
|
||||
/* XXX: need to define this to use them in non ISOC99 context */
|
||||
extern float strtof (const char *__nptr, char **__endptr);
|
||||
extern long double strtold (const char *__nptr, char **__endptr);
|
||||
extern float strtof (const char *__nptr, char **__endptr);
|
||||
extern long double strtold (const char *__nptr, char **__endptr);
|
||||
#endif
|
||||
|
||||
#else /* on _WIN32: */
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <io.h> /* open, close etc. */
|
||||
# include <direct.h> /* getcwd */
|
||||
@ -52,7 +53,6 @@
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
# define inline __inline
|
||||
# define inp next_inp /* inp is an intrinsic on msvc */
|
||||
# define snprintf _snprintf
|
||||
# define vsnprintf _vsnprintf
|
||||
# ifndef __GNUC__
|
||||
@ -65,6 +65,7 @@
|
||||
# define LIBTCCAPI __declspec(dllexport)
|
||||
# define PUB_FUNC LIBTCCAPI
|
||||
# endif
|
||||
# define inp next_inp /* inp is an intrinsic on msvc/mingw */
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data
|
||||
# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data
|
||||
@ -72,9 +73,6 @@
|
||||
# pragma warning (disable : 4018) // signed/unsigned mismatch
|
||||
# pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
|
||||
# define ssize_t intptr_t
|
||||
# define __attribute__(x) __declspec x
|
||||
# define aligned align
|
||||
# else
|
||||
# endif
|
||||
# undef CONFIG_TCC_STATIC
|
||||
#endif
|
||||
@ -83,12 +81,12 @@
|
||||
# define O_BINARY 0
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define NORETURN __attribute__ ((noreturn))
|
||||
#elif defined _MSC_VER
|
||||
#ifdef _MSC_VER
|
||||
# define NORETURN __declspec(noreturn)
|
||||
# define ALIGNED(x) __declspec(align(x))
|
||||
#else
|
||||
# define NORETURN
|
||||
# define NORETURN __attribute__((noreturn))
|
||||
# define ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -540,7 +538,7 @@ typedef struct BufferedFile {
|
||||
int *ifdef_stack_ptr; /* ifdef_stack value at the start of the file */
|
||||
int include_next_index; /* next search path */
|
||||
char filename[1024]; /* filename */
|
||||
char filename2[1024]; /* filename not modified by # line directive */
|
||||
char *true_filename; /* filename not modified by # line directive */
|
||||
unsigned char unget[4];
|
||||
unsigned char buffer[1]; /* extra size for CH_EOB char */
|
||||
} BufferedFile;
|
||||
|
14
tccgen.c
14
tccgen.c
@ -1752,8 +1752,8 @@ static void gen_opic(int op)
|
||||
vtop--;
|
||||
} else if (!const_wanted &&
|
||||
c2 && ((l2 == 0 && (op == '&' || op == '*')) ||
|
||||
(l2 == -1 && op == '|') ||
|
||||
(l2 == 0xffffffff && t2 != VT_LLONG && op == '|') ||
|
||||
(op == '|' &&
|
||||
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))) ||
|
||||
(l2 == 1 && (op == '%' || op == TOK_UMOD)))) {
|
||||
/* treat (x & 0), (x * 0), (x | -1) and (x % 1) as constant */
|
||||
if (l2 == 1)
|
||||
@ -1767,7 +1767,7 @@ static void gen_opic(int op)
|
||||
op == TOK_SHL || op == TOK_SHR || op == TOK_SAR) &&
|
||||
l2 == 0) ||
|
||||
(op == '&' &&
|
||||
l2 == -1))) {
|
||||
(l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
|
||||
/* filter out NOP operations like x*1, x-0, x&-1... */
|
||||
vtop--;
|
||||
} else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {
|
||||
@ -1817,6 +1817,10 @@ static void gen_opif(int op)
|
||||
{
|
||||
int c1, c2;
|
||||
SValue *v1, *v2;
|
||||
#if defined _MSC_VER && defined _AMD64_
|
||||
/* avoid bad optimization with f1 -= f2 for f1:-0.0, f2:0.0 */
|
||||
volatile
|
||||
#endif
|
||||
long double f1, f2;
|
||||
|
||||
v1 = vtop - 1;
|
||||
@ -3497,7 +3501,7 @@ static void struct_decl(CType *type, AttributeDef *ad, int u)
|
||||
if (v < TOK_IDENT)
|
||||
expect("struct/union/enum name");
|
||||
s = struct_find(v);
|
||||
if (s && (s->scope == local_scope || (tok != '{' && tok != ';'))) {
|
||||
if (s && (s->scope == local_scope || tok != '{')) {
|
||||
if (s->type.t != a)
|
||||
tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
|
||||
goto do_decl;
|
||||
@ -4381,6 +4385,8 @@ ST_FUNC void unary(void)
|
||||
case TOK_STR:
|
||||
/* string parsing */
|
||||
t = VT_BYTE;
|
||||
if (tcc_state->char_is_unsigned)
|
||||
t = VT_BYTE | VT_UNSIGNED;
|
||||
str_init:
|
||||
if (tcc_state->warn_write_strings)
|
||||
t |= VT_CONSTANT;
|
||||
|
37
tccpe.c
37
tccpe.c
@ -1547,11 +1547,7 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
IMAGE_DOS_HEADER dh;
|
||||
IMAGE_FILE_HEADER ih;
|
||||
DWORD sig, ref, addr, ptr, namep;
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
IMAGE_OPTIONAL_HEADER64 oh;
|
||||
#else
|
||||
IMAGE_OPTIONAL_HEADER32 oh;
|
||||
#endif
|
||||
|
||||
int pef_hdroffset, opt_hdroffset, sec_hdroffset;
|
||||
|
||||
n = n0 = 0;
|
||||
@ -1562,7 +1558,6 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
if (fd < 0)
|
||||
goto the_end_1;
|
||||
ret = 1;
|
||||
|
||||
if (!read_mem(fd, 0, &dh, sizeof dh))
|
||||
goto the_end;
|
||||
if (!read_mem(fd, dh.e_lfanew, &sig, sizeof sig))
|
||||
@ -1572,22 +1567,26 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
pef_hdroffset = dh.e_lfanew + sizeof sig;
|
||||
if (!read_mem(fd, pef_hdroffset, &ih, sizeof ih))
|
||||
goto the_end;
|
||||
if (IMAGE_FILE_MACHINE != ih.Machine) {
|
||||
if (ih.Machine == 0x014C)
|
||||
ret = 32;
|
||||
else if (ih.Machine == 0x8664)
|
||||
ret = 64;
|
||||
goto the_end;
|
||||
}
|
||||
opt_hdroffset = pef_hdroffset + sizeof ih;
|
||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||
if (ih.Machine == 0x014C) {
|
||||
IMAGE_OPTIONAL_HEADER32 oh;
|
||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||
goto the_end;
|
||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||
goto the_end_0;
|
||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
} else if (ih.Machine == 0x8664) {
|
||||
IMAGE_OPTIONAL_HEADER64 oh;
|
||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||
goto the_end;
|
||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||
goto the_end_0;
|
||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
} else
|
||||
goto the_end;
|
||||
|
||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||
goto the_end_0;
|
||||
|
||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
//printf("addr: %08x\n", addr);
|
||||
for (i = 0; i < ih.NumberOfSections; ++i) {
|
||||
if (!read_mem(fd, sec_hdroffset + i * sizeof ish, &ish, sizeof ish))
|
||||
|
11
tccpp.c
11
tccpp.c
@ -531,7 +531,6 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
||||
break;
|
||||
|
||||
/* above tokens have value, the ones below don't */
|
||||
|
||||
case TOK_LT:
|
||||
v = '<';
|
||||
goto addv;
|
||||
@ -544,6 +543,8 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
||||
return strcpy(p, "<<=");
|
||||
case TOK_A_SAR:
|
||||
return strcpy(p, ">>=");
|
||||
case TOK_EOF:
|
||||
return strcpy(p, "<eof>");
|
||||
default:
|
||||
if (v < TOK_IDENT) {
|
||||
/* search in two bytes table */
|
||||
@ -1791,7 +1792,7 @@ ST_FUNC void preprocess(int is_bof)
|
||||
if (c != '\"')
|
||||
continue;
|
||||
/* https://savannah.nongnu.org/bugs/index.php?50847 */
|
||||
path = file->filename2;
|
||||
path = file->true_filename;
|
||||
pstrncpy(buf1, path, tcc_basename(path) - path);
|
||||
|
||||
} else {
|
||||
@ -1921,9 +1922,11 @@ include_done:
|
||||
_line_num:
|
||||
next();
|
||||
if (tok != TOK_LINEFEED) {
|
||||
if (tok == TOK_STR)
|
||||
if (tok == TOK_STR) {
|
||||
if (file->true_filename == file->filename)
|
||||
file->true_filename = tcc_strdup(file->filename);
|
||||
pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.str.data);
|
||||
else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||
break;
|
||||
else
|
||||
goto _line_err;
|
||||
|
@ -363,9 +363,8 @@ usage:
|
||||
ret = tcc_get_dllexports(file, &p);
|
||||
if (ret || !p) {
|
||||
fprintf(stderr, "tcc: impdef: %s '%s'\n",
|
||||
ret == 32 ? "can't read symbols from 32bit" :
|
||||
ret == 64 ? "can't read symbols from 64bit" :
|
||||
ret == -1 ? "can't find file" :
|
||||
ret == 1 ? "can't read symbols" :
|
||||
ret == 0 ? "no symbols found in" :
|
||||
"unknown file type", file);
|
||||
ret = 1;
|
||||
|
35
x86_64-gen.c
35
x86_64-gen.c
@ -728,13 +728,13 @@ static int arg_prepare_reg(int idx) {
|
||||
return arg_regs[idx];
|
||||
}
|
||||
|
||||
static int func_scratch;
|
||||
static int func_scratch, func_alloca;
|
||||
|
||||
/* Generate function call. The function address is pushed first, then
|
||||
all the parameters in call order. This functions pops all the
|
||||
parameters and the function address. */
|
||||
|
||||
void gen_offs_sp(int b, int r, int d)
|
||||
static void gen_offs_sp(int b, int r, int d)
|
||||
{
|
||||
orex(1,0,r & 0x100 ? 0 : r, b);
|
||||
if (d == (char)d) {
|
||||
@ -746,6 +746,11 @@ void gen_offs_sp(int b, int r, int d)
|
||||
}
|
||||
}
|
||||
|
||||
static int using_regs(int size)
|
||||
{
|
||||
return !(size > 8 || (size & (size - 1)));
|
||||
}
|
||||
|
||||
/* Return the number of registers needed to return the struct, or 0 if
|
||||
returning via struct pointer. */
|
||||
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
|
||||
@ -754,7 +759,7 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int
|
||||
*ret_align = 1; // Never have to re-align return values for x86-64
|
||||
*regsize = 8;
|
||||
size = type_size(vt, &align);
|
||||
if (size > 8 || (size & (size - 1)))
|
||||
if (!using_regs(size))
|
||||
return 0;
|
||||
if (size == 8)
|
||||
ret->t = VT_LLONG;
|
||||
@ -774,7 +779,7 @@ static int is_sse_float(int t) {
|
||||
return bt == VT_DOUBLE || bt == VT_FLOAT;
|
||||
}
|
||||
|
||||
int gfunc_arg_size(CType *type) {
|
||||
static int gfunc_arg_size(CType *type) {
|
||||
int align;
|
||||
if (type->t & (VT_ARRAY|VT_BITFIELD))
|
||||
return 8;
|
||||
@ -801,7 +806,7 @@ void gfunc_call(int nb_args)
|
||||
bt = (sv->type.t & VT_BTYPE);
|
||||
size = gfunc_arg_size(&sv->type);
|
||||
|
||||
if (size <= 8)
|
||||
if (using_regs(size))
|
||||
continue; /* arguments smaller than 8 bytes passed in registers or on stack */
|
||||
|
||||
if (bt == VT_STRUCT) {
|
||||
@ -835,7 +840,7 @@ void gfunc_call(int nb_args)
|
||||
bt = (vtop->type.t & VT_BTYPE);
|
||||
|
||||
size = gfunc_arg_size(&vtop->type);
|
||||
if (size > 8) {
|
||||
if (!using_regs(size)) {
|
||||
/* align to stack align size */
|
||||
size = (size + 15) & ~15;
|
||||
if (arg >= REGN) {
|
||||
@ -895,6 +900,12 @@ void gfunc_call(int nb_args)
|
||||
}
|
||||
|
||||
gcall_or_jmp(0);
|
||||
|
||||
if ((vtop->r & VT_SYM) && vtop->sym->v == TOK_alloca) {
|
||||
/* need to add the "func_scratch" area after alloca */
|
||||
o(0x0548), gen_le32(func_alloca), func_alloca = ind - 4;
|
||||
}
|
||||
|
||||
/* other compilers don't clear the upper bits when returning char/short */
|
||||
bt = vtop->type.ref->type.t & (VT_BTYPE | VT_UNSIGNED);
|
||||
if (bt == (VT_BYTE | VT_UNSIGNED))
|
||||
@ -926,6 +937,7 @@ void gfunc_prolog(CType *func_type)
|
||||
|
||||
func_ret_sub = 0;
|
||||
func_scratch = 0;
|
||||
func_alloca = 0;
|
||||
loc = 0;
|
||||
|
||||
addr = PTR_SIZE * 2;
|
||||
@ -940,7 +952,7 @@ void gfunc_prolog(CType *func_type)
|
||||
func_vt = sym->type;
|
||||
func_var = (sym->c == FUNC_ELLIPSIS);
|
||||
size = gfunc_arg_size(&func_vt);
|
||||
if (size > 8) {
|
||||
if (!using_regs(size)) {
|
||||
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
|
||||
func_vc = addr;
|
||||
reg_param_index++;
|
||||
@ -952,7 +964,7 @@ void gfunc_prolog(CType *func_type)
|
||||
type = &sym->type;
|
||||
bt = type->t & VT_BTYPE;
|
||||
size = gfunc_arg_size(type);
|
||||
if (size > 8) {
|
||||
if (!using_regs(size)) {
|
||||
if (reg_param_index < REGN) {
|
||||
gen_modrm64(0x89, arg_regs[reg_param_index], VT_LOCAL, NULL, addr);
|
||||
}
|
||||
@ -1015,6 +1027,13 @@ void gfunc_epilog(void)
|
||||
gen_le32(v);
|
||||
}
|
||||
|
||||
/* add the "func_scratch" area after each alloca seen */
|
||||
while (func_alloca) {
|
||||
unsigned char *ptr = cur_text_section->data + func_alloca;
|
||||
func_alloca = read32le(ptr);
|
||||
write32le(ptr, func_scratch);
|
||||
}
|
||||
|
||||
cur_text_section->data_offset = saved_ind;
|
||||
pe_add_unwind_data(ind, saved_ind, v);
|
||||
ind = cur_text_section->data_offset;
|
||||
|
Loading…
Reference in New Issue
Block a user