Browse Source

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!
mob/mob_pipcet/mixed-structs
jiang 10 years ago
parent
commit
5e56fb635a
  1. 58
      Makefile
  2. 93
      arm-gen.c
  3. 44
      c67-gen.c
  4. 41
      i386-asm.c
  5. 190
      i386-gen.c
  6. 0
      i386-tok.h
  7. 15
      il-gen.c
  8. 16
      lib/Makefile
  9. 44
      lib/libtcc1.c
  10. 10
      libtcc.c
  11. 40
      tcc.h
  12. 49
      tccasm.c
  13. 12
      tccelf.c
  14. 850
      tccgen.c
  15. 2
      tccpe.c
  16. 302
      tccpp.c
  17. 4
      tcctok.h
  18. 20
      tests/Makefile
  19. 2
      tests/abitest.c
  20. 2
      tests/libtcc_test.c
  21. 54
      tests/tcctest.c
  22. 2
      win32/tools/tiny_libmaker.c
  23. 1376
      x86_64-gen.c

58
Makefile

@ -22,7 +22,7 @@ endif
endif
else # not GCC
ifeq (-$(findstring clang,$(CC))-,-clang-)
# make clang accept gnuisms in libcrt.c
# make clang accept gnuisms in libtcc1.c
CFLAGS+=-fheinous-gnu-extensions
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.h config.h libtcc.h tcctok.h
I386_FILES = $(CORE_FILES) i386-gen.c asmx86.c i386-asm.h asmx86-tok.h
WIN32_FILES = $(CORE_FILES) i386-gen.c asmx86.c i386-asm.h asmx86-tok.h tccpe.c
WIN64_FILES = $(CORE_FILES) x86_64-gen.c asmx86.c x86_64-asm.h tccpe.c
I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h
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 i386-asm.c x86_64-asm.h 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
C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
@ -113,29 +113,29 @@ ifdef CONFIG_WIN64
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
NATIVE_FILES=$(WIN64_FILES)
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
LIBTCC1_CROSS=lib/i386-win32/libcrt.a
LIBCRT=libcrt.a
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a
LIBTCC1=libtcc1.a
else ifdef CONFIG_WIN32
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
NATIVE_FILES=$(WIN32_FILES)
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(C67_CROSS)
LIBTCC1_CROSS=lib/x86_64-win32/libcrt.a
LIBCRT=libcrt.a
LIBTCC1_CROSS=lib/x86_64-win32/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),i386)
NATIVE_FILES=$(I386_FILES)
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
LIBCRT=libcrt.a
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),x86-64)
NATIVE_FILES=$(X86_64_FILES)
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
LIBCRT=libcrt.a
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a lib/i386/libtcc1.a
LIBTCC1=libtcc1.a
else ifeq ($(ARCH),arm)
NATIVE_FILES=$(ARM_FILES)
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(C67_CROSS)
LIBCRT=libcrt.a
LIBTCC1_CROSS=lib/i386-win32/libcrt.a lib/x86_64-win32/libcrt.a lib/i386/libcrt.a
LIBTCC1=libtcc1.a
LIBTCC1_CROSS=lib/i386-win32/libtcc1.a lib/x86_64-win32/libtcc1.a lib/i386/libtcc1.a
endif
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
@ -143,7 +143,7 @@ ifeq ($(TARGETOS),Darwin)
PROGS+=tiny_libmaker$(EXESUF)
endif
TCCLIBS = $(LIBCRT) $(LIBTCC) $(LIBTCC_EXTRA)
TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCC_EXTRA)
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
ifdef CONFIG_CROSS
@ -225,9 +225,9 @@ tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
# TinyCC runtime libraries
libcrt.a : FORCE
libtcc1.a : FORCE
$(MAKE) -C lib native
lib/%/libcrt.a : FORCE $(PROGS_CROSS)
lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
$(MAKE) -C lib cross TARGET=$*
FORCE:
@ -258,8 +258,8 @@ endif
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
mkdir -p "$(tccdir)"
mkdir -p "$(tccdir)/include"
ifneq ($(LIBCRT),)
$(INSTALL) -m644 $(LIBCRT) "$(tccdir)"
ifneq ($(LIBTCC1),)
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)"
endif
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
mkdir -p "$(libdir)"
@ -277,19 +277,19 @@ ifdef CONFIG_CROSS
mkdir -p "$(tccdir)/win32/lib/64"
ifneq ($(ARCH),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"
endif
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
$(INSTALL) -m644 lib/i386-win32/libcrt.a "$(tccdir)/win32/lib/32"
$(INSTALL) -m644 lib/x86_64-win32/libcrt.a "$(tccdir)/win32/lib/64"
$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/win32/lib/32"
$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/win32/lib/64"
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
cp -r "$(tccdir)/include" "$(tccdir)/win32"
endif
uninstall:
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 "$(tccdir)/include/tcclib.h"
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)/libtcc"
$(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/examples/. "$(tccdir)/examples"
$(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
mkdir -p "$(tccdir)/lib/32"
mkdir -p "$(tccdir)/lib/64"
-$(INSTALL) -m644 lib/i386-win32/libcrt.a "$(tccdir)/lib/32"
-$(INSTALL) -m644 lib/x86_64-win32/libcrt.a "$(tccdir)/lib/64"
-$(INSTALL) -m644 lib/i386-win32/libtcc1.a "$(tccdir)/lib/32"
-$(INSTALL) -m644 lib/x86_64-win32/libtcc1.a "$(tccdir)/lib/64"
endif
uninstall:
@ -340,7 +340,7 @@ tcc-doc.info: tcc-doc.texi
-makeinfo $<
# in tests subdir
export LIBCRT
export LIBTCC1
%est:
$(MAKE) -C tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
@ -348,7 +348,7 @@ export LIBCRT
clean:
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.exe libtcc_test$(EXESUF)
$(MAKE) -C tests $@
ifneq ($(LIBCRT),)
ifneq ($(LIBTCC1),)
$(MAKE) -C lib $@
endif

93
arm-gen.c

@ -61,7 +61,7 @@
#define RC_IRET RC_R0 /* function return: integer register */
#define RC_LRET RC_R1 /* function return: second integer register */
#define RC_FRET RC_F0 /* function return: float register */
#define RC_MASK (RC_INT|RC_FLOAT)
/* pretty names for the registers */
enum {
TREG_R0 = 0,
@ -540,14 +540,6 @@ void load(int r, SValue *sv)
v = fr & VT_VALMASK;
if (fr & VT_LVAL) {
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) {
v1.type.t = VT_PTR;
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 */
int gtst(int inv, int t)
{
int v, r;
uint32_t op;
v = vtop->r & VT_VALMASK;
r=ind;
if (v == VT_CMP) {
op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
op|=encbranch(r,t,1);
o(op);
t=r;
} else if (v == VT_JMP || v == VT_JMPI) {
if ((v & 1) == inv) {
if(!vtop->c.i)
vtop->c.i=t;
else {
uint32_t *x;
int p,lp;
if(t) {
p = vtop->c.i;
do {
p = decbranch(lp=p);
} while(p);
x = (uint32_t *)(cur_text_section->data + lp);
*x &= 0xff000000;
*x |= encbranch(lp,t,1);
}
t = vtop->c.i;
}
} else {
t = gjmp(t);
gsym(vtop->c.i);
int v, r;
uint32_t op;
v = vtop->r & VT_VALMASK;
r=ind;
if (v == VT_CMP) {
op=mapcc(inv?negcc(vtop->c.i):vtop->c.i);
op|=encbranch(r,t,1);
o(op);
t=r;
} else { /* VT_JMP || VT_JMPI */
if ((v & 1) == inv) {
if(!vtop->c.i)
vtop->c.i=t;
else {
uint32_t *x;
int p,lp;
if(t) {
p = vtop->c.i;
do {
p = decbranch(lp=p);
} while(p);
x = (uint32_t *)(cur_text_section->data + lp);
*x &= 0xff000000;
*x |= encbranch(lp,t,1);
}
t = vtop->c.i;
}
} else {
t = gjmp(t);
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--;
return t;

44
c67-gen.c

@ -58,7 +58,7 @@
#define RC_IRET RC_C67_A4 /* function return: 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_MASK (RC_INT|RC_FLOAT)
/* pretty names for the registers */
enum {
TREG_EAX = 0, // really A2
@ -1571,21 +1571,12 @@ void load(int r, SValue * sv)
v = fr & VT_VALMASK;
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) {
v1.type.t = VT_INT;
v1.r = VT_LOCAL | VT_LVAL;
v1.c.ul = fc;
load(r, &v1);
fr = r;
fc = 0;
} else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
tcc_error("long double not supported");
} else if ((ft & VT_TYPE) == VT_BYTE) {
@ -2111,7 +2102,7 @@ int gtst(int inv, int t)
C67_NOP(5);
t = ind1; //return where we need to patch
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -2137,37 +2128,6 @@ int gtst(int inv, int t)
t = gjmp(t);
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--;
return t;

41
asmx86.c → i386-asm.c

@ -239,36 +239,6 @@ static const uint16_t op0_codes[] = {
#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)
{
int shift, v;
@ -746,8 +716,9 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
g(b >> 8);
g(b);
return;
} else if (opcode <= TOK_ASM_alllast) {
tcc_error("bad operand with opcode '%s'", get_tok_str(opcode, NULL));
} else if (opcode <= TOK_ASM_alllast) {
tcc_error("bad operand with opcode '%s'",
get_tok_str(opcode, NULL));
} else {
tcc_error("unknown opcode '%s'",
get_tok_str(opcode, NULL));
@ -1098,7 +1069,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands,
uint8_t regs_allocated[NB_ASM_REGS];
/* init fields */
for(i=0; i<nb_operands; i++) {
for(i=0;i<nb_operands;i++) {
op = &operands[i];
op->input_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
constraints if input constraints */
for(i=0; i<nb_operands; i++) {
for(i=0;i<nb_operands;i++) {
op = &operands[i];
str = op->constraint;
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);
}
clobber_regs[reg] = 1;
}
}

190
i386-gen.c

@ -21,7 +21,7 @@
#ifdef TARGET_DEFS_ONLY
/* number of available registers */
#define NB_REGS 8
#define NB_REGS 4
#define NB_ASM_REGS 8
/* a register can belong to several classes. The classes must be
@ -33,24 +33,17 @@
#define RC_ST0 0x0008
#define RC_ECX 0x0010
#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_LRET RC_EDX /* function return: second integer register */
#define RC_FRET RC_ST0 /* function return: float register */
#define RC_MASK (RC_INT|RC_INT2|RC_FLOAT)
/* pretty names for the registers */
enum {
TREG_EAX = 0,
TREG_ECX,
TREG_EDX,
TREG_EBX,
TREG_ESP,
TREG_ST0,
TREG_ESI,
TREG_EDI,
TREG_ESP = 4
};
/* return registers for function */
@ -97,14 +90,10 @@ enum {
#include "tcc.h"
ST_DATA const int reg_classes[NB_REGS] = {
/* eax */ RC_INT | RC_EAX | RC_INT2,
/* ecx */ RC_INT | RC_ECX | RC_INT2,
/* eax */ RC_INT | RC_EAX,
/* ecx */ RC_INT | RC_ECX,
/* edx */ RC_INT | RC_EDX,
RC_INT|RC_INT2|RC_EBX,
0,
/* st0 */ RC_FLOAT | RC_ST0,
RC_ESI|RC_INT2,
RC_EDI|RC_INT2,
};
static unsigned long func_sub_sp_offset;
@ -237,14 +226,6 @@ ST_FUNC void load(int r, SValue *sv)
v = fr & VT_VALMASK;
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) {
v1.type.t = VT_INT;
v1.r = VT_LOCAL | VT_LVAL;
@ -253,7 +234,6 @@ ST_FUNC void load(int r, SValue *sv)
if (!(reg_classes[fr] & RC_INT))
fr = get_reg(RC_INT);
load(fr, &v1);
fc = 0;
}
if ((ft & VT_BTYPE) == VT_FLOAT) {
o(0xd9); /* flds */
@ -697,7 +677,7 @@ ST_FUNC int gtst(int inv, int t)
/* fast case : can jump directly since flags are set */
g(0x0f);
t = psym((vtop->c.i - 16) ^ inv, t);
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -710,23 +690,6 @@ ST_FUNC int gtst(int inv, int t)
t = gjmp(t);
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--;
return t;
@ -735,48 +698,40 @@ ST_FUNC int gtst(int inv, int t)
/* generate an integer binary operation */
ST_FUNC void gen_opi(int op)
{
int r, fr, opc, fc, 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;
int r, fr, opc, c;
switch(op) {
case '+':
case TOK_ADDC1: /* add with carry generation */
opc = 0;
gen_op8:
vswap();
r = gv(RC_INT);
vswap();
if (cc) {
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
/* constant case */
vswap();
r = gv(RC_INT);
vswap();
c = vtop->c.i;
if (c == (char)c) {
/* generate inc and dec for smaller code */
if (c == 1 && opc == 0) {
if (c==1 && opc==0) {
o (0x40 | r); // inc
} else if (c == 1 && opc == 5) {
} else if (c==1 && opc==5) {
o (0x48 | r); // dec
} else {
o(0x83);
o(0xc0 + r + opc*8);
o(0xc0 | (opc << 3) | r);
g(c);
}
} else {
o(0x81);
oad(0xc0 + r+ opc*8, c);
oad(0xc0 | (opc << 3) | r, c);
}
} else {
if(!tt2)
fr = gv(RC_INT);
o(0x03 + opc*8);
if(fr >= VT_CONST)
gen_modrm(r, fr, vtop->sym, fc);
else
o(0xc0 + fr + r*8);
gv2(RC_INT, RC_INT);
r = vtop[-1].r;
fr = vtop[0].r;
o((opc << 3) | 0x01);
o(0xc0 + r + fr * 8);
}
vtop--;
if (op >= TOK_ULT && op <= TOK_GT) {
@ -804,28 +759,12 @@ ST_FUNC void gen_opi(int op)
opc = 1;
goto gen_op8;
case '*':
opc = 5;
vswap();
r = gv(RC_INT);
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);
}
gv2(RC_INT, RC_INT);
r = vtop[-1].r;
fr = vtop[0].r;
vtop--;
o(0xaf0f); /* imul fr, r */
o(0xc0 + fr + r * 8);
break;
case TOK_SHL:
opc = 4;
@ -836,71 +775,56 @@ ST_FUNC void gen_opi(int op)
case TOK_SAR:
opc = 7;
gen_shift:
if (cc) {
opc = 0xc0 | (opc << 3);
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
/* constant case */
vswap();
r = gv(RC_INT);
vswap();
c = vtop->c.i;
if(c == 1){
o(0xd1);
o(0xc0 + r + opc*8);
}else{
o(0xc1); /* shl/shr/sar $xxx, r */
o(0xc0 + r + opc*8);
g(c & 0x1f);
}
c = vtop->c.i & 0x1f;
o(0xc1); /* shl/shr/sar $xxx, r */
o(opc | r);
g(c);
} else {
/* we generate the shift in ecx */
gv2(RC_INT, RC_ECX);
r = vtop[-1].r;
o(0xd3); /* shl/shr/sar %cl, r */
o(0xc0 + r + opc*8);
o(opc | r);
}
vtop--;
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 TOK_UDIV:
case TOK_PDIV:
opc = 7;
uu = 0;
divmod:
case '%':
case TOK_UMOD:
case TOK_UMULL:
/* first operand must be in eax */
/* XXX: need better constraint for second operand */
if(!tt2){
gv2(RC_EAX, RC_INT2);
fr = vtop[0].r;
}else{
vswap();
gv(RC_EAX);
vswap();
}
save_reg(TREG_EDX);
if (op == TOK_UMULL) {
gv2(RC_EAX, RC_ECX);
r = vtop[-1].r;
fr = vtop[0].r;
vtop--;
save_reg(TREG_EDX);
if (op == TOK_UMULL) {
o(0xf7); /* mul fr */
vtop->r2 = TREG_EDX;
}else{
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
o(0xe0 + fr);
vtop->r2 = TREG_EDX;
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;
break;
default:

0
asmx86-tok.h → i386-tok.h

15
il-gen.c

@ -516,7 +516,7 @@ int gtst(int inv, int t)
break;
}
t = out_opj(c, t);
} else if (v == VT_JMP || v == VT_JMPI) {
} else { /* VT_JMP || VT_JMPI */
/* && or || optimization */
if ((v & 1) == inv) {
/* insert vtop->c jump list in t */
@ -529,19 +529,6 @@ int gtst(int inv, int t)
t = gjmp(t);
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--;
return t;

16
lib/Makefile

@ -1,5 +1,5 @@
#
# Tiny C Compiler Makefile for libcrt.a
# Tiny C Compiler Makefile for libtcc1.a
#
TOP = ..
@ -38,15 +38,15 @@ endif
DIR = $(TARGET)
native : ../libcrt.a
cross : $(DIR)/libcrt.a
native : ../libtcc1.a
cross : $(DIR)/libtcc1.a
native : TCC = $(TOP)/tcc$(EXESUF)
cross : TCC = $(TOP)/$(TARGET)-tcc$(EXESUF)
I386_O = libcrt.o alloca86.o alloca86-bt.o $(BCHECK_O)
X86_64_O = libcrt.o alloca86_64.o
ARM_O = libcrt.o armeabi.o alloca-arm.o
I386_O = libtcc1.o alloca86.o alloca86-bt.o $(BCHECK_O)
X86_64_O = libtcc1.o alloca86_64.o
ARM_O = libtcc1.o armeabi.o alloca-arm.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
@ -83,7 +83,7 @@ ifeq "$(TARGET)" "arm"
TGT = -DTCC_TARGET_ARM
XCC ?= $(TCC) -B$(TOP)
else
$(error libcrt.a not supported on target '$(TARGET)')
$(error libtcc1.a not supported on target '$(TARGET)')
endif
endif
endif
@ -102,7 +102,7 @@ ifdef XAR
AR = $(XAR)
endif
$(DIR)/libcrt.a ../libcrt.a : $(OBJ) $(XAR)
$(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
$(AR) rcs $@ $(OBJ)
$(DIR)/%.o : %.c
$(XCC) -c $< -o $@ $(XFLAGS)

44
lib/libcrt.c → lib/libtcc1.c

@ -533,24 +533,23 @@ unsigned long long __fixunssfdi (float a1)
register union float_long fl1;
register int exp;
register unsigned long l;
int s;
fl1.f = a1;
if (fl1.l == 0)
return 0;
return (0);
exp = EXP (fl1.l) - EXCESS - 24;
l = MANT(fl1.l);
s = SIGN(fl1.l)? -1: 1;
if (exp >= 64)
if (exp >= 41)
return (unsigned long long)-1;
else if (exp >= 0)
return ((unsigned long long)l << exp)*s;
return (unsigned long long)l << exp;
else if (exp >= -23)
return (l >> -exp)*s;
return l >> -exp;
else
return 0;
return 0;
}
unsigned long long __fixunsdfdi (double a1)
@ -558,7 +557,7 @@ unsigned long long __fixunsdfdi (double a1)
register union double_long dl1;
register int exp;
register unsigned long long l;
int s;
dl1.d = a1;
if (dl1.ll == 0)
@ -567,15 +566,15 @@ unsigned long long __fixunsdfdi (double a1)
exp = EXPD (dl1) - EXCESSD - 53;
l = MANTD_LL(dl1);
s = SIGND(dl1)? -1: 1;
if (exp >= 64)
if (exp >= 12)
return (unsigned long long)-1;
else if (exp >= 0)
return (l << exp)*s;
return l << exp;
else if (exp >= -52)
return (l >> -exp)*s;
return l >> -exp;
else
return 0;
return 0;
}
unsigned long long __fixunsxfdi (long double a1)
@ -583,24 +582,22 @@ unsigned long long __fixunsxfdi (long double a1)
register union ldouble_long dl1;
register int exp;
register unsigned long long l;
int s;
dl1.ld = a1;
if (dl1.l.lower == 0 && dl1.l.upper == 0)
return (0);
exp = EXPLD (dl1) - EXCESSLD - 64;
s = SIGNLD(dl1)? -1: 1;
l = dl1.l.lower;
if (exp >= 64)
if (exp > 0)
return (unsigned long long)-1;
else if (exp >= 0)
return ((unsigned long long)l << exp)*s;
else if (exp >= -64)
return (l >> -exp)*s;
else if (exp >= -63)
return l >> -exp;
else
return 0;
return 0;
}
long long __fixsfdi (float a1)
@ -640,7 +637,7 @@ extern void abort(void);
#endif
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
@ -691,11 +688,10 @@ void *__va_arg(__va_list_struct *ap,
size = 8;
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:
use_overflow_area:
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;
default:

10
libtcc.c

@ -52,10 +52,10 @@ ST_DATA struct TCCState *tcc_state;
#include "x86_64-gen.c"
#endif
#ifdef CONFIG_TCC_ASM
#include "tccasm.c"
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
#include "asmx86.c"
#include "i386-asm.c"
#endif
#include "tccasm.c"
#endif
#ifdef TCC_TARGET_COFF
#include "tcccoff.c"
@ -868,7 +868,6 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
static void tcc_cleanup(void)
{
int i, n;
CSym *def;
if (NULL == tcc_state)
return;
tcc_state = NULL;
@ -878,11 +877,8 @@ static void tcc_cleanup(void)
/* free tokens */
n = tok_ident - TOK_IDENT;
for(i = 0; i < n; i++){
def = &table_ident[i]->sym_define;
tcc_free(def->data);
for(i = 0; i < n; i++)
tcc_free(table_ident[i]);
}
tcc_free(table_ident);
/* free sym_pools */

40
tcc.h

@ -39,7 +39,6 @@
#include <fcntl.h>
#include <setjmp.h>
#include <time.h>
#include <assert.h>
#ifdef CONFIG_TCCASSERT
#include <assert.h>
@ -148,7 +147,6 @@
/* #define MEM_DEBUG */
/* assembler debug */
/* #define ASM_DEBUG */
/* #define PRINTF_ASM_CODE */
/* target selection */
/* #define TCC_TARGET_I386 *//* i386 code generator */
@ -276,7 +274,7 @@
# define DEFAULT_ELFINTERP(s) default_elfinterp(s)
#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"
/* -------------------------------------------- */
@ -305,22 +303,15 @@
#define VSTACK_SIZE 256
#define STRING_MAX_SIZE 1024
#define PACK_STACK_SIZE 8
#define MACRO_STACK_SIZE 4
#define TOK_HASH_SIZE 8192 /* 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 */
typedef struct CSym {
int off;
int size;/* size in *sym */
struct Sym **data; /* if non NULL, data has been malloced */
} CSym;
/* token symbol management */
typedef struct TokenSym {
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_struct; /* direct pointer to structure */
struct Sym *sym_identifier; /* direct pointer to identifier */
@ -366,8 +357,8 @@ typedef union CValue {
/* value on stack */
typedef struct SValue {
CType type; /* type */
unsigned int r; /* register + flags */
unsigned int r2; /* second register, used for 'long long'
unsigned short r; /* register + flags */
unsigned short r2; /* second register, used for 'long long'
type. If not used, set to VT_CONST */
CValue c; /* constant, if 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_JMP 0x0034 /* value is the consequence of jmp true (even) */
#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 0x0080 /* value is pointer to structure rather than address */
#define VT_REF 0x0040 /* value is pointer to structure rather than address */
#define VT_LVAL 0x0100 /* var is an lvalue */
#define VT_SYM 0x0200 /* a symbol value is added */
#define VT_MUSTCAST 0x0400 /* value must be casted to be correct (used for
char/short stored in integer registers) */
#define VT_MUSTBOUND 0x0800 /* bound checking must be done before
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_SHORT 0x2000 /* lvalue is a short */
#define VT_LVAL_UNSIGNED 0x4000 /* lvalue is 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 */
#define VT_BTYPE 0x000f /* mask for basic type */
@ -789,7 +778,6 @@ struct TCCState {
#define VT_VOLATILE 0x1000 /* volatile modifier */
#define VT_DEFSIGN 0x2000 /* signed type */
#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 */
#define VT_EXTERN 0x00000080 /* extern definition */
@ -800,14 +788,14 @@ struct TCCState {
#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
#define VT_WEAK 0x00010000 /* weak symbol */
#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
have linkage and hence never have
visibility. */
#define VT_VIS_SIZE 2 /* We have four visibilities. */
#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) */
@ -1136,8 +1124,7 @@ ST_DATA TokenSym **table_ident;
token. line feed is also
returned at eof */
#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_PACK 0x0020 /* #pragma pack */
#define PARSE_FLAG_SPACES 0x0010 /* next() returns space tokens (for -E) */
ST_FUNC TokenSym *tok_alloc(const char *str, int len);
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 SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop;
#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 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 last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA char *funcname;
ST_DATA int pop_stack;
ST_INLN int is_float(int t);
ST_FUNC int ieee_finite(double d);
ST_FUNC void test_lvalue(void);
ST_FUNC void swap(int *p, int *q);
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 void vset(CType *type, int r, int v);
ST_FUNC void vswap(void);
@ -1246,9 +1231,6 @@ ST_FUNC void gexpr(void);
ST_FUNC int expr_const(void);
ST_FUNC void gen_inline_functions(void);
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
ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsigned long size);
#endif

49
tccasm.c

@ -20,6 +20,7 @@
#include "tcc.h"
#ifdef CONFIG_TCC_ASM
ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
{
char buf[64];
@ -482,7 +483,7 @@ static void asm_parse_directive(TCCState *s1)
case TOK_ASM_globl:
case TOK_ASM_global:
case TOK_ASM_weak:
case TOK_ASM_hidden:
case TOK_ASM_hidden:
tok1 = tok;
do {
Sym *sym;
@ -493,12 +494,12 @@ static void asm_parse_directive(TCCState *s1)
sym = label_push(&s1->asm_labels, tok, 0);
sym->type.t = VT_VOID;
}
if (tok1 != TOK_ASM_hidden)
if (tok1 != TOK_ASM_hidden)
sym->type.t &= ~VT_STATIC;
if (tok1 == TOK_ASM_weak)
sym->type.t |= VT_WEAK;
else if (tok1 == TOK_ASM_hidden)
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
else if (tok1 == TOK_ASM_hidden)
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
next();
} while (tok == ',');
break;
@ -696,15 +697,42 @@ static void asm_parse_directive(TCCState *s1)
}
}
/* assemble a file */
static int tcc_assemble_internal(TCCState *s1, int do_preprocess)
{
int opcode;
#ifdef PRINTF_ASM_CODE
ST_FUNC void printf_asm_opcode();
#if 0
/* 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
/* 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
symbols can be safely used */
put_elf_sym(symtab_section, 0, 0, ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
SHN_ABS, file->filename);
put_elf_sym(symtab_section, 0, 0,
ELFW(ST_INFO)(STB_LOCAL, STT_FILE), 0,
SHN_ABS, file->filename);
ret = tcc_assemble_internal(s1, do_preprocess);
@ -1090,4 +1119,4 @@ ST_FUNC void asm_global_instr(void)
cstr_free(&astr);
}
#endif /* CONFIG_TCC_ASM */
#endif /* CONFIG_TCC_ASM */

12
tccelf.c

@ -1443,16 +1443,16 @@ ST_FUNC void tcc_add_runtime(TCCState *s1)
#ifdef CONFIG_USE_LIBGCC
if (!s1->static_link) {
tcc_add_file(s1, TCC_LIBGCC);
tcc_add_support(s1, "libcrt.a");
tcc_add_support(s1, "libtcc1.a");
} else
tcc_add_support(s1, "libcrt.a");
tcc_add_support(s1, "libtcc1.a");
#else
tcc_add_support(s1, "libcrt.a");
tcc_add_support(s1, "libtcc1.a");
#endif
}
/* 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. */
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);
}
/* Perform relocation to GOT or PLT entries */
/* Perform relocation to GOT or PLT entries */
ST_FUNC void fill_got(TCCState *s1)
{
Section *s;
@ -2469,7 +2469,7 @@ static int elf_output_file(TCCState *s1, const char *filename)
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)
fill_got(s1);

850
tccgen.c

File diff suppressed because it is too large

2
tccpe.c

@ -1773,7 +1773,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
if (0 == s1->nostdlib) {
static const char *libs[] = {
"libcrt.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
"libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
};
const char **pp, *p;
for (pp = libs; 0 != (p = *pp); ++pp) {

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);
table_ident[i] = ts;
ts->tok = tok_ident++;
ts->sym_define.data = tcc_malloc(sizeof(Sym**));
ts->sym_define.off = 0;
ts->sym_define.data[0] = NULL;
ts->sym_define.size = 1;
ts->sym_define = NULL;
ts->sym_label = NULL;
ts->sym_struct = 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)
{
Sym *s;
CSym *def;
s = define_find(v);
if (s && !macro_is_equal(s->d, str))
tcc_warning("%s redefined", get_tok_str(v, NULL));
s = sym_push2(&define_stack, v, macro_type, 0);
s->d = str;
s->next = first_arg;
def = &table_ident[v - TOK_IDENT]->sym_define;
def->data[def->off] = s;
table_ident[v - TOK_IDENT]->sym_define = s;
}
/* undefined a define symbol. Its name is just set to zero */
ST_FUNC void define_undef(Sym *s)
{
int v;
CSym *def;
v = s->v - TOK_IDENT;
if ((unsigned)v < (unsigned)(tok_ident - TOK_IDENT)){
def = &table_ident[v]->sym_define;
def->data[def->off] = NULL;
}
v = s->v;
if (v >= TOK_IDENT && v < tok_ident)
table_ident[v - TOK_IDENT]->sym_define = NULL;
s->v = 0;
}
ST_INLN Sym *define_find(int v)
{
CSym *def;
v -= TOK_IDENT;
if ((unsigned)v >= (unsigned)(tok_ident - TOK_IDENT))
return NULL;
def = &table_ident[v]->sym_define;
return def->data[def->off];
return table_ident[v]->sym_define;
}
/* free define stack until top reaches 'b' */
ST_FUNC void free_defines(Sym *b)
{
Sym *top, *tmp;
Sym *top, *top1;
int v;
CSym *def;
top