Return to: e20c1eb99e
1: The new patch for the other machines still have the problem.
2: libcrt Rename (what if gcc had libcrt as well)
3: parse_number exact problem
4: VT_VLS is to allow tcc
Compile the following
int b = 9;
struct st {
int a;
int b [b]
};
struct st st1;
st1.b [8] = 9;
printf ("% d \ n", st1.b [8]);
tcc a problem. Due to problems in front, and now can not be improved
5: they commit much, bug difficult to lock, you can not let other people help develop.
6: ('\ t') too
Thanks to Michael and Ray
Their criticism I have benefited!
This commit is contained in:
parent
089dea355a
commit
5e56fb635a
23 changed files with 1416 additions and 1814 deletions
58
Makefile
58
Makefile
|
|
@ -22,7 +22,7 @@ endif
|
||||||
endif
|
endif
|
||||||
else # not GCC
|
else # not GCC
|
||||||
ifeq (-$(findstring clang,$(CC))-,-clang-)
|
ifeq (-$(findstring clang,$(CC))-,-clang-)
|
||||||
# make clang accept gnuisms in libcrt.c
|
# make clang accept gnuisms in libtcc1.c
|
||||||
CFLAGS+=-fheinous-gnu-extensions
|
CFLAGS+=-fheinous-gnu-extensions
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
@ -101,11 +101,11 @@ $(ARM_EABI_CROSS)_LINK = arm-eabi-tcc$(EXESUF)
|
||||||
|
|
||||||
CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
||||||
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
||||||
I386_FILES = $(CORE_FILES) i386-gen.c asmx86.c i386-asm.h asmx86-tok.h
|
I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h
|
||||||
WIN32_FILES = $(CORE_FILES) i386-gen.c asmx86.c i386-asm.h asmx86-tok.h tccpe.c
|
WIN32_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h tccpe.c
|
||||||
WIN64_FILES = $(CORE_FILES) x86_64-gen.c asmx86.c x86_64-asm.h tccpe.c
|
WIN64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h tccpe.c
|
||||||
WINCE_FILES = $(CORE_FILES) arm-gen.c tccpe.c
|
WINCE_FILES = $(CORE_FILES) arm-gen.c tccpe.c
|
||||||
X86_64_FILES = $(CORE_FILES) x86_64-gen.c asmx86.c x86_64-asm.h
|
X86_64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h
|
||||||
ARM_FILES = $(CORE_FILES) arm-gen.c
|
ARM_FILES = $(CORE_FILES) arm-gen.c
|
||||||
C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
|
C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
|
||||||
|
|
||||||
|
|
@ -113,29 +113,29 @@ ifdef CONFIG_WIN64
|
||||||
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
||||||
NATIVE_FILES=$(WIN64_FILES)
|
NATIVE_FILES=$(WIN64_FILES)
|
||||||
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
||||||
LIBTCC1_CROSS=lib/i386-win32/libcrt.a
|
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a
|
||||||
LIBCRT=libcrt.a
|
LIBTCC1=libtcc1.a
|
||||||
else ifdef CONFIG_WIN32
|
else ifdef CONFIG_WIN32
|
||||||
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
||||||
NATIVE_FILES=$(WIN32_FILES)
|
NATIVE_FILES=$(WIN32_FILES)
|
||||||
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
||||||
LIBTCC1_CROSS=lib/x86_64-win32/libcrt.a
|
LIBTCC1_CROSS=lib/x86_64-win32/libtcc1.a
|
||||||
LIBCRT=libcrt.a
|
LIBTCC1=libtcc1.a
|
||||||
else ifeq ($(ARCH),i386)
|
else ifeq ($(ARCH),i386)
|
||||||
NATIVE_FILES=$(I386_FILES)
|
NATIVE_FILES=$(I386_FILES)
|
||||||
PROGS_CROSS=$(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
PROGS_CROSS=$(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
||||||
LIBTCC1_CROSS=lib/i386-win32/libcrt.a lib/x86_64-win32/libcrt.a
|
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a
|
||||||
LIBCRT=libcrt.a
|
LIBTCC1=libtcc1.a
|
||||||
else ifeq ($(ARCH),x86-64)
|
else ifeq ($(ARCH),x86-64)
|
||||||
NATIVE_FILES=$(X86_64_FILES)
|
NATIVE_FILES=$(X86_64_FILES)
|
||||||
PROGS_CROSS=$(I386_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
PROGS_CROSS=$(I386_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS)
|
||||||
LIBTCC1_CROSS=lib/i386-win32/libcrt.a lib/x86_64-win32/libcrt.a lib/i386/libcrt.a
|
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a lib/i386/libtcc1.a
|
||||||
LIBCRT=libcrt.a
|
LIBTCC1=libtcc1.a
|
||||||
else ifeq ($(ARCH),arm)
|
else ifeq ($(ARCH),arm)
|
||||||
NATIVE_FILES=$(ARM_FILES)
|
NATIVE_FILES=$(ARM_FILES)
|
||||||
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(C67_CROSS)
|
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(C67_CROSS)
|
||||||
LIBCRT=libcrt.a
|
LIBTCC1=libtcc1.a
|
||||||
LIBTCC1_CROSS=lib/i386-win32/libcrt.a lib/x86_64-win32/libcrt.a lib/i386/libcrt.a
|
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a lib/i386/libtcc1.a
|
||||||
endif
|
endif
|
||||||
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
|
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
|
||||||
|
|
||||||
|
|
@ -143,7 +143,7 @@ ifeq ($(TARGETOS),Darwin)
|
||||||
PROGS+=tiny_libmaker$(EXESUF)
|
PROGS+=tiny_libmaker$(EXESUF)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
TCCLIBS = $(LIBCRT) $(LIBTCC) $(LIBTCC_EXTRA)
|
TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCC_EXTRA)
|
||||||
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
|
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
|
||||||
|
|
||||||
ifdef CONFIG_CROSS
|
ifdef CONFIG_CROSS
|
||||||
|
|
@ -225,9 +225,9 @@ tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
|
||||||
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||||
|
|
||||||
# TinyCC runtime libraries
|
# TinyCC runtime libraries
|
||||||
libcrt.a : FORCE
|
libtcc1.a : FORCE
|
||||||
$(MAKE) -C lib native
|
$(MAKE) -C lib native
|
||||||
lib/%/libcrt.a : FORCE $(PROGS_CROSS)
|
lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
|
||||||
$(MAKE) -C lib cross TARGET=$*
|
$(MAKE) -C lib cross TARGET=$*
|
||||||
|
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
@ -258,8 +258,8 @@ endif
|
||||||
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
|
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
|
||||||
mkdir -p "$(tccdir)"
|
mkdir -p "$(tccdir)"
|
||||||
mkdir -p "$(tccdir)/include"
|
mkdir -p "$(tccdir)/include"
|
||||||
ifneq ($(LIBCRT),)
|
ifneq ($(LIBTCC1),)
|
||||||
$(INSTALL) -m644 $(LIBCRT) "$(tccdir)"
|
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)"
|
||||||
endif
|
endif
|
||||||
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
||||||
mkdir -p "$(libdir)"
|
mkdir -p "$(libdir)"
|
||||||
|
|
@ -277,19 +277,19 @@ ifdef CONFIG_CROSS
|
||||||
mkdir -p "$(tccdir)/win32/lib/64"
|
mkdir -p "$(tccdir)/win32/lib/64"
|
||||||
ifneq ($(ARCH),i386)
|
ifneq ($(ARCH),i386)
|
||||||
mkdir -p "$(tccdir)/i386"
|
mkdir -p "$(tccdir)/i386"
|
||||||
$(INSTALL) -m644 lib/i386/libcrt.a "$(tccdir)/i386"
|
$(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
|
||||||
cp -r "$(tccdir)/include" "$(tccdir)/i386"
|
cp -r "$(tccdir)/include" "$(tccdir)/i386"
|
||||||
endif
|
endif
|
||||||
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
|
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
|
||||||
$(INSTALL) -m644 lib/i386-win32/libcrt.a "$(tccdir)/win32/lib/32"
|
$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/win32/lib/32"
|
||||||
$(INSTALL) -m644 lib/x86_64-win32/libcrt.a "$(tccdir)/win32/lib/64"
|
$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/win32/lib/64"
|
||||||
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
|
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
|
||||||
cp -r "$(tccdir)/include" "$(tccdir)/win32"
|
cp -r "$(tccdir)/include" "$(tccdir)/win32"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
|
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
|
||||||
rm -fv $(foreach P,$(LIBCRT),"$(tccdir)/$P")
|
rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
|
||||||
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
|
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
|
||||||
rm -fv "$(tccdir)/include/tcclib.h"
|
rm -fv "$(tccdir)/include/tcclib.h"
|
||||||
rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
|
rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
|
||||||
|
|
@ -310,7 +310,7 @@ install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||||
mkdir -p "$(tccdir)/doc"
|
mkdir -p "$(tccdir)/doc"
|
||||||
mkdir -p "$(tccdir)/libtcc"
|
mkdir -p "$(tccdir)/libtcc"
|
||||||
$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
|
$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
|
||||||
$(INSTALL) -m644 $(LIBCRT) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib"
|
$(INSTALL) -m644 $(LIBTCC1) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib"
|
||||||
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include"
|
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include"
|
||||||
cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples"
|
cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples"
|
||||||
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
||||||
|
|
@ -320,8 +320,8 @@ install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||||
ifdef CONFIG_CROSS
|
ifdef CONFIG_CROSS
|
||||||
mkdir -p "$(tccdir)/lib/32"
|
mkdir -p "$(tccdir)/lib/32"
|
||||||
mkdir -p "$(tccdir)/lib/64"
|
mkdir -p "$(tccdir)/lib/64"
|
||||||
-$(INSTALL) -m644 lib/i386-win32/libcrt.a "$(tccdir)/lib/32"
|
-$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/lib/32"
|
||||||
-$(INSTALL) -m644 lib/x86_64-win32/libcrt.a "$(tccdir)/lib/64"
|
-$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/lib/64"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
|
|
@ -340,7 +340,7 @@ tcc-doc.info: tcc-doc.texi
|
||||||
-makeinfo $<
|
-makeinfo $<
|
||||||
|
|
||||||
# in tests subdir
|
# in tests subdir
|
||||||
export LIBCRT
|
export LIBTCC1
|
||||||
|
|
||||||
%est:
|
%est:
|
||||||
$(MAKE) -C tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
|
$(MAKE) -C tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
|
||||||
|
|
@ -348,7 +348,7 @@ export LIBCRT
|
||||||
clean:
|
clean:
|
||||||
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.exe libtcc_test$(EXESUF)
|
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.exe libtcc_test$(EXESUF)
|
||||||
$(MAKE) -C tests $@
|
$(MAKE) -C tests $@
|
||||||
ifneq ($(LIBCRT),)
|
ifneq ($(LIBTCC1),)
|
||||||
$(MAKE) -C lib $@
|
$(MAKE) -C lib $@
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
93
arm-gen.c
93
arm-gen.c
|
|
@ -61,7 +61,7 @@
|
||||||
#define RC_IRET RC_R0 /* function return: integer register */
|
#define RC_IRET RC_R0 /* function return: integer register */
|
||||||
#define RC_LRET RC_R1 /* function return: second integer register */
|
#define RC_LRET RC_R1 /* function return: second integer register */
|
||||||
#define RC_FRET RC_F0 /* function return: float register */
|
#define RC_FRET RC_F0 /* function return: float register */
|
||||||
#define RC_MASK (RC_INT|RC_FLOAT)
|
|
||||||
/* pretty names for the registers */
|
/* pretty names for the registers */
|
||||||
enum {
|
enum {
|
||||||
TREG_R0 = 0,
|
TREG_R0 = 0,
|
||||||
|
|
@ -540,14 +540,6 @@ void load(int r, SValue *sv)
|
||||||
v = fr & VT_VALMASK;
|
v = fr & VT_VALMASK;
|
||||||
if (fr & VT_LVAL) {
|
if (fr & VT_LVAL) {
|
||||||
uint32_t base = 0xB; // fp
|
uint32_t base = 0xB; // fp
|
||||||
if(fr & VT_TMP){
|
|
||||||
int size, align;
|
|
||||||
if((ft & VT_BTYPE) == VT_FUNC)
|
|
||||||
size = PTR_SIZE;
|
|
||||||
else
|
|
||||||
size = type_size(&sv->type, &align);
|
|
||||||
loc_stack(size, 0);
|
|
||||||
}
|
|
||||||
if(v == VT_LLOCAL) {
|
if(v == VT_LLOCAL) {
|
||||||
v1.type.t = VT_PTR;
|
v1.type.t = VT_PTR;
|
||||||
v1.r = VT_LOCAL | VT_LVAL;
|
v1.r = VT_LOCAL | VT_LVAL;
|
||||||
|
|
@ -1417,60 +1409,37 @@ void gjmp_addr(int a)
|
||||||
/* generate a test. set 'inv' to invert test. Stack entry is popped */
|
/* generate a test. set 'inv' to invert test. Stack entry is popped */
|
||||||
int gtst(int inv, int t)
|
int gtst(int inv, int t)
|
||||||
{
|
{
|
||||||
int v, r;
|
int v, r;
|
||||||
uint32_t op;
|
uint32_t op;
|
||||||
v = vtop->r & VT_VALMASK;
|
v = vtop->r & VT_VALMASK;
|
||||||
r=ind;
|
r=ind;
|
||||||
if (v == VT_CMP) {
|
if (v == VT_CMP) {
|
||||||
op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
|
op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
|
||||||
op|=encbranch(r,t,1);
|
op|=encbranch(r,t,1);
|
||||||
o(op);
|
o(op);
|
||||||
t=r;
|
t=r;
|
||||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
} else { /* VT_JMP || VT_JMPI */
|
||||||
if ((v & 1) == inv) {
|
if ((v & 1) == inv) {
|
||||||
if(!vtop->c.i)
|
if(!vtop->c.i)
|
||||||
vtop->c.i=t;
|
vtop->c.i=t;
|
||||||
else {
|
else {
|
||||||
uint32_t *x;
|
uint32_t *x;
|
||||||
int p,lp;
|
int p,lp;
|
||||||
if(t) {
|
if(t) {
|
||||||
p = vtop->c.i;
|
p = vtop->c.i;
|
||||||
do {
|
do {
|
||||||
p = decbranch(lp=p);
|
p = decbranch(lp=p);
|
||||||
} while(p);
|
} while(p);
|
||||||
x = (uint32_t *)(cur_text_section->data + lp);
|
x = (uint32_t *)(cur_text_section->data + lp);
|
||||||
*x &= 0xff000000;
|
*x &= 0xff000000;
|
||||||
*x |= encbranch(lp,t,1);
|
*x |= encbranch(lp,t,1);
|
||||||
}
|
}
|
||||||
t = vtop->c.i;
|
t = vtop->c.i;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
t = gjmp(t);
|
t = gjmp(t);
|
||||||
gsym(vtop->c.i);
|
gsym(vtop->c.i);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (is_float(vtop->type.t)) {
|
|
||||||
r=gv(RC_FLOAT);
|
|
||||||
#ifdef TCC_ARM_VFP
|
|
||||||
o(0xEEB50A40|(vfpr(r)<<12)|T2CPR(vtop->type.t)); /* fcmpzX */
|
|
||||||
o(0xEEF1FA10); /* fmstat */
|
|
||||||
#else
|
|
||||||
o(0xEE90F118|(fpr(r)<<16));
|
|
||||||
#endif
|
|
||||||
vtop->r = VT_CMP;
|
|
||||||
vtop->c.i = TOK_NE;
|
|
||||||
return gtst(inv, t);
|
|
||||||
} else if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
|
||||||
/* constant jmp optimization */
|
|
||||||
if ((vtop->c.i != 0) != inv)
|
|
||||||
t = gjmp(t);
|
|
||||||
} else {
|
|
||||||
v = gv(RC_INT);
|
|
||||||
o(0xE3300000|(intr(v)<<16));
|
|
||||||
vtop->r = VT_CMP;
|
|
||||||
vtop->c.i = TOK_NE;
|
|
||||||
return gtst(inv, t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
return t;
|
return t;
|
||||||
|
|
|
||||||
44
c67-gen.c
44
c67-gen.c
|
|
@ -58,7 +58,7 @@
|
||||||
#define RC_IRET RC_C67_A4 /* function return: integer register */
|
#define RC_IRET RC_C67_A4 /* function return: integer register */
|
||||||
#define RC_LRET RC_C67_A5 /* function return: second integer register */
|
#define RC_LRET RC_C67_A5 /* function return: second integer register */
|
||||||
#define RC_FRET RC_C67_A4 /* function return: float register */
|
#define RC_FRET RC_C67_A4 /* function return: float register */
|
||||||
#define RC_MASK (RC_INT|RC_FLOAT)
|
|
||||||
/* pretty names for the registers */
|
/* pretty names for the registers */
|
||||||
enum {
|
enum {
|
||||||
TREG_EAX = 0, // really A2
|
TREG_EAX = 0, // really A2
|
||||||
|
|
@ -1571,21 +1571,12 @@ void load(int r, SValue * sv)
|
||||||
|
|
||||||
v = fr & VT_VALMASK;
|
v = fr & VT_VALMASK;
|
||||||
if (fr & VT_LVAL) {
|
if (fr & VT_LVAL) {
|
||||||
if(fr & VT_TMP){
|
|
||||||
int size, align;
|
|
||||||
if((ft & VT_BTYPE) == VT_FUNC)
|
|
||||||
size = PTR_SIZE;
|
|
||||||
else
|
|
||||||
size = type_size(&sv->type, &align);
|
|
||||||
loc_stack(size, 0);
|
|
||||||
}
|
|
||||||
if (v == VT_LLOCAL) {
|
if (v == VT_LLOCAL) {
|
||||||
v1.type.t = VT_INT;
|
v1.type.t = VT_INT;
|
||||||
v1.r = VT_LOCAL | VT_LVAL;
|
v1.r = VT_LOCAL | VT_LVAL;
|
||||||
v1.c.ul = fc;
|
v1.c.ul = fc;
|
||||||
load(r, &v1);
|
load(r, &v1);
|
||||||
fr = r;
|
fr = r;
|
||||||
fc = 0;
|
|
||||||
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
|
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
|
||||||
tcc_error("long double not supported");
|
tcc_error("long double not supported");
|
||||||
} else if ((ft & VT_TYPE) == VT_BYTE) {
|
} else if ((ft & VT_TYPE) == VT_BYTE) {
|
||||||
|
|
@ -2111,7 +2102,7 @@ int gtst(int inv, int t)
|
||||||
C67_NOP(5);
|
C67_NOP(5);
|
||||||
t = ind1; //return where we need to patch
|
t = ind1; //return where we need to patch
|
||||||
|
|
||||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
} else { /* VT_JMP || VT_JMPI */
|
||||||
/* && or || optimization */
|
/* && or || optimization */
|
||||||
if ((v & 1) == inv) {
|
if ((v & 1) == inv) {
|
||||||
/* insert vtop->c jump list in t */
|
/* insert vtop->c jump list in t */
|
||||||
|
|
@ -2137,37 +2128,6 @@ int gtst(int inv, int t)
|
||||||
t = gjmp(t);
|
t = gjmp(t);
|
||||||
gsym(vtop->c.i);
|
gsym(vtop->c.i);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (is_float(vtop->type.t)) {
|
|
||||||
vpushi(0);
|
|
||||||
gen_op(TOK_NE);
|
|
||||||
}
|
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
|
||||||
/* constant jmp optimization */
|
|
||||||
if ((vtop->c.i != 0) != inv)
|
|
||||||
t = gjmp(t);
|
|
||||||
} else {
|
|
||||||
// I think we need to get the value on the stack
|
|
||||||
// into a register, test it, and generate a branch
|
|
||||||
// return the address of the branch, so it can be
|
|
||||||
// later patched
|
|
||||||
|
|
||||||
v = gv(RC_INT); // get value into a reg
|
|
||||||
ind1 = ind;
|
|
||||||
C67_MVKL(C67_A0, t); //r=reg to load, constant
|
|
||||||
C67_MVKH(C67_A0, t); //r=reg to load, constant
|
|
||||||
|
|
||||||
if (v != TREG_EAX && // check if not already in a conditional test reg
|
|
||||||
v != TREG_EDX && v != TREG_ST0 && v != C67_B2) {
|
|
||||||
C67_MV(v, C67_B2);
|
|
||||||
v = C67_B2;
|
|
||||||
}
|
|
||||||
|
|
||||||
C67_IREG_B_REG(inv, v, C67_A0); // [!R] B.S2x A0
|
|
||||||
C67_NOP(5);
|
|
||||||
t = ind1; //return where we need to patch
|
|
||||||
ind1 = ind;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
return t;
|
return t;
|
||||||
|
|
|
||||||
|
|
@ -239,36 +239,6 @@ static const uint16_t op0_codes[] = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef PRINTF_ASM_CODE
|
|
||||||
void printf_asm_opcode(){
|
|
||||||
const ASMInstr *pa;
|
|
||||||
int freq[4];
|
|
||||||
int op_vals[500];
|
|
||||||
int nb_op_vals, i, j;
|
|
||||||
nb_op_vals = 0;
|
|
||||||
memset(freq, 0, sizeof(freq));
|
|
||||||
for(pa = asm_instrs; pa->sym != 0; pa++) {
|
|
||||||
freq[pa->nb_ops]++;
|
|
||||||
for(i=0;i<pa->nb_ops;i++) {
|
|
||||||
for(j=0;j<nb_op_vals;j++) {
|
|
||||||
if (pa->op_type[i] == op_vals[j])
|
|
||||||
goto found;
|
|
||||||
}
|
|
||||||
op_vals[nb_op_vals++] = pa->op_type[i];
|
|
||||||
found: ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(i=0;i<nb_op_vals;i++) {
|
|
||||||
int v = op_vals[i];
|
|
||||||
if ((v & (v - 1)) != 0)
|
|
||||||
printf("%3d: %08x\n", i, v);
|
|
||||||
}
|
|
||||||
printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
|
|
||||||
(int)sizeof(asm_instrs), (int)sizeof(asm_instrs) / sizeof(ASMInstr),
|
|
||||||
freq[0], freq[1], freq[2], freq[3]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int get_reg_shift(TCCState *s1)
|
static inline int get_reg_shift(TCCState *s1)
|
||||||
{
|
{
|
||||||
int shift, v;
|
int shift, v;
|
||||||
|
|
@ -746,8 +716,9 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
||||||
g(b >> 8);
|
g(b >> 8);
|
||||||
g(b);
|
g(b);
|
||||||
return;
|
return;
|
||||||
} else if (opcode <= TOK_ASM_alllast) {
|
} else if (opcode <= TOK_ASM_alllast) {
|
||||||
tcc_error("bad operand with opcode '%s'", get_tok_str(opcode, NULL));
|
tcc_error("bad operand with opcode '%s'",
|
||||||
|
get_tok_str(opcode, NULL));
|
||||||
} else {
|
} else {
|
||||||
tcc_error("unknown opcode '%s'",
|
tcc_error("unknown opcode '%s'",
|
||||||
get_tok_str(opcode, NULL));
|
get_tok_str(opcode, NULL));
|
||||||
|
|
@ -1098,7 +1069,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
||||||
uint8_t regs_allocated[NB_ASM_REGS];
|
uint8_t regs_allocated[NB_ASM_REGS];
|
||||||
|
|
||||||
/* init fields */
|
/* init fields */
|
||||||
for(i=0; i<nb_operands; i++) {
|
for(i=0;i<nb_operands;i++) {
|
||||||
op = &operands[i];
|
op = &operands[i];
|
||||||
op->input_index = -1;
|
op->input_index = -1;
|
||||||
op->ref_index = -1;
|
op->ref_index = -1;
|
||||||
|
|
@ -1108,7 +1079,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
|
||||||
}
|
}
|
||||||
/* compute constraint priority and evaluate references to output
|
/* compute constraint priority and evaluate references to output
|
||||||
constraints if input constraints */
|
constraints if input constraints */
|
||||||
for(i=0; i<nb_operands; i++) {
|
for(i=0;i<nb_operands;i++) {
|
||||||
op = &operands[i];
|
op = &operands[i];
|
||||||
str = op->constraint;
|
str = op->constraint;
|
||||||
str = skip_constraint_modifiers(str);
|
str = skip_constraint_modifiers(str);
|
||||||
|
|
@ -1528,4 +1499,4 @@ ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
||||||
tcc_error("invalid clobber register '%s'", str);
|
tcc_error("invalid clobber register '%s'", str);
|
||||||
}
|
}
|
||||||
clobber_regs[reg] = 1;
|
clobber_regs[reg] = 1;
|
||||||
}
|
}
|
||||||
190
i386-gen.c
190
i386-gen.c
|
|
@ -21,7 +21,7 @@
|
||||||
#ifdef TARGET_DEFS_ONLY
|
#ifdef TARGET_DEFS_ONLY
|
||||||
|
|
||||||
/* number of available registers */
|
/* number of available registers */
|
||||||
#define NB_REGS 8
|
#define NB_REGS 4
|
||||||
#define NB_ASM_REGS 8
|
#define NB_ASM_REGS 8
|
||||||
|
|
||||||
/* a register can belong to several classes. The classes must be
|
/* a register can belong to several classes. The classes must be
|
||||||
|
|
@ -33,24 +33,17 @@
|
||||||
#define RC_ST0 0x0008
|
#define RC_ST0 0x0008
|
||||||
#define RC_ECX 0x0010
|
#define RC_ECX 0x0010
|
||||||
#define RC_EDX 0x0020
|
#define RC_EDX 0x0020
|
||||||
#define RC_EBX 0x0040
|
|
||||||
#define RC_ESI 0x0080
|
|
||||||
#define RC_EDI 0x0100
|
|
||||||
#define RC_INT2 0x0200
|
|
||||||
#define RC_IRET RC_EAX /* function return: integer register */
|
#define RC_IRET RC_EAX /* function return: integer register */
|
||||||
#define RC_LRET RC_EDX /* function return: second integer register */
|
#define RC_LRET RC_EDX /* function return: second integer register */
|
||||||
#define RC_FRET RC_ST0 /* function return: float register */
|
#define RC_FRET RC_ST0 /* function return: float register */
|
||||||
#define RC_MASK (RC_INT|RC_INT2|RC_FLOAT)
|
|
||||||
/* pretty names for the registers */
|
/* pretty names for the registers */
|
||||||
enum {
|
enum {
|
||||||
TREG_EAX = 0,
|
TREG_EAX = 0,
|
||||||
TREG_ECX,
|
TREG_ECX,
|
||||||
TREG_EDX,
|
TREG_EDX,
|
||||||
TREG_EBX,
|
|
||||||
TREG_ESP,
|
|
||||||
TREG_ST0,
|
TREG_ST0,
|
||||||
TREG_ESI,
|
TREG_ESP = 4
|
||||||
TREG_EDI,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* return registers for function */
|
/* return registers for function */
|
||||||
|
|
@ -97,14 +90,10 @@ enum {
|
||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
|
|
||||||
ST_DATA const int reg_classes[NB_REGS] = {
|
ST_DATA const int reg_classes[NB_REGS] = {
|
||||||
/* eax */ RC_INT | RC_EAX | RC_INT2,
|
/* eax */ RC_INT | RC_EAX,
|
||||||
/* ecx */ RC_INT | RC_ECX | RC_INT2,
|
/* ecx */ RC_INT | RC_ECX,
|
||||||
/* edx */ RC_INT | RC_EDX,
|
/* edx */ RC_INT | RC_EDX,
|
||||||
RC_INT|RC_INT2|RC_EBX,
|
|
||||||
0,
|
|
||||||
/* st0 */ RC_FLOAT | RC_ST0,
|
/* st0 */ RC_FLOAT | RC_ST0,
|
||||||
RC_ESI|RC_INT2,
|
|
||||||
RC_EDI|RC_INT2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long func_sub_sp_offset;
|
static unsigned long func_sub_sp_offset;
|
||||||
|
|
@ -237,14 +226,6 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
|
|
||||||
v = fr & VT_VALMASK;
|
v = fr & VT_VALMASK;
|
||||||
if (fr & VT_LVAL) {
|
if (fr & VT_LVAL) {
|
||||||
if(fr & VT_TMP){
|
|
||||||
int size, align;
|
|
||||||
if((ft & VT_BTYPE) == VT_FUNC)
|
|
||||||
size = PTR_SIZE;
|
|
||||||
else
|
|
||||||
size = type_size(&sv->type, &align);
|
|
||||||
loc_stack(size, 0);
|
|
||||||
}
|
|
||||||
if (v == VT_LLOCAL) {
|
if (v == VT_LLOCAL) {
|
||||||
v1.type.t = VT_INT;
|
v1.type.t = VT_INT;
|
||||||
v1.r = VT_LOCAL | VT_LVAL;
|
v1.r = VT_LOCAL | VT_LVAL;
|
||||||
|
|
@ -253,7 +234,6 @@ ST_FUNC void load(int r, SValue *sv)
|
||||||
if (!(reg_classes[fr] & RC_INT))
|
if (!(reg_classes[fr] & RC_INT))
|
||||||
fr = get_reg(RC_INT);
|
fr = get_reg(RC_INT);
|
||||||
load(fr, &v1);
|
load(fr, &v1);
|
||||||
fc = 0;
|
|
||||||
}
|
}
|
||||||
if ((ft & VT_BTYPE) == VT_FLOAT) {
|
if ((ft & VT_BTYPE) == VT_FLOAT) {
|
||||||
o(0xd9); /* flds */
|
o(0xd9); /* flds */
|
||||||
|
|
@ -697,7 +677,7 @@ ST_FUNC int gtst(int inv, int t)
|
||||||
/* fast case : can jump directly since flags are set */
|
/* fast case : can jump directly since flags are set */
|
||||||
g(0x0f);
|
g(0x0f);
|
||||||
t = psym((vtop->c.i - 16) ^ inv, t);
|
t = psym((vtop->c.i - 16) ^ inv, t);
|
||||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
} else { /* VT_JMP || VT_JMPI */
|
||||||
/* && or || optimization */
|
/* && or || optimization */
|
||||||
if ((v & 1) == inv) {
|
if ((v & 1) == inv) {
|
||||||
/* insert vtop->c jump list in t */
|
/* insert vtop->c jump list in t */
|
||||||
|
|
@ -710,23 +690,6 @@ ST_FUNC int gtst(int inv, int t)
|
||||||
t = gjmp(t);
|
t = gjmp(t);
|
||||||
gsym(vtop->c.i);
|
gsym(vtop->c.i);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (is_float(vtop->type.t) ||
|
|
||||||
(vtop->type.t & VT_BTYPE) == VT_LLONG) {
|
|
||||||
vpushi(0);
|
|
||||||
gen_op(TOK_NE);
|
|
||||||
}
|
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
|
||||||
/* constant jmp optimization */
|
|
||||||
if ((vtop->c.i != 0) != inv)
|
|
||||||
t = gjmp(t);
|
|
||||||
} else {
|
|
||||||
v = gv(RC_INT);
|
|
||||||
o(0x85);
|
|
||||||
o(0xc0 + v * 9);
|
|
||||||
g(0x0f);
|
|
||||||
t = psym(0x85 ^ inv, t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
return t;
|
return t;
|
||||||
|
|
@ -735,48 +698,40 @@ ST_FUNC int gtst(int inv, int t)
|
||||||
/* generate an integer binary operation */
|
/* generate an integer binary operation */
|
||||||
ST_FUNC void gen_opi(int op)
|
ST_FUNC void gen_opi(int op)
|
||||||
{
|
{
|
||||||
int r, fr, opc, fc, c;
|
int r, fr, opc, c;
|
||||||
int cc, uu, tt2;
|
|
||||||
|
|
||||||
fr = vtop[0].r;
|
|
||||||
fc = vtop->c.ul;
|
|
||||||
cc = (fr & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST;
|
|
||||||
tt2 = (fr & (VT_LVAL | VT_LVAL_TYPE)) == VT_LVAL;
|
|
||||||
|
|
||||||
switch(op) {
|
switch(op) {
|
||||||
case '+':
|
case '+':
|
||||||
case TOK_ADDC1: /* add with carry generation */
|
case TOK_ADDC1: /* add with carry generation */
|
||||||
opc = 0;
|
opc = 0;
|
||||||
gen_op8:
|
gen_op8:
|
||||||
vswap();
|
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||||
r = gv(RC_INT);
|
|
||||||
vswap();
|
|
||||||
if (cc) {
|
|
||||||
/* constant case */
|
/* constant case */
|
||||||
|
vswap();
|
||||||
|
r = gv(RC_INT);
|
||||||
|
vswap();
|
||||||
c = vtop->c.i;
|
c = vtop->c.i;
|
||||||
if (c == (char)c) {
|
if (c == (char)c) {
|
||||||
/* generate inc and dec for smaller code */
|
/* generate inc and dec for smaller code */
|
||||||
if (c == 1 && opc == 0) {
|
if (c==1 && opc==0) {
|
||||||
o (0x40 | r); // inc
|
o (0x40 | r); // inc
|
||||||
} else if (c == 1 && opc == 5) {
|
} else if (c==1 && opc==5) {
|
||||||
o (0x48 | r); // dec
|
o (0x48 | r); // dec
|
||||||
} else {
|
} else {
|
||||||
o(0x83);
|
o(0x83);
|
||||||
o(0xc0 + r + opc*8);
|
o(0xc0 | (opc << 3) | r);
|
||||||
g(c);
|
g(c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
o(0x81);
|
o(0x81);
|
||||||
oad(0xc0 + r+ opc*8, c);
|
oad(0xc0 | (opc << 3) | r, c);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!tt2)
|
gv2(RC_INT, RC_INT);
|
||||||
fr = gv(RC_INT);
|
r = vtop[-1].r;
|
||||||
o(0x03 + opc*8);
|
fr = vtop[0].r;
|
||||||
if(fr >= VT_CONST)
|
o((opc << 3) | 0x01);
|
||||||
gen_modrm(r, fr, vtop->sym, fc);
|
o(0xc0 + r + fr * 8);
|
||||||
else
|
|
||||||
o(0xc0 + fr + r*8);
|
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||||
|
|
@ -804,28 +759,12 @@ ST_FUNC void gen_opi(int op)
|
||||||
opc = 1;
|
opc = 1;
|
||||||
goto gen_op8;
|
goto gen_op8;
|
||||||
case '*':
|
case '*':
|
||||||
opc = 5;
|
gv2(RC_INT, RC_INT);
|
||||||
vswap();
|
r = vtop[-1].r;
|
||||||
r = gv(RC_INT);
|
fr = vtop[0].r;
|
||||||
vswap();
|
|
||||||
if(!tt2)
|
|
||||||
fr = gv(RC_INT);
|
|
||||||
if(r == TREG_EAX){
|
|
||||||
if(fr != TREG_EDX)
|
|
||||||
save_reg(TREG_EDX);
|
|
||||||
o(0xf7);
|
|
||||||
if(fr >= VT_CONST)
|
|
||||||
gen_modrm(opc, fr, vtop->sym, fc);
|
|
||||||
else
|
|
||||||
o(0xc0 + fr + opc*8);
|
|
||||||
}else{
|
|
||||||
o(0xaf0f); /* imul fr, r */
|
|
||||||
if(fr >= VT_CONST)
|
|
||||||
gen_modrm(r, fr, vtop->sym, fc);
|
|
||||||
else
|
|
||||||
o(0xc0 + fr + r*8);
|
|
||||||
}
|
|
||||||
vtop--;
|
vtop--;
|
||||||
|
o(0xaf0f); /* imul fr, r */
|
||||||
|
o(0xc0 + fr + r * 8);
|
||||||
break;
|
break;
|
||||||
case TOK_SHL:
|
case TOK_SHL:
|
||||||
opc = 4;
|
opc = 4;
|
||||||
|
|
@ -836,71 +775,56 @@ ST_FUNC void gen_opi(int op)
|
||||||
case TOK_SAR:
|
case TOK_SAR:
|
||||||
opc = 7;
|
opc = 7;
|
||||||
gen_shift:
|
gen_shift:
|
||||||
if (cc) {
|
opc = 0xc0 | (opc << 3);
|
||||||
|
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
|
||||||
/* constant case */
|
/* constant case */
|
||||||
vswap();
|
vswap();
|
||||||
r = gv(RC_INT);
|
r = gv(RC_INT);
|
||||||
vswap();
|
vswap();
|
||||||
c = vtop->c.i;
|
c = vtop->c.i & 0x1f;
|
||||||
if(c == 1){
|
o(0xc1); /* shl/shr/sar $xxx, r */
|
||||||
o(0xd1);
|
o(opc | r);
|
||||||
o(0xc0 + r + opc*8);
|
g(c);
|
||||||
}else{
|
|
||||||
o(0xc1); /* shl/shr/sar $xxx, r */
|
|
||||||
o(0xc0 + r + opc*8);
|
|
||||||
g(c & 0x1f);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* we generate the shift in ecx */
|
/* we generate the shift in ecx */
|
||||||
gv2(RC_INT, RC_ECX);
|
gv2(RC_INT, RC_ECX);
|
||||||
r = vtop[-1].r;
|
r = vtop[-1].r;
|
||||||
o(0xd3); /* shl/shr/sar %cl, r */
|
o(0xd3); /* shl/shr/sar %cl, r */
|
||||||
o(0xc0 + r + opc*8);
|
o(opc | r);
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
break;
|
break;
|
||||||
case TOK_UMOD:
|
|
||||||
opc = 4;
|
|
||||||
uu = 1;
|
|
||||||
goto divmod;
|
|
||||||
case TOK_UDIV:
|
|
||||||
case TOK_UMULL:
|
|
||||||
opc = 6;
|
|
||||||
uu = 1;
|
|
||||||
goto divmod;
|
|
||||||
case '/':
|
case '/':
|
||||||
case '%':
|
case TOK_UDIV:
|
||||||
case TOK_PDIV:
|
case TOK_PDIV:
|
||||||
opc = 7;
|
case '%':
|
||||||
uu = 0;
|
case TOK_UMOD:
|
||||||
divmod:
|
case TOK_UMULL:
|
||||||
/* first operand must be in eax */
|
/* first operand must be in eax */
|
||||||
/* XXX: need better constraint for second operand */
|
/* XXX: need better constraint for second operand */
|
||||||
if(!tt2){
|
gv2(RC_EAX, RC_ECX);
|
||||||
gv2(RC_EAX, RC_INT2);
|
r = vtop[-1].r;
|
||||||
fr = vtop[0].r;
|
fr = vtop[0].r;
|
||||||
}else{
|
vtop--;
|
||||||
vswap();
|
save_reg(TREG_EDX);
|
||||||
gv(RC_EAX);
|
if (op == TOK_UMULL) {
|
||||||
vswap();
|
|
||||||
}
|
|
||||||
save_reg(TREG_EDX);
|
|
||||||
if (op == TOK_UMULL) {
|
|
||||||
o(0xf7); /* mul fr */
|
o(0xf7); /* mul fr */
|
||||||
vtop->r2 = TREG_EDX;
|
o(0xe0 + fr);
|
||||||
}else{
|
vtop->r2 = TREG_EDX;
|
||||||
o(uu ? 0xd231 : 0x99); /* xor %edx,%edx : cdq RDX:RAX <- sign-extend of RAX. */
|
|
||||||
o(0xf7); /* div fr, %eax */
|
|
||||||
}
|
|
||||||
if(fr >= VT_CONST)
|
|
||||||
gen_modrm(opc, fr, vtop->sym, fc);
|
|
||||||
else
|
|
||||||
o(0xc0 + fr + opc*8);
|
|
||||||
if (op == '%' || op == TOK_UMOD)
|
|
||||||
r = TREG_EDX;
|
|
||||||
else
|
|
||||||
r = TREG_EAX;
|
r = TREG_EAX;
|
||||||
vtop--;
|
} else {
|
||||||
|
if (op == TOK_UDIV || op == TOK_UMOD) {
|
||||||
|
o(0xf7d231); /* xor %edx, %edx, div fr, %eax */
|
||||||
|
o(0xf0 + fr);
|
||||||
|
} else {
|
||||||
|
o(0xf799); /* cltd, idiv fr, %eax */
|
||||||
|
o(0xf8 + fr);
|
||||||
|
}
|
||||||
|
if (op == '%' || op == TOK_UMOD)
|
||||||
|
r = TREG_EDX;
|
||||||
|
else
|
||||||
|
r = TREG_EAX;
|
||||||
|
}
|
||||||
vtop->r = r;
|
vtop->r = r;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
15
il-gen.c
15
il-gen.c
|
|
@ -516,7 +516,7 @@ int gtst(int inv, int t)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
t = out_opj(c, t);
|
t = out_opj(c, t);
|
||||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
} else { /* VT_JMP || VT_JMPI */
|
||||||
/* && or || optimization */
|
/* && or || optimization */
|
||||||
if ((v & 1) == inv) {
|
if ((v & 1) == inv) {
|
||||||
/* insert vtop->c jump list in t */
|
/* insert vtop->c jump list in t */
|
||||||
|
|
@ -529,19 +529,6 @@ int gtst(int inv, int t)
|
||||||
t = gjmp(t);
|
t = gjmp(t);
|
||||||
gsym(vtop->c.i);
|
gsym(vtop->c.i);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (is_float(vtop->t)) {
|
|
||||||
vpushi(0);
|
|
||||||
gen_op(TOK_NE);
|
|
||||||
}
|
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) {
|
|
||||||
/* constant jmp optimization */
|
|
||||||
if ((vtop->c.i != 0) != inv)
|
|
||||||
t = gjmp(t);
|
|
||||||
} else {
|
|
||||||
v = gv(RC_INT);
|
|
||||||
t = out_opj(IL_OP_BRTRUE - inv, t);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
return t;
|
return t;
|
||||||
|
|
|
||||||
16
lib/Makefile
16
lib/Makefile
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Tiny C Compiler Makefile for libcrt.a
|
# Tiny C Compiler Makefile for libtcc1.a
|
||||||
#
|
#
|
||||||
|
|
||||||
TOP = ..
|
TOP = ..
|
||||||
|
|
@ -38,15 +38,15 @@ endif
|
||||||
|
|
||||||
DIR = $(TARGET)
|
DIR = $(TARGET)
|
||||||
|
|
||||||
native : ../libcrt.a
|
native : ../libtcc1.a
|
||||||
cross : $(DIR)/libcrt.a
|
cross : $(DIR)/libtcc1.a
|
||||||
|
|
||||||
native : TCC = $(TOP)/tcc$(EXESUF)
|
native : TCC = $(TOP)/tcc$(EXESUF)
|
||||||
cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
|
cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
|
||||||
|
|
||||||
I386_O = libcrt.o alloca86.o alloca86-bt.o $(BCHECK_O)
|
I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
|
||||||
X86_64_O = libcrt.o alloca86_64.o
|
X86_64_O = libtcc1.o alloca86_64.o
|
||||||
ARM_O = libcrt.o armeabi.o alloca-arm.o
|
ARM_O = libtcc1.o armeabi.o alloca-arm.o
|
||||||
WIN32_O = $(I386_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
|
WIN32_O = $(I386_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
|
||||||
WIN64_O = $(X86_64_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
|
WIN64_O = $(X86_64_O) crt1.o wincrt1.o dllcrt1.o dllmain.o chkstk.o
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@ ifeq "$(TARGET)" "arm"
|
||||||
TGT = -DTCC_TARGET_ARM
|
TGT = -DTCC_TARGET_ARM
|
||||||
XCC ?= $(TCC) -B$(TOP)
|
XCC ?= $(TCC) -B$(TOP)
|
||||||
else
|
else
|
||||||
$(error libcrt.a not supported on target '$(TARGET)')
|
$(error libtcc1.a not supported on target '$(TARGET)')
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
@ -102,7 +102,7 @@ ifdef XAR
|
||||||
AR = $(XAR)
|
AR = $(XAR)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(DIR)/libcrt.a ../libcrt.a : $(OBJ) $(XAR)
|
$(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
|
||||||
$(AR) rcs $@ $(OBJ)
|
$(AR) rcs $@ $(OBJ)
|
||||||
$(DIR)/%.o : %.c
|
$(DIR)/%.o : %.c
|
||||||
$(XCC) -c $< -o $@ $(XFLAGS)
|
$(XCC) -c $< -o $@ $(XFLAGS)
|
||||||
|
|
|
||||||
|
|
@ -533,24 +533,23 @@ unsigned long long __fixunssfdi (float a1)
|
||||||
register union float_long fl1;
|
register union float_long fl1;
|
||||||
register int exp;
|
register int exp;
|
||||||
register unsigned long l;
|
register unsigned long l;
|
||||||
int s;
|
|
||||||
fl1.f = a1;
|
fl1.f = a1;
|
||||||
|
|
||||||
if (fl1.l == 0)
|
if (fl1.l == 0)
|
||||||
return 0;
|
return (0);
|
||||||
|
|
||||||
exp = EXP (fl1.l) - EXCESS - 24;
|
exp = EXP (fl1.l) - EXCESS - 24;
|
||||||
|
|
||||||
l = MANT(fl1.l);
|
l = MANT(fl1.l);
|
||||||
s = SIGN(fl1.l)? -1: 1;
|
if (exp >= 41)
|
||||||
if (exp >= 64)
|
|
||||||
return (unsigned long long)-1;
|
return (unsigned long long)-1;
|
||||||
else if (exp >= 0)
|
else if (exp >= 0)
|
||||||
return ((unsigned long long)l << exp)*s;
|
return (unsigned long long)l << exp;
|
||||||
else if (exp >= -23)
|
else if (exp >= -23)
|
||||||
return (l >> -exp)*s;
|
return l >> -exp;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long __fixunsdfdi (double a1)
|
unsigned long long __fixunsdfdi (double a1)
|
||||||
|
|
@ -558,7 +557,7 @@ unsigned long long __fixunsdfdi (double a1)
|
||||||
register union double_long dl1;
|
register union double_long dl1;
|
||||||
register int exp;
|
register int exp;
|
||||||
register unsigned long long l;
|
register unsigned long long l;
|
||||||
int s;
|
|
||||||
dl1.d = a1;
|
dl1.d = a1;
|
||||||
|
|
||||||
if (dl1.ll == 0)
|
if (dl1.ll == 0)
|
||||||
|
|
@ -567,15 +566,15 @@ unsigned long long __fixunsdfdi (double a1)
|
||||||
exp = EXPD (dl1) - EXCESSD - 53;
|
exp = EXPD (dl1) - EXCESSD - 53;
|
||||||
|
|
||||||
l = MANTD_LL(dl1);
|
l = MANTD_LL(dl1);
|
||||||
s = SIGND(dl1)? -1: 1;
|
|
||||||
if (exp >= 64)
|
if (exp >= 12)
|
||||||
return (unsigned long long)-1;
|
return (unsigned long long)-1;
|
||||||
else if (exp >= 0)
|
else if (exp >= 0)
|
||||||
return (l << exp)*s;
|
return l << exp;
|
||||||
else if (exp >= -52)
|
else if (exp >= -52)
|
||||||
return (l >> -exp)*s;
|
return l >> -exp;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long __fixunsxfdi (long double a1)
|
unsigned long long __fixunsxfdi (long double a1)
|
||||||
|
|
@ -583,24 +582,22 @@ unsigned long long __fixunsxfdi (long double a1)
|
||||||
register union ldouble_long dl1;
|
register union ldouble_long dl1;
|
||||||
register int exp;
|
register int exp;
|
||||||
register unsigned long long l;
|
register unsigned long long l;
|
||||||
int s;
|
|
||||||
dl1.ld = a1;
|
dl1.ld = a1;
|
||||||
|
|
||||||
if (dl1.l.lower == 0 && dl1.l.upper == 0)
|
if (dl1.l.lower == 0 && dl1.l.upper == 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
exp = EXPLD (dl1) - EXCESSLD - 64;
|
exp = EXPLD (dl1) - EXCESSLD - 64;
|
||||||
s = SIGNLD(dl1)? -1: 1;
|
|
||||||
l = dl1.l.lower;
|
l = dl1.l.lower;
|
||||||
|
|
||||||
if (exp >= 64)
|
if (exp > 0)
|
||||||
return (unsigned long long)-1;
|
return (unsigned long long)-1;
|
||||||
else if (exp >= 0)
|
else if (exp >= -63)
|
||||||
return ((unsigned long long)l << exp)*s;
|
return l >> -exp;
|
||||||
else if (exp >= -64)
|
|
||||||
return (l >> -exp)*s;
|
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long long __fixsfdi (float a1)
|
long long __fixsfdi (float a1)
|
||||||
|
|
@ -640,7 +637,7 @@ extern void abort(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum __va_arg_type {
|
enum __va_arg_type {
|
||||||
__va_gen_reg, __va_float_reg, __va_ld_reg, __va_stack
|
__va_gen_reg, __va_float_reg, __va_stack
|
||||||
};
|
};
|
||||||
|
|
||||||
//This should be in sync with the declaration on our include/stdarg.h
|
//This should be in sync with the declaration on our include/stdarg.h
|
||||||
|
|
@ -691,11 +688,10 @@ void *__va_arg(__va_list_struct *ap,
|
||||||
size = 8;
|
size = 8;
|
||||||
goto use_overflow_area;
|
goto use_overflow_area;
|
||||||
|
|
||||||
case __va_ld_reg:
|
|
||||||
ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
|
|
||||||
case __va_stack:
|
case __va_stack:
|
||||||
use_overflow_area:
|
use_overflow_area:
|
||||||
ap->overflow_arg_area += size;
|
ap->overflow_arg_area += size;
|
||||||
|
ap->overflow_arg_area = (char*)((intptr_t)(ap->overflow_arg_area + align - 1) & -(intptr_t)align);
|
||||||
return ap->overflow_arg_area - size;
|
return ap->overflow_arg_area - size;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
12
libtcc.c
12
libtcc.c
|
|
@ -52,10 +52,10 @@ ST_DATA struct TCCState *tcc_state;
|
||||||
#include "x86_64-gen.c"
|
#include "x86_64-gen.c"
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_TCC_ASM
|
#ifdef CONFIG_TCC_ASM
|
||||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
|
||||||
#include "asmx86.c"
|
|
||||||
#endif
|
|
||||||
#include "tccasm.c"
|
#include "tccasm.c"
|
||||||
|
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||||
|
#include "i386-asm.c"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_COFF
|
#ifdef TCC_TARGET_COFF
|
||||||
#include "tcccoff.c"
|
#include "tcccoff.c"
|
||||||
|
|
@ -868,7 +868,6 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
|
||||||
static void tcc_cleanup(void)
|
static void tcc_cleanup(void)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
CSym *def;
|
|
||||||
if (NULL == tcc_state)
|
if (NULL == tcc_state)
|
||||||
return;
|
return;
|
||||||
tcc_state = NULL;
|
tcc_state = NULL;
|
||||||
|
|
@ -878,11 +877,8 @@ static void tcc_cleanup(void)
|
||||||
|
|
||||||
/* free tokens */
|
/* free tokens */
|
||||||
n = tok_ident - TOK_IDENT;
|
n = tok_ident - TOK_IDENT;
|
||||||
for(i = 0; i < n; i++){
|
for(i = 0; i < n; i++)
|
||||||
def = &table_ident[i]->sym_define;
|
|
||||||
tcc_free(def->data);
|
|
||||||
tcc_free(table_ident[i]);
|
tcc_free(table_ident[i]);
|
||||||
}
|
|
||||||
tcc_free(table_ident);
|
tcc_free(table_ident);
|
||||||
|
|
||||||
/* free sym_pools */
|
/* free sym_pools */
|
||||||
|
|
|
||||||
40
tcc.h
40
tcc.h
|
|
@ -39,7 +39,6 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#ifdef CONFIG_TCCASSERT
|
#ifdef CONFIG_TCCASSERT
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -148,7 +147,6 @@
|
||||||
/* #define MEM_DEBUG */
|
/* #define MEM_DEBUG */
|
||||||
/* assembler debug */
|
/* assembler debug */
|
||||||
/* #define ASM_DEBUG */
|
/* #define ASM_DEBUG */
|
||||||
/* #define PRINTF_ASM_CODE */
|
|
||||||
|
|
||||||
/* target selection */
|
/* target selection */
|
||||||
/* #define TCC_TARGET_I386 *//* i386 code generator */
|
/* #define TCC_TARGET_I386 *//* i386 code generator */
|
||||||
|
|
@ -276,7 +274,7 @@
|
||||||
# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
|
# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* library to use with CONFIG_USE_LIBGCC instead of libcrt.a */
|
/* library to use with CONFIG_USE_LIBGCC instead of libtcc1.a */
|
||||||
#define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
|
#define TCC_LIBGCC USE_MUADIR(CONFIG_SYSROOT "/" CONFIG_LDDIR) "/libgcc_s.so.1"
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
@ -305,22 +303,15 @@
|
||||||
#define VSTACK_SIZE 256
|
#define VSTACK_SIZE 256
|
||||||
#define STRING_MAX_SIZE 1024
|
#define STRING_MAX_SIZE 1024
|
||||||
#define PACK_STACK_SIZE 8
|
#define PACK_STACK_SIZE 8
|
||||||
#define MACRO_STACK_SIZE 4
|
|
||||||
|
|
||||||
#define TOK_HASH_SIZE 8192 /* must be a power of two */
|
#define TOK_HASH_SIZE 8192 /* must be a power of two */
|
||||||
#define TOK_ALLOC_INCR 512 /* must be a power of two */
|
#define TOK_ALLOC_INCR 512 /* must be a power of two */
|
||||||
#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
|
#define TOK_MAX_SIZE 4 /* token max size in int unit when stored in string */
|
||||||
|
|
||||||
typedef struct CSym {
|
|
||||||
int off;
|
|
||||||
int size;/* size in *sym */
|
|
||||||
struct Sym **data; /* if non NULL, data has been malloced */
|
|
||||||
} CSym;
|
|
||||||
|
|
||||||
/* token symbol management */
|
/* token symbol management */
|
||||||
typedef struct TokenSym {
|
typedef struct TokenSym {
|
||||||
struct TokenSym *hash_next;
|
struct TokenSym *hash_next;
|
||||||
struct CSym sym_define; /* direct pointer to define */
|
struct Sym *sym_define; /* direct pointer to define */
|
||||||
struct Sym *sym_label; /* direct pointer to label */
|
struct Sym *sym_label; /* direct pointer to label */
|
||||||
struct Sym *sym_struct; /* direct pointer to structure */
|
struct Sym *sym_struct; /* direct pointer to structure */
|
||||||
struct Sym *sym_identifier; /* direct pointer to identifier */
|
struct Sym *sym_identifier; /* direct pointer to identifier */
|
||||||
|
|
@ -366,8 +357,8 @@ typedef union CValue {
|
||||||
/* value on stack */
|
/* value on stack */
|
||||||
typedef struct SValue {
|
typedef struct SValue {
|
||||||
CType type; /* type */
|
CType type; /* type */
|
||||||
unsigned int r; /* register + flags */
|
unsigned short r; /* register + flags */
|
||||||
unsigned int r2; /* second register, used for 'long long'
|
unsigned short r2; /* second register, used for 'long long'
|
||||||
type. If not used, set to VT_CONST */
|
type. If not used, set to VT_CONST */
|
||||||
CValue c; /* constant, if VT_CONST */
|
CValue c; /* constant, if VT_CONST */
|
||||||
struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
|
struct Sym *sym; /* symbol, if (VT_SYM | VT_CONST) */
|
||||||
|
|
@ -747,21 +738,19 @@ struct TCCState {
|
||||||
#define VT_CMP 0x0033 /* the value is stored in processor flags (in vc) */
|
#define VT_CMP 0x0033 /* the value is stored in processor flags (in vc) */
|
||||||
#define VT_JMP 0x0034 /* value is the consequence of jmp true (even) */
|
#define VT_JMP 0x0034 /* value is the consequence of jmp true (even) */
|
||||||
#define VT_JMPI 0x0035 /* value is the consequence of jmp false (odd) */
|
#define VT_JMPI 0x0035 /* value is the consequence of jmp false (odd) */
|
||||||
#define TREG_MEM 0x0040 /* x86_64-gen.c add for tcc.h: The current value can be */
|
#define VT_REF 0x0040 /* value is pointer to structure rather than address */
|
||||||
#define VT_REF 0x0080 /* value is pointer to structure rather than address */
|
|
||||||
#define VT_LVAL 0x0100 /* var is an lvalue */
|
#define VT_LVAL 0x0100 /* var is an lvalue */
|
||||||
#define VT_SYM 0x0200 /* a symbol value is added */
|
#define VT_SYM 0x0200 /* a symbol value is added */
|
||||||
#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
|
#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
|
||||||
char/short stored in integer registers) */
|
char/short stored in integer registers) */
|
||||||
#define VT_MUSTBOUND 0x0800 /* bound checking must be done before
|
#define VT_MUSTBOUND 0x0800 /* bound checking must be done before
|
||||||
dereferencing value */
|
dereferencing value */
|
||||||
|
#define VT_BOUNDED 0x8000 /* value is bounded. The address of the
|
||||||
|
bounding function call point is in vc */
|
||||||
#define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
|
#define VT_LVAL_BYTE 0x1000 /* lvalue is a byte */
|
||||||
#define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
|
#define VT_LVAL_SHORT 0x2000 /* lvalue is a short */
|
||||||
#define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
|
#define VT_LVAL_UNSIGNED 0x4000 /* lvalue is unsigned */
|
||||||
#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
|
#define VT_LVAL_TYPE (VT_LVAL_BYTE | VT_LVAL_SHORT | VT_LVAL_UNSIGNED)
|
||||||
#define VT_BOUNDED 0x8000 /* value is bounded. The address of the
|
|
||||||
bounding function call point is in vc */
|
|
||||||
#define VT_TMP 0x10000 /* luck or tmp stack */
|
|
||||||
|
|
||||||
/* types */
|
/* types */
|
||||||
#define VT_BTYPE 0x000f /* mask for basic type */
|
#define VT_BTYPE 0x000f /* mask for basic type */
|
||||||
|
|
@ -789,7 +778,6 @@ struct TCCState {
|
||||||
#define VT_VOLATILE 0x1000 /* volatile modifier */
|
#define VT_VOLATILE 0x1000 /* volatile modifier */
|
||||||
#define VT_DEFSIGN 0x2000 /* signed type */
|
#define VT_DEFSIGN 0x2000 /* signed type */
|
||||||
#define VT_VLA 0x00020000 /* VLA type (also has VT_PTR and VT_ARRAY) */
|
#define VT_VLA 0x00020000 /* VLA type (also has VT_PTR and VT_ARRAY) */
|
||||||
#define VT_VLS 0x00080000 /* VLA type (also has VT_PTR and VT_STRUCT) */
|
|
||||||
|
|
||||||
/* storage */
|
/* storage */
|
||||||
#define VT_EXTERN 0x00000080 /* extern definition */
|
#define VT_EXTERN 0x00000080 /* extern definition */
|
||||||
|
|
@ -800,14 +788,14 @@ struct TCCState {
|
||||||
#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
|
#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
|
||||||
#define VT_WEAK 0x00010000 /* weak symbol */
|
#define VT_WEAK 0x00010000 /* weak symbol */
|
||||||
#define VT_TLS 0x00040000 /* thread-local storage */
|
#define VT_TLS 0x00040000 /* thread-local storage */
|
||||||
#define VT_VIS_SHIFT 20 /* shift for symbol visibility, overlapping
|
#define VT_VIS_SHIFT 19 /* shift for symbol visibility, overlapping
|
||||||
bitfield values, because bitfields never
|
bitfield values, because bitfields never
|
||||||
have linkage and hence never have
|
have linkage and hence never have
|
||||||
visibility. */
|
visibility. */
|
||||||
#define VT_VIS_SIZE 2 /* We have four visibilities. */
|
#define VT_VIS_SIZE 2 /* We have four visibilities. */
|
||||||
#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT)
|
#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT)
|
||||||
|
|
||||||
#define VT_STRUCT_SHIFT 20 /* shift for bitfield shift values (max: 32 - 2*6) */
|
#define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */
|
||||||
|
|
||||||
|
|
||||||
/* type mask (except storage) */
|
/* type mask (except storage) */
|
||||||
|
|
@ -1136,8 +1124,7 @@ ST_DATA TokenSym **table_ident;
|
||||||
token. line feed is also
|
token. line feed is also
|
||||||
returned at eof */
|
returned at eof */
|
||||||
#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
|
#define PARSE_FLAG_ASM_COMMENTS 0x0008 /* '#' can be used for line comment */
|
||||||
#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
|
#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
|
||||||
#define PARSE_FLAG_PACK 0x0020 /* #pragma pack */
|
|
||||||
|
|
||||||
ST_FUNC TokenSym *tok_alloc(const char *str, int len);
|
ST_FUNC TokenSym *tok_alloc(const char *str, int len);
|
||||||
ST_FUNC char *get_tok_str(int v, CValue *cv);
|
ST_FUNC char *get_tok_str(int v, CValue *cv);
|
||||||
|
|
@ -1195,7 +1182,7 @@ ST_DATA Sym *define_stack;
|
||||||
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
||||||
ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop;
|
ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop;
|
||||||
#define vstack (__vstack + 1)
|
#define vstack (__vstack + 1)
|
||||||
ST_DATA int rsym, anon_sym, ind, loc, ex_rc;
|
ST_DATA int rsym, anon_sym, ind, loc;
|
||||||
|
|
||||||
ST_DATA int const_wanted; /* true if constant wanted */
|
ST_DATA int const_wanted; /* true if constant wanted */
|
||||||
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
|
ST_DATA int nocode_wanted; /* true if no code generation wanted for an expression */
|
||||||
|
|
@ -1205,14 +1192,12 @@ ST_DATA int func_var; /* true if current function is variadic */
|
||||||
ST_DATA int func_vc;
|
ST_DATA int func_vc;
|
||||||
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
|
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
|
||||||
ST_DATA char *funcname;
|
ST_DATA char *funcname;
|
||||||
ST_DATA int pop_stack;
|
|
||||||
|
|
||||||
ST_INLN int is_float(int t);
|
ST_INLN int is_float(int t);
|
||||||
ST_FUNC int ieee_finite(double d);
|
ST_FUNC int ieee_finite(double d);
|
||||||
ST_FUNC void test_lvalue(void);
|
ST_FUNC void test_lvalue(void);
|
||||||
ST_FUNC void swap(int *p, int *q);
|
ST_FUNC void swap(int *p, int *q);
|
||||||
ST_FUNC void vpushi(int v);
|
ST_FUNC void vpushi(int v);
|
||||||
ST_FUNC void vpushs(addr_t v);
|
|
||||||
ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
|
ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
|
||||||
ST_FUNC void vset(CType *type, int r, int v);
|
ST_FUNC void vset(CType *type, int r, int v);
|
||||||
ST_FUNC void vswap(void);
|
ST_FUNC void vswap(void);
|
||||||
|
|
@ -1246,9 +1231,6 @@ ST_FUNC void gexpr(void);
|
||||||
ST_FUNC int expr_const(void);
|
ST_FUNC int expr_const(void);
|
||||||
ST_FUNC void gen_inline_functions(void);
|
ST_FUNC void gen_inline_functions(void);
|
||||||
ST_FUNC void decl(int l);
|
ST_FUNC void decl(int l);
|
||||||
ST_FUNC void vdup(void);
|
|
||||||
ST_FUNC void gaddrof(void);
|
|
||||||
ST_FUNC int loc_stack(int size, int is_sub);
|
|
||||||
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
|
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_C67
|
||||||
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
|
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
49
tccasm.c
49
tccasm.c
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
#ifdef CONFIG_TCC_ASM
|
#ifdef CONFIG_TCC_ASM
|
||||||
|
|
||||||
ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
|
ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
@ -482,7 +483,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
case TOK_ASM_globl:
|
case TOK_ASM_globl:
|
||||||
case TOK_ASM_global:
|
case TOK_ASM_global:
|
||||||
case TOK_ASM_weak:
|
case TOK_ASM_weak:
|
||||||
case TOK_ASM_hidden:
|
case TOK_ASM_hidden:
|
||||||
tok1 = tok;
|
tok1 = tok;
|
||||||
do {
|
do {
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
|
@ -493,12 +494,12 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
sym = label_push(&s1->asm_labels, tok, 0);
|
sym = label_push(&s1->asm_labels, tok, 0);
|
||||||
sym->type.t = VT_VOID;
|
sym->type.t = VT_VOID;
|
||||||
}
|
}
|
||||||
if (tok1 != TOK_ASM_hidden)
|
if (tok1 != TOK_ASM_hidden)
|
||||||
sym->type.t &= ~VT_STATIC;
|
sym->type.t &= ~VT_STATIC;
|
||||||
if (tok1 == TOK_ASM_weak)
|
if (tok1 == TOK_ASM_weak)
|
||||||
sym->type.t |= VT_WEAK;
|
sym->type.t |= VT_WEAK;
|
||||||
else if (tok1 == TOK_ASM_hidden)
|
else if (tok1 == TOK_ASM_hidden)
|
||||||
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
|
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
|
||||||
next();
|
next();
|
||||||
} while (tok == ',');
|
} while (tok == ',');
|
||||||
break;
|
break;
|
||||||
|
|
@ -696,15 +697,42 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* assemble a file */
|
/* assemble a file */
|
||||||
static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
|
static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
|
||||||
{
|
{
|
||||||
int opcode;
|
int opcode;
|
||||||
|
|
||||||
#ifdef PRINTF_ASM_CODE
|
#if 0
|
||||||
ST_FUNC void printf_asm_opcode();
|
|
||||||
/* print stats about opcodes */
|
/* print stats about opcodes */
|
||||||
printf_asm_opcode();
|
{
|
||||||
|
const ASMInstr *pa;
|
||||||
|
int freq[4];
|
||||||
|
int op_vals[500];
|
||||||
|
int nb_op_vals, i, j;
|
||||||
|
|
||||||
|
nb_op_vals = 0;
|
||||||
|
memset(freq, 0, sizeof(freq));
|
||||||
|
for(pa = asm_instrs; pa->sym != 0; pa++) {
|
||||||
|
freq[pa->nb_ops]++;
|
||||||
|
for(i=0;i<pa->nb_ops;i++) {
|
||||||
|
for(j=0;j<nb_op_vals;j++) {
|
||||||
|
if (pa->op_type[i] == op_vals[j])
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
op_vals[nb_op_vals++] = pa->op_type[i];
|
||||||
|
found: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i=0;i<nb_op_vals;i++) {
|
||||||
|
int v = op_vals[i];
|
||||||
|
if ((v & (v - 1)) != 0)
|
||||||
|
printf("%3d: %08x\n", i, v);
|
||||||
|
}
|
||||||
|
printf("size=%d nb=%d f0=%d f1=%d f2=%d f3=%d\n",
|
||||||
|
sizeof(asm_instrs), sizeof(asm_instrs) / sizeof(ASMInstr),
|
||||||
|
freq[0], freq[1], freq[2], freq[3]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX: undefine C labels */
|
/* XXX: undefine C labels */
|
||||||
|
|
@ -786,8 +814,9 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
|
||||||
|
|
||||||
/* an elf symbol of type STT_FILE must be put so that STB_LOCAL
|
/* an elf symbol of type STT_FILE must be put so that STB_LOCAL
|
||||||
symbols can be safely used */
|
symbols can be safely used */
|
||||||
put_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
|
put_elf_sym(symtab_section, 0, 0,
|
||||||
SHN_ABS, file->filename);
|
ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
|
||||||
|
SHN_ABS, file->filename);
|
||||||
|
|
||||||
ret = tcc_assemble_internal(s1, do_preprocess);
|
ret = tcc_assemble_internal(s1, do_preprocess);
|
||||||
|
|
||||||
|
|
@ -1090,4 +1119,4 @@ ST_FUNC void asm_global_instr(void)
|
||||||
|
|
||||||
cstr_free(&astr);
|
cstr_free(&astr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_TCC_ASM */
|
#endif /* CONFIG_TCC_ASM */
|
||||||
|
|
|
||||||
12
tccelf.c
12
tccelf.c
|
|
@ -1443,16 +1443,16 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
|
||||||
#ifdef CONFIG_USE_LIBGCC
|
#ifdef CONFIG_USE_LIBGCC
|
||||||
if (!s1->static_link) {
|
if (!s1->static_link) {
|
||||||
tcc_add_file(s1, TCC_LIBGCC);
|
tcc_add_file(s1, TCC_LIBGCC);
|
||||||
tcc_add_support(s1, "libcrt.a");
|
tcc_add_support(s1, "libtcc1.a");
|
||||||
} else
|
} else
|
||||||
tcc_add_support(s1, "libcrt.a");
|
tcc_add_support(s1, "libtcc1.a");
|
||||||
#else
|
#else
|
||||||
tcc_add_support(s1, "libcrt.a");
|
tcc_add_support(s1, "libtcc1.a");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tcc_add_bcheck tries to relocate a call to __bound_init in _init so
|
/* tcc_add_bcheck tries to relocate a call to __bound_init in _init so
|
||||||
libcrt.a must be loaded before for __bound_init to be defined and
|
libtcc1.a must be loaded before for __bound_init to be defined and
|
||||||
crtn.o must be loaded after to not finalize _init too early. */
|
crtn.o must be loaded after to not finalize _init too early. */
|
||||||
tcc_add_bcheck(s1);
|
tcc_add_bcheck(s1);
|
||||||
|
|
||||||
|
|
@ -1596,7 +1596,7 @@ ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
|
||||||
put32(s1->got->data + offset, sym->st_value & 0xffffffff);
|
put32(s1->got->data + offset, sym->st_value & 0xffffffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform relocation to GOT or PLT entries */
|
/* Perform relocation to GOT or PLT entries */
|
||||||
ST_FUNC void fill_got(TCCState *s1)
|
ST_FUNC void fill_got(TCCState *s1)
|
||||||
{
|
{
|
||||||
Section *s;
|
Section *s;
|
||||||
|
|
@ -2469,7 +2469,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
goto the_end;
|
goto the_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform relocation to GOT or PLT entries */
|
/* Perform relocation to GOT or PLT entries */
|
||||||
if (file_type == TCC_OUTPUT_EXE && s1->static_link)
|
if (file_type == TCC_OUTPUT_EXE && s1->static_link)
|
||||||
fill_got(s1);
|
fill_got(s1);
|
||||||
|
|
||||||
|
|
|
||||||
2
tccpe.c
2
tccpe.c
|
|
@ -1773,7 +1773,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
|
||||||
|
|
||||||
if (0 == s1->nostdlib) {
|
if (0 == s1->nostdlib) {
|
||||||
static const char *libs[] = {
|
static const char *libs[] = {
|
||||||
"libcrt.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
|
"libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
|
||||||
};
|
};
|
||||||
const char **pp, *p;
|
const char **pp, *p;
|
||||||
for (pp = libs; 0 != (p = *pp); ++pp) {
|
for (pp = libs; 0 != (p = *pp); ++pp) {
|
||||||
|
|
|
||||||
302
tccpp.c
302
tccpp.c
|
|
@ -233,10 +233,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
|
||||||
ts = tcc_malloc(sizeof(TokenSym) + len);
|
ts = tcc_malloc(sizeof(TokenSym) + len);
|
||||||
table_ident[i] = ts;
|
table_ident[i] = ts;
|
||||||
ts->tok = tok_ident++;
|
ts->tok = tok_ident++;
|
||||||
ts->sym_define.data = tcc_malloc(sizeof(Sym**));
|
ts->sym_define = NULL;
|
||||||
ts->sym_define.off = 0;
|
|
||||||
ts->sym_define.data[0] = NULL;
|
|
||||||
ts->sym_define.size = 1;
|
|
||||||
ts->sym_label = NULL;
|
ts->sym_label = NULL;
|
||||||
ts->sym_struct = NULL;
|
ts->sym_struct = NULL;
|
||||||
ts->sym_identifier = NULL;
|
ts->sym_identifier = NULL;
|
||||||
|
|
@ -1055,62 +1052,52 @@ static int macro_is_equal(const int *a, const int *b)
|
||||||
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
|
ST_INLN void define_push(int v, int macro_type, int *str, Sym *first_arg)
|
||||||
{
|
{
|
||||||
Sym *s;
|
Sym *s;
|
||||||
CSym *def;
|
|
||||||
s = define_find(v);
|
s = define_find(v);
|
||||||
if (s && !macro_is_equal(s->d, str))
|
if (s && !macro_is_equal(s->d, str))
|
||||||
tcc_warning("%s redefined", get_tok_str(v, NULL));
|
tcc_warning("%s redefined", get_tok_str(v, NULL));
|
||||||
|
|
||||||
s = sym_push2(&define_stack, v, macro_type, 0);
|
s = sym_push2(&define_stack, v, macro_type, 0);
|
||||||
s->d = str;
|
s->d = str;
|
||||||
s->next = first_arg;
|
s->next = first_arg;
|
||||||
def = &table_ident[v - TOK_IDENT]->sym_define;
|
table_ident[v - TOK_IDENT]->sym_define = s;
|
||||||
def->data[def->off] = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* undefined a define symbol. Its name is just set to zero */
|
/* undefined a define symbol. Its name is just set to zero */
|
||||||
ST_FUNC void define_undef(Sym *s)
|
ST_FUNC void define_undef(Sym *s)
|
||||||
{
|
{
|
||||||
int v;
|
int v;
|
||||||
CSym *def;
|
v = s->v;
|
||||||
v = s->v - TOK_IDENT;
|
if (v >= TOK_IDENT && v < tok_ident)
|
||||||
if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
|
table_ident[v - TOK_IDENT]->sym_define = NULL;
|
||||||
def = &table_ident[v]->sym_define;
|
s->v = 0;
|
||||||
def->data[def->off] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_INLN Sym *define_find(int v)
|
ST_INLN Sym *define_find(int v)
|
||||||
{
|
{
|
||||||
CSym *def;
|
|
||||||
v -= TOK_IDENT;
|
v -= TOK_IDENT;
|
||||||
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
|
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
|
||||||
return NULL;
|
return NULL;
|
||||||
def = &table_ident[v]->sym_define;
|
return table_ident[v]->sym_define;
|
||||||
return def->data[def->off];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free define stack until top reaches 'b' */
|
/* free define stack until top reaches 'b' */
|
||||||
ST_FUNC void free_defines(Sym *b)
|
ST_FUNC void free_defines(Sym *b)
|
||||||
{
|
{
|
||||||
Sym *top, *tmp;
|
Sym *top, *top1;
|
||||||
int v;
|
int v;
|
||||||
CSym *def;
|
|
||||||
|
|
||||||
top = define_stack;
|
top = define_stack;
|
||||||
while (top != b) {
|
while (top != b) {
|
||||||
tmp = top->prev;
|
top1 = top->prev;
|
||||||
/* do not free args or predefined defines */
|
/* do not free args or predefined defines */
|
||||||
if (top->d)
|
if (top->d)
|
||||||
tok_str_free(top->d);
|
tok_str_free(top->d);
|
||||||
v = top->v - TOK_IDENT;
|
v = top->v;
|
||||||
if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
|
if (v >= TOK_IDENT && v < tok_ident)
|
||||||
def = &table_ident[v]->sym_define;
|
table_ident[v - TOK_IDENT]->sym_define = NULL;
|
||||||
if(def->off)
|
|
||||||
def->off = 0;
|
|
||||||
if(def->data[0])
|
|
||||||
def->data[0] = NULL;
|
|
||||||
}
|
|
||||||
sym_free(top);
|
sym_free(top);
|
||||||
top = tmp;
|
top = top1;
|
||||||
}
|
}
|
||||||
define_stack = b;
|
define_stack = b;
|
||||||
}
|
}
|
||||||
|
|
@ -1351,18 +1338,66 @@ static inline void add_cached_include(TCCState *s1, const char *filename, int if
|
||||||
s1->cached_includes_hash[h] = s1->nb_cached_includes;
|
s1->cached_includes_hash[h] = s1->nb_cached_includes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pragma_parse(TCCState *s1)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
|
||||||
|
next();
|
||||||
|
if (tok == TOK_pack) {
|
||||||
|
/*
|
||||||
|
This may be:
|
||||||
|
#pragma pack(1) // set
|
||||||
|
#pragma pack() // reset to default
|
||||||
|
#pragma pack(push,1) // push & set
|
||||||
|
#pragma pack(pop) // restore previous
|
||||||
|
*/
|
||||||
|
next();
|
||||||
|
skip('(');
|
||||||
|
if (tok == TOK_ASM_pop) {
|
||||||
|
next();
|
||||||
|
if (s1->pack_stack_ptr <= s1->pack_stack) {
|
||||||
|
stk_error:
|
||||||
|
tcc_error("out of pack stack");
|
||||||
|
}
|
||||||
|
s1->pack_stack_ptr--;
|
||||||
|
} else {
|
||||||
|
val = 0;
|
||||||
|
if (tok != ')') {
|
||||||
|
if (tok == TOK_ASM_push) {
|
||||||
|
next();
|
||||||
|
if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE - 1)
|
||||||
|
goto stk_error;
|
||||||
|
s1->pack_stack_ptr++;
|
||||||
|
skip(',');
|
||||||
|
}
|
||||||
|
if (tok != TOK_CINT) {
|
||||||
|
pack_error:
|
||||||
|
tcc_error("invalid pack pragma");
|
||||||
|
}
|
||||||
|
val = tokc.i;
|
||||||
|
if (val < 1 || val > 16 || (val & (val - 1)) != 0)
|
||||||
|
goto pack_error;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
*s1->pack_stack_ptr = val;
|
||||||
|
skip(')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* is_bof is true if first non space token at beginning of file */
|
/* is_bof is true if first non space token at beginning of file */
|
||||||
ST_FUNC void preprocess(int is_bof)
|
ST_FUNC void preprocess(int is_bof)
|
||||||
{
|
{
|
||||||
TCCState *s1 = tcc_state;
|
TCCState *s1 = tcc_state;
|
||||||
int i, c, n, saved_parse_flags;
|
int i, c, n, saved_parse_flags;
|
||||||
uint8_t buf[1024], *p;
|
char buf[1024], *q;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
|
|
||||||
saved_parse_flags = parse_flags;
|
saved_parse_flags = parse_flags;
|
||||||
parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_LINEFEED;
|
parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM |
|
||||||
|
PARSE_FLAG_LINEFEED;
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
redo:
|
redo:
|
||||||
switch(tok) {
|
switch(tok) {
|
||||||
case TOK_DEFINE:
|
case TOK_DEFINE:
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
|
|
@ -1385,21 +1420,19 @@ redo:
|
||||||
goto read_name;
|
goto read_name;
|
||||||
} else if (ch == '\"') {
|
} else if (ch == '\"') {
|
||||||
c = ch;
|
c = ch;
|
||||||
read_name:
|
read_name:
|
||||||
inp();
|
inp();
|
||||||
p = buf;
|
q = buf;
|
||||||
while (ch != c && ch != '\n' && ch != CH_EOF) {
|
while (ch != c && ch != '\n' && ch != CH_EOF) {
|
||||||
if ((p - buf) < sizeof(buf) - 1)
|
if ((q - buf) < sizeof(buf) - 1)
|
||||||
*p++ = ch;
|
*q++ = ch;
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
if (handle_stray_noerror() == 0)
|
if (handle_stray_noerror() == 0)
|
||||||
--p;
|
--q;
|
||||||
} else
|
} else
|
||||||
inp();
|
inp();
|
||||||
}
|
}
|
||||||
if (ch != c)
|
*q = '\0';
|
||||||
goto include_syntax;
|
|
||||||
*p = '\0';
|
|
||||||
minp();
|
minp();
|
||||||
#if 0
|
#if 0
|
||||||
/* eat all spaces and comments after include */
|
/* eat all spaces and comments after include */
|
||||||
|
|
@ -1437,8 +1470,6 @@ read_name:
|
||||||
c = '>';
|
c = '>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!buf[0])
|
|
||||||
tcc_error(" empty filename in #include");
|
|
||||||
|
|
||||||
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
|
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)
|
||||||
tcc_error("#include recursion too deep");
|
tcc_error("#include recursion too deep");
|
||||||
|
|
@ -1505,7 +1536,8 @@ include_trynext:
|
||||||
printf("%s: including %s\n", file->prev->filename, file->filename);
|
printf("%s: including %s\n", file->prev->filename, file->filename);
|
||||||
#endif
|
#endif
|
||||||
/* update target deps */
|
/* update target deps */
|
||||||
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps, tcc_strdup(buf1));
|
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
|
||||||
|
tcc_strdup(buf1));
|
||||||
/* push current file in stack */
|
/* push current file in stack */
|
||||||
++s1->include_stack_ptr;
|
++s1->include_stack_ptr;
|
||||||
/* add include file debug info */
|
/* add include file debug info */
|
||||||
|
|
@ -1538,7 +1570,7 @@ include_done:
|
||||||
file->ifndef_macro = tok;
|
file->ifndef_macro = tok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c = !!define_find(tok) ^ c;
|
c = (define_find(tok) != 0) ^ c;
|
||||||
do_if:
|
do_if:
|
||||||
if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
|
if (s1->ifdef_stack_ptr >= s1->ifdef_stack + IFDEF_STACK_SIZE)
|
||||||
tcc_error("memory full (ifdef)");
|
tcc_error("memory full (ifdef)");
|
||||||
|
|
@ -1562,12 +1594,12 @@ include_done:
|
||||||
goto skip;
|
goto skip;
|
||||||
c = expr_preprocess();
|
c = expr_preprocess();
|
||||||
s1->ifdef_stack_ptr[-1] = c;
|
s1->ifdef_stack_ptr[-1] = c;
|
||||||
test_else:
|
test_else:
|
||||||
if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
|
if (s1->ifdef_stack_ptr == file->ifdef_stack_ptr + 1)
|
||||||
file->ifndef_macro = 0;
|
file->ifndef_macro = 0;
|
||||||
test_skip:
|
test_skip:
|
||||||
if (!(c & 1)) {
|
if (!(c & 1)) {
|
||||||
skip:
|
skip:
|
||||||
preprocess_skip();
|
preprocess_skip();
|
||||||
is_bof = 0;
|
is_bof = 0;
|
||||||
goto redo;
|
goto redo;
|
||||||
|
|
@ -1585,11 +1617,11 @@ skip:
|
||||||
/* need to set to zero to avoid false matches if another
|
/* need to set to zero to avoid false matches if another
|
||||||
#ifndef at middle of file */
|
#ifndef at middle of file */
|
||||||
file->ifndef_macro = 0;
|
file->ifndef_macro = 0;
|
||||||
|
while (tok != TOK_LINEFEED)
|
||||||
|
next_nomacro();
|
||||||
tok_flags |= TOK_FLAG_ENDIF;
|
tok_flags |= TOK_FLAG_ENDIF;
|
||||||
|
goto the_end;
|
||||||
}
|
}
|
||||||
next_nomacro();
|
|
||||||
if (tok != TOK_LINEFEED)
|
|
||||||
tcc_warning("Ignoring: %s", get_tok_str(tok, &tokc));
|
|
||||||
break;
|
break;
|
||||||
case TOK_LINE:
|
case TOK_LINE:
|
||||||
next();
|
next();
|
||||||
|
|
@ -1600,7 +1632,8 @@ skip:
|
||||||
if (tok != TOK_LINEFEED) {
|
if (tok != TOK_LINEFEED) {
|
||||||
if (tok != TOK_STR)
|
if (tok != TOK_STR)
|
||||||
tcc_error("#line");
|
tcc_error("#line");
|
||||||
pstrcpy(file->filename, sizeof(file->filename), (char *)tokc.cstr->data);
|
pstrcpy(file->filename, sizeof(file->filename),
|
||||||
|
(char *)tokc.cstr->data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
|
|
@ -1608,161 +1641,24 @@ skip:
|
||||||
c = tok;
|
c = tok;
|
||||||
ch = file->buf_ptr[0];
|
ch = file->buf_ptr[0];
|
||||||
skip_spaces();
|
skip_spaces();
|
||||||
p = buf;
|
q = buf;
|
||||||
while (ch != '\n' && ch != CH_EOF) {
|
while (ch != '\n' && ch != CH_EOF) {
|
||||||
if ((p - buf) < sizeof(buf) - 1)
|
if ((q - buf) < sizeof(buf) - 1)
|
||||||
*p++ = ch;
|
*q++ = ch;
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
if (handle_stray_noerror() == 0)
|
if (handle_stray_noerror() == 0)
|
||||||
--p;
|
--q;
|
||||||
} else
|
} else
|
||||||
inp();
|
inp();
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*q = '\0';
|
||||||
if (c == TOK_ERROR)
|
if (c == TOK_ERROR)
|
||||||
tcc_error("#error %s", buf);
|
tcc_error("#error %s", buf);
|
||||||
else
|
else
|
||||||
tcc_warning("#warning %s", buf);
|
tcc_warning("#warning %s", buf);
|
||||||
break;
|
break;
|
||||||
case TOK_PRAGMA:
|
case TOK_PRAGMA:
|
||||||
next();
|
pragma_parse(s1);
|
||||||
if (tok == TOK_pack && parse_flags & PARSE_FLAG_PACK) {
|
|
||||||
/*
|
|
||||||
This may be:
|
|
||||||
#pragma pack(1) // set
|
|
||||||
#pragma pack() // reset to default
|
|
||||||
#pragma pack(push,1) // push & set
|
|
||||||
#pragma pack(pop) // restore previous
|
|
||||||
*/
|
|
||||||
next();
|
|
||||||
skip('(');
|
|
||||||
if (tok == TOK_ASM_pop) {
|
|
||||||
next();
|
|
||||||
if (s1->pack_stack_ptr <= s1->pack_stack) {
|
|
||||||
stk_error:
|
|
||||||
tcc_error("out of pack stack");
|
|
||||||
}
|
|
||||||
s1->pack_stack_ptr--;
|
|
||||||
} else {
|
|
||||||
int val = 0;
|
|
||||||
if (tok != ')') {
|
|
||||||
if (tok == TOK_ASM_push) {
|
|
||||||
next();
|
|
||||||
s1->pack_stack_ptr++;
|
|
||||||
if (s1->pack_stack_ptr >= s1->pack_stack + PACK_STACK_SIZE)
|
|
||||||
goto stk_error;
|
|
||||||
skip(',');
|
|
||||||
}
|
|
||||||
if (tok != TOK_CINT) {
|
|
||||||
pack_error:
|
|
||||||
tcc_error("invalid pack pragma");
|
|
||||||
}
|
|
||||||
val = tokc.i;
|
|
||||||
if (val < 1 || val > 16)
|
|
||||||
goto pack_error;
|
|
||||||
if (val < 1 || val > 16)
|
|
||||||
tcc_error("Value must be greater than 1 is less than or equal to 16");
|
|
||||||
if ((val & (val - 1)) != 0)
|
|
||||||
tcc_error("Value must be a power of 2 curtain");
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
*s1->pack_stack_ptr = val;
|
|
||||||
skip(')');
|
|
||||||
}
|
|
||||||
}else if (tok == TOK_PUSH_MACRO || tok == TOK_POP_MACRO) {
|
|
||||||
TokenSym *ts;
|
|
||||||
CSym *def;
|
|
||||||
uint8_t *p1;
|
|
||||||
int len, t;
|
|
||||||
t = tok;
|
|
||||||
ch = file->buf_ptr[0];
|
|
||||||
skip_spaces();
|
|
||||||
if (ch != '(')
|
|
||||||
goto macro_xxx_syntax;
|
|
||||||
/* XXX: incorrect if comments : use next_nomacro with a special mode */
|
|
||||||
inp();
|
|
||||||
skip_spaces();
|
|
||||||
if (ch == '\"'){
|
|
||||||
inp();
|
|
||||||
p = buf;
|
|
||||||
while (ch != '\"' && ch != '\n' && ch != CH_EOF) {
|
|
||||||
if ((p - buf) < sizeof(buf) - 1)
|
|
||||||
*p++ = ch;
|
|
||||||
if (ch == CH_EOB) {
|
|
||||||
--p;
|
|
||||||
handle_stray();
|
|
||||||
}else
|
|
||||||
inp();
|
|
||||||
}
|
|
||||||
if(ch != '\"')
|
|
||||||
goto macro_xxx_syntax;
|
|
||||||
*p = '\0';
|
|
||||||
minp();
|
|
||||||
next();
|
|
||||||
}else{
|
|
||||||
/* computed #pragma macro_xxx for #define xxx */
|
|
||||||
next();
|
|
||||||
buf[0] = '\0';
|
|
||||||
while (tok != ')') {
|
|
||||||
if (tok != TOK_STR) {
|
|
||||||
macro_xxx_syntax:
|
|
||||||
tcc_error("'macro_xxx' expects (\"NAME\")");
|
|
||||||
}
|
|
||||||
pstrcat(buf, sizeof(buf), (char *)tokc.cstr->data);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
skip (')');
|
|
||||||
if(!buf[0])
|
|
||||||
tcc_error(" empty string in #pragma");
|
|
||||||
/* find TokenSym */
|
|
||||||
p = buf;
|
|
||||||
while (is_space(*p))
|
|
||||||
p++;
|
|
||||||
p1 = p;
|
|
||||||
for(;;){
|
|
||||||
if (!isidnum_table[p[0] - CH_EOF])
|
|
||||||
break;
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
len = p - p1;
|
|
||||||
while (is_space(*p))
|
|
||||||
p++;
|
|
||||||
if(!p) //'\0'
|
|
||||||
tcc_error("unrecognized string: %s", buf);
|
|
||||||
ts = tok_alloc(p1, len);
|
|
||||||
if(ts){
|
|
||||||
def = &ts->sym_define;
|
|
||||||
if(t == TOK_PUSH_MACRO){
|
|
||||||
void *tmp = def->data[def->off];
|
|
||||||
if(tmp){
|
|
||||||
def->off++;
|
|
||||||
if(def->off >= def->size){
|
|
||||||
int size = def->size;
|
|
||||||
size *= 2;
|
|
||||||
if (size >= MACRO_STACK_SIZE)
|
|
||||||
tcc_error("stack full");
|
|
||||||
def->data = tcc_realloc(def->data, size*sizeof(Sym**));
|
|
||||||
def->size = size;
|
|
||||||
}
|
|
||||||
def->data[def->off] = tmp;
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if(def->off){
|
|
||||||
--def->off;
|
|
||||||
}else{
|
|
||||||
tcc_warning("stack empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
fputs("#pragma ", s1->ppfp);
|
|
||||||
while (tok != TOK_LINEFEED){
|
|
||||||
fputs(get_tok_str(tok, &tokc), s1->ppfp);
|
|
||||||
next();
|
|
||||||
}
|
|
||||||
goto the_end;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
|
if (tok == TOK_LINEFEED || tok == '!' || tok == TOK_PPNUM) {
|
||||||
|
|
@ -1782,7 +1678,7 @@ pack_error:
|
||||||
/* ignore other preprocess commands or #! for C scripts */
|
/* ignore other preprocess commands or #! for C scripts */
|
||||||
while (tok != TOK_LINEFEED)
|
while (tok != TOK_LINEFEED)
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
the_end:
|
the_end:
|
||||||
parse_flags = saved_parse_flags;
|
parse_flags = saved_parse_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3134,13 +3030,12 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
|
||||||
ch = file->buf_ptr[0];
|
ch = file->buf_ptr[0];
|
||||||
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||||
parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
|
parse_flags = PARSE_FLAG_ASM_COMMENTS | PARSE_FLAG_PREPROCESS |
|
||||||
PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
|
PARSE_FLAG_LINEFEED | PARSE_FLAG_SPACES;
|
||||||
token_seen = 0;
|
token_seen = 0;
|
||||||
line_ref = 0;
|
line_ref = 0;
|
||||||
file_ref = NULL;
|
file_ref = NULL;
|
||||||
iptr = s1->include_stack_ptr;
|
iptr = s1->include_stack_ptr;
|
||||||
tok = TOK_LINEFEED; /* print line */
|
|
||||||
goto print_line;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
next();
|
next();
|
||||||
if (tok == TOK_EOF) {
|
if (tok == TOK_EOF) {
|
||||||
|
|
@ -3148,11 +3043,11 @@ ST_FUNC int tcc_preprocess(TCCState *s1)
|
||||||
} else if (file != file_ref) {
|
} else if (file != file_ref) {
|
||||||
goto print_line;
|
goto print_line;
|
||||||
} else if (tok == TOK_LINEFEED) {
|
} else if (tok == TOK_LINEFEED) {
|
||||||
if (token_seen)
|
if (!token_seen)
|
||||||
continue;
|
continue;
|
||||||
++line_ref;
|
++line_ref;
|
||||||
token_seen = 1;
|
token_seen = 0;
|
||||||
} else if (token_seen) {
|
} else if (!token_seen) {
|
||||||
d = file->line_num - line_ref;
|
d = file->line_num - line_ref;
|
||||||
if (file != file_ref || d < 0 || d >= 8) {
|
if (file != file_ref || d < 0 || d >= 8) {
|
||||||
print_line:
|
print_line:
|
||||||
|
|
@ -3160,7 +3055,8 @@ print_line:
|
||||||
s = iptr_new > iptr ? " 1"
|
s = iptr_new > iptr ? " 1"
|
||||||
: iptr_new < iptr ? " 2"
|
: iptr_new < iptr ? " 2"
|
||||||
: iptr_new > s1->include_stack ? " 3"
|
: iptr_new > s1->include_stack ? " 3"
|
||||||
: "";
|
: ""
|
||||||
|
;
|
||||||
iptr = iptr_new;
|
iptr = iptr_new;
|
||||||
fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
|
fprintf(s1->ppfp, "# %d \"%s\"%s\n", file->line_num, file->filename, s);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -3168,8 +3064,8 @@ print_line:
|
||||||
fputs("\n", s1->ppfp), --d;
|
fputs("\n", s1->ppfp), --d;
|
||||||
}
|
}
|
||||||
line_ref = (file_ref = file)->line_num;
|
line_ref = (file_ref = file)->line_num;
|
||||||
token_seen = tok == TOK_LINEFEED;
|
token_seen = tok != TOK_LINEFEED;
|
||||||
if (token_seen)
|
if (!token_seen)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fputs(get_tok_str(tok, &tokc), s1->ppfp);
|
fputs(get_tok_str(tok, &tokc), s1->ppfp);
|
||||||
|
|
|
||||||
4
tcctok.h
4
tcctok.h
|
|
@ -138,8 +138,6 @@
|
||||||
|
|
||||||
/* pragma */
|
/* pragma */
|
||||||
DEF(TOK_pack, "pack")
|
DEF(TOK_pack, "pack")
|
||||||
DEF(TOK_PUSH_MACRO, "push_macro")
|
|
||||||
DEF(TOK_POP_MACRO, "pop_macro")
|
|
||||||
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
|
#if !defined(TCC_TARGET_I386) && !defined(TCC_TARGET_X86_64)
|
||||||
/* already defined for assembler */
|
/* already defined for assembler */
|
||||||
DEF(TOK_ASM_push, "push")
|
DEF(TOK_ASM_push, "push")
|
||||||
|
|
@ -287,5 +285,5 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||||
#include "asmx86-tok.h"
|
#include "i386-tok.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -66,11 +66,11 @@ RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(top_srcdir)/tcc.c $(TCCFLAGS)
|
||||||
DISAS = objdump -d
|
DISAS = objdump -d
|
||||||
|
|
||||||
# libtcc test
|
# libtcc test
|
||||||
ifdef LIBCRT
|
ifdef LIBTCC1
|
||||||
LIBCRT:=$(TOP)/$(LIBCRT)
|
LIBTCC1:=$(TOP)/$(LIBTCC1)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all test : clean $(TESTS)
|
all test : $(TESTS)
|
||||||
|
|
||||||
hello-exe: ../examples/ex1.c
|
hello-exe: ../examples/ex1.c
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
|
|
@ -89,7 +89,7 @@ hello-run: ../examples/ex1.c
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
$(TCC) -run $<
|
$(TCC) -run $<
|
||||||
|
|
||||||
libtest: libtcc_test$(EXESUF) $(LIBCRT)
|
libtest: libtcc_test$(EXESUF) $(LIBTCC1)
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
./libtcc_test$(EXESUF) lib_path=..
|
./libtcc_test$(EXESUF) lib_path=..
|
||||||
|
|
||||||
|
|
@ -101,7 +101,7 @@ moretests:
|
||||||
$(MAKE) -C tests2
|
$(MAKE) -C tests2
|
||||||
|
|
||||||
w32-prep:
|
w32-prep:
|
||||||
cp ../libcrt.a ../lib
|
cp ../libtcc1.a ../lib
|
||||||
|
|
||||||
# test.ref - generate using cc
|
# test.ref - generate using cc
|
||||||
test.ref: tcctest.c
|
test.ref: tcctest.c
|
||||||
|
|
@ -210,14 +210,10 @@ abitest-cc$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC)
|
||||||
abitest-tcc$(EXESUF): abitest.c libtcc.c
|
abitest-tcc$(EXESUF): abitest.c libtcc.c
|
||||||
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) $(LDFLAGS) -I$(top_srcdir)
|
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) $(LDFLAGS) -I$(top_srcdir)
|
||||||
|
|
||||||
abitest-tcc1$(EXESUF): abitest.c $(top_builddir)/$(LIBTCC)
|
abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF)
|
||||||
$(CC) -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(NATIVE_DEFINES) $(LIBS) $(LINK_LIBTCC) $(LDFLAGS) -I$(top_srcdir)
|
|
||||||
|
|
||||||
abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF) abitest-tcc1$(EXESUF)
|
|
||||||
@echo ------------ $@ ------------
|
@echo ------------ $@ ------------
|
||||||
./abitest-cc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
|
./abitest-cc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
|
||||||
./abitest-tcc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
|
./abitest-tcc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
|
||||||
./abitest-tcc1$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
|
|
||||||
|
|
||||||
vla_test$(EXESUF): vla_test.c
|
vla_test$(EXESUF): vla_test.c
|
||||||
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS)
|
$(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS)
|
||||||
|
|
@ -244,6 +240,6 @@ cache: tcc_g
|
||||||
clean:
|
clean:
|
||||||
$(MAKE) -C tests2 $@
|
$(MAKE) -C tests2 $@
|
||||||
rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc \
|
rm -vf *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc \
|
||||||
*-cc *-tcc *.exe *-tcc1\
|
*-cc *-tcc *.exe \
|
||||||
hello libtcc_test vla_test tcctest[1234] ex? tcc_g tcclib.h \
|
hello libtcc_test vla_test tcctest[1234] ex? tcc_g tcclib.h \
|
||||||
../lib/libcrt.a
|
../lib/libtcc1.a
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,7 @@ int main(int argc, char **argv) {
|
||||||
const char *testname = NULL;
|
const char *testname = NULL;
|
||||||
int retval = EXIT_SUCCESS;
|
int retval = EXIT_SUCCESS;
|
||||||
|
|
||||||
/* if tcclib.h and libcrt.a are not installed, where can we find them */
|
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
|
||||||
for (i = 1; i < argc; ++i) {
|
for (i = 1; i < argc; ++i) {
|
||||||
if (!memcmp(argv[i], "lib_path=",9))
|
if (!memcmp(argv[i], "lib_path=",9))
|
||||||
tccdir = argv[i] + 9;
|
tccdir = argv[i] + 9;
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ int main(int argc, char **argv)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if tcclib.h and libcrt.a are not installed, where can we find them */
|
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
|
||||||
if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
|
if (argc == 2 && !memcmp(argv[1], "lib_path=",9))
|
||||||
tcc_set_lib_path(s, argv[1]+9);
|
tcc_set_lib_path(s, argv[1]+9);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ void intdiv_test(void)
|
||||||
|
|
||||||
void macro_test(void)
|
void macro_test(void)
|
||||||
{
|
{
|
||||||
printf("macro:\n");
|
printf("macro:\n");
|
||||||
pf("N=%d\n", N);
|
pf("N=%d\n", N);
|
||||||
printf("aaa=%d\n", AAA);
|
printf("aaa=%d\n", AAA);
|
||||||
|
|
||||||
|
|
@ -379,23 +379,6 @@ comment
|
||||||
/* And again when the name and parenthes are separated by a
|
/* And again when the name and parenthes are separated by a
|
||||||
comment. */
|
comment. */
|
||||||
TEST2 /* the comment */ ();
|
TEST2 /* the comment */ ();
|
||||||
/* macro_push and macro_pop test */
|
|
||||||
#define MACRO_TEST "macro_test1\n"
|
|
||||||
#pragma push_macro("MACRO_TEST")
|
|
||||||
#undef MACRO_TEST
|
|
||||||
#define MACRO_TEST "macro_test2\n"
|
|
||||||
printf(MACRO_TEST);
|
|
||||||
#pragma pop_macro("MACRO_TEST")
|
|
||||||
printf(MACRO_TEST);
|
|
||||||
/* gcc does not support
|
|
||||||
#define MACRO_TEST_MACRO "MACRO_TEST"
|
|
||||||
#pragma push_macro(MACRO_TEST_MACRO)
|
|
||||||
#undef MACRO_TEST
|
|
||||||
#define MACRO_TEST "macro_test3\n"
|
|
||||||
printf(MACRO_TEST);
|
|
||||||
#pragma pop_macro(MACRO_TEST_MACRO)
|
|
||||||
printf(MACRO_TEST);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1697,6 +1680,7 @@ void prefix ## fcast(type a)\
|
||||||
printf("ftof: %f %f %Lf\n", fa, da, la);\
|
printf("ftof: %f %f %Lf\n", fa, da, la);\
|
||||||
ia = (int)a;\
|
ia = (int)a;\
|
||||||
llia = (long long)a;\
|
llia = (long long)a;\
|
||||||
|
a = (a >= 0) ? a : -a;\
|
||||||
ua = (unsigned int)a;\
|
ua = (unsigned int)a;\
|
||||||
llua = (unsigned long long)a;\
|
llua = (unsigned long long)a;\
|
||||||
printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
|
printf("ftoi: %d %u %lld %llu\n", ia, ua, llia, llua);\
|
||||||
|
|
@ -1726,18 +1710,6 @@ void prefix ## call(void)\
|
||||||
printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
|
printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\
|
||||||
}\
|
}\
|
||||||
\
|
\
|
||||||
void prefix ## calc(type x, type y)\
|
|
||||||
{\
|
|
||||||
x=x*x;y=y*y;\
|
|
||||||
printf("%d, %d\n", (int)x, (int)y);\
|
|
||||||
x=x-y;y=y-x;\
|
|
||||||
printf("%d, %d\n", (int)x, (int)y);\
|
|
||||||
x=x/y;y=y/x;\
|
|
||||||
printf("%d, %d\n", (int)x, (int)y);\
|
|
||||||
x=x+x;y=y+y;\
|
|
||||||
printf("%d, %d\n", (int)x, (int)y);\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
void prefix ## signed_zeros(void) \
|
void prefix ## signed_zeros(void) \
|
||||||
{\
|
{\
|
||||||
type x = 0.0, y = -0.0, n, p;\
|
type x = 0.0, y = -0.0, n, p;\
|
||||||
|
|
@ -1760,7 +1732,7 @@ void prefix ## signed_zeros(void) \
|
||||||
1.0 / x != 1.0 / p);\
|
1.0 / x != 1.0 / p);\
|
||||||
else\
|
else\
|
||||||
printf ("x != +y; this is wrong!\n");\
|
printf ("x != +y; this is wrong!\n");\
|
||||||
p = -y;\
|
p = -y;\
|
||||||
if (x == p)\
|
if (x == p)\
|
||||||
printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
|
printf ("Test 1.0 / x != 1.0 / -y returns %d (should be 0).\n",\
|
||||||
1.0 / x != 1.0 / p);\
|
1.0 / x != 1.0 / p);\
|
||||||
|
|
@ -1776,8 +1748,7 @@ void prefix ## test(void)\
|
||||||
prefix ## fcast(234.6);\
|
prefix ## fcast(234.6);\
|
||||||
prefix ## fcast(-2334.6);\
|
prefix ## fcast(-2334.6);\
|
||||||
prefix ## call();\
|
prefix ## call();\
|
||||||
prefix ## calc(1, 1.0000000000000001);\
|
prefix ## signed_zeros();\
|
||||||
prefix ## signed_zeros();\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FTEST(f, float, float, "%f")
|
FTEST(f, float, float, "%f")
|
||||||
|
|
@ -2184,15 +2155,14 @@ void whitespace_test(void)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
|
#if 1
|
||||||
#if 1
|
|
||||||
pri\
|
pri\
|
||||||
ntf("whitspace:\n");
|
ntf("whitspace:\n");
|
||||||
#endif
|
#endif
|
||||||
pf("N=%d\n", 2);
|
pf("N=%d\n", 2);
|
||||||
|
|
||||||
#ifdef CORRECT_CR_HANDLING
|
#ifdef CORRECT_CR_HANDLING
|
||||||
pri\
|
pri\
|
||||||
ntf("aaa=%d\n", 3);
|
ntf("aaa=%d\n", 3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -2204,12 +2174,11 @@ ntf("min=%d\n", 4);
|
||||||
printf("len1=%d\n", strlen("
|
printf("len1=%d\n", strlen("
|
||||||
"));
|
"));
|
||||||
#ifdef CORRECT_CR_HANDLING
|
#ifdef CORRECT_CR_HANDLING
|
||||||
str = "
|
str = "
|
||||||
";
|
";
|
||||||
printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
|
printf("len1=%d str[0]=%d\n", strlen(str), str[0]);
|
||||||
#endif
|
#endif
|
||||||
printf("len1=%d\n", strlen("
|
printf("len1=%d\n", strlen("
a
|
||||||
a
|
|
||||||
"));
|
"));
|
||||||
#endif /* ACCEPT_CR_IN_STRINGS */
|
#endif /* ACCEPT_CR_IN_STRINGS */
|
||||||
}
|
}
|
||||||
|
|
@ -2603,6 +2572,7 @@ int constant_p_var;
|
||||||
|
|
||||||
void builtin_test(void)
|
void builtin_test(void)
|
||||||
{
|
{
|
||||||
|
#if GCC_MAJOR >= 3
|
||||||
COMPAT_TYPE(int, int);
|
COMPAT_TYPE(int, int);
|
||||||
COMPAT_TYPE(int, unsigned int);
|
COMPAT_TYPE(int, unsigned int);
|
||||||
COMPAT_TYPE(int, char);
|
COMPAT_TYPE(int, char);
|
||||||
|
|
@ -2612,9 +2582,9 @@ void builtin_test(void)
|
||||||
COMPAT_TYPE(int *, void *);
|
COMPAT_TYPE(int *, void *);
|
||||||
COMPAT_TYPE(int *, const int *);
|
COMPAT_TYPE(int *, const int *);
|
||||||
COMPAT_TYPE(char *, unsigned char *);
|
COMPAT_TYPE(char *, unsigned char *);
|
||||||
COMPAT_TYPE(char, unsigned char);
|
|
||||||
/* space is needed because tcc preprocessor introduces a space between each token */
|
/* space is needed because tcc preprocessor introduces a space between each token */
|
||||||
COMPAT_TYPE(char **, void *);
|
COMPAT_TYPE(char * *, void *);
|
||||||
|
#endif
|
||||||
printf("res = %d\n", __builtin_constant_p(1));
|
printf("res = %d\n", __builtin_constant_p(1));
|
||||||
printf("res = %d\n", __builtin_constant_p(1 + 2));
|
printf("res = %d\n", __builtin_constant_p(1 + 2));
|
||||||
printf("res = %d\n", __builtin_constant_p(&constant_p_var));
|
printf("res = %d\n", __builtin_constant_p(&constant_p_var));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* This program is for making libcrt.a without ar
|
* This program is for making libtcc1.a without ar
|
||||||
* tiny_libmaker - tiny elf lib maker
|
* tiny_libmaker - tiny elf lib maker
|
||||||
* usage: tiny_libmaker [lib] files...
|
* usage: tiny_libmaker [lib] files...
|
||||||
* Copyright (c) 2007 Timppa
|
* Copyright (c) 2007 Timppa
|
||||||
|
|
|
||||||
1378
x86_64-gen.c
1378
x86_64-gen.c
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue