Trim trailing spaces everywhere.

This commit is contained in:
gus knight 2015-07-27 12:43:40 -04:00
parent 5e67f24e6b
commit 41031221c8
27 changed files with 430 additions and 430 deletions

View file

@ -154,7 +154,7 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS}) foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS})
set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def}) set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def})
endforeach() endforeach()
if (TCC_BUILD_NATIVE) if (TCC_BUILD_NATIVE)
add_library(libtcc add_library(libtcc
libtcc.c libtcc.c
@ -179,7 +179,7 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
endif() endif()
install(TARGETS tcc libtcc RUNTIME DESTINATION ${EXE_PATH} LIBRARY DESTINATION ${NATIVE_LIB_PATH} ARCHIVE DESTINATION ${NATIVE_LIB_PATH}) install(TARGETS tcc libtcc RUNTIME DESTINATION ${EXE_PATH} LIBRARY DESTINATION ${NATIVE_LIB_PATH} ARCHIVE DESTINATION ${NATIVE_LIB_PATH})
set_target_properties(tcc libtcc PROPERTIES COMPILE_DEFINITIONS "${TCC_NATIVE_DEFINITIONS}") set_target_properties(tcc libtcc PROPERTIES COMPILE_DEFINITIONS "${TCC_NATIVE_DEFINITIONS}")
if("${libtcc_sources}" STRGREATER "") if("${libtcc_sources}" STRGREATER "")
make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}") make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}")
endif() endif()
@ -188,7 +188,7 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
add_executable(${cross_name}-tcc tcc.c) add_executable(${cross_name}-tcc tcc.c)
set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}") set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}")
install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH}) install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH})
if("${libtcc_sources}" STRGREATER "") if("${libtcc_sources}" STRGREATER "")
make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}") make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}")
endif() endif()

View file

@ -1,6 +1,6 @@
/* /*
* TMS320C67xx code generator for TCC * TMS320C67xx code generator for TCC
* *
* Copyright (c) 2001, 2002 Fabrice Bellard * Copyright (c) 2001, 2002 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -130,7 +130,7 @@ 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_FLOAT | RC_EAX, /* eax */ RC_INT | RC_FLOAT | RC_EAX,
// only allow even regs for floats (allow for doubles) // only allow even regs for floats (allow for doubles)
/* ecx */ RC_INT | RC_ECX, /* ecx */ RC_INT | RC_ECX,
/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX, /* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
@ -161,7 +161,7 @@ ST_DATA const int reg_classes[NB_REGS] = {
// although tcc thinks it is passing parameters on the stack, // although tcc thinks it is passing parameters on the stack,
// the C67 really passes up to the first 10 params in special // the C67 really passes up to the first 10 params in special
// regs or regs pairs (for 64 bit params). So keep track of // regs or regs pairs (for 64 bit params). So keep track of
// the stack offsets so we can translate to the appropriate // the stack offsets so we can translate to the appropriate
// reg (pair) // reg (pair)
#define NoCallArgsPassedOnStack 10 #define NoCallArgsPassedOnStack 10
@ -246,7 +246,7 @@ void gsym(int t)
gsym_addr(t, ind); gsym_addr(t, ind);
} }
// these are regs that tcc doesn't really know about, // these are regs that tcc doesn't really know about,
// but assign them unique values so the mapping routines // but assign them unique values so the mapping routines
// can distinguish them // can distinguish them
@ -298,7 +298,7 @@ int C67_map_regn(int r)
return 0; return 0;
} }
// mapping from tcc reg number to // mapping from tcc reg number to
// C67 register to condition code field // C67 register to condition code field
// //
// valid condition code regs are: // valid condition code regs are:
@ -343,15 +343,15 @@ int C67_map_regs(int r)
else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
return (r & 2) >> 1; return (r & 2) >> 1;
else if (r == C67_A0) else if (r == C67_A0)
return 0; // set to A side return 0; // set to A side
else if (r == C67_B2) else if (r == C67_B2)
return 1; // set to B side return 1; // set to B side
else if (r == C67_B3) else if (r == C67_B3)
return 1; // set to B side return 1; // set to B side
else if (r == C67_SP) else if (r == C67_SP)
return 0x1; // set to SP (B15) B side return 0x1; // set to SP (B15) B side
else if (r == C67_FP) else if (r == C67_FP)
return 0x0; // set to FP (A15) A side return 0x0; // set to FP (A15) A side
else else
ALWAYS_ASSERT(FALSE); ALWAYS_ASSERT(FALSE);
@ -420,7 +420,7 @@ void C67_asm(char *s, int a, int b, int c)
(5 << 9) | //mode 5 = pos offset, base reg + off reg (5 << 9) | //mode 5 = pos offset, base reg + off reg
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(0 << 7) | //y D1/D2 A side (0 << 7) | //y D1/D2 A side
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -442,7 +442,7 @@ void C67_asm(char *s, int a, int b, int c)
(5 << 9) | //mode 5 = pos offset, base reg + off reg (5 << 9) | //mode 5 = pos offset, base reg + off reg
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(0 << 7) | //y D1/D2 A side (0 << 7) | //y D1/D2 A side
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -464,7 +464,7 @@ void C67_asm(char *s, int a, int b, int c)
(5 << 9) | //mode 5 = pos offset, base reg + off reg (5 << 9) | //mode 5 = pos offset, base reg + off reg
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(0 << 7) | //y D1/D2 A side (0 << 7) | //y D1/D2 A side
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -475,7 +475,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -486,7 +486,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -497,7 +497,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -509,7 +509,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(b) << 7) | //y D1/D2 base reg side (C67_map_regs(b) << 7) | //y D1/D2 base reg side
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(a) << 1) | //side of src (C67_map_regs(a) << 1) | //side of src
(0 << 0)); //parallel (0 << 0)); //parallel
@ -641,7 +641,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(a) << 7) | //y D1/D2 src side (C67_map_regs(a) << 7) | //y D1/D2 src side
(2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(b) << 1) | //side of dst (C67_map_regs(b) << 1) | //side of dst
(0 << 0)); //parallel (0 << 0)); //parallel
@ -652,7 +652,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(a) << 7) | //y D1/D2 src side (C67_map_regs(a) << 7) | //y D1/D2 src side
(0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(b) << 1) | //side of dst (C67_map_regs(b) << 1) | //side of dst
(0 << 0)); //parallel (0 << 0)); //parallel
@ -674,7 +674,7 @@ void C67_asm(char *s, int a, int b, int c)
(1 << 9) | //mode 1 = pos cst offset (1 << 9) | //mode 1 = pos cst offset
(0 << 8) | //r (LDDW bit 0) (0 << 8) | //r (LDDW bit 0)
(C67_map_regs(a) << 7) | //y D1/D2 src side (C67_map_regs(a) << 7) | //y D1/D2 src side
(6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU (6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
(1 << 2) | //opcode (1 << 2) | //opcode
(C67_map_regs(b) << 1) | //side of dst (C67_map_regs(b) << 1) | //side of dst
(0 << 0)); //parallel (0 << 0)); //parallel
@ -877,7 +877,7 @@ void C67_asm(char *s, int a, int b, int c)
C67_g((0 << 29) | //creg C67_g((0 << 29) | //creg
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(0 << 13) | //src1 NA (0 << 13) | //src1 NA
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x4a << 5) | //opcode (0x4a << 5) | //opcode
@ -890,7 +890,7 @@ void C67_asm(char *s, int a, int b, int c)
C67_g((0 << 29) | //creg C67_g((0 << 29) | //creg
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(0 << 13) | //src1 NA (0 << 13) | //src1 NA
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x49 << 5) | //opcode (0x49 << 5) | //opcode
@ -903,7 +903,7 @@ void C67_asm(char *s, int a, int b, int c)
C67_g((0 << 29) | //creg C67_g((0 << 29) | //creg
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(0 << 13) | //src1 NA (0 << 13) | //src1 NA
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x39 << 5) | //opcode (0x39 << 5) | //opcode
@ -958,7 +958,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x3 << 5) | //opcode (0x3 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -973,7 +973,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x7 << 5) | //opcode (0x7 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -988,7 +988,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x7f << 5) | //opcode (0x7f << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1003,7 +1003,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x7b << 5) | //opcode (0x7b << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1018,7 +1018,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x6f << 5) | //opcode (0x6f << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1033,7 +1033,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x10 << 5) | //opcode (0x10 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1048,7 +1048,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x18 << 5) | //opcode (0x18 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1063,7 +1063,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x11 << 5) | //opcode (0x11 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1078,7 +1078,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x19 << 5) | //opcode (0x19 << 5) | //opcode
(0x6 << 2) | //opcode fixed (0x6 << 2) | //opcode fixed
@ -1093,7 +1093,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x1c << 7) | //opcode (0x1c << 7) | //opcode
(0x0 << 2) | //opcode fixed (0x0 << 2) | //opcode fixed
@ -1108,7 +1108,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (possible x path) (C67_map_regn(b) << 18) | //src2 (possible x path)
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x0e << 7) | //opcode (0x0e << 7) | //opcode
(0x0 << 2) | //opcode fixed (0x0 << 2) | //opcode fixed
@ -1138,7 +1138,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x37 << 6) | //opcode (0x37 << 6) | //opcode
(0x8 << 2) | //opcode fixed (0x8 << 2) | //opcode fixed
@ -1153,7 +1153,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x27 << 6) | //opcode (0x27 << 6) | //opcode
(0x8 << 2) | //opcode fixed (0x8 << 2) | //opcode fixed
@ -1168,7 +1168,7 @@ void C67_asm(char *s, int a, int b, int c)
(0 << 28) | //inv (0 << 28) | //inv
(C67_map_regn(c) << 23) | //dst (C67_map_regn(c) << 23) | //dst
(C67_map_regn(b) << 18) | //src2 (C67_map_regn(b) << 18) | //src2
(C67_map_regn(a) << 13) | //src1 (C67_map_regn(a) << 13) | //src1
(xpath << 12) | //x cross path if opposite sides (xpath << 12) | //x cross path if opposite sides
(0x33 << 6) | //opcode (0x33 << 6) | //opcode
(0x8 << 2) | //opcode fixed (0x8 << 2) | //opcode fixed
@ -1597,7 +1597,7 @@ void load(int r, SValue * sv)
size = 4; size = 4;
} }
// check if fc is a positive reference on the stack, // check if fc is a positive reference on the stack,
// if it is tcc is referencing what it thinks is a parameter // if it is tcc is referencing what it thinks is a parameter
// on the stack, so check if it is really in a register. // on the stack, so check if it is really in a register.
@ -1962,7 +1962,7 @@ void gfunc_call(int nb_args)
// ending with B12:B13. // ending with B12:B13.
// //
// When a call is made, if the caller has its parameters // When a call is made, if the caller has its parameters
// in regs A4-B13 these must be saved before/as the call // in regs A4-B13 these must be saved before/as the call
// parameters are loaded and restored upon return (or if/when needed). // parameters are loaded and restored upon return (or if/when needed).
/* generate function prolog of type 't' */ /* generate function prolog of type 't' */
@ -2033,7 +2033,7 @@ void gfunc_prolog(CType * func_type)
TotalBytesPushedOnStack = -loc; TotalBytesPushedOnStack = -loc;
func_sub_sp_offset = ind; // remember where we put the stack instruction func_sub_sp_offset = ind; // remember where we put the stack instruction
C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily) C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
C67_PUSH(C67_A0); C67_PUSH(C67_A0);
@ -2049,11 +2049,11 @@ void gfunc_epilog(void)
C67_NOP(4); // NOP wait for load C67_NOP(4); // NOP wait for load
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3 C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
C67_POP(C67_FP); C67_POP(C67_FP);
C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
C67_Adjust_ADDK((int *) (cur_text_section->data + C67_Adjust_ADDK((int *) (cur_text_section->data +
func_sub_sp_offset), func_sub_sp_offset),
-local + TotalBytesPushedOnStack); -local + TotalBytesPushedOnStack);
C67_NOP(3); // NOP C67_NOP(3); // NOP
} }
} }

12
coff.h
View file

@ -31,9 +31,9 @@ struct filehdr {
#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */ #define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */ #define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
#define F_PATCH 0x400 /* contains "patch" list in optional header */ #define F_PATCH 0x400 /* contains "patch" list in optional header */
#define F_NODF 0x400 #define F_NODF 0x400
#define F_VERSION (F_GSP10 | F_GSP20) #define F_VERSION (F_GSP10 | F_GSP20)
#define F_BYTE_ORDER (F_LITTLE | F_BIG) #define F_BYTE_ORDER (F_LITTLE | F_BIG)
#define FILHDR struct filehdr #define FILHDR struct filehdr
@ -68,7 +68,7 @@ typedef struct aouthdr {
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* When a UNIX aout header is to be built in the optional header, */ /* When a UNIX aout header is to be built in the optional header, */
/* the following magic numbers can appear in that header: */ /* the following magic numbers can appear in that header: */
/* */ /* */
/* AOUT1MAGIC : default : readonly sharable text segment */ /* AOUT1MAGIC : default : readonly sharable text segment */
/* AOUT2MAGIC: : writable text segment */ /* AOUT2MAGIC: : writable text segment */
@ -164,7 +164,7 @@ struct scnhdr {
#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */ #define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */ #define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */ #define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */
#define STYP_COPY 0x10 /* "copy" : used for C init tables - #define STYP_COPY 0x10 /* "copy" : used for C init tables -
not allocated, relocated, not allocated, relocated,
loaded; reloc & lineno loaded; reloc & lineno
entries processed normally */ entries processed normally */
@ -358,11 +358,11 @@ struct syment
#define N_BTSHFT_COFF 4 #define N_BTSHFT_COFF 4
#define N_TSHIFT_COFF 2 #define N_TSHIFT_COFF 2
#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF) #define BTYPE_COFF(x) ((x) & N_BTMASK_COFF)
#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \ #define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \
((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM) ((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT) #define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT)
#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF)) #define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF))
#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF)) #define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF)) #define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG) #define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)

2
configure vendored
View file

@ -66,7 +66,7 @@ case $targetos in
esac esac
# find source path # find source path
# XXX: we assume an absolute path is given when launching configure, # XXX: we assume an absolute path is given when launching configure,
# except in './configure' case. # except in './configure' case.
source_path=${0%configure} source_path=${0%configure}
source_path=${source_path%/} source_path=${source_path%/}

View file

@ -712,7 +712,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
a32 = addr32 = 1; a32 = addr32 = 1;
} }
#endif #endif
if (b & 0xff00) if (b & 0xff00)
g(b >> 8); g(b >> 8);
g(b); g(b);
return; return;

View file

@ -57,7 +57,7 @@ ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL)) ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
/* bits */ /* bits */
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW)) ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
@ -91,7 +91,7 @@ ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)
DEF_ASM_OP0(repz, 0xf3) DEF_ASM_OP0(repz, 0xf3)
DEF_ASM_OP0(repne, 0xf2) DEF_ASM_OP0(repne, 0xf2)
DEF_ASM_OP0(repnz, 0xf2) DEF_ASM_OP0(repnz, 0xf2)
DEF_ASM_OP0(invd, 0x0f08) DEF_ASM_OP0(invd, 0x0f08)
DEF_ASM_OP0(wbinvd, 0x0f09) DEF_ASM_OP0(wbinvd, 0x0f09)
DEF_ASM_OP0(cpuid, 0x0fa2) DEF_ASM_OP0(cpuid, 0x0fa2)
@ -236,7 +236,7 @@ ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
/* float */ /* float */
/* specific fcomp handling */ /* specific fcomp handling */
ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0)) ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
@ -298,7 +298,7 @@ ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA) DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA) DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA) DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
/* fp store */ /* fp store */
DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST) DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST) DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
@ -380,7 +380,7 @@ ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT
/* pentium */ /* pentium */
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA ) DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
/* pentium pro */ /* pentium pro */
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32)) ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
#ifdef I386_ASM_16 #ifdef I386_ASM_16

View file

@ -1,6 +1,6 @@
/* /*
* X86 code generator for TCC * X86 code generator for TCC
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -32,7 +32,7 @@ typedef int RegArgs;
#define RC_INT 0x0001 /* generic integer register */ #define RC_INT 0x0001 /* generic integer register */
#define RC_FLOAT 0x0002 /* generic float register */ #define RC_FLOAT 0x0002 /* generic float register */
#define RC_EAX 0x0004 #define RC_EAX 0x0004
#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_IRET RC_EAX /* function return: integer register */ #define RC_IRET RC_EAX /* function return: integer register */
@ -357,11 +357,11 @@ static void gcall_or_jmp(int is_jmp)
/* constant case */ /* constant case */
if (vtop->r & VT_SYM) { if (vtop->r & VT_SYM) {
/* relocation case */ /* relocation case */
greloc(cur_text_section, vtop->sym, greloc(cur_text_section, vtop->sym,
ind + 1, R_386_PC32); ind + 1, R_386_PC32);
} else { } else {
/* put an empty PC32 relocation */ /* put an empty PC32 relocation */
put_elf_reloc(symtab_section, cur_text_section, put_elf_reloc(symtab_section, cur_text_section,
ind + 1, R_386_PC32, 0); ind + 1, R_386_PC32, 0);
} }
oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */ oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
@ -417,7 +417,7 @@ ST_FUNC void gfunc_call(int nb_args)
{ {
int size, align, r, args_size, i, func_call; int size, align, r, args_size, i, func_call;
Sym *func_sym; Sym *func_sym;
args_size = 0; args_size = 0;
for(i = 0;i < nb_args; i++) { for(i = 0;i < nb_args; i++) {
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) { if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
@ -610,7 +610,7 @@ ST_FUNC void gfunc_epilog(void)
/* generate bound local allocation */ /* generate bound local allocation */
saved_ind = ind; saved_ind = ind;
ind = func_sub_sp_offset; ind = func_sub_sp_offset;
sym_data = get_sym_ref(&char_pointer_type, lbounds_section, sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
func_bound_offset, lbounds_section->data_offset); func_bound_offset, lbounds_section->data_offset);
greloc(cur_text_section, sym_data, greloc(cur_text_section, sym_data,
ind + 1, R_386_32); ind + 1, R_386_32);
@ -637,8 +637,8 @@ ST_FUNC void gfunc_epilog(void)
g(func_ret_sub >> 8); g(func_ret_sub >> 8);
} }
/* align local size to word & save local variables */ /* align local size to word & save local variables */
v = (-loc + 3) & -4; v = (-loc + 3) & -4;
saved_ind = ind; saved_ind = ind;
ind = func_sub_sp_offset - FUNC_PROLOG_SIZE; ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
@ -741,7 +741,7 @@ ST_FUNC void gen_opi(int op)
r = vtop[-1].r; r = vtop[-1].r;
fr = vtop[0].r; fr = vtop[0].r;
o((opc << 3) | 0x01); o((opc << 3) | 0x01);
o(0xc0 + r + fr * 8); o(0xc0 + r + fr * 8);
} }
vtop--; vtop--;
if (op >= TOK_ULT && op <= TOK_GT) { if (op >= TOK_ULT && op <= TOK_GT) {
@ -911,7 +911,7 @@ ST_FUNC void gen_opf(int op)
load(TREG_ST0, vtop); load(TREG_ST0, vtop);
swapped = !swapped; swapped = !swapped;
} }
switch(op) { switch(op) {
default: default:
case '+': case '+':
@ -972,7 +972,7 @@ ST_FUNC void gen_cvt_itof(int t)
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */ o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
o(0x242cdf); /* fildll (%esp) */ o(0x242cdf); /* fildll (%esp) */
o(0x08c483); /* add $8, %esp */ o(0x08c483); /* add $8, %esp */
} else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == } else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_INT | VT_UNSIGNED)) { (VT_INT | VT_UNSIGNED)) {
/* unsigned int to float/double/long double */ /* unsigned int to float/double/long double */
o(0x6a); /* push $0 */ o(0x6a); /* push $0 */
@ -1060,7 +1060,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
vtop++; vtop++;
vtop->r = TREG_EAX | VT_BOUNDED; vtop->r = TREG_EAX | VT_BOUNDED;
/* address of bounding function call point */ /* address of bounding function call point */
vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
} }
/* patch pointer addition in vtop so that pointer dereferencing is /* patch pointer addition in vtop so that pointer dereferencing is

View file

@ -1,6 +1,6 @@
/* /*
* CIL code generator for TCC * CIL code generator for TCC
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -112,7 +112,7 @@ static void init_outfile(void)
{ {
if (!il_outfile) { if (!il_outfile) {
il_outfile = stdout; il_outfile = stdout;
fprintf(il_outfile, fprintf(il_outfile,
".assembly extern mscorlib\n" ".assembly extern mscorlib\n"
"{\n" "{\n"
".ver 1:0:2411:0\n" ".ver 1:0:2411:0\n"
@ -149,7 +149,7 @@ static void out_opi(int op, int c)
} }
/* XXX: not complete */ /* XXX: not complete */
static void il_type_to_str(char *buf, int buf_size, static void il_type_to_str(char *buf, int buf_size,
int t, const char *varstr) int t, const char *varstr)
{ {
int bt; int bt;
@ -301,12 +301,12 @@ void load(int r, SValue *sv)
out_op(IL_OP_LDIND_U2); out_op(IL_OP_LDIND_U2);
else else
out_op(IL_OP_LDIND_I4); out_op(IL_OP_LDIND_I4);
} }
} else { } else {
if (v == VT_CONST) { if (v == VT_CONST) {
/* XXX: handle globals */ /* XXX: handle globals */
if (fc >= -1 && fc <= 8) { if (fc >= -1 && fc <= 8) {
out_op(IL_OP_LDC_I4_M1 + fc + 1); out_op(IL_OP_LDC_I4_M1 + fc + 1);
} else { } else {
out_opi(IL_OP_LDC_I4, fc); out_opi(IL_OP_LDC_I4, fc);
} }
@ -430,10 +430,10 @@ void gfunc_prolog(int t)
/* XXX: cannot do better now */ /* XXX: cannot do better now */
fprintf(il_outfile, " .maxstack %d\n", NB_REGS); fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n"); fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
if (!strcmp(funcname, "main")) if (!strcmp(funcname, "main"))
fprintf(il_outfile, " .entrypoint\n"); fprintf(il_outfile, " .entrypoint\n");
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT); sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
func_call = sym->r; func_call = sym->r;

View file

@ -1,6 +1,6 @@
/* /*
* CIL opcode definition * CIL opcode definition
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify

View file

@ -1,6 +1,6 @@
/* /*
* Tiny C Memory and bounds checker * Tiny C Memory and bounds checker
* *
* Copyright (c) 2002 Fabrice Bellard * Copyright (c) 2002 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -88,7 +88,7 @@ int __bound_delete_region(void *p);
#ifdef __attribute__ #ifdef __attribute__
/* an __attribute__ macro is defined in the system headers */ /* an __attribute__ macro is defined in the system headers */
#undef __attribute__ #undef __attribute__
#endif #endif
#define FASTCALL __attribute__((regparm(3))) #define FASTCALL __attribute__((regparm(3)))
@ -177,8 +177,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset); dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset);
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e + e = (BoundEntry *)((char *)e +
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
addr -= e->start; addr -= e->start;
if (addr > e->size) { if (addr > e->size) {
@ -236,7 +236,7 @@ BOUND_PTR_INDIR(16)
} }
/* called when entering a function to add all the local regions */ /* called when entering a function to add all the local regions */
void FASTCALL __bound_local_new(void *p1) void FASTCALL __bound_local_new(void *p1)
{ {
size_t addr, size, fp, *p = p1; size_t addr, size, fp, *p = p1;
@ -255,7 +255,7 @@ void FASTCALL __bound_local_new(void *p1)
} }
/* called when leaving a function to delete all the local regions */ /* called when leaving a function to delete all the local regions */
void FASTCALL __bound_local_delete(void *p1) void FASTCALL __bound_local_delete(void *p1)
{ {
size_t addr, fp, *p = p1; size_t addr, fp, *p = p1;
GET_CALLER_FP(fp); GET_CALLER_FP(fp);
@ -331,14 +331,14 @@ static void mark_invalid(size_t addr, size_t size)
#if 0 #if 0
dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end); dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
#endif #endif
/* first we handle full pages */ /* first we handle full pages */
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS; t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
t1_end = t2_end >> BOUND_T2_BITS; t1_end = t2_end >> BOUND_T2_BITS;
i = t2_start & (BOUND_T2_SIZE - 1); i = t2_start & (BOUND_T2_SIZE - 1);
j = t2_end & (BOUND_T2_SIZE - 1); j = t2_end & (BOUND_T2_SIZE - 1);
if (t1_start == t1_end) { if (t1_start == t1_end) {
page = get_page(t2_start >> BOUND_T2_BITS); page = get_page(t2_start >> BOUND_T2_BITS);
for(; i < j; i++) { for(; i < j; i++) {
@ -456,7 +456,7 @@ void __bound_main_arg(void **p)
void *start = p; void *start = p;
while (*p++); while (*p++);
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, (void *) p - start); __FILE__, __FUNCTION__, (void *) p - start);
__bound_new_region(start, (void *) p - start); __bound_new_region(start, (void *) p - start);
@ -467,7 +467,7 @@ void __bound_exit(void)
restore_malloc_hooks(); restore_malloc_hooks();
} }
static inline void add_region(BoundEntry *e, static inline void add_region(BoundEntry *e,
size_t start, size_t size) size_t start, size_t size)
{ {
BoundEntry *e1; BoundEntry *e1;
@ -496,7 +496,7 @@ void __bound_new_region(void *p, size_t size)
__bound_init(); __bound_init();
dprintf(stderr, "%s, %s(%p, %p) start\n", dprintf(stderr, "%s, %s(%p, %p) start\n",
__FILE__, __FUNCTION__, p, size); __FILE__, __FUNCTION__, p, size);
start = (size_t)p; start = (size_t)p;
@ -506,9 +506,9 @@ void __bound_new_region(void *p, size_t size)
/* start */ /* start */
page = get_page(t1_start); page = get_page(t1_start);
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
@ -557,7 +557,7 @@ void __bound_new_region(void *p, size_t size)
} }
/* delete a region */ /* delete a region */
static inline void delete_region(BoundEntry *e, static inline void delete_region(BoundEntry *e,
void *p, size_t empty_size) void *p, size_t empty_size)
{ {
size_t addr; size_t addr;
@ -612,9 +612,9 @@ int __bound_delete_region(void *p)
start = (size_t)p; start = (size_t)p;
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS); t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
/* find region size */ /* find region size */
page = __bound_t1[t1_start]; page = __bound_t1[t1_start];
e = (BoundEntry *)((char *)page + t2_start); e = (BoundEntry *)((char *)page + t2_start);
@ -622,7 +622,7 @@ int __bound_delete_region(void *p)
if (addr > e->size) if (addr > e->size)
e = __bound_find_region(e, p); e = __bound_find_region(e, p);
/* test if invalid region */ /* test if invalid region */
if (e->size == EMPTY_SIZE || (size_t)p != e->start) if (e->size == EMPTY_SIZE || (size_t)p != e->start)
return -1; return -1;
/* compute the size we put in invalid regions */ /* compute the size we put in invalid regions */
if (e->is_invalid) if (e->is_invalid)
@ -634,7 +634,7 @@ int __bound_delete_region(void *p)
/* now we can free each entry */ /* now we can free each entry */
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS); t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) & t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
delete_region(e, p, empty_size); delete_region(e, p, empty_size);
@ -690,8 +690,8 @@ static size_t get_region_size(void *p)
BoundEntry *e; BoundEntry *e;
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)]; e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
e = (BoundEntry *)((char *)e + e = (BoundEntry *)((char *)e +
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) & ((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
((BOUND_T2_SIZE - 1) << BOUND_E_BITS))); ((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
addr -= e->start; addr -= e->start;
if (addr > e->size) if (addr > e->size)
@ -756,16 +756,16 @@ static void libc_free(void *ptr)
void *__bound_malloc(size_t size, const void *caller) void *__bound_malloc(size_t size, const void *caller)
{ {
void *ptr; void *ptr;
/* we allocate one more byte to ensure the regions will be /* we allocate one more byte to ensure the regions will be
separated by at least one byte. With the glibc malloc, it may separated by at least one byte. With the glibc malloc, it may
be in fact not necessary */ be in fact not necessary */
ptr = libc_malloc(size + 1); ptr = libc_malloc(size + 1);
if (!ptr) if (!ptr)
return NULL; return NULL;
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, ptr, size); __FILE__, __FUNCTION__, ptr, size);
__bound_new_region(ptr, size); __bound_new_region(ptr, size);
@ -792,13 +792,13 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
be in fact not necessary */ be in fact not necessary */
ptr = memalign(size + 1, align); ptr = memalign(size + 1, align);
#endif #endif
install_malloc_hooks(); install_malloc_hooks();
if (!ptr) if (!ptr)
return NULL; return NULL;
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n", dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
__FILE__, __FUNCTION__, ptr, size); __FILE__, __FUNCTION__, ptr, size);
__bound_new_region(ptr, size); __bound_new_region(ptr, size);
@ -862,8 +862,8 @@ static void bound_dump(void)
e = page + j; e = page + j;
/* do not print invalid or empty entries */ /* do not print invalid or empty entries */
if (e->size != EMPTY_SIZE && e->start != 0) { if (e->size != EMPTY_SIZE && e->start != 0) {
fprintf(stderr, "%08x:", fprintf(stderr, "%08x:",
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) + (i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
(j << BOUND_T3_BITS)); (j << BOUND_T3_BITS));
do { do {
fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size); fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);

View file

@ -1,5 +1,5 @@
/* TCC runtime library. /* TCC runtime library.
Parts of this code are (c) 2002 Fabrice Bellard Parts of this code are (c) 2002 Fabrice Bellard
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc. Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
@ -25,7 +25,7 @@ General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. Boston, MA 02111-1307, USA.
*/ */
#include <stdint.h> #include <stdint.h>
@ -370,10 +370,10 @@ long long __divdi3(long long u, long long v)
int c = 0; int c = 0;
DWunion uu, vv; DWunion uu, vv;
DWtype w; DWtype w;
uu.ll = u; uu.ll = u;
vv.ll = v; vv.ll = v;
if (uu.s.high < 0) { if (uu.s.high < 0) {
c = ~c; c = ~c;
uu.ll = __negdi2 (uu.ll); uu.ll = __negdi2 (uu.ll);
@ -393,17 +393,17 @@ long long __moddi3(long long u, long long v)
int c = 0; int c = 0;
DWunion uu, vv; DWunion uu, vv;
DWtype w; DWtype w;
uu.ll = u; uu.ll = u;
vv.ll = v; vv.ll = v;
if (uu.s.high < 0) { if (uu.s.high < 0) {
c = ~c; c = ~c;
uu.ll = __negdi2 (uu.ll); uu.ll = __negdi2 (uu.ll);
} }
if (vv.s.high < 0) if (vv.s.high < 0)
vv.ll = __negdi2 (vv.ll); vv.ll = __negdi2 (vv.ll);
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w); __udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
if (c) if (c)
w = __negdi2 (w); w = __negdi2 (w);
@ -418,7 +418,7 @@ unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
unsigned long long __umoddi3(unsigned long long u, unsigned long long v) unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
{ {
UDWtype w; UDWtype w;
__udivmoddi4 (u, v, &w); __udivmoddi4 (u, v, &w);
return w; return w;
} }
@ -499,7 +499,7 @@ long long __tcc_cvt_ftol(long double x)
/* XXX: fix tcc's code generator to do this instead */ /* XXX: fix tcc's code generator to do this instead */
float __floatundisf(unsigned long long a) float __floatundisf(unsigned long long a)
{ {
DWunion uu; DWunion uu;
XFtype r; XFtype r;
uu.ll = a; uu.ll = a;
@ -514,7 +514,7 @@ float __floatundisf(unsigned long long a)
double __floatundidf(unsigned long long a) double __floatundidf(unsigned long long a)
{ {
DWunion uu; DWunion uu;
XFtype r; XFtype r;
uu.ll = a; uu.ll = a;
@ -529,7 +529,7 @@ double __floatundidf(unsigned long long a)
long double __floatundixf(unsigned long long a) long double __floatundixf(unsigned long long a)
{ {
DWunion uu; DWunion uu;
XFtype r; XFtype r;
uu.ll = a; uu.ll = a;
@ -608,7 +608,7 @@ unsigned long long __fixunsxfdi (long double a1)
if (exp > 0) if (exp > 0)
return (unsigned long long)-1; return (unsigned long long)-1;
else if (exp >= -63) else if (exp >= -63)
return l >> -exp; return l >> -exp;
else else
return 0; return 0;

View file

@ -318,7 +318,7 @@ PUB_FUNC void tcc_free_debug(void *ptr)
mem_cur_size -= header->size; mem_cur_size -= header->size;
header->size = (size_t)-1; header->size = (size_t)-1;
if (header->next) if (header->next)
header->next->prev = header->prev; header->next->prev = header->prev;

View file

@ -99,9 +99,9 @@ the @code{main()} of a.c.
@item @samp{tcc a.c -run b.c arg1} @item @samp{tcc a.c -run b.c arg1}
Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
as first argument to the @code{main()} of the resulting program. as first argument to the @code{main()} of the resulting program.
@ignore @ignore
Because multiple C files are specified, @option{--} are necessary to clearly Because multiple C files are specified, @option{--} are necessary to clearly
separate the program arguments from the TCC options. separate the program arguments from the TCC options.
@end ignore @end ignore
@ -136,14 +136,14 @@ need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source:
#!/usr/local/bin/tcc -run #!/usr/local/bin/tcc -run
#include <stdio.h> #include <stdio.h>
int main() int main()
@{ @{
printf("Hello World\n"); printf("Hello World\n");
return 0; return 0;
@} @}
@end example @end example
TCC can read C source code from @emph{standard input} when @option{-} is used in TCC can read C source code from @emph{standard input} when @option{-} is used in
place of @option{infile}. Example: place of @option{infile}. Example:
@example @example
@ -271,7 +271,7 @@ Make string constants be of type @code{const char *} instead of @code{char
@item -Werror @item -Werror
Abort compilation if warnings are issued. Abort compilation if warnings are issued.
@item -Wall @item -Wall
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
@option{-Wwrite-strings}. @option{-Wwrite-strings}.
@ -451,7 +451,7 @@ function name.
int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@}; int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
@end example @end example
@item Compound initializers are supported: @item Compound initializers are supported:
@example @example
int *p = (int [])@{ 1, 2, 3 @}; int *p = (int [])@{ 1, 2, 3 @};
@ -465,7 +465,7 @@ works for structures and strings.
@end example @end example
@noindent @noindent
is the same as writing is the same as writing
@example @example
double d = 4771840.0; double d = 4771840.0;
@end example @end example
@ -481,12 +481,12 @@ TCC implements some GNU C extensions:
@itemize @itemize
@item array designators can be used without '=': @item array designators can be used without '=':
@example @example
int a[10] = @{ [0] 1, [5] 2, 3, 4 @}; int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
@end example @end example
@item Structure field designators can be a label: @item Structure field designators can be a label:
@example @example
struct @{ int x, y; @} st = @{ x: 1, y: 1@}; struct @{ int x, y; @} st = @{ x: 1, y: 1@};
@end example @end example
@ -555,7 +555,7 @@ Here are some examples:
align variable @code{a} to 8 bytes and put it in section @code{.mysection}. align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
@example @example
int my_add(int a, int b) __attribute__ ((section(".mycodesection"))) int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
@{ @{
return a + b; return a + b;
@} @}
@ -572,17 +572,17 @@ generate function @code{my_add} in section @code{.mycodesection}.
dprintf("one arg %d\n", 1); dprintf("one arg %d\n", 1);
@end example @end example
@item @code{__FUNCTION__} is interpreted as C99 @code{__func__} @item @code{__FUNCTION__} is interpreted as C99 @code{__func__}
(so it has not exactly the same semantics as string literal GNUC (so it has not exactly the same semantics as string literal GNUC
where it is a string literal). where it is a string literal).
@item The @code{__alignof__} keyword can be used as @code{sizeof} @item The @code{__alignof__} keyword can be used as @code{sizeof}
to get the alignment of a type or an expression. to get the alignment of a type or an expression.
@item The @code{typeof(x)} returns the type of @code{x}. @item The @code{typeof(x)} returns the type of @code{x}.
@code{x} is an expression or a type. @code{x} is an expression or a type.
@item Computed gotos: @code{&&label} returns a pointer of type @item Computed gotos: @code{&&label} returns a pointer of type
@code{void *} on the goto label @code{label}. @code{goto *expr} can be @code{void *} on the goto label @code{label}. @code{goto *expr} can be
used to jump on the pointer resulting from @code{expr}. used to jump on the pointer resulting from @code{expr}.
@ -616,7 +616,7 @@ TCC includes its own x86 inline assembler with a @code{gas}-like (GNU
assembler) syntax. No intermediate files are generated. GCC 3.x named assembler) syntax. No intermediate files are generated. GCC 3.x named
operands are supported. operands are supported.
@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()} @item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()}
are supported. are supported.
@item @code{#pragma pack} is supported for win32 compatibility. @item @code{#pragma pack} is supported for win32 compatibility.
@ -681,7 +681,7 @@ same as C.
@item +, - @item +, -
@end enumerate @end enumerate
@item A value is either an absolute number or a label plus an offset. @item A value is either an absolute number or a label plus an offset.
All operators accept absolute values except '+' and '-'. '+' or '-' can be All operators accept absolute values except '+' and '-'. '+' or '-' can be
used to add an offset to a label. '-' supports two labels only if they used to add an offset to a label. '-' supports two labels only if they
are the same or if they are both defined and in the same section. are the same or if they are both defined and in the same section.
@ -694,7 +694,7 @@ are the same or if they are both defined and in the same section.
@item All labels are considered as local, except undefined ones. @item All labels are considered as local, except undefined ones.
@item Numeric labels can be used as local @code{gas}-like labels. @item Numeric labels can be used as local @code{gas}-like labels.
They can be defined several times in the same source. Use 'b' They can be defined several times in the same source. Use 'b'
(backward) or 'f' (forward) as suffix to reference them: (backward) or 'f' (forward) as suffix to reference them:
@ -901,7 +901,7 @@ Here are some examples of caught errors:
@chapter The @code{libtcc} library @chapter The @code{libtcc} library
The @code{libtcc} library enables you to use TCC as a backend for The @code{libtcc} library enables you to use TCC as a backend for
dynamic code generation. dynamic code generation.
Read the @file{libtcc.h} to have an overview of the API. Read Read the @file{libtcc.h} to have an overview of the API. Read
@file{libtcc_test.c} to have a very simple example. @file{libtcc_test.c} to have a very simple example.
@ -941,10 +941,10 @@ except:
@itemize @itemize
@item For initialized arrays with unknown size, a first pass @item For initialized arrays with unknown size, a first pass
is done to count the number of elements. is done to count the number of elements.
@item For architectures where arguments are evaluated in @item For architectures where arguments are evaluated in
reverse order, a first pass is done to reverse the argument order. reverse order, a first pass is done to reverse the argument order.
@end itemize @end itemize
@ -1156,7 +1156,7 @@ stack.
@item VT_CMP @item VT_CMP
indicates that the value is actually stored in the CPU flags (i.e. the indicates that the value is actually stored in the CPU flags (i.e. the
value is the consequence of a test). The value is either 0 or 1. The value is the consequence of a test). The value is either 0 or 1. The
actual CPU flags used is indicated in @code{SValue.c.i}. actual CPU flags used is indicated in @code{SValue.c.i}.
If any code is generated which destroys the CPU flags, this value MUST be If any code is generated which destroys the CPU flags, this value MUST be
put in a normal register. put in a normal register.
@ -1176,7 +1176,7 @@ taken.
@item VT_LVAL @item VT_LVAL
is a flag indicating that the value is actually an lvalue (left value of is a flag indicating that the value is actually an lvalue (left value of
an assignment). It means that the value stored is actually a pointer to an assignment). It means that the value stored is actually a pointer to
the wanted value. the wanted value.
Understanding the use @code{VT_LVAL} is very important if you want to Understanding the use @code{VT_LVAL} is very important if you want to
understand how TCC works. understand how TCC works.

2
tcc.c
View file

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or

8
tcc.h
View file

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -605,7 +605,7 @@ struct TCCState {
int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used. int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used.
Liuux 2.4.26 can't find initrd when compiled with a new algorithm */ Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
int dollars_in_identifiers; /* allows '$' char in indentifiers */ int dollars_in_identifiers; /* allows '$' char in indentifiers */
/* warning switches */ /* warning switches */
int warn_write_strings; int warn_write_strings;
int warn_unsupported; int warn_unsupported;
@ -631,7 +631,7 @@ struct TCCState {
char *init_symbol; /* symbols to call at load-time (not used currently) */ char *init_symbol; /* symbols to call at load-time (not used currently) */
char *fini_symbol; /* symbols to call at unload-time (not used currently) */ char *fini_symbol; /* symbols to call at unload-time (not used currently) */
#ifdef TCC_TARGET_I386 #ifdef TCC_TARGET_I386
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */ int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
#endif #endif
@ -885,7 +885,7 @@ struct TCCState {
#define TOK_SHL 0x01 /* shift left */ #define TOK_SHL 0x01 /* shift left */
#define TOK_SAR 0x02 /* signed shift right */ #define TOK_SAR 0x02 /* signed shift right */
/* assignement operators : normal operator or 0x80 */ /* assignement operators : normal operator or 0x80 */
#define TOK_A_MOD 0xa5 #define TOK_A_MOD 0xa5
#define TOK_A_AND 0xa6 #define TOK_A_AND 0xa6

View file

@ -1,6 +1,6 @@
/* /*
* GAS like assembler for TCC * GAS like assembler for TCC
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -125,7 +125,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
break; break;
} }
} }
static void asm_expr_prod(TCCState *s1, ExprValue *pe) static void asm_expr_prod(TCCState *s1, ExprValue *pe)
{ {
int op; int op;
@ -134,7 +134,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
asm_expr_unary(s1, pe); asm_expr_unary(s1, pe);
for(;;) { for(;;) {
op = tok; op = tok;
if (op != '*' && op != '/' && op != '%' && if (op != '*' && op != '/' && op != '%' &&
op != TOK_SHL && op != TOK_SAR) op != TOK_SHL && op != TOK_SAR)
break; break;
next(); next();
@ -145,14 +145,14 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
case '*': case '*':
pe->v *= e2.v; pe->v *= e2.v;
break; break;
case '/': case '/':
if (e2.v == 0) { if (e2.v == 0) {
div_error: div_error:
tcc_error("division by zero"); tcc_error("division by zero");
} }
pe->v /= e2.v; pe->v /= e2.v;
break; break;
case '%': case '%':
if (e2.v == 0) if (e2.v == 0)
goto div_error; goto div_error;
pe->v %= e2.v; pe->v %= e2.v;
@ -186,7 +186,7 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe)
case '&': case '&':
pe->v &= e2.v; pe->v &= e2.v;
break; break;
case '|': case '|':
pe->v |= e2.v; pe->v |= e2.v;
break; break;
default: default:
@ -224,7 +224,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
} else if (pe->sym && !e2.sym) { } else if (pe->sym && !e2.sym) {
/* OK */ /* OK */
} else if (pe->sym && e2.sym) { } else if (pe->sym && e2.sym) {
if (pe->sym == e2.sym) { if (pe->sym == e2.sym) {
/* OK */ /* OK */
} else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) { } else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
/* we also accept defined symbols in the same section */ /* we also accept defined symbols in the same section */
@ -267,7 +267,7 @@ static void asm_new_label1(TCCState *s1, int label, int is_local,
if (sym->r) { if (sym->r) {
/* the label is already defined */ /* the label is already defined */
if (!is_local) { if (!is_local) {
tcc_error("assembler label '%s' already defined", tcc_error("assembler label '%s' already defined",
get_tok_str(label, NULL)); get_tok_str(label, NULL));
} else { } else {
/* redefinition of local labels is possible */ /* redefinition of local labels is possible */
@ -493,7 +493,7 @@ static void asm_parse_directive(TCCState *s1)
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;
next(); next();
@ -541,7 +541,7 @@ static void asm_parse_directive(TCCState *s1)
case TOK_ASM_text: case TOK_ASM_text:
case TOK_ASM_data: case TOK_ASM_data:
case TOK_ASM_bss: case TOK_ASM_bss:
{ {
char sname[64]; char sname[64];
tok1 = tok; tok1 = tok;
n = 0; n = 0;
@ -591,7 +591,7 @@ static void asm_parse_directive(TCCState *s1)
} }
break; break;
case TOK_ASM_size: case TOK_ASM_size:
{ {
Sym *sym; Sym *sym;
next(); next();
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *s1)
} }
break; break;
case TOK_ASM_type: case TOK_ASM_type:
{ {
Sym *sym; Sym *sym;
const char *newtype; const char *newtype;
@ -637,7 +637,7 @@ static void asm_parse_directive(TCCState *s1)
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
} }
else if (s1->warn_unsupported) else if (s1->warn_unsupported)
tcc_warning("change type of '%s' from 0x%x to '%s' ignored", tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
get_tok_str(sym->v, NULL), sym->type.t, newtype); get_tok_str(sym->v, NULL), sym->type.t, newtype);
next(); next();
@ -669,7 +669,7 @@ static void asm_parse_directive(TCCState *s1)
} }
break; break;
case TOK_ASM_previous: case TOK_ASM_previous:
{ {
Section *sec; Section *sec;
next(); next();
if (!last_text_section) if (!last_text_section)
@ -830,7 +830,7 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
cur_text_section->data_offset = ind; cur_text_section->data_offset = ind;
free_defines(define_start); free_defines(define_start);
return ret; return ret;
} }
@ -863,7 +863,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len)
/* find a constraint by its number or id (gcc 3 extended /* find a constraint by its number or id (gcc 3 extended
syntax). return -1 if not found. Return in *pp in char after the syntax). return -1 if not found. Return in *pp in char after the
constraint */ constraint */
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands, ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
const char *name, const char **pp) const char *name, const char **pp)
{ {
int index; int index;
@ -901,7 +901,7 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
return index; return index;
} }
static void subst_asm_operands(ASMOperand *operands, int nb_operands, static void subst_asm_operands(ASMOperand *operands, int nb_operands,
int nb_outputs, int nb_outputs,
CString *out_str, CString *in_str) CString *out_str, CString *in_str)
{ {
@ -1052,12 +1052,12 @@ ST_FUNC void asm_instr(void)
token after the assembler parsing */ token after the assembler parsing */
if (tok != ';') if (tok != ';')
expect("';'"); expect("';'");
/* save all values in the memory */ /* save all values in the memory */
save_regs(0); save_regs(0);
/* compute constraints */ /* compute constraints */
asm_compute_constraints(operands, nb_operands, nb_outputs, asm_compute_constraints(operands, nb_operands, nb_outputs,
clobber_regs, &out_reg); clobber_regs, &out_reg);
/* substitute the operands in the asm string. No substitution is /* substitute the operands in the asm string. No substitution is
@ -1076,8 +1076,8 @@ ST_FUNC void asm_instr(void)
#endif #endif
/* generate loads */ /* generate loads */
asm_gen_code(operands, nb_operands, nb_outputs, 0, asm_gen_code(operands, nb_operands, nb_outputs, 0,
clobber_regs, out_reg); clobber_regs, out_reg);
/* assemble the string with tcc internal assembler */ /* assemble the string with tcc internal assembler */
tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1); tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
@ -1086,9 +1086,9 @@ ST_FUNC void asm_instr(void)
next(); next();
/* store the output values if needed */ /* store the output values if needed */
asm_gen_code(operands, nb_operands, nb_outputs, 1, asm_gen_code(operands, nb_operands, nb_outputs, 1,
clobber_regs, out_reg); clobber_regs, out_reg);
/* free everything */ /* free everything */
for(i=0;i<nb_operands;i++) { for(i=0;i<nb_operands;i++) {
ASMOperand *op; ASMOperand *op;
@ -1110,7 +1110,7 @@ ST_FUNC void asm_global_instr(void)
token after the assembler parsing */ token after the assembler parsing */
if (tok != ';') if (tok != ';')
expect("';'"); expect("';'");
#ifdef ASM_DEBUG #ifdef ASM_DEBUG
printf("asm_global: \"%s\"\n", (char *)astr.data); printf("asm_global: \"%s\"\n", (char *)astr.data);
#endif #endif
@ -1119,7 +1119,7 @@ ST_FUNC void asm_global_instr(void)
/* assemble the string with tcc internal assembler */ /* assemble the string with tcc internal assembler */
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1); tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
cur_text_section->data_offset = ind; cur_text_section->data_offset = ind;
/* restore the current C token */ /* restore the current C token */

View file

@ -1,6 +1,6 @@
/* /*
* COFF file handling for TCC * COFF file handling for TCC
* *
* Copyright (c) 2003, 2004 TK * Copyright (c) 2003, 2004 TK
* Copyright (c) 2004 Fabrice Bellard * Copyright (c) 2004 Fabrice Bellard
* *
@ -606,7 +606,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
// put a .ef // put a .ef
strcpy(csym._n._n_name, ".ef"); strcpy(csym._n._n_name, ".ef");
csym.n_value = EndAddress[k]; // physical address csym.n_value = EndAddress[k]; // physical address
csym.n_scnum = CoffTextSectionNo; csym.n_scnum = CoffTextSectionNo;
csym.n_type = 0; csym.n_type = 0;
csym.n_sclass = C_FCN; csym.n_sclass = C_FCN;

View file

@ -1179,7 +1179,7 @@ static unsigned long put_got_entry(TCCState *s1,
p[11] = 0xe9; /* jmp plt_start */ p[11] = 0xe9; /* jmp plt_start */
put32(p + 12, -(plt->data_offset)); put32(p + 12, -(plt->data_offset));
/* If this was an UNDEF symbol set the offset in the /* If this was an UNDEF symbol set the offset in the
dynsymtab to the PLT slot, so that PC32 relocs to it dynsymtab to the PLT slot, so that PC32 relocs to it
can be resolved. */ can be resolved. */
if (sym->st_shndx == SHN_UNDEF) if (sym->st_shndx == SHN_UNDEF)

220
tccgen.c
View file

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -299,7 +299,7 @@ static void weaken_symbol(Sym *sym)
if (sym->c > 0) { if (sym->c > 0) {
int esym_type; int esym_type;
ElfW(Sym) *esym; ElfW(Sym) *esym;
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
esym_type = ELFW(ST_TYPE)(esym->st_info); esym_type = ELFW(ST_TYPE)(esym->st_info);
esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type); esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
@ -321,7 +321,7 @@ static void apply_visibility(Sym *sym, CType *type)
if (sym->c > 0) { if (sym->c > 0) {
ElfW(Sym) *esym; ElfW(Sym) *esym;
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
vis >>= VT_VIS_SHIFT; vis >>= VT_VIS_SHIFT;
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis; esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
@ -425,7 +425,7 @@ ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsign
/* push a reference to a section offset by adding a dummy symbol */ /* push a reference to a section offset by adding a dummy symbol */
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size) static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
{ {
vpushsym(type, get_sym_ref(type, sec, offset, size)); vpushsym(type, get_sym_ref(type, sec, offset, size));
} }
/* define a new external reference to a symbol 'v' of type 'u' */ /* define a new external reference to a symbol 'v' of type 'u' */
@ -461,7 +461,7 @@ static Sym *external_sym(int v, CType *type, int r, char *asm_label)
s->r = r | VT_CONST | VT_SYM; s->r = r | VT_CONST | VT_SYM;
s->type.t |= VT_EXTERN; s->type.t |= VT_EXTERN;
} else if (!is_compatible_types(&s->type, type)) { } else if (!is_compatible_types(&s->type, type)) {
tcc_error("incompatible types for redefinition of '%s'", tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
/* Merge some storage attributes. */ /* Merge some storage attributes. */
@ -600,7 +600,7 @@ ST_FUNC int get_reg_ex(int rc, int rc2)
{ {
int r; int r;
SValue *p; SValue *p;
for(r=0;r<NB_REGS;r++) { for(r=0;r<NB_REGS;r++) {
if (reg_classes[r] & rc2) { if (reg_classes[r] & rc2) {
int n; int n;
@ -636,7 +636,7 @@ ST_FUNC int get_reg(int rc)
} }
notfound: ; notfound: ;
} }
/* no register left : free the first one on the stack (VERY /* no register left : free the first one on the stack (VERY
IMPORTANT to start from the bottom to ensure that we don't IMPORTANT to start from the bottom to ensure that we don't
spill registers used in gen_opi()) */ spill registers used in gen_opi()) */
@ -761,7 +761,7 @@ ST_FUNC int gv(int rc)
gen_op(TOK_SAR); gen_op(TOK_SAR);
r = gv(rc); r = gv(rc);
} else { } else {
if (is_float(vtop->type.t) && if (is_float(vtop->type.t) &&
(vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) { (vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
Sym *sym; Sym *sym;
int *ptr; int *ptr;
@ -769,7 +769,7 @@ ST_FUNC int gv(int rc)
#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP) #if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
CValue check; CValue check;
#endif #endif
/* XXX: unify with initializers handling ? */ /* XXX: unify with initializers handling ? */
/* CPUs usually cannot use float constants, so we store them /* CPUs usually cannot use float constants, so we store them
generically in data segment */ generically in data segment */
@ -803,7 +803,7 @@ ST_FUNC int gv(int rc)
vtop->c.ptr_offset = 0; vtop->c.ptr_offset = 0;
} }
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
if (vtop->r & VT_MUSTBOUND) if (vtop->r & VT_MUSTBOUND)
gbound(); gbound();
#endif #endif
@ -921,7 +921,7 @@ ST_FUNC int gv(int rc)
vtop->r = r; vtop->r = r;
#ifdef TCC_TARGET_C67 #ifdef TCC_TARGET_C67
/* uses register pairs for doubles */ /* uses register pairs for doubles */
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
vtop->r2 = r+1; vtop->r2 = r+1;
#endif #endif
} }
@ -1036,7 +1036,7 @@ static void lbuild(int t)
vpop(); vpop();
} }
/* rotate n first stack elements to the bottom /* rotate n first stack elements to the bottom
I1 ... In -> I2 ... In I1 [top is right] I1 ... In -> I2 ... In I1 [top is right]
*/ */
ST_FUNC void vrotb(int n) ST_FUNC void vrotb(int n)
@ -1476,7 +1476,7 @@ static void gen_opic(int op)
vtop--; vtop--;
} else { } else {
/* if commutative ops, put c2 as constant */ /* if commutative ops, put c2 as constant */
if (c1 && (op == '+' || op == '&' || op == '^' || if (c1 && (op == '+' || op == '&' || op == '^' ||
op == '|' || op == '*')) { op == '|' || op == '*')) {
vswap(); vswap();
c2 = c1; //c = c1, c1 = c2, c2 = c; c2 = c1; //c = c1, c1 = c2, c2 = c;
@ -1582,13 +1582,13 @@ static void gen_opif(int op)
case '+': f1 += f2; break; case '+': f1 += f2; break;
case '-': f1 -= f2; break; case '-': f1 -= f2; break;
case '*': f1 *= f2; break; case '*': f1 *= f2; break;
case '/': case '/':
if (f2 == 0.0) { if (f2 == 0.0) {
if (const_wanted) if (const_wanted)
tcc_error("division by zero in constant"); tcc_error("division by zero in constant");
goto general_case; goto general_case;
} }
f1 /= f2; f1 /= f2;
break; break;
/* XXX: also handles tests ? */ /* XXX: also handles tests ? */
default: default:
@ -1636,7 +1636,7 @@ static inline int is_null_pointer(SValue *p)
static inline int is_integer_btype(int bt) static inline int is_integer_btype(int bt)
{ {
return (bt == VT_BYTE || bt == VT_SHORT || return (bt == VT_BYTE || bt == VT_SHORT ||
bt == VT_INT || bt == VT_LLONG); bt == VT_INT || bt == VT_LLONG);
} }
@ -1645,7 +1645,7 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
{ {
CType *type1, *type2, tmp_type1, tmp_type2; CType *type1, *type2, tmp_type1, tmp_type2;
int bt1, bt2; int bt1, bt2;
/* null pointers are accepted for all comparisons as gcc */ /* null pointers are accepted for all comparisons as gcc */
if (is_null_pointer(p1) || is_null_pointer(p2)) if (is_null_pointer(p1) || is_null_pointer(p2))
return; return;
@ -1663,16 +1663,16 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
/* both must be pointers or implicit function pointers */ /* both must be pointers or implicit function pointers */
if (bt1 == VT_PTR) { if (bt1 == VT_PTR) {
type1 = pointed_type(type1); type1 = pointed_type(type1);
} else if (bt1 != VT_FUNC) } else if (bt1 != VT_FUNC)
goto invalid_operands; goto invalid_operands;
if (bt2 == VT_PTR) { if (bt2 == VT_PTR) {
type2 = pointed_type(type2); type2 = pointed_type(type2);
} else if (bt2 != VT_FUNC) { } else if (bt2 != VT_FUNC) {
invalid_operands: invalid_operands:
tcc_error("invalid operands to binary %s", get_tok_str(op, NULL)); tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
} }
if ((type1->t & VT_BTYPE) == VT_VOID || if ((type1->t & VT_BTYPE) == VT_VOID ||
(type2->t & VT_BTYPE) == VT_VOID) (type2->t & VT_BTYPE) == VT_VOID)
return; return;
tmp_type1 = *type1; tmp_type1 = *type1;
@ -1698,7 +1698,7 @@ ST_FUNC void gen_op(int op)
t2 = vtop[0].type.t; t2 = vtop[0].type.t;
bt1 = t1 & VT_BTYPE; bt1 = t1 & VT_BTYPE;
bt2 = t2 & VT_BTYPE; bt2 = t2 & VT_BTYPE;
if (bt1 == VT_PTR || bt2 == VT_PTR) { if (bt1 == VT_PTR || bt2 == VT_PTR) {
/* at least one operand is a pointer */ /* at least one operand is a pointer */
/* relationnal op: must be both pointers */ /* relationnal op: must be both pointers */
@ -1729,7 +1729,7 @@ ST_FUNC void gen_op(int op)
#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64) #if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
vtop->type.t = VT_LLONG; vtop->type.t = VT_LLONG;
#else #else
vtop->type.t = VT_INT; vtop->type.t = VT_INT;
#endif #endif
vswap(); vswap();
gen_op(TOK_PDIV); gen_op(TOK_PDIV);
@ -1770,7 +1770,7 @@ ST_FUNC void gen_op(int op)
fprintf(stderr, "v+i-j = %p\n", v+i-j); fprintf(stderr, "v+i-j = %p\n", v+i-j);
fprintf(stderr, "v+(i-j) = %p\n", v+(i-j)); fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
} }
When this code is on. then the output looks like When this code is on. then the output looks like
v+i-j = 0xfffffffe v+i-j = 0xfffffffe
v+(i-j) = 0xbff84000 v+(i-j) = 0xbff84000
*/ */
@ -1880,7 +1880,7 @@ static void gen_cvt_itof1(int t)
#ifdef TCC_TARGET_ARM64 #ifdef TCC_TARGET_ARM64
gen_cvt_itof(t); gen_cvt_itof(t);
#else #else
if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) == if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
(VT_LLONG | VT_UNSIGNED)) { (VT_LLONG | VT_UNSIGNED)) {
if (t == VT_FLOAT) if (t == VT_FLOAT)
@ -2127,7 +2127,7 @@ static void gen_cast(CType *type)
/* scalar to bool */ /* scalar to bool */
vpushi(0); vpushi(0);
gen_op(TOK_NE); gen_op(TOK_NE);
} else if ((dbt & VT_BTYPE) == VT_BYTE || } else if ((dbt & VT_BTYPE) == VT_BYTE ||
(dbt & VT_BTYPE) == VT_SHORT) { (dbt & VT_BTYPE) == VT_SHORT) {
if (sbt == VT_PTR) { if (sbt == VT_PTR) {
vtop->type.t = VT_INT; vtop->type.t = VT_INT;
@ -2140,7 +2140,7 @@ static void gen_cast(CType *type)
/* from long long: just take low order word */ /* from long long: just take low order word */
lexpand(); lexpand();
vpop(); vpop();
} }
/* if lvalue and single word type, nothing to do because /* if lvalue and single word type, nothing to do because
the lvalue already contains the real type size (see the lvalue already contains the real type size (see
VT_LVAL_xxx constants) */ VT_LVAL_xxx constants) */
@ -2194,7 +2194,7 @@ ST_FUNC int type_size(CType *type, int *a)
#endif #endif
#elif defined(TCC_TARGET_ARM) #elif defined(TCC_TARGET_ARM)
#ifdef TCC_ARM_EABI #ifdef TCC_ARM_EABI
*a = 8; *a = 8;
#else #else
*a = 4; *a = 4;
#endif #endif
@ -2289,7 +2289,7 @@ static int is_compatible_func(CType *type1, CType *type2)
/* return true if type1 and type2 are the same. If unqualified is /* return true if type1 and type2 are the same. If unqualified is
true, qualifiers on the types are ignored. true, qualifiers on the types are ignored.
- enums are not checked as gcc __builtin_types_compatible_p () - enums are not checked as gcc __builtin_types_compatible_p ()
*/ */
static int compare_types(CType *type1, CType *type2, int unqualified) static int compare_types(CType *type1, CType *type2, int unqualified)
{ {
@ -2326,7 +2326,7 @@ static int compare_types(CType *type1, CType *type2, int unqualified)
} }
/* return true if type1 and type2 are exactly the same (including /* return true if type1 and type2 are exactly the same (including
qualifiers). qualifiers).
*/ */
static int is_compatible_types(CType *type1, CType *type2) static int is_compatible_types(CType *type1, CType *type2)
{ {
@ -2344,7 +2344,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2)
printed in the type */ printed in the type */
/* XXX: union */ /* XXX: union */
/* XXX: add array and function pointers */ /* XXX: add array and function pointers */
static void type_to_str(char *buf, int buf_size, static void type_to_str(char *buf, int buf_size,
CType *type, const char *varstr) CType *type, const char *varstr)
{ {
int bt, v, t; int bt, v, t;
@ -2487,7 +2487,7 @@ static void gen_assign_cast(CType *dt)
if (sbt != VT_PTR) if (sbt != VT_PTR)
goto error; goto error;
type2 = pointed_type(st); type2 = pointed_type(st);
if ((type1->t & VT_BTYPE) == VT_VOID || if ((type1->t & VT_BTYPE) == VT_VOID ||
(type2->t & VT_BTYPE) == VT_VOID) { (type2->t & VT_BTYPE) == VT_VOID) {
/* void * can match anything */ /* void * can match anything */
} else { } else {
@ -2716,7 +2716,7 @@ ST_FUNC void inc(int post, int c)
vrotb(3); vrotb(3);
} }
/* add constant */ /* add constant */
vpushi(c - TOK_MID); vpushi(c - TOK_MID);
gen_op('+'); gen_op('+');
vstore(); /* store value */ vstore(); /* store value */
if (post) if (post)
@ -2734,7 +2734,7 @@ ST_FUNC void inc(int post, int c)
static void parse_attribute(AttributeDef *ad) static void parse_attribute(AttributeDef *ad)
{ {
int t, n; int t, n;
while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) { while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
next(); next();
skip('('); skip('(');
@ -2787,7 +2787,7 @@ static void parse_attribute(AttributeDef *ad)
if (tok == '(') { if (tok == '(') {
next(); next();
n = expr_const(); n = expr_const();
if (n <= 0 || (n & (n - 1)) != 0) if (n <= 0 || (n & (n - 1)) != 0)
tcc_error("alignment must be a positive power of two"); tcc_error("alignment must be a positive power of two");
skip(')'); skip(')');
} else { } else {
@ -2828,7 +2828,7 @@ static void parse_attribute(AttributeDef *ad)
case TOK_REGPARM2: case TOK_REGPARM2:
skip('('); skip('(');
n = expr_const(); n = expr_const();
if (n > 3) if (n > 3)
n = 3; n = 3;
else if (n < 0) else if (n < 0)
n = 0; n = 0;
@ -2840,7 +2840,7 @@ static void parse_attribute(AttributeDef *ad)
case TOK_FASTCALL2: case TOK_FASTCALL2:
case TOK_FASTCALL3: case TOK_FASTCALL3:
ad->a.func_call = FUNC_FASTCALLW; ad->a.func_call = FUNC_FASTCALLW;
break; break;
#endif #endif
case TOK_MODE: case TOK_MODE:
skip('('); skip('(');
@ -2874,9 +2874,9 @@ static void parse_attribute(AttributeDef *ad)
if (tok == '(') { if (tok == '(') {
int parenthesis = 0; int parenthesis = 0;
do { do {
if (tok == '(') if (tok == '(')
parenthesis++; parenthesis++;
else if (tok == ')') else if (tok == ')')
parenthesis--; parenthesis--;
next(); next();
} while (parenthesis && tok != -1); } while (parenthesis && tok != -1);
@ -2928,7 +2928,7 @@ static void struct_decl(CType *type, int u, int tdef)
do_decl: do_decl:
type->t = u; type->t = u;
type->ref = s; type->ref = s;
if (tok == '{') { if (tok == '{') {
next(); next();
if (s->c != -1) if (s->c != -1)
@ -3001,7 +3001,7 @@ static void struct_decl(CType *type, int u, int tdef)
} }
if ((type1.t & VT_BTYPE) == VT_FUNC || if ((type1.t & VT_BTYPE) == VT_FUNC ||
(type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE))) (type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
tcc_error("invalid type for '%s'", tcc_error("invalid type for '%s'",
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
if (tok == ':') { if (tok == ':') {
@ -3009,10 +3009,10 @@ static void struct_decl(CType *type, int u, int tdef)
bit_size = expr_const(); bit_size = expr_const();
/* XXX: handle v = 0 case for messages */ /* XXX: handle v = 0 case for messages */
if (bit_size < 0) if (bit_size < 0)
tcc_error("negative width in bit-field '%s'", tcc_error("negative width in bit-field '%s'",
get_tok_str(v, NULL)); get_tok_str(v, NULL));
if (v && bit_size == 0) if (v && bit_size == 0)
tcc_error("zero width for bit-field '%s'", tcc_error("zero width for bit-field '%s'",
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
size = type_size(&type1, &align); size = type_size(&type1, &align);
@ -3028,8 +3028,8 @@ static void struct_decl(CType *type, int u, int tdef)
lbit_pos = 0; lbit_pos = 0;
if (bit_size >= 0) { if (bit_size >= 0) {
bt = type1.t & VT_BTYPE; bt = type1.t & VT_BTYPE;
if (bt != VT_INT && if (bt != VT_INT &&
bt != VT_BYTE && bt != VT_BYTE &&
bt != VT_SHORT && bt != VT_SHORT &&
bt != VT_BOOL && bt != VT_BOOL &&
bt != VT_ENUM && bt != VT_ENUM &&
@ -3056,7 +3056,7 @@ static void struct_decl(CType *type, int u, int tdef)
bit_pos = 0; bit_pos = 0;
lbit_pos = bit_pos; lbit_pos = bit_pos;
/* XXX: handle LSB first */ /* XXX: handle LSB first */
type1.t |= VT_BITFIELD | type1.t |= VT_BITFIELD |
(bit_pos << VT_STRUCT_SHIFT) | (bit_pos << VT_STRUCT_SHIFT) |
(bit_size << (VT_STRUCT_SHIFT + 6)); (bit_size << (VT_STRUCT_SHIFT + 6));
bit_pos += bit_size; bit_pos += bit_size;
@ -3083,10 +3083,10 @@ static void struct_decl(CType *type, int u, int tdef)
maxalign = align; maxalign = align;
} }
#if 0 #if 0
printf("add field %s offset=%d", printf("add field %s offset=%d",
get_tok_str(v, NULL), offset); get_tok_str(v, NULL), offset);
if (type1.t & VT_BITFIELD) { if (type1.t & VT_BITFIELD) {
printf(" pos=%d size=%d", printf(" pos=%d size=%d",
(type1.t >> VT_STRUCT_SHIFT) & 0x3f, (type1.t >> VT_STRUCT_SHIFT) & 0x3f,
(type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f); (type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
} }
@ -3113,7 +3113,7 @@ static void struct_decl(CType *type, int u, int tdef)
} }
skip('}'); skip('}');
/* store size and alignment */ /* store size and alignment */
s->c = (c + maxalign - 1) & -maxalign; s->c = (c + maxalign - 1) & -maxalign;
s->r = maxalign; s->r = maxalign;
} }
} }
@ -3126,7 +3126,7 @@ ST_FUNC int is_btype_size(int bt)
} }
/* return 0 if no type declaration. otherwise, return the basic type /* return 0 if no type declaration. otherwise, return the basic type
and skip it. and skip it.
*/ */
static int parse_btype(CType *type, AttributeDef *ad) static int parse_btype(CType *type, AttributeDef *ad)
{ {
@ -3436,9 +3436,9 @@ static void post_type(CType *type, AttributeDef *ad)
skip(')'); skip(')');
/* NOTE: const is ignored in returned type as it has a special /* NOTE: const is ignored in returned type as it has a special
meaning in gcc / C++ */ meaning in gcc / C++ */
type->t &= ~VT_CONSTANT; type->t &= ~VT_CONSTANT;
/* some ancient pre-K&R C allows a function to return an array /* some ancient pre-K&R C allows a function to return an array
and the array brackets to be put after the arguments, such and the array brackets to be put after the arguments, such
that "int c()[]" means something like "int[] c()" */ that "int c()[]" means something like "int[] c()" */
if (tok == '[') { if (tok == '[') {
next(); next();
@ -3479,7 +3479,7 @@ static void post_type(CType *type, AttributeDef *ad)
if (type->t == VT_FUNC) if (type->t == VT_FUNC)
tcc_error("declaration of an array of functions"); tcc_error("declaration of an array of functions");
t1 |= type->t & VT_VLA; t1 |= type->t & VT_VLA;
if (t1 & VT_VLA) { if (t1 & VT_VLA) {
loc -= type_size(&int_type, &align); loc -= type_size(&int_type, &align);
loc &= -align; loc &= -align;
@ -3493,7 +3493,7 @@ static void post_type(CType *type, AttributeDef *ad)
} }
if (n != -1) if (n != -1)
vpop(); vpop();
/* we push an anonymous symbol which will contain the array /* we push an anonymous symbol which will contain the array
element type */ element type */
s = sym_push(SYM_FIELD, type, 0, n); s = sym_push(SYM_FIELD, type, 0, n);
@ -3506,7 +3506,7 @@ static void post_type(CType *type, AttributeDef *ad)
in 'type'. 'td' is a bitmask indicating which kind of type decl is in 'type'. 'td' is a bitmask indicating which kind of type decl is
expected. 'type' should contain the basic type. 'ad' is the expected. 'type' should contain the basic type. 'ad' is the
attribute definition of the basic type. It can be modified by attribute definition of the basic type. It can be modified by
type_decl(). type_decl().
*/ */
static void type_decl(CType *type, AttributeDef *ad, int *v, int td) static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
{ {
@ -3537,7 +3537,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
mk_pointer(type); mk_pointer(type);
type->t |= qualifiers; type->t |= qualifiers;
} }
/* XXX: clarify attribute handling */ /* XXX: clarify attribute handling */
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
parse_attribute(ad); parse_attribute(ad);
@ -3576,7 +3576,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
type->t |= storage; type->t |= storage;
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
parse_attribute(ad); parse_attribute(ad);
if (!type1.t) if (!type1.t)
return; return;
/* append type at the end of type1 */ /* append type at the end of type1 */
@ -3711,7 +3711,7 @@ ST_FUNC void unary(void)
next(); next();
goto tok_next; goto tok_next;
case TOK_CINT: case TOK_CINT:
case TOK_CCHAR: case TOK_CCHAR:
case TOK_LCHAR: case TOK_LCHAR:
vpushi(tokc.i); vpushi(tokc.i);
next(); next();
@ -3814,7 +3814,7 @@ ST_FUNC void unary(void)
linux/include/net/tcp.h:945: error: statement expression in global scope */ linux/include/net/tcp.h:945: error: statement expression in global scope */
/* save all registers */ /* save all registers */
save_regs(0); save_regs(0);
/* statement expression : we do not accept break/continue /* statement expression : we do not accept break/continue
inside as GCC does */ inside as GCC does */
block(NULL, NULL, NULL, NULL, 0, 1); block(NULL, NULL, NULL, NULL, 0, 1);
@ -4087,7 +4087,7 @@ ST_FUNC void unary(void)
vpushsym(&s->type, s); vpushsym(&s->type, s);
next(); next();
break; break;
// special qnan , snan and infinity values // special qnan , snan and infinity values
case TOK___NAN__: case TOK___NAN__:
vpush64(VT_DOUBLE, 0x7ff8000000000000ULL); vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
@ -4123,7 +4123,7 @@ ST_FUNC void unary(void)
#endif #endif
) )
tcc_warning("implicit declaration of function '%s'", name); tcc_warning("implicit declaration of function '%s'", name);
s = external_global_sym(t, &func_old_type, 0); s = external_global_sym(t, &func_old_type, 0);
} }
if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) == if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
(VT_STATIC | VT_INLINE | VT_FUNC)) { (VT_STATIC | VT_INLINE | VT_FUNC)) {
@ -4146,7 +4146,7 @@ ST_FUNC void unary(void)
} }
break; break;
} }
/* post operations */ /* post operations */
while (1) { while (1) {
if (tok == TOK_INC || tok == TOK_DEC) { if (tok == TOK_INC || tok == TOK_DEC) {
@ -4154,8 +4154,8 @@ ST_FUNC void unary(void)
next(); next();
} else if (tok == '.' || tok == TOK_ARROW) { } else if (tok == '.' || tok == TOK_ARROW) {
int qualifiers; int qualifiers;
/* field */ /* field */
if (tok == TOK_ARROW) if (tok == TOK_ARROW)
indir(); indir();
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE); qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
test_lvalue(); test_lvalue();
@ -4637,7 +4637,7 @@ static void expr_cond(void)
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)) (t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
type.t |= VT_UNSIGNED; type.t |= VT_UNSIGNED;
} }
/* now we convert second operand */ /* now we convert second operand */
gen_cast(&type); gen_cast(&type);
if (VT_STRUCT == (vtop->type.t & VT_BTYPE)) if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
@ -4653,9 +4653,9 @@ static void expr_cond(void)
} else if ((type.t & VT_BTYPE) == VT_LLONG) { } else if ((type.t & VT_BTYPE) == VT_LLONG) {
/* for long longs, we use fixed registers to avoid having /* for long longs, we use fixed registers to avoid having
to handle a complicated move */ to handle a complicated move */
rc = RC_IRET; rc = RC_IRET;
} }
r2 = gv(rc); r2 = gv(rc);
/* this is horrible, but we must also convert first /* this is horrible, but we must also convert first
operand */ operand */
@ -4677,7 +4677,7 @@ static void expr_cond(void)
static void expr_eq(void) static void expr_eq(void)
{ {
int t; int t;
expr_cond(); expr_cond();
if (tok == '=' || if (tok == '=' ||
(tok >= TOK_A_MOD && tok <= TOK_A_DIV) || (tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
@ -4797,7 +4797,7 @@ static void label_or_decl(int l)
decl(l); decl(l);
} }
static void block(int *bsym, int *csym, int *case_sym, int *def_sym, static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
int case_reg, int is_expr) int case_reg, int is_expr)
{ {
int a, b, c, d; int a, b, c, d;
@ -4858,7 +4858,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
frame_bottom->next = scope_stack_bottom; frame_bottom->next = scope_stack_bottom;
scope_stack_bottom = frame_bottom; scope_stack_bottom = frame_bottom;
llabel = local_label_stack; llabel = local_label_stack;
/* handle local labels declarations */ /* handle local labels declarations */
if (tok == TOK_LABEL) { if (tok == TOK_LABEL) {
next(); next();
@ -4906,14 +4906,14 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
/* pop locally defined symbols */ /* pop locally defined symbols */
scope_stack_bottom = scope_stack_bottom->next; scope_stack_bottom = scope_stack_bottom->next;
sym_pop(&local_stack, s); sym_pop(&local_stack, s);
/* Pop VLA frames and restore stack pointer if required */ /* Pop VLA frames and restore stack pointer if required */
if (vlas_in_scope > saved_vlas_in_scope) { if (vlas_in_scope > saved_vlas_in_scope) {
vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc; vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
vla_sp_restore(); vla_sp_restore();
} }
vlas_in_scope = saved_vlas_in_scope; vlas_in_scope = saved_vlas_in_scope;
next(); next();
} else if (tok == TOK_RETURN) { } else if (tok == TOK_RETURN) {
next(); next();
@ -5080,7 +5080,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
gsym_addr(b, c); gsym_addr(b, c);
scope_stack_bottom = scope_stack_bottom->next; scope_stack_bottom = scope_stack_bottom->next;
sym_pop(&local_stack, s); sym_pop(&local_stack, s);
} else } else
if (tok == TOK_DO) { if (tok == TOK_DO) {
next(); next();
a = 0; a = 0;
@ -5154,7 +5154,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
skip(':'); skip(':');
is_expr = 0; is_expr = 0;
goto block_after_label; goto block_after_label;
} else } else
if (tok == TOK_DEFAULT) { if (tok == TOK_DEFAULT) {
next(); next();
skip(':'); skip(':');
@ -5185,7 +5185,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
s->r = LABEL_FORWARD; s->r = LABEL_FORWARD;
} }
vla_sp_restore_root(); vla_sp_restore_root();
if (s->r & LABEL_FORWARD) if (s->r & LABEL_FORWARD)
s->jnext = gjmp(s->jnext); s->jnext = gjmp(s->jnext);
else else
gjmp_addr(s->jnext); gjmp_addr(s->jnext);
@ -5240,8 +5240,8 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
address. cur_index/cur_field is the pointer to the current address. cur_index/cur_field is the pointer to the current
value. 'size_only' is true if only size info is needed (only used value. 'size_only' is true if only size info is needed (only used
in arrays) */ in arrays) */
static void decl_designator(CType *type, Section *sec, unsigned long c, static void decl_designator(CType *type, Section *sec, unsigned long c,
int *cur_index, Sym **cur_field, int *cur_index, Sym **cur_field,
int size_only) int size_only)
{ {
Sym *s, *f; Sym *s, *f;
@ -5265,7 +5265,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
if (tok == TOK_DOTS && gnu_ext) { if (tok == TOK_DOTS && gnu_ext) {
next(); next();
index_last = expr_const(); index_last = expr_const();
if (index_last < 0 || if (index_last < 0 ||
(s->c >= 0 && index_last >= s->c) || (s->c >= 0 && index_last >= s->c) ||
index_last < index) index_last < index)
expect("invalid index"); expect("invalid index");
@ -5361,7 +5361,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
#define EXPR_ANY 2 #define EXPR_ANY 2
/* store a value or an expression directly in global data or in local array */ /* store a value or an expression directly in global data or in local array */
static void init_putv(CType *type, Section *sec, unsigned long c, static void init_putv(CType *type, Section *sec, unsigned long c,
int v, int expr_type) int v, int expr_type)
{ {
int saved_global_expr, bt, bit_pos, bit_size; int saved_global_expr, bt, bit_pos, bit_size;
@ -5387,7 +5387,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
expr_eq(); expr_eq();
break; break;
} }
dtype = *type; dtype = *type;
dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */ dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
@ -5502,7 +5502,7 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size)
allocation. 'first' is true if array '{' must be read (multi allocation. 'first' is true if array '{' must be read (multi
dimension implicit array init handling). 'size_only' is true if dimension implicit array init handling). 'size_only' is true if
size only evaluation is wanted (only for arrays). */ size only evaluation is wanted (only for arrays). */
static void decl_initializer(CType *type, Section *sec, unsigned long c, static void decl_initializer(CType *type, Section *sec, unsigned long c,
int first, int size_only) int first, int size_only)
{ {
int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i; int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
@ -5512,14 +5512,14 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
if (type->t & VT_VLA) { if (type->t & VT_VLA) {
int a; int a;
/* save current stack pointer */ /* save current stack pointer */
if (vlas_in_scope == 0) { if (vlas_in_scope == 0) {
if (vla_sp_root_loc == -1) if (vla_sp_root_loc == -1)
vla_sp_root_loc = (loc -= PTR_SIZE); vla_sp_root_loc = (loc -= PTR_SIZE);
gen_vla_sp_save(vla_sp_root_loc); gen_vla_sp_save(vla_sp_root_loc);
} }
vla_runtime_type_size(type, &a); vla_runtime_type_size(type, &a);
gen_vla_alloc(type, a); gen_vla_alloc(type, a);
gen_vla_sp_save(c); gen_vla_sp_save(c);
@ -5533,7 +5533,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
size1 = type_size(t1, &align1); size1 = type_size(t1, &align1);
no_oblock = 1; no_oblock = 1;
if ((first && tok != TOK_LSTR && tok != TOK_STR) || if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
tok == '{') { tok == '{') {
if (tok != '{') if (tok != '{')
tcc_error("character array initializer must be a literal," tcc_error("character array initializer must be a literal,"
@ -5544,7 +5544,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
/* only parse strings here if correct type (otherwise: handle /* only parse strings here if correct type (otherwise: handle
them as ((w)char *) expressions */ them as ((w)char *) expressions */
if ((tok == TOK_LSTR && if ((tok == TOK_LSTR &&
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
(t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED) (t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
#else #else
@ -5604,7 +5604,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
/* must put zero in holes (note that doing it that way /* must put zero in holes (note that doing it that way
ensures that it even works with designators) */ ensures that it even works with designators) */
if (!size_only && array_length < index) { if (!size_only && array_length < index) {
init_putz(t1, sec, c + array_length * size1, init_putz(t1, sec, c + array_length * size1,
(index - array_length) * size1); (index - array_length) * size1);
} }
index++; index++;
@ -5624,7 +5624,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
skip('}'); skip('}');
/* put zeros at the end */ /* put zeros at the end */
if (!size_only && n >= 0 && array_length < n) { if (!size_only && n >= 0 && array_length < n) {
init_putz(t1, sec, c + array_length * size1, init_putz(t1, sec, c + array_length * size1,
(n - array_length) * size1); (n - array_length) * size1);
} }
/* patch type size if needed */ /* patch type size if needed */
@ -5690,7 +5690,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
decl_designator(type, sec, c, NULL, &f, size_only); decl_designator(type, sec, c, NULL, &f, size_only);
index = f->c; index = f->c;
if (!size_only && array_length < index) { if (!size_only && array_length < index) {
init_putz(type, sec, c + array_length, init_putz(type, sec, c + array_length,
index - array_length); index - array_length);
} }
index = index + type_size(&f->type, &align1); index = index + type_size(&f->type, &align1);
@ -5743,7 +5743,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
} }
/* put zeros at the end */ /* put zeros at the end */
if (!size_only && array_length < n) { if (!size_only && array_length < n) {
init_putz(type, sec, c + array_length, init_putz(type, sec, c + array_length,
n - array_length); n - array_length);
} }
if (!no_oblock) if (!no_oblock)
@ -5795,7 +5795,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
zero, then a reference to the new object is put in the value stack. zero, then a reference to the new object is put in the value stack.
If 'has_init' is 2, a special parsing is done to handle string If 'has_init' is 2, a special parsing is done to handle string
constants. */ constants. */
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
int has_init, int v, char *asm_label, int has_init, int v, char *asm_label,
int scope) int scope)
{ {
@ -5826,7 +5826,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
initializers handling */ initializers handling */
tok_str_new(&init_str); tok_str_new(&init_str);
if (size < 0 || (flexible_array && has_init)) { if (size < 0 || (flexible_array && has_init)) {
if (!has_init) if (!has_init)
tcc_error("unknown type size"); tcc_error("unknown type size");
/* get all init string */ /* get all init string */
if (has_init == 2) { if (has_init == 2) {
@ -5855,7 +5855,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
} }
tok_str_add(&init_str, -1); tok_str_add(&init_str, -1);
tok_str_add(&init_str, 0); tok_str_add(&init_str, 0);
/* compute size */ /* compute size */
save_parse_state(&saved_parse_state); save_parse_state(&saved_parse_state);
@ -5865,10 +5865,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
/* prepare second initializer parsing */ /* prepare second initializer parsing */
macro_ptr = init_str.str; macro_ptr = init_str.str;
next(); next();
/* if still unknown size, error */ /* if still unknown size, error */
size = type_size(type, &align); size = type_size(type, &align);
if (size < 0) if (size < 0)
tcc_error("unknown type size"); tcc_error("unknown type size");
} }
if (flexible_array) if (flexible_array)
@ -5919,14 +5919,14 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
sym = sym_find(v); sym = sym_find(v);
if (sym) { if (sym) {
if (!is_compatible_types(&sym->type, type)) if (!is_compatible_types(&sym->type, type))
tcc_error("incompatible types for redefinition of '%s'", tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(v, NULL)); get_tok_str(v, NULL));
if (sym->type.t & VT_EXTERN) { if (sym->type.t & VT_EXTERN) {
/* if the variable is extern, it was not allocated */ /* if the variable is extern, it was not allocated */
sym->type.t &= ~VT_EXTERN; sym->type.t &= ~VT_EXTERN;
/* set array size if it was omitted in extern /* set array size if it was omitted in extern
declaration */ declaration */
if ((sym->type.t & VT_ARRAY) && if ((sym->type.t & VT_ARRAY) &&
sym->type.ref->c < 0 && sym->type.ref->c < 0 &&
type->ref->c >= 0) type->ref->c >= 0)
sym->type.ref->c = type->ref->c; sym->type.ref->c = type->ref->c;
@ -5966,7 +5966,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
#endif #endif
sec->data_offset = data_offset; sec->data_offset = data_offset;
/* allocate section space to put the data */ /* allocate section space to put the data */
if (sec->sh_type != SHT_NOBITS && if (sec->sh_type != SHT_NOBITS &&
data_offset > sec->data_allocated) data_offset > sec->data_allocated)
section_realloc(sec, data_offset); section_realloc(sec, data_offset);
/* align section if needed */ /* align section if needed */
@ -6036,12 +6036,12 @@ static void put_func_debug(Sym *sym)
/* stabs info */ /* stabs info */
/* XXX: we put here a dummy type */ /* XXX: we put here a dummy type */
snprintf(buf, sizeof(buf), "%s:%c1", snprintf(buf, sizeof(buf), "%s:%c1",
funcname, sym->type.t & VT_STATIC ? 'f' : 'F'); funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
put_stabs_r(buf, N_FUN, 0, file->line_num, 0, put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
cur_text_section, sym->c); cur_text_section, sym->c);
/* //gr gdb wants a line at the function */ /* //gr gdb wants a line at the function */
put_stabn(N_SLINE, 0, file->line_num, 0); put_stabn(N_SLINE, 0, file->line_num, 0);
last_ind = 0; last_ind = 0;
last_line_num = 0; last_line_num = 0;
} }
@ -6058,10 +6058,10 @@ static void func_decl_list(Sym *func_sym)
/* parse each declaration */ /* parse each declaration */
while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF && while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) { tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
if (!parse_btype(&btype, &ad)) if (!parse_btype(&btype, &ad))
expect("declaration list"); expect("declaration list");
if (((btype.t & VT_BTYPE) == VT_ENUM || if (((btype.t & VT_BTYPE) == VT_ENUM ||
(btype.t & VT_BTYPE) == VT_STRUCT) && (btype.t & VT_BTYPE) == VT_STRUCT) &&
tok == ';') { tok == ';') {
/* we accept no variable after */ /* we accept no variable after */
} else { } else {
@ -6080,7 +6080,7 @@ static void func_decl_list(Sym *func_sym)
found: found:
/* check that no storage specifier except 'register' was given */ /* check that no storage specifier except 'register' was given */
if (type.t & VT_STORAGE) if (type.t & VT_STORAGE)
tcc_error("storage class specified for '%s'", get_tok_str(v, NULL)); tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
convert_parameter_type(&type); convert_parameter_type(&type);
/* we can add the type (NOTE: it could be local to the function) */ /* we can add the type (NOTE: it could be local to the function) */
s->type = type; s->type = type;
@ -6140,7 +6140,7 @@ static void gen_function(Sym *sym)
sym_pop(&local_stack, NULL); sym_pop(&local_stack, NULL);
/* end of function */ /* end of function */
/* patch symbol size */ /* patch symbol size */
((ElfW(Sym) *)symtab_section->data)[sym->c].st_size = ((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
ind - func_ind; ind - func_ind;
/* patch symbol weakness (this definition overrules any prototype) */ /* patch symbol weakness (this definition overrules any prototype) */
if (sym->type.t & VT_WEAK) if (sym->type.t & VT_WEAK)
@ -6234,7 +6234,7 @@ static int decl0(int l, int is_for_loop_init)
btype.t = VT_INT; btype.t = VT_INT;
} }
if (((btype.t & VT_BTYPE) == VT_ENUM || if (((btype.t & VT_BTYPE) == VT_ENUM ||
(btype.t & VT_BTYPE) == VT_STRUCT) && (btype.t & VT_BTYPE) == VT_STRUCT) &&
tok == ';') { tok == ';') {
if ((btype.t & VT_BTYPE) == VT_STRUCT) { if ((btype.t & VT_BTYPE) == VT_STRUCT) {
int v = btype.ref->v; int v = btype.ref->v;
@ -6273,7 +6273,7 @@ static int decl0(int l, int is_for_loop_init)
asm_label_instr(&astr); asm_label_instr(&astr);
asm_label = tcc_strdup(astr.data); asm_label = tcc_strdup(astr.data);
cstr_free(&astr); cstr_free(&astr);
/* parse one last attribute list, after asm label */ /* parse one last attribute list, after asm label */
parse_attribute(&ad); parse_attribute(&ad);
} }
@ -6299,11 +6299,11 @@ static int decl0(int l, int is_for_loop_init)
while ((sym = sym->next) != NULL) while ((sym = sym->next) != NULL)
if (!(sym->v & ~SYM_FIELD)) if (!(sym->v & ~SYM_FIELD))
expect("identifier"); expect("identifier");
/* XXX: cannot do better now: convert extern line to static inline */ /* XXX: cannot do better now: convert extern line to static inline */
if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE)) if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
type.t = (type.t & ~VT_EXTERN) | VT_STATIC; type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
sym = sym_find(v); sym = sym_find(v);
if (sym) { if (sym) {
Sym *ref; Sym *ref;
@ -6334,7 +6334,7 @@ static int decl0(int l, int is_for_loop_init)
if (!is_compatible_types(&sym->type, &type)) { if (!is_compatible_types(&sym->type, &type)) {
func_error1: func_error1:
tcc_error("incompatible types for redefinition of '%s'", tcc_error("incompatible types for redefinition of '%s'",
get_tok_str(v, NULL)); get_tok_str(v, NULL));
} }
type.ref->a.func_proto = 0; type.ref->a.func_proto = 0;
@ -6349,18 +6349,18 @@ static int decl0(int l, int is_for_loop_init)
/* static inline functions are just recorded as a kind /* static inline functions are just recorded as a kind
of macro. Their code will be emitted at the end of of macro. Their code will be emitted at the end of
the compilation unit only if they are used */ the compilation unit only if they are used */
if ((type.t & (VT_INLINE | VT_STATIC)) == if ((type.t & (VT_INLINE | VT_STATIC)) ==
(VT_INLINE | VT_STATIC)) { (VT_INLINE | VT_STATIC)) {
int block_level; int block_level;
struct InlineFunc *fn; struct InlineFunc *fn;
const char *filename; const char *filename;
filename = file ? file->filename : ""; filename = file ? file->filename : "";
fn = tcc_malloc(sizeof *fn + strlen(filename)); fn = tcc_malloc(sizeof *fn + strlen(filename));
strcpy(fn->filename, filename); strcpy(fn->filename, filename);
fn->sym = sym; fn->sym = sym;
tok_str_new(&fn->func_str); tok_str_new(&fn->func_str);
block_level = 0; block_level = 0;
for(;;) { for(;;) {
int t; int t;

View file

@ -1,8 +1,8 @@
/* Simple libc header for TCC /* Simple libc header for TCC
* *
* Add any function you want from the libc there. This file is here * Add any function you want from the libc there. This file is here
* only for your convenience so that you do not need to put the whole * only for your convenience so that you do not need to put the whole
* glibc include files on your floppy disk * glibc include files on your floppy disk
*/ */
#ifndef _TCCLIB_H #ifndef _TCCLIB_H
#define _TCCLIB_H #define _TCCLIB_H

View file

@ -1266,7 +1266,7 @@ static int pe_check_symbols(struct pe_info *pe)
put_elf_reloc(symtab_section, text_section, put_elf_reloc(symtab_section, text_section,
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
#else #else
put_elf_reloc(symtab_section, text_section, put_elf_reloc(symtab_section, text_section,
offset + 2, R_XXX_THUNKFIX, is->iat_index); offset + 2, R_XXX_THUNKFIX, is->iat_index);
#endif #endif
is->thk_offset = offset; is->thk_offset = offset;

72
tccpp.c
View file

@ -1,6 +1,6 @@
/* /*
* TCC - Tiny C Compiler * TCC - Tiny C Compiler
* *
* Copyright (c) 2001-2004 Fabrice Bellard * Copyright (c) 2001-2004 Fabrice Bellard
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
@ -50,7 +50,7 @@ static unsigned char isidnum_table[256 - CH_EOF];
static TokenString *macro_stack; static TokenString *macro_stack;
static const char tcc_keywords[] = static const char tcc_keywords[] =
#define DEF(id, str) str "\0" #define DEF(id, str) str "\0"
#include "tcctok.h" #include "tcctok.h"
#undef DEF #undef DEF
@ -221,7 +221,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
TokenSym *ts, **ptable; TokenSym *ts, **ptable;
int i; int i;
if (tok_ident >= SYM_FIRST_ANOM) if (tok_ident >= SYM_FIRST_ANOM)
tcc_error("memory full (symbols)"); tcc_error("memory full (symbols)");
/* expand token table if needed */ /* expand token table if needed */
@ -255,7 +255,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len)
TokenSym *ts, **pts; TokenSym *ts, **pts;
int i; int i;
unsigned int h; unsigned int h;
h = TOK_HASH_INIT; h = TOK_HASH_INIT;
for(i=0;i<len;i++) for(i=0;i<len;i++)
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]); h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
@ -511,7 +511,7 @@ static int handle_stray1(uint8_t *p)
ST_FUNC void minp(void) ST_FUNC void minp(void)
{ {
inp(); inp();
if (ch == '\\') if (ch == '\\')
handle_stray(); handle_stray();
} }
@ -557,7 +557,7 @@ static uint8_t *parse_line_comment(uint8_t *p)
ST_FUNC uint8_t *parse_comment(uint8_t *p) ST_FUNC uint8_t *parse_comment(uint8_t *p)
{ {
int c; int c;
p++; p++;
for(;;) { for(;;) {
/* fast skip loop */ /* fast skip loop */
@ -635,13 +635,13 @@ static inline void skip_spaces(void)
cinp(); cinp();
} }
static inline int check_space(int t, int *spc) static inline int check_space(int t, int *spc)
{ {
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) { if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
if (*spc) if (*spc)
return 1; return 1;
*spc = 1; *spc = 1;
} else } else
*spc = 0; *spc = 0;
return 0; return 0;
} }
@ -774,7 +774,7 @@ redo_start:
file->buf_ptr = p; file->buf_ptr = p;
next_nomacro(); next_nomacro();
p = file->buf_ptr; p = file->buf_ptr;
if (a == 0 && if (a == 0 &&
(tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF)) (tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
goto the_end; goto the_end;
if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF) if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
@ -930,7 +930,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
cstr->size = cv->cstr->size; cstr->size = cv->cstr->size;
cstr->data_allocated = NULL; cstr->data_allocated = NULL;
cstr->size_allocated = cstr->size; cstr->size_allocated = cstr->size;
memcpy((char *)cstr + sizeof(CString), memcpy((char *)cstr + sizeof(CString),
cv->cstr->data, cstr->size); cv->cstr->data, cstr->size);
len += nb_words; len += nb_words;
} }
@ -1253,14 +1253,14 @@ static int expr_preprocess(void)
{ {
int c, t; int c, t;
TokenString str; TokenString str;
tok_str_new(&str); tok_str_new(&str);
while (tok != TOK_LINEFEED && tok != TOK_EOF) { while (tok != TOK_LINEFEED && tok != TOK_EOF) {
next(); /* do macro subst */ next(); /* do macro subst */
if (tok == TOK_DEFINED) { if (tok == TOK_DEFINED) {
next_nomacro(); next_nomacro();
t = tok; t = tok;
if (t == '(') if (t == '(')
next_nomacro(); next_nomacro();
c = define_find(tok) != 0; c = define_find(tok) != 0;
if (t == '(') if (t == '(')
@ -1914,7 +1914,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
break; break;
case '\'': case '\'':
case '\"': case '\"':
case '\\': case '\\':
case '?': case '?':
break; break;
default: default:
@ -2070,7 +2070,7 @@ static void parse_number(const char *p)
*q = '\0'; *q = '\0';
if (b == 16) if (b == 16)
shift = 4; shift = 4;
else else
shift = 1; shift = 1;
bn_zero(bn); bn_zero(bn);
q = token_buf; q = token_buf;
@ -2126,7 +2126,7 @@ static void parse_number(const char *p)
ch = *p++; ch = *p++;
} }
exp_val = exp_val * s; exp_val = exp_val * s;
/* now we can generate the number */ /* now we can generate the number */
/* XXX: should patch directly float number */ /* XXX: should patch directly float number */
d = (double)bn[1] * 4294967296.0 + (double)bn[0]; d = (double)bn[1] * 4294967296.0 + (double)bn[0];
@ -2363,7 +2363,7 @@ static inline void next_nomacro1(void)
} else { } else {
tok_flags &= ~TOK_FLAG_EOF; tok_flags &= ~TOK_FLAG_EOF;
/* pop include file */ /* pop include file */
/* test if previous '#endif' was after a #ifdef at /* test if previous '#endif' was after a #ifdef at
start of file */ start of file */
if (tok_flags & TOK_FLAG_ENDIF) { if (tok_flags & TOK_FLAG_ENDIF) {
@ -2400,7 +2400,7 @@ maybe_newline:
case '#': case '#':
/* XXX: simplify */ /* XXX: simplify */
PEEKC(c, p); PEEKC(c, p);
if ((tok_flags & TOK_FLAG_BOL) && if ((tok_flags & TOK_FLAG_BOL) &&
(parse_flags & PARSE_FLAG_PREPROCESS)) { (parse_flags & PARSE_FLAG_PREPROCESS)) {
file->buf_ptr = p; file->buf_ptr = p;
preprocess(tok_flags & TOK_FLAG_BOF); preprocess(tok_flags & TOK_FLAG_BOF);
@ -2420,7 +2420,7 @@ maybe_newline:
} }
} }
break; break;
/* dollar is allowed to start identifiers when not parsing asm */ /* dollar is allowed to start identifiers when not parsing asm */
case '$': case '$':
if (!(isidnum_table[c - CH_EOF] & IS_ID) if (!(isidnum_table[c - CH_EOF] & IS_ID)
@ -2433,14 +2433,14 @@ maybe_newline:
case 'm': case 'n': case 'o': case 'p': case 'm': case 'n': case 'o': case 'p':
case 'q': case 'r': case 's': case 't': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'A': case 'B': case 'C': case 'D':
case 'E': case 'F': case 'G': case 'H': case 'E': case 'F': case 'G': case 'H':
case 'I': case 'J': case 'K': case 'I': case 'J': case 'K':
case 'M': case 'N': case 'O': case 'P': case 'M': case 'N': case 'O': case 'P':
case 'Q': case 'R': case 'S': case 'T': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z': case 'Y': case 'Z':
case '_': case '_':
parse_ident_fast: parse_ident_fast:
p1 = p; p1 = p;
@ -2594,7 +2594,7 @@ maybe_newline:
tok = TOK_GT; tok = TOK_GT;
} }
break; break;
case '&': case '&':
PEEKC(c, p); PEEKC(c, p);
if (c == '&') { if (c == '&') {
@ -2607,7 +2607,7 @@ maybe_newline:
tok = '&'; tok = '&';
} }
break; break;
case '|': case '|':
PEEKC(c, p); PEEKC(c, p);
if (c == '|') { if (c == '|') {
@ -2633,7 +2633,7 @@ maybe_newline:
tok = '+'; tok = '+';
} }
break; break;
case '-': case '-':
PEEKC(c, p); PEEKC(c, p);
if (c == '-') { if (c == '-') {
@ -2655,7 +2655,7 @@ maybe_newline:
PARSE2('*', '*', '=', TOK_A_MUL) PARSE2('*', '*', '=', TOK_A_MUL)
PARSE2('%', '%', '=', TOK_A_MOD) PARSE2('%', '%', '=', TOK_A_MOD)
PARSE2('^', '^', '=', TOK_A_XOR) PARSE2('^', '^', '=', TOK_A_XOR)
/* comments or operator */ /* comments or operator */
case '/': case '/':
PEEKC(c, p); PEEKC(c, p);
@ -2675,7 +2675,7 @@ maybe_newline:
tok = '/'; tok = '/';
} }
break; break;
/* simple tokens */ /* simple tokens */
case '(': case '(':
case ')': case ')':
@ -2730,7 +2730,7 @@ ST_FUNC void next_nomacro(void)
next_nomacro_spc(); next_nomacro_spc();
} while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC)); } while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
} }
static void macro_subst( static void macro_subst(
TokenString *tok_str, TokenString *tok_str,
@ -2924,7 +2924,7 @@ static int macro_subst_tok(
CValue cval; CValue cval;
CString cstr; CString cstr;
char buf[32]; char buf[32];
/* if symbol is a macro, prepare substitution */ /* if symbol is a macro, prepare substitution */
/* special macros */ /* special macros */
if (tok == TOK___LINE__) { if (tok == TOK___LINE__) {
@ -2942,10 +2942,10 @@ static int macro_subst_tok(
time(&ti); time(&ti);
tm = localtime(&ti); tm = localtime(&ti);
if (tok == TOK___DATE__) { if (tok == TOK___DATE__) {
snprintf(buf, sizeof(buf), "%s %2d %d", snprintf(buf, sizeof(buf), "%s %2d %d",
ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900); ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
} else { } else {
snprintf(buf, sizeof(buf), "%02d:%02d:%02d", snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_hour, tm->tm_min, tm->tm_sec);
} }
cstrval = buf; cstrval = buf;
@ -3010,8 +3010,8 @@ static int macro_subst_tok(
tok_str_new(&str); tok_str_new(&str);
parlevel = spc = 0; parlevel = spc = 0;
/* NOTE: non zero sa->t indicates VA_ARGS */ /* NOTE: non zero sa->t indicates VA_ARGS */
while ((parlevel > 0 || while ((parlevel > 0 ||
(tok != ')' && (tok != ')' &&
(tok != ',' || sa->type.t)))) { (tok != ',' || sa->type.t)))) {
if (tok == TOK_EOF || tok == 0) if (tok == TOK_EOF || tok == 0)
break; break;
@ -3143,7 +3143,7 @@ static inline int *macro_twosharps(const int *ptr0)
/* given 'a##b', remove nosubsts preceding 'b' */ /* given 'a##b', remove nosubsts preceding 'b' */
while ((t1 = *++ptr) == TOK_NOSUBST) while ((t1 = *++ptr) == TOK_NOSUBST)
; ;
if (t1 && t1 != TOK_TWOSHARPS if (t1 && t1 != TOK_TWOSHARPS
&& t1 != ':') /* 'a##:' don't build a new token */ && t1 != ':') /* 'a##:' don't build a new token */
{ {
TOK_GET(&t1, &ptr, &cv1); TOK_GET(&t1, &ptr, &cv1);
@ -3181,7 +3181,7 @@ static void macro_subst(
int t, spc, nosubst; int t, spc, nosubst;
CValue cval; CValue cval;
int *macro_str1 = NULL; int *macro_str1 = NULL;
/* first scan for '##' operator handling */ /* first scan for '##' operator handling */
ptr = macro_str; ptr = macro_str;
spc = nosubst = 0; spc = nosubst = 0;
@ -3334,7 +3334,7 @@ ST_FUNC void preprocess_new(void)
: 0; : 0;
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *)); memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
tok_ident = TOK_IDENT; tok_ident = TOK_IDENT;
p = tcc_keywords; p = tcc_keywords;
while (*p) { while (*p) {

View file

@ -36,7 +36,7 @@
DEF(TOK_RESTRICT2, "__restrict") DEF(TOK_RESTRICT2, "__restrict")
DEF(TOK_RESTRICT3, "__restrict__") DEF(TOK_RESTRICT3, "__restrict__")
DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */ DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
DEF(TOK_FLOAT, "float") DEF(TOK_FLOAT, "float")
DEF(TOK_DOUBLE, "double") DEF(TOK_DOUBLE, "double")
DEF(TOK_BOOL, "_Bool") DEF(TOK_BOOL, "_Bool")

View file

@ -41,7 +41,7 @@ static int run_callback(const char *src, callback_type callback) {
TCCState *s; TCCState *s;
int result; int result;
void *ptr; void *ptr;
s = tcc_new(); s = tcc_new();
if (!s) if (!s)
return -1; return -1;
@ -54,14 +54,14 @@ static int run_callback(const char *src, callback_type callback) {
return -1; return -1;
if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1) if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
return -1; return -1;
ptr = tcc_get_symbol(s, "f"); ptr = tcc_get_symbol(s, "f");
if (!ptr) if (!ptr)
return -1; return -1;
result = callback(ptr); result = callback(ptr);
tcc_delete(s); tcc_delete(s);
return result; return result;
} }
@ -89,7 +89,7 @@ RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
/* /*
* ret_2float_test: * ret_2float_test:
* *
* On x86-64, a struct with 2 floats should be packed into a single * On x86-64, a struct with 2 floats should be packed into a single
* SSE register (VT_DOUBLE is used for this purpose). * SSE register (VT_DOUBLE is used for this purpose).
*/ */
@ -117,7 +117,7 @@ static int ret_2float_test(void) {
/* /*
* ret_2double_test: * ret_2double_test:
* *
* On x86-64, a struct with 2 doubles should be passed in two SSE * On x86-64, a struct with 2 doubles should be passed in two SSE
* registers. * registers.
*/ */
@ -281,7 +281,7 @@ static int reg_pack_test(void) {
" reg_pack_test_type r = {a.x*5, a.y*3};\n" " reg_pack_test_type r = {a.x*5, a.y*3};\n"
" return r;\n" " return r;\n"
"}\n"; "}\n";
return run_callback(src, reg_pack_test_callback); return run_callback(src, reg_pack_test_callback);
} }
@ -307,7 +307,7 @@ static int reg_pack_longlong_test(void) {
" reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n" " reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
" return r;\n" " return r;\n"
"}\n"; "}\n";
return run_callback(src, reg_pack_longlong_test_callback); return run_callback(src, reg_pack_longlong_test_callback);
} }
@ -365,13 +365,13 @@ static int sret_test(void) {
" sret_test_type r = {x.a*35, x.b*19, x.c*21};\n" " sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
" return r;\n" " return r;\n"
"}\n"; "}\n";
return run_callback(src, sret_test_callback); return run_callback(src, sret_test_callback);
} }
/* /*
* one_member_union_test: * one_member_union_test:
* *
* In the x86-64 ABI a union should always be passed on the stack. However * In the x86-64 ABI a union should always be passed on the stack. However
* it appears that a single member union is treated by GCC as its member. * it appears that a single member union is treated by GCC as its member.
*/ */
@ -399,7 +399,7 @@ static int one_member_union_test(void) {
/* /*
* two_member_union_test: * two_member_union_test:
* *
* In the x86-64 ABI a union should always be passed on the stack. * In the x86-64 ABI a union should always be passed on the stack.
*/ */
typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type; typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
@ -430,7 +430,7 @@ static int two_member_union_test(void) {
typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type; typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type); typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
static int many_struct_test_callback(void *ptr) { static int many_struct_test_callback(void *ptr) {
many_struct_test_function_type f = (many_struct_test_function_type)ptr; many_struct_test_function_type f = (many_struct_test_function_type)ptr;
many_struct_test_type v = {1, 2, 3}; many_struct_test_type v = {1, 2, 3};
@ -457,7 +457,7 @@ static int many_struct_test(void) {
typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type; typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type); typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
static int many_struct_test_2_callback(void *ptr) { static int many_struct_test_2_callback(void *ptr) {
many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr; many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
many_struct_test_2_type v = {1,2}; many_struct_test_2_type v = {1,2};
@ -598,7 +598,7 @@ static int arg_align_test_callback(void *ptr) {
} }
static int arg_align_test(void) { static int arg_align_test(void) {
const char *src = const char *src =
"long double f(long double a, int b, long double c, int d, long double e) {\n" "long double f(long double a, int b, long double c, int d, long double e) {\n"
" return a + c + e;\n" " return a + c + e;\n"
"}\n"; "}\n";
@ -621,7 +621,7 @@ int main(int argc, char **argv) {
int i; int i;
const char *testname = NULL; const char *testname = NULL;
int retval = EXIT_SUCCESS; int retval = EXIT_SUCCESS;
/* if tcclib.h and libtcc1.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], "run_test=", 9)) if (!memcmp(argv[i], "run_test=", 9))

View file

@ -320,7 +320,7 @@ void macro_test(void)
#line 200 #line 200
printf("__LINE__=%d __FILE__=%s\n", printf("__LINE__=%d __FILE__=%s\n",
__LINE__, __FILE__); __LINE__, __FILE__);
#line 203 "test" #line 203 "test"
printf("__LINE__=%d __FILE__=%s\n", printf("__LINE__=%d __FILE__=%s\n",
__LINE__, __FILE__); __LINE__, __FILE__);
#line 227 "tcctest.c" #line 227 "tcctest.c"
@ -348,7 +348,7 @@ void macro_test(void)
glue(a <, <= 2); glue(a <, <= 2);
printf("a=%d\n", a); printf("a=%d\n", a);
} }
/* macro function with argument outside the macro string */ /* macro function with argument outside the macro string */
#define MF_s MF_hello #define MF_s MF_hello
#define MF_hello(msg) printf("%s\n",msg) #define MF_hello(msg) printf("%s\n",msg)
@ -357,7 +357,7 @@ void macro_test(void)
MF_s("hi"); MF_s("hi");
MF_t("hi"); MF_t("hi");
/* test macro substituion inside args (should not eat stream) */ /* test macro substituion inside args (should not eat stream) */
printf("qq=%d\n", qq(qq)(2)); printf("qq=%d\n", qq(qq)(2));
@ -398,7 +398,7 @@ void recursive_macro_test(void)
printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123))); printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
#define WRAP(x) x #define WRAP(x) x
#define print_num(x) print_num(__FILE__,__LINE__,x) #define print_num(x) print_num(__FILE__,__LINE__,x)
print_num(123); print_num(123);
WRAP(print_num(123)); WRAP(print_num(123));
@ -537,7 +537,7 @@ void goto_test()
/* This needs to parse as label, not as start of decl. */ /* This needs to parse as label, not as start of decl. */
typedef_and_label: typedef_and_label:
s_loop: s_loop:
if (i >= 10) if (i >= 10)
goto s_end; goto s_end;
printf("%d", i); printf("%d", i);
i++; i++;
@ -688,7 +688,7 @@ int main(int argc, char **argv)
callsave_test(); callsave_test();
builtin_frame_address_test(); builtin_frame_address_test();
intdiv_test(); intdiv_test();
return 0; return 0;
} }
int tab[3]; int tab[3];
@ -797,10 +797,10 @@ void expr_test()
printf("%d\n", ~12); printf("%d\n", ~12);
printf("%d\n", -12); printf("%d\n", -12);
printf("%d\n", +12); printf("%d\n", +12);
printf("%d %d %d %d\n", printf("%d %d %d %d\n",
isid('a'), isid('a'),
isid('g'), isid('g'),
isid('T'), isid('T'),
isid('(')); isid('('));
} }
@ -984,7 +984,7 @@ void struct_test()
sizeof(struct aligntest3), __alignof__(struct aligntest3)); sizeof(struct aligntest3), __alignof__(struct aligntest3));
printf("aligntest4 sizeof=%d alignof=%d\n", printf("aligntest4 sizeof=%d alignof=%d\n",
sizeof(struct aligntest4), __alignof__(struct aligntest4)); sizeof(struct aligntest4), __alignof__(struct aligntest4));
/* empty structures (GCC extension) */ /* empty structures (GCC extension) */
printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
@ -999,17 +999,17 @@ void char_short_test()
var1 = 0x01020304; var1 = 0x01020304;
var2 = 0xfffefdfc; var2 = 0xfffefdfc;
printf("s8=%d %d\n", printf("s8=%d %d\n",
*(char *)&var1, *(char *)&var2); *(char *)&var1, *(char *)&var2);
printf("u8=%d %d\n", printf("u8=%d %d\n",
*(unsigned char *)&var1, *(unsigned char *)&var2); *(unsigned char *)&var1, *(unsigned char *)&var2);
printf("s16=%d %d\n", printf("s16=%d %d\n",
*(short *)&var1, *(short *)&var2); *(short *)&var1, *(short *)&var2);
printf("u16=%d %d\n", printf("u16=%d %d\n",
*(unsigned short *)&var1, *(unsigned short *)&var2); *(unsigned short *)&var1, *(unsigned short *)&var2);
printf("s32=%d %d\n", printf("s32=%d %d\n",
*(int *)&var1, *(int *)&var2); *(int *)&var1, *(int *)&var2);
printf("u32=%d %d\n", printf("u32=%d %d\n",
*(unsigned int *)&var1, *(unsigned int *)&var2); *(unsigned int *)&var1, *(unsigned int *)&var2);
*(char *)&var1 = 0x08; *(char *)&var1 = 0x08;
printf("var1=%x\n", var1); printf("var1=%x\n", var1);
@ -1099,7 +1099,7 @@ void bool_test()
static int v1 = 34 ? : -1; /* constant case */ static int v1 = 34 ? : -1; /* constant case */
static int v2 = 0 ? : -1; /* constant case */ static int v2 = 0 ? : -1; /* constant case */
int a = 30; int a = 30;
printf("%d %d\n", v1, v2); printf("%d %d\n", v1, v2);
printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2); printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
} }
@ -1116,8 +1116,8 @@ static int tab_reinit[];
static int tab_reinit[10]; static int tab_reinit[10];
//int cinit1; /* a global variable can be defined several times without error ! */ //int cinit1; /* a global variable can be defined several times without error ! */
int cinit1; int cinit1;
int cinit1; int cinit1;
int cinit1 = 0; int cinit1 = 0;
int *cinit2 = (int []){3, 2, 1}; int *cinit2 = (int []){3, 2, 1};
@ -1157,7 +1157,7 @@ void compound_literal_test(void)
for(i=0;i<3;i++) { for(i=0;i<3;i++) {
p = (int []){1, 2, 4 + i}; p = (int []){1, 2, 4 + i};
printf("%d %d %d\n", printf("%d %d %d\n",
p[0], p[0],
p[1], p[1],
p[2]); p[2]);
@ -1188,7 +1188,7 @@ kr_test()
void num(int n) void num(int n)
{ {
char *tab, *p; char *tab, *p;
tab = (char*)malloc(20); tab = (char*)malloc(20);
p = tab; p = tab;
while (1) { while (1) {
*p = 48 + (n % 10); *p = 48 + (n % 10);
@ -1231,7 +1231,7 @@ void struct_assign_test(void)
struct structa1 lsta1, lsta2; struct structa1 lsta1, lsta2;
int i; int i;
} s, *ps; } s, *ps;
ps = &s; ps = &s;
ps->i = 4; ps->i = 4;
#if 0 #if 0
@ -1247,7 +1247,7 @@ void struct_assign_test(void)
s.lsta2.f2 = 2; s.lsta2.f2 = 2;
#endif #endif
struct_assign_test1(ps->lsta2, 3, 4.5); struct_assign_test1(ps->lsta2, 3, 4.5);
printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2); printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i); ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2); printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
@ -1300,9 +1300,9 @@ void cast_test()
printf("%d\n", a); printf("%d\n", a);
a = (scast = 65536) + 1; a = (scast = 65536) + 1;
printf("%d\n", a); printf("%d\n", a);
printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c)); printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
/* test cast from unsigned to signed short to int */ /* test cast from unsigned to signed short to int */
b = 0xf000; b = 0xf000;
d = (short)b; d = (short)b;
@ -1310,7 +1310,7 @@ void cast_test()
b = 0xf0f0; b = 0xf0f0;
d = (char)b; d = (char)b;
printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d); printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
/* test implicit int casting for array accesses */ /* test implicit int casting for array accesses */
c = 0; c = 0;
tab[1] = 2; tab[1] = 2;
@ -1352,7 +1352,7 @@ char sinit8[] = "hello" "trala";
struct structinit1 sinit9 = { 1, 2, 3 }; struct structinit1 sinit9 = { 1, 2, 3 };
struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 }; struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
#ifdef ALL_ISOC99 #ifdef ALL_ISOC99
.farray[0] = 10, .farray[0] = 10,
.farray[1] = 11, .farray[1] = 11,
@ -1437,36 +1437,36 @@ void init_test(void)
int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, }; int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
int linit17 = sizeof(linit17); int linit17 = sizeof(linit17);
printf("init_test:\n"); printf("init_test:\n");
printf("sinit1=%d\n", sinit1); printf("sinit1=%d\n", sinit1);
printf("sinit2=%d\n", sinit2); printf("sinit2=%d\n", sinit2);
printf("sinit3=%d %d %d %d\n", printf("sinit3=%d %d %d %d\n",
sizeof(sinit3), sizeof(sinit3),
sinit3[0], sinit3[0],
sinit3[1], sinit3[1],
sinit3[2] sinit3[2]
); );
printf("sinit6=%d\n", sizeof(sinit6)); printf("sinit6=%d\n", sizeof(sinit6));
printf("sinit7=%d %d %d %d\n", printf("sinit7=%d %d %d %d\n",
sizeof(sinit7), sizeof(sinit7),
sinit7[0], sinit7[0],
sinit7[1], sinit7[1],
sinit7[2] sinit7[2]
); );
printf("sinit8=%s\n", sinit8); printf("sinit8=%s\n", sinit8);
printf("sinit9=%d %d %d\n", printf("sinit9=%d %d %d\n",
sinit9.f1, sinit9.f1,
sinit9.f2, sinit9.f2,
sinit9.f3 sinit9.f3
); );
printf("sinit10=%d %d %d\n", printf("sinit10=%d %d %d\n",
sinit10.f1, sinit10.f1,
sinit10.f2, sinit10.f2,
sinit10.f3 sinit10.f3
); );
printf("sinit11=%d %d %d %d %d %d\n", printf("sinit11=%d %d %d %d %d %d\n",
sinit11.f1, sinit11.f1,
sinit11.f2, sinit11.f2,
sinit11.f3, sinit11.f3,
@ -1477,7 +1477,7 @@ void init_test(void)
for(i=0;i<3;i++) for(i=0;i<3;i++)
for(j=0;j<2;j++) for(j=0;j<2;j++)
printf("[%d][%d] = %d %d %d\n", printf("[%d][%d] = %d %d %d\n",
i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]); i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
printf("linit1=%d\n", linit1); printf("linit1=%d\n", linit1);
printf("linit2=%d\n", linit2); printf("linit2=%d\n", linit2);
@ -1486,7 +1486,7 @@ void init_test(void)
printf("sinit12=%s\n", sinit12); printf("sinit12=%s\n", sinit12);
printf("sinit13=%d %s %s %s\n", printf("sinit13=%d %s %s %s\n",
sizeof(sinit13), sizeof(sinit13),
sinit13[0], sinit13[0],
sinit13[1], sinit13[1],
sinit13[2]); sinit13[2]);
@ -1500,7 +1500,7 @@ void init_test(void)
printf("\n"); printf("\n");
for(i=0;i<10;i++) printf(" %d", linit15[i]); for(i=0;i<10;i++) printf(" %d", linit15[i]);
printf("\n"); printf("\n");
printf("%d %d %d %d\n", printf("%d %d %d %d\n",
linit16.a1, linit16.a1,
linit16.a2, linit16.a2,
linit16.a3, linit16.a3,
@ -1599,13 +1599,13 @@ void bitfield_test(void)
printf("%d %d\n", sa, ca); printf("%d %d\n", sa, ca);
st1.f1 = 7; st1.f1 = 7;
if (st1.f1 == -1) if (st1.f1 == -1)
printf("st1.f1 == -1\n"); printf("st1.f1 == -1\n");
else else
printf("st1.f1 != -1\n"); printf("st1.f1 != -1\n");
if (st1.f2 == -1) if (st1.f2 == -1)
printf("st1.f2 == -1\n"); printf("st1.f2 == -1\n");
else else
printf("st1.f2 != -1\n"); printf("st1.f2 != -1\n");
/* bit sizes below must be bigger than 32 since GCC doesn't allow /* bit sizes below must be bigger than 32 since GCC doesn't allow
@ -1835,7 +1835,7 @@ void lloptest(long long a, long long b)
a + b, a + b,
a - b, a - b,
a * b); a * b);
if (b != 0) { if (b != 0) {
printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
a / b, a / b,
@ -1856,7 +1856,7 @@ void lloptest(long long a, long long b)
a > b, a > b,
a >= b, a >= b,
a <= b); a <= b);
printf("utest: %d %d %d %d %d %d\n", printf("utest: %d %d %d %d %d %d\n",
ua == ub, ua == ub,
ua != ub, ua != ub,
@ -1932,7 +1932,7 @@ long long llfunc1(int a)
} }
struct S { struct S {
int id; int id;
char item; char item;
}; };
@ -1953,8 +1953,8 @@ void longlong_test(void)
a = ia; a = ia;
b = ua; b = ua;
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b); printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n", printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
(long long)1, (long long)1,
(long long)-2, (long long)-2,
1LL, 1LL,
0x1234567812345679); 0x1234567812345679);
@ -2049,7 +2049,7 @@ void vprintf1(const char *fmt, ...)
va_start(aq, fmt); va_start(aq, fmt);
va_copy(ap, aq); va_copy(ap, aq);
p = fmt; p = fmt;
for(;;) { for(;;) {
c = *p; c = *p;
@ -2250,10 +2250,10 @@ void c99_vla_test(int size1, int size2)
int tab1[size][2], tab2[10][2]; int tab1[size][2], tab2[10][2];
void *tab1_ptr, *tab2_ptr, *bad_ptr; void *tab1_ptr, *tab2_ptr, *bad_ptr;
/* "size" should have been 'captured' at tab1 declaration, /* "size" should have been 'captured' at tab1 declaration,
so modifying it should have no effect on VLA behaviour. */ so modifying it should have no effect on VLA behaviour. */
size = size-1; size = size-1;
printf("Test C99 VLA 1 (sizeof): "); printf("Test C99 VLA 1 (sizeof): ");
printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED"); printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
tab1_ptr = tab1; tab1_ptr = tab1;
@ -2325,7 +2325,7 @@ void sizeof_test(void)
t <<= 16; t <<= 16;
t <<= 16; t <<= 16;
t++; t++;
/* This checks that sizeof really can be used to manipulate /* This checks that sizeof really can be used to manipulate
uintptr_t objects, without truncation. */ uintptr_t objects, without truncation. */
t2 = t & -sizeof(uintptr_t); t2 = t & -sizeof(uintptr_t);
printf ("%lu %lu\n", t, t2); printf ("%lu %lu\n", t, t2);
@ -2358,15 +2358,15 @@ void statement_expr_test(void)
a = 0; a = 0;
for(i=0;i<10;i++) { for(i=0;i<10;i++) {
a += 1 + a += 1 +
( { int b, j; ( { int b, j;
b = 0; b = 0;
for(j=0;j<5;j++) for(j=0;j<5;j++)
b += j; b; b += j; b;
} ); } );
} }
printf("a=%d\n", a); printf("a=%d\n", a);
} }
void local_label_test(void) void local_label_test(void)
@ -2589,7 +2589,7 @@ void builtin_test(void)
COMPAT_TYPE(char *, signed char *); COMPAT_TYPE(char *, signed char *);
COMPAT_TYPE(char *, char *); COMPAT_TYPE(char *, 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 #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));
@ -2640,7 +2640,7 @@ void __attribute__((weak)) weak_test(void)
printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123); printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123); printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123); printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL); printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL); printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL); printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);

View file

@ -229,7 +229,7 @@ while(<$inf>) {
$inf = gensym(); $inf = gensym();
# Try cwd and $ibase. # Try cwd and $ibase.
open($inf, "<" . $1) open($inf, "<" . $1)
or open($inf, "<" . $ibase . "/" . $1) or open($inf, "<" . $ibase . "/" . $1)
or die "cannot open $1 or $ibase/$1: $!\n"; or die "cannot open $1 or $ibase/$1: $!\n";
next; next;

View file

@ -681,7 +681,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
/* relocation offset of the bounding function call point */ /* relocation offset of the bounding function call point */
vtop->c.ull = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela))); vtop->c.ull = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
} }
/* patch pointer addition in vtop so that pointer dereferencing is /* patch pointer addition in vtop so that pointer dereferencing is
@ -823,7 +823,7 @@ void gfunc_call(int nb_args)
struct_size = args_size; struct_size = args_size;
for(i = 0; i < nb_args; i++) { for(i = 0; i < nb_args; i++) {
SValue *sv; SValue *sv;
--arg; --arg;
sv = &vtop[-i]; sv = &vtop[-i];
bt = (sv->type.t & VT_BTYPE); bt = (sv->type.t & VT_BTYPE);
@ -897,7 +897,7 @@ void gfunc_call(int nb_args)
vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
: size > 1 ? VT_SHORT : VT_BYTE; : size > 1 ? VT_SHORT : VT_BYTE;
} }
r = gv(RC_INT); r = gv(RC_INT);
if (arg >= REGN) { if (arg >= REGN) {
gen_offs_sp(0x89, r, arg*8); gen_offs_sp(0x89, r, arg*8);
@ -911,7 +911,7 @@ void gfunc_call(int nb_args)
vtop--; vtop--;
} }
save_regs(0); save_regs(0);
/* Copy R10 and R11 into RCX and RDX, respectively */ /* Copy R10 and R11 into RCX and RDX, respectively */
if (nb_args > 0) { if (nb_args > 0) {
o(0xd1894c); /* mov %r10, %rcx */ o(0xd1894c); /* mov %r10, %rcx */
@ -919,7 +919,7 @@ void gfunc_call(int nb_args)
o(0xda894c); /* mov %r11, %rdx */ o(0xda894c); /* mov %r11, %rdx */
} }
} }
gcall_or_jmp(0); gcall_or_jmp(0);
vtop--; vtop--;
} }
@ -1072,10 +1072,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
{ {
X86_64_Mode mode; X86_64_Mode mode;
Sym *f; Sym *f;
switch (ty->t & VT_BTYPE) { switch (ty->t & VT_BTYPE) {
case VT_VOID: return x86_64_mode_none; case VT_VOID: return x86_64_mode_none;
case VT_INT: case VT_INT:
case VT_BYTE: case VT_BYTE:
case VT_SHORT: case VT_SHORT:
@ -1084,12 +1084,12 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
case VT_PTR: case VT_PTR:
case VT_FUNC: case VT_FUNC:
case VT_ENUM: return x86_64_mode_integer; case VT_ENUM: return x86_64_mode_integer;
case VT_FLOAT: case VT_FLOAT:
case VT_DOUBLE: return x86_64_mode_sse; case VT_DOUBLE: return x86_64_mode_sse;
case VT_LDOUBLE: return x86_64_mode_x87; case VT_LDOUBLE: return x86_64_mode_x87;
case VT_STRUCT: case VT_STRUCT:
f = ty->ref; f = ty->ref;
@ -1098,10 +1098,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
if (f->c + offset >= start && f->c + offset < end) if (f->c + offset >= start && f->c + offset < end)
mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end)); mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end));
} }
return mode; return mode;
} }
assert(0); assert(0);
} }
@ -1305,7 +1305,7 @@ void gfunc_call(int nb_args)
args_size = 0; args_size = 0;
while (run_start != nb_args) { while (run_start != nb_args) {
int run_gen_reg = gen_reg, run_sse_reg = sse_reg; int run_gen_reg = gen_reg, run_sse_reg = sse_reg;
run_end = nb_args; run_end = nb_args;
stack_adjust = 0; stack_adjust = 0;
for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) { for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) {
@ -1319,10 +1319,10 @@ void gfunc_call(int nb_args)
stack_adjust += size; stack_adjust += size;
} }
} }
gen_reg = run_gen_reg; gen_reg = run_gen_reg;
sse_reg = run_sse_reg; sse_reg = run_sse_reg;
/* adjust stack to align SSE boundary */ /* adjust stack to align SSE boundary */
if (stack_adjust &= 15) { if (stack_adjust &= 15) {
/* fetch cpu flag before the following sub will change the value */ /* fetch cpu flag before the following sub will change the value */
@ -1334,7 +1334,7 @@ void gfunc_call(int nb_args)
oad(0xec81, stack_adjust); /* sub $xxx, %rsp */ oad(0xec81, stack_adjust); /* sub $xxx, %rsp */
args_size += stack_adjust; args_size += stack_adjust;
} }
for(i = run_start; i < run_end;) { for(i = run_start; i < run_end;) {
int arg_stored = regargs_nregs(&reg_args[i]) == 0; int arg_stored = regargs_nregs(&reg_args[i]) == 0;
SValue tmp; SValue tmp;
@ -1344,7 +1344,7 @@ void gfunc_call(int nb_args)
++i; ++i;
continue; continue;
} }
/* Swap argument to top, it will possibly be changed here, /* Swap argument to top, it will possibly be changed here,
and might use more temps. At the end of the loop we keep and might use more temps. At the end of the loop we keep
in on the stack and swap it back to its original position in on the stack and swap it back to its original position
@ -1352,7 +1352,7 @@ void gfunc_call(int nb_args)
tmp = vtop[0]; tmp = vtop[0];
vtop[0] = vtop[-i]; vtop[0] = vtop[-i];
vtop[-i] = tmp; vtop[-i] = tmp;
classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args); classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args);
switch (vtop->type.t & VT_BTYPE) { switch (vtop->type.t & VT_BTYPE) {
@ -1369,11 +1369,11 @@ void gfunc_call(int nb_args)
vstore(); vstore();
args_size += size; args_size += size;
break; break;
case VT_LDOUBLE: case VT_LDOUBLE:
assert(0); assert(0);
break; break;
case VT_FLOAT: case VT_FLOAT:
case VT_DOUBLE: case VT_DOUBLE:
r = gv(RC_FLOAT); r = gv(RC_FLOAT);
@ -1384,7 +1384,7 @@ void gfunc_call(int nb_args)
o(0x24); o(0x24);
args_size += size; args_size += size;
break; break;
default: default:
/* simple type */ /* simple type */
/* XXX: implicit cast ? */ /* XXX: implicit cast ? */
@ -1417,7 +1417,7 @@ void gfunc_call(int nb_args)
break; break;
vrotb(i+1); vrotb(i+1);
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) { if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
gv(RC_ST0); gv(RC_ST0);
oad(0xec8148, size); /* sub $xxx, %rsp */ oad(0xec8148, size); /* sub $xxx, %rsp */
@ -1440,7 +1440,7 @@ void gfunc_call(int nb_args)
vstore(); vstore();
args_size += size; args_size += size;
} }
vpop(); vpop();
memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args); memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args);
--nb_args; --nb_args;
@ -1698,7 +1698,7 @@ void gfunc_prolog(CType *func_type)
addr += size; addr += size;
} }
break; break;
case x86_64_mode_memory: case x86_64_mode_memory:
case x86_64_mode_x87: case x86_64_mode_x87:
addr = (addr + align - 1) & -align; addr = (addr + align - 1) & -align;
@ -2104,7 +2104,7 @@ void gen_opf(int op)
vswap(); vswap();
} }
assert(!(vtop[-1].r & VT_LVAL)); assert(!(vtop[-1].r & VT_LVAL));
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
o(0x66); o(0x66);
if (op == TOK_EQ || op == TOK_NE) if (op == TOK_EQ || op == TOK_NE)
@ -2141,7 +2141,7 @@ void gen_opf(int op)
ft = vtop->type.t; ft = vtop->type.t;
fc = vtop->c.ul; fc = vtop->c.ul;
assert((ft & VT_BTYPE) != VT_LDOUBLE); assert((ft & VT_BTYPE) != VT_LDOUBLE);
r = vtop->r; r = vtop->r;
/* if saved lvalue, then we must reload it */ /* if saved lvalue, then we must reload it */
if ((vtop->r & VT_VALMASK) == VT_LLOCAL) { if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
@ -2153,14 +2153,14 @@ void gen_opf(int op)
load(r, &v1); load(r, &v1);
fc = 0; fc = 0;
} }
assert(!(vtop[-1].r & VT_LVAL)); assert(!(vtop[-1].r & VT_LVAL));
if (swapped) { if (swapped) {
assert(vtop->r & VT_LVAL); assert(vtop->r & VT_LVAL);
gv(RC_FLOAT); gv(RC_FLOAT);
vswap(); vswap();
} }
if ((ft & VT_BTYPE) == VT_DOUBLE) { if ((ft & VT_BTYPE) == VT_DOUBLE) {
o(0xf2); o(0xf2);
} else { } else {
@ -2168,7 +2168,7 @@ void gen_opf(int op)
} }
o(0x0f); o(0x0f);
o(0x58 + a); o(0x58 + a);
if (vtop->r & VT_LVAL) { if (vtop->r & VT_LVAL) {
gen_modrm(vtop[-1].r, r, vtop->sym, fc); gen_modrm(vtop[-1].r, r, vtop->sym, fc);
} else { } else {
@ -2231,7 +2231,7 @@ void gen_cvt_ftof(int t)
ft = vtop->type.t; ft = vtop->type.t;
bt = ft & VT_BTYPE; bt = ft & VT_BTYPE;
tbt = t & VT_BTYPE; tbt = t & VT_BTYPE;
if (bt == VT_FLOAT) { if (bt == VT_FLOAT) {
gv(RC_FLOAT); gv(RC_FLOAT);
if (tbt == VT_DOUBLE) { if (tbt == VT_DOUBLE) {