mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
Revert all of my changes to directories & codingstyle.
This commit is contained in:
parent
5a16f5ea98
commit
89ad24e7d6
4
.gitignore
vendored
4
.gitignore
vendored
@ -5,7 +5,7 @@ a.out
|
||||
*.log
|
||||
tcc_g
|
||||
tcc
|
||||
/src/*-tcc
|
||||
/*-tcc
|
||||
tc2.c
|
||||
doc
|
||||
tc3s.c
|
||||
@ -63,7 +63,7 @@ lib/i386-win32
|
||||
lib/arm
|
||||
lib/arm64
|
||||
tcc-doc.info
|
||||
conftest*!conftest.c
|
||||
conftest*
|
||||
tiny_libmaker
|
||||
*.dSYM
|
||||
*~
|
||||
|
@ -85,14 +85,14 @@ endif()
|
||||
|
||||
file(STRINGS "VERSION" TCC_VERSION)
|
||||
list(GET TCC_VERSION 0 TCC_VERSION)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/)
|
||||
configure_file(src/config.h.in ${CMAKE_CURRENT_SOURCE_DIR}/src/config.h)
|
||||
configure_file(docs/config.texi.in ${CMAKE_CURRENT_SOURCE_DIR}/docs/config.texi)
|
||||
include_directories(${CMAKE_BINARY_DIR})
|
||||
configure_file(config.h.in config.h)
|
||||
configure_file(config.texi.in config.texi)
|
||||
|
||||
# Utility variables
|
||||
set(I386_SOURCES src/x86/i386-gen.c src/x86/i386-asm.c src/x86/i386-asm.h src/x86/i386-tok.h)
|
||||
set(X86_64_SOURCES src/x86/x86_64-gen.c src/x86/i386-asm.c src/x86/x86_64-asm.h)
|
||||
set(ARM_SOURCES src/arm/arm_gen.c)
|
||||
set(I386_SOURCES i386-gen.c i386-asm.c i386-asm.h i386-tok.h)
|
||||
set(X86_64_SOURCES x86_64-gen.c i386-asm.c x86_64-asm.h)
|
||||
set(ARM_SOURCES arm_gen.c)
|
||||
|
||||
set(LIBTCC1_I386_SOURCES lib/alloca86.S lib/alloca86-bt.S)
|
||||
set(LIBTCC1_WIN_SOURCES win32/lib/crt1.c win32/lib/wincrt1.c win32/lib/dllcrt1.c win32/lib/dllmain.c win32/lib/chkstk.S)
|
||||
@ -154,41 +154,41 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
|
||||
foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS})
|
||||
set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def})
|
||||
endforeach()
|
||||
|
||||
|
||||
if (TCC_BUILD_NATIVE)
|
||||
add_library(libtcc
|
||||
src/libtcc.c
|
||||
src/tccpp.c
|
||||
src/tccgen.c
|
||||
src/tccelf.c
|
||||
src/tccasm.c
|
||||
src/tccrun.c
|
||||
src/tcc.h
|
||||
src/libtcc.h
|
||||
src/tcctok.h
|
||||
libtcc.c
|
||||
tccpp.c
|
||||
tccgen.c
|
||||
tccelf.c
|
||||
tccasm.c
|
||||
tccrun.c
|
||||
tcc.h
|
||||
libtcc.h
|
||||
tcctok.h
|
||||
${tcc_sources}
|
||||
)
|
||||
set_target_properties(libtcc PROPERTIES OUTPUT_NAME tcc PREFIX lib)
|
||||
if(WIN32)
|
||||
set_target_properties(libtcc PROPERTIES LINK_FLAGS "-Wl,--output-def,libtcc.def")
|
||||
endif()
|
||||
add_executable(tcc src/tcc.c)
|
||||
add_executable(tcc tcc.c)
|
||||
target_link_libraries(tcc libtcc)
|
||||
if(NOT WIN32)
|
||||
target_link_libraries(tcc dl)
|
||||
endif()
|
||||
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}")
|
||||
|
||||
|
||||
if("${libtcc_sources}" STRGREATER "")
|
||||
make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}")
|
||||
endif()
|
||||
endif()
|
||||
elseif(${cross_enabled})
|
||||
add_executable(${cross_name}-tcc src/tcc.c)
|
||||
add_executable(${cross_name}-tcc tcc.c)
|
||||
set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}")
|
||||
install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH})
|
||||
|
||||
|
||||
if("${libtcc_sources}" STRGREATER "")
|
||||
make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}")
|
||||
endif()
|
||||
@ -197,17 +197,17 @@ endmacro()
|
||||
|
||||
make_tcc("Win32" i386-w64-mingw32 TCC_BUILD_WIN32
|
||||
"TCC_TARGET_I386;TCC_TARGET_PE"
|
||||
"${I386_SOURCES};src/tccpe.c"
|
||||
"${I386_SOURCES};tccpe.c"
|
||||
tiny_libmaker_32 "${LIBTCC1_I386_SOURCES};${LIBTCC1_WIN_SOURCES}" "win32/include;win32/include/winapi"
|
||||
)
|
||||
make_tcc("Win64" x86_64-w64-mingw32 TCC_BUILD_WIN64
|
||||
"TCC_TARGET_X86_64;TCC_TARGET_PE"
|
||||
"${X86_64_SOURCES};src/tccpe.c"
|
||||
"${X86_64_SOURCES};tccpe.c"
|
||||
tiny_libmaker_64 "lib/alloca86_64.S;${LIBTCC1_WIN_SOURCES}" "win32/include;win32/include/winapi"
|
||||
)
|
||||
make_tcc("WinCE" arm-wince-mingw32ce TCC_BUILD_WINCE
|
||||
"TCC_TARGET_ARM;TCC_ARM_VERSION=${TCC_ARM_VERSION};TCC_TARGET_PE"
|
||||
"${ARM_SOURCES};src/tccpe.c"
|
||||
"${ARM_SOURCES};tccpe.c"
|
||||
"" "" ""
|
||||
)
|
||||
make_tcc("i386" i386-linux-gnu TCC_BUILD_I386
|
||||
@ -248,7 +248,7 @@ make_tcc("" arm-linux-gnu TCC_BUILD_ARM_VFP
|
||||
)
|
||||
make_tcc("" c67 TCC_BUILD_C67
|
||||
TCC_TARGET_C67
|
||||
"c67-gen.c;src/tcccoff.c"
|
||||
"c67-gen.c;tcccoff.c"
|
||||
"" "" ""
|
||||
)
|
||||
|
||||
@ -257,14 +257,14 @@ add_subdirectory(tests)
|
||||
find_program(MAKEINFO NAMES makeinfo PATHS C:/MinGW/MSYS/1.0/bin)
|
||||
if(MAKEINFO)
|
||||
add_custom_command(OUTPUT tcc-doc.html
|
||||
COMMAND ${MAKEINFO} --no-split --html -o tcc-doc.html ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi
|
||||
COMMAND ${MAKEINFO} --no-split --html -o tcc-doc.html ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
|
||||
)
|
||||
set(TCC_DOC_FILES tcc-doc.html)
|
||||
if(NOT WIN32)
|
||||
add_custom_command(OUTPUT tcc-doc.info
|
||||
COMMAND ${MAKEINFO} -o tcc-doc.info ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/docs/tcc-doc.texi
|
||||
COMMAND ${MAKEINFO} -o tcc-doc.info ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/tcc-doc.texi
|
||||
)
|
||||
set(TCC_DOC_FILES ${TCC_DOC_FILES} tcc-doc.info)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tcc-doc.info DESTINATION share/info)
|
||||
@ -290,3 +290,4 @@ else()
|
||||
install(DIRECTORY win32/include/ DESTINATION lib/tcc/win32/include)
|
||||
install(DIRECTORY include/ DESTINATION lib/tcc/win32/include)
|
||||
endif()
|
||||
|
||||
|
@ -1,9 +1,5 @@
|
||||
TinyCC Coding Style
|
||||
==========================
|
||||
Lines should be no more than 80 columns long.
|
||||
Indentation
|
||||
|
||||
Indentation
|
||||
--------------------------------------
|
||||
Turn on a "fill tabs with spaces" option in your editor.
|
||||
|
||||
Be also careful that some files are indented with 2 spaces (when they
|
423
Makefile
423
Makefile
@ -1,8 +1,421 @@
|
||||
SRC_DIR = src
|
||||
#
|
||||
# Tiny C Compiler Makefile
|
||||
#
|
||||
|
||||
.PHONY: default
|
||||
default:
|
||||
$(MAKE) -C $(SRC_DIR)
|
||||
TOP ?= .
|
||||
include $(TOP)/config.mak
|
||||
VPATH = $(top_srcdir)
|
||||
|
||||
CPPFLAGS += -I$(TOP) # for config.h
|
||||
|
||||
ifneq (-$(findstring gcc,$(CC))-,-gcc-)
|
||||
ifeq (-$(findstring clang,$(CC))-,-clang-)
|
||||
# make clang accept gnuisms in libtcc1.c
|
||||
CFLAGS+=-fheinous-gnu-extensions
|
||||
endif
|
||||
endif
|
||||
|
||||
CPPFLAGS_P=$(CPPFLAGS) -DCONFIG_TCC_STATIC
|
||||
CFLAGS_P=$(CFLAGS) -pg -static
|
||||
LIBS_P=
|
||||
LDFLAGS_P=$(LDFLAGS)
|
||||
|
||||
ifdef CONFIG_WIN64
|
||||
CONFIG_WIN32=yes
|
||||
endif
|
||||
|
||||
ifndef CONFIG_WIN32
|
||||
LIBS=-lm
|
||||
ifndef CONFIG_NOLDL
|
||||
LIBS+=-ldl
|
||||
endif
|
||||
endif
|
||||
|
||||
# make libtcc as static or dynamic library?
|
||||
ifdef DISABLE_STATIC
|
||||
ifndef CONFIG_WIN32
|
||||
LIBTCC=libtcc.so.1.0
|
||||
else
|
||||
LIBTCC=libtcc.dll
|
||||
LIBTCC_DLL=yes
|
||||
LIBTCC_EXTRA=libtcc.def libtcc.a
|
||||
endif
|
||||
LINK_LIBTCC=-Wl,-rpath,"$(libdir)"
|
||||
ifdef DISABLE_RPATH
|
||||
LINK_LIBTCC=
|
||||
endif
|
||||
else
|
||||
LIBTCC=libtcc.a
|
||||
LINK_LIBTCC=
|
||||
endif
|
||||
|
||||
CONFIG_$(ARCH) = yes
|
||||
NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
|
||||
NATIVE_DEFINES_$(CONFIG_x86-64) += -DTCC_TARGET_X86_64
|
||||
NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
|
||||
NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
|
||||
NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
|
||||
NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
|
||||
NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
|
||||
NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
|
||||
NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
|
||||
NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
|
||||
|
||||
ifeq ($(TOP),.)
|
||||
|
||||
PROGS=tcc$(EXESUF)
|
||||
I386_CROSS = i386-linux-gnu-tcc$(EXESUF)
|
||||
WIN32_CROSS = i386-win-mingw32-tcc$(EXESUF)
|
||||
WIN64_CROSS = x86_64-win-mingw32-tcc$(EXESUF)
|
||||
WINCE_CROSS = arm-win-mingw32ce-tcc$(EXESUF)
|
||||
X64_CROSS = x86_64-linux-gnu-tcc$(EXESUF)
|
||||
ARM_FPA_CROSS = arm-linux-fpa-tcc$(EXESUF)
|
||||
ARM_FPA_LD_CROSS = arm-linux-fpa-ld-tcc$(EXESUF)
|
||||
ARM_VFP_CROSS = arm-linux-gnu-tcc$(EXESUF)
|
||||
ARM_EABI_CROSS = arm-linux-gnueabi-tcc$(EXESUF)
|
||||
ARM_EABIHF_CROSS = arm-linux-gnueabihf-tcc$(EXESUF)
|
||||
ARM_CROSS = $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS)
|
||||
ARM64_CROSS = arm64-tcc$(EXESUF)
|
||||
C67_CROSS = c67-tcc$(EXESUF)
|
||||
|
||||
# Legacy symlinks for cross compilers
|
||||
$(I386_CROSS)_LINK = i386-tcc$(EXESUF)
|
||||
$(WIN32_CROSS)_LINK = i386-win-tcc$(EXESUF)
|
||||
$(WIN64_CROSS)_LINK = x86_64-win-tcc$(EXESUF)
|
||||
$(WINCE_CROSS)_LINK = arm-win-tcc$(EXESUF)
|
||||
$(X64_CROSS)_LINK = x86_64-tcc$(EXESUF)
|
||||
$(ARM_FPA_CROSS)_LINK = arm-fpa-tcc$(EXESUF)
|
||||
$(ARM_FPA_LD_CROSS)_LINK = arm-fpa-ld-tcc$(EXESUF)
|
||||
$(ARM_VFP_CROSS)_LINK = arm-vfp-tcc$(EXESUF)
|
||||
$(ARM_EABI_CROSS)_LINK = arm-eabi-tcc$(EXESUF)
|
||||
|
||||
ifeq ($(TARGETOS),Windows)
|
||||
ifeq ($(ARCH),i386)
|
||||
PROGS:=$($(WIN32_CROSS)_LINK)
|
||||
$($(WIN32_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
ifeq ($(ARCH),x86-64)
|
||||
PROGS:=$($(WIN64_CROSS)_LINK)
|
||||
$($(WIN64_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGETOS),Linux)
|
||||
ifeq ($(ARCH),i386)
|
||||
PROGS:=$($(I386_CROSS)_LINK)
|
||||
$($(I386_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
ifeq ($(ARCH),x86-64)
|
||||
PROGS:=$($(X64_CROSS)_LINK)
|
||||
$($(X64_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
endif
|
||||
|
||||
CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
||||
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
||||
I386_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h
|
||||
WIN32_FILES = $(CORE_FILES) i386-gen.c i386-asm.c i386-asm.h i386-tok.h tccpe.c
|
||||
WIN64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h tccpe.c
|
||||
WINCE_FILES = $(CORE_FILES) arm-gen.c tccpe.c
|
||||
X86_64_FILES = $(CORE_FILES) x86_64-gen.c i386-asm.c x86_64-asm.h
|
||||
ARM_FILES = $(CORE_FILES) arm-gen.c
|
||||
ARM64_FILES = $(CORE_FILES) arm64-gen.c
|
||||
C67_FILES = $(CORE_FILES) c67-gen.c tcccoff.c
|
||||
|
||||
ifdef CONFIG_WIN64
|
||||
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
||||
NATIVE_FILES=$(WIN64_FILES)
|
||||
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else ifdef CONFIG_WIN32
|
||||
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
||||
NATIVE_FILES=$(WIN32_FILES)
|
||||
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/x86_64-win/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else ifeq ($(ARCH),i386)
|
||||
NATIVE_FILES=$(I386_FILES)
|
||||
PROGS_CROSS=$($(X64_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
|
||||
lib/arm64/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else ifeq ($(ARCH),x86-64)
|
||||
ifeq ($(TARGETOS),Darwin)
|
||||
NATIVE_FILES=$(X86_64_FILES)
|
||||
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else
|
||||
NATIVE_FILES=$(X86_64_FILES)
|
||||
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
|
||||
lib/arm64/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
endif
|
||||
else ifeq ($(ARCH),arm)
|
||||
NATIVE_FILES=$(ARM_FILES)
|
||||
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1=libtcc1.a
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
|
||||
else ifeq ($(ARCH),arm64)
|
||||
NATIVE_FILES=$(ARM64_FILES)
|
||||
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1=libtcc1.a
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
|
||||
endif
|
||||
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
|
||||
|
||||
ifeq ($(TARGETOS),Darwin)
|
||||
PROGS+=tiny_libmaker$(EXESUF)
|
||||
endif
|
||||
|
||||
TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCC_EXTRA)
|
||||
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
|
||||
|
||||
ifdef CONFIG_CROSS
|
||||
PROGS+=$(PROGS_CROSS)
|
||||
TCCLIBS+=$(LIBTCC1_CROSS)
|
||||
endif
|
||||
|
||||
all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||
|
||||
# Host Tiny C Compiler
|
||||
tcc$(EXESUF): tcc.o $(LIBTCC)
|
||||
$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
|
||||
|
||||
# Cross Tiny C Compilers
|
||||
%-tcc$(EXESUF): tcc.c
|
||||
$(CC) -o $@ $< -DONE_SOURCE $(if $($@_TCC),$(NATIVE_DEFINES),$(DEFINES)) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
|
||||
$(if $($@_LINK),ln -sf $@ $($@_LINK))
|
||||
$(if $($@_TCC),ln -sf $@ tcc$(EXESUF))
|
||||
|
||||
# profiling version
|
||||
tcc_p$(EXESUF): $(NATIVE_FILES)
|
||||
$(CC) -o $@ $< -DONE_SOURCE $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
|
||||
|
||||
$(I386_CROSS) $($(I386_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386
|
||||
$(X64_CROSS) $($(X64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64
|
||||
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \
|
||||
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
|
||||
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/32;{B}/lib\""
|
||||
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \
|
||||
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
|
||||
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/64;{B}/lib\""
|
||||
$(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE
|
||||
$(C67_CROSS): DEFINES = -DTCC_TARGET_C67
|
||||
$(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM
|
||||
$(ARM_FPA_LD_CROSS)$(EXESUF): DEFINES = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
|
||||
$(ARM_VFP_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_VFP
|
||||
$(ARM_EABI_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP
|
||||
$(ARM64_CROSS): DEFINES = -DTCC_TARGET_ARM64
|
||||
|
||||
$(I386_CROSS) $($(I386_CROSS)_LINK): $(I386_FILES)
|
||||
$(X64_CROSS) $($(X64_CROSS)_LINK): $(X86_64_FILES)
|
||||
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): $(WIN32_FILES)
|
||||
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): $(WIN64_FILES)
|
||||
$(WINCE_CROSS) $($(WINCE_CROSS)_LINK): $(WINCE_FILES)
|
||||
$(C67_CROSS) $($(C67_CROSS)_LINK): $(C67_FILES)
|
||||
$(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS): $(ARM_FILES)
|
||||
$($(ARM_FPA_CROSS)_LINK) $($(ARM_FPA_LD_CROSS)_LINK) $($(ARM_VFP_CROSS)_LINK) $($(ARM_EABI_CROSS)_LINK): $(ARM_FILES)
|
||||
$(ARM64_CROSS): $(ARM64_FILES)
|
||||
|
||||
# libtcc generation and test
|
||||
ifndef ONE_SOURCE
|
||||
LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
|
||||
LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
|
||||
else
|
||||
LIBTCC_OBJ = libtcc.o
|
||||
LIBTCC_INC = $(NATIVE_FILES)
|
||||
libtcc.o : NATIVE_DEFINES += -DONE_SOURCE
|
||||
endif
|
||||
|
||||
$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
|
||||
$(CC) -o $@ -c $< $(NATIVE_DEFINES) $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
ifndef LIBTCC_DLL
|
||||
libtcc.a: $(LIBTCC_OBJ)
|
||||
$(AR) rcs $@ $^
|
||||
endif
|
||||
|
||||
libtcc.so.1.0: $(LIBTCC_OBJ)
|
||||
$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
|
||||
|
||||
libtcc.so.1.0: CFLAGS+=-fPIC
|
||||
|
||||
ifdef LIBTCC_DLL
|
||||
libtcc.dll libtcc.def libtcc.a: $(LIBTCC_OBJ)
|
||||
$(CC) -shared $^ -o $@ $(LDFLAGS) -Wl,--output-def,libtcc.def,--out-implib,libtcc.a
|
||||
endif
|
||||
|
||||
# windows utilities
|
||||
tiny_impdef$(EXESUF): win32/tools/tiny_impdef.c
|
||||
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
tiny_libmaker$(EXESUF): win32/tools/tiny_libmaker.c
|
||||
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
# TinyCC runtime libraries
|
||||
libtcc1.a : FORCE
|
||||
$(MAKE) -C lib native
|
||||
if test ! -d $(ARCH); then mkdir $(ARCH); fi
|
||||
if test ! -L $(ARCH)/$@; then ln -sf ../$@ $(ARCH)/$@; fi
|
||||
lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
|
||||
$(MAKE) -C lib cross TARGET=$*
|
||||
|
||||
FORCE:
|
||||
|
||||
# install
|
||||
TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h
|
||||
INSTALL=install
|
||||
ifdef STRIP_BINARIES
|
||||
INSTALLBIN=$(INSTALL) -s
|
||||
else
|
||||
INSTALLBIN=$(INSTALL)
|
||||
endif
|
||||
|
||||
install-strip: install
|
||||
strip $(foreach PROG,$(PROGS),"$(bindir)"/$(PROG))
|
||||
|
||||
ifndef CONFIG_WIN32
|
||||
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||
mkdir -p "$(bindir)"
|
||||
$(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
|
||||
cp -P tcc$(EXESUF) "$(bindir)"
|
||||
mkdir -p "$(mandir)/man1"
|
||||
-$(INSTALL) -m644 tcc.1 "$(mandir)/man1"
|
||||
mkdir -p "$(infodir)"
|
||||
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
|
||||
mkdir -p "$(tccdir)"
|
||||
mkdir -p "$(tccdir)/include"
|
||||
ifneq ($(LIBTCC1),)
|
||||
mkdir -p "$(tccdir)/$(ARCH)"
|
||||
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)/$(ARCH)"
|
||||
endif
|
||||
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
||||
mkdir -p "$(libdir)"
|
||||
$(INSTALL) -m644 $(LIBTCC) "$(libdir)"
|
||||
ifdef DISABLE_STATIC
|
||||
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so.1"
|
||||
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so"
|
||||
endif
|
||||
mkdir -p "$(includedir)"
|
||||
$(INSTALL) -m644 $(top_srcdir)/libtcc.h "$(includedir)"
|
||||
mkdir -p "$(docdir)"
|
||||
-$(INSTALL) -m644 tcc-doc.html "$(docdir)"
|
||||
ifdef CONFIG_CROSS
|
||||
mkdir -p "$(tccdir)/win32/lib/32"
|
||||
mkdir -p "$(tccdir)/win32/lib/64"
|
||||
mkdir -p "$(tccdir)/i386"
|
||||
mkdir -p "$(tccdir)/x86-64"
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
mkdir -p "$(tccdir)/arm64"
|
||||
$(INSTALL) -m644 lib/arm64/libtcc1.a "$(tccdir)/arm64"
|
||||
endif
|
||||
$(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
|
||||
$(INSTALL) -m644 lib/x86_64/libtcc1.a "$(tccdir)/x86-64"
|
||||
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
|
||||
$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/win32/lib/32"
|
||||
$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/win32/lib/64"
|
||||
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
|
||||
cp -r "$(tccdir)/include" "$(tccdir)/win32"
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
|
||||
rm -fv "$(bindir)/tcc$(EXESUF)"
|
||||
rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
|
||||
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
|
||||
rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
|
||||
rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
|
||||
rm -fv "$(libdir)/libtcc.so*"
|
||||
rm -rv "$(tccdir)"
|
||||
rm -rv "$(docdir)"
|
||||
else
|
||||
# on windows
|
||||
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||
mkdir -p "$(tccdir)"
|
||||
mkdir -p "$(tccdir)/lib"
|
||||
mkdir -p "$(tccdir)/include"
|
||||
mkdir -p "$(tccdir)/examples"
|
||||
mkdir -p "$(tccdir)/doc"
|
||||
mkdir -p "$(tccdir)/libtcc"
|
||||
$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
|
||||
$(INSTALLBIN) -m755 tcc.exe "$(tccdir)"
|
||||
$(INSTALL) -m644 $(LIBTCC1) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib"
|
||||
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include"
|
||||
cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples"
|
||||
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
||||
$(INSTALL) -m644 tcc-doc.html $(top_srcdir)/win32/tcc-win32.txt "$(tccdir)/doc"
|
||||
$(INSTALL) -m644 $(top_srcdir)/libtcc.h $(LIBTCC_EXTRA) "$(tccdir)/libtcc"
|
||||
$(INSTALL) -m644 $(LIBTCC) "$(tccdir)"
|
||||
ifdef CONFIG_CROSS
|
||||
mkdir -p "$(tccdir)/lib/32"
|
||||
mkdir -p "$(tccdir)/lib/64"
|
||||
-$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/lib/32"
|
||||
-$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/lib/64"
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
rm -rfv "$(tccdir)/*"
|
||||
endif
|
||||
|
||||
# documentation and man page
|
||||
tcc-doc.html: tcc-doc.texi
|
||||
-makeinfo --no-split --html --number-sections -o $@ $<
|
||||
|
||||
tcc.1: tcc-doc.texi
|
||||
-$(top_srcdir)/texi2pod.pl $< tcc.pod
|
||||
-pod2man --section=1 --center="Tiny C Compiler" --release=`cat $(top_srcdir)/VERSION` tcc.pod > $@
|
||||
|
||||
tcc-doc.info: tcc-doc.texi
|
||||
-makeinfo $<
|
||||
|
||||
# in tests subdir
|
||||
export LIBTCC1
|
||||
|
||||
%est:
|
||||
$(MAKE) -C tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(SRC_DIR) clean
|
||||
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.log \
|
||||
*.exe a.out tags TAGS libtcc_test$(EXESUF) tcc$(EXESUF)
|
||||
-rm -r $(ARCH) arm64
|
||||
ifeq ($(HOST_OS),Linux)
|
||||
-rm -r ./C:
|
||||
endif
|
||||
-rm *-tcc$(EXESUF)
|
||||
$(MAKE) -C tests $@
|
||||
ifneq ($(LIBTCC1),)
|
||||
$(MAKE) -C lib $@
|
||||
endif
|
||||
|
||||
distclean: clean
|
||||
rm -vf config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
|
||||
|
||||
config.mak:
|
||||
@echo "Please run ./configure."
|
||||
@exit 1
|
||||
|
||||
tags:
|
||||
ctags $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
|
||||
|
||||
TAGS:
|
||||
ctags -e $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
|
||||
|
||||
# create release tarball from *current* git branch (including tcc-doc.html
|
||||
# and converting two files to CRLF)
|
||||
TCC-VERSION := tcc-$(shell cat $(top_srcdir)/VERSION)
|
||||
tar: tcc-doc.html
|
||||
mkdir $(TCC-VERSION)
|
||||
( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
|
||||
cp tcc-doc.html $(TCC-VERSION)
|
||||
for f in tcc-win32.txt build-tcc.bat ; do \
|
||||
cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
|
||||
done
|
||||
tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
|
||||
rm -rf $(TCC-VERSION)
|
||||
git reset
|
||||
|
||||
.PHONY: all clean tar tags TAGS distclean install uninstall FORCE
|
||||
|
||||
endif # ifeq ($(TOP),.)
|
||||
|
@ -58,7 +58,7 @@ typedef int RegArgs;
|
||||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
#include "../tcc.h"
|
||||
#include "tcc.h"
|
||||
#include <assert.h>
|
||||
|
||||
ST_DATA const int reg_classes[NB_REGS] = {
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TMS320C67xx code generator for TCC
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001, 2002 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -127,10 +127,10 @@ enum {
|
||||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
#include "../tcc.h"
|
||||
#include "tcc.h"
|
||||
|
||||
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)
|
||||
/* ecx */ RC_INT | RC_ECX,
|
||||
/* 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,
|
||||
// the C67 really passes up to the first 10 params in special
|
||||
// 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)
|
||||
|
||||
#define NoCallArgsPassedOnStack 10
|
||||
@ -204,7 +204,7 @@ void C67_g(int c)
|
||||
#endif
|
||||
ind1 = ind + 4;
|
||||
if (ind1 > (int) cur_text_section->data_allocated)
|
||||
section_realloc(cur_text_section, ind1);
|
||||
section_realloc(cur_text_section, ind1);
|
||||
cur_text_section->data[ind] = c & 0xff;
|
||||
cur_text_section->data[ind + 1] = (c >> 8) & 0xff;
|
||||
cur_text_section->data[ind + 2] = (c >> 16) & 0xff;
|
||||
@ -218,26 +218,26 @@ void gsym_addr(int t, int a)
|
||||
{
|
||||
int n, *ptr;
|
||||
while (t) {
|
||||
ptr = (int *) (cur_text_section->data + t);
|
||||
{
|
||||
Sym *sym;
|
||||
ptr = (int *) (cur_text_section->data + t);
|
||||
{
|
||||
Sym *sym;
|
||||
|
||||
// extract 32 bit address from MVKH/MVKL
|
||||
n = ((*ptr >> 7) & 0xffff);
|
||||
n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
|
||||
// extract 32 bit address from MVKH/MVKL
|
||||
n = ((*ptr >> 7) & 0xffff);
|
||||
n |= ((*(ptr + 1) >> 7) & 0xffff) << 16;
|
||||
|
||||
// define a label that will be relocated
|
||||
// define a label that will be relocated
|
||||
|
||||
sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
|
||||
greloc(cur_text_section, sym, t, R_C60LO16);
|
||||
greloc(cur_text_section, sym, t + 4, R_C60HI16);
|
||||
sym = get_sym_ref(&char_pointer_type, cur_text_section, a, 0);
|
||||
greloc(cur_text_section, sym, t, R_C60LO16);
|
||||
greloc(cur_text_section, sym, t + 4, R_C60HI16);
|
||||
|
||||
// clear out where the pointer was
|
||||
// clear out where the pointer was
|
||||
|
||||
*ptr &= ~(0xffff << 7);
|
||||
*(ptr + 1) &= ~(0xffff << 7);
|
||||
}
|
||||
t = n;
|
||||
*ptr &= ~(0xffff << 7);
|
||||
*(ptr + 1) &= ~(0xffff << 7);
|
||||
}
|
||||
t = n;
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ void gsym(int t)
|
||||
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
|
||||
// can distinguish them
|
||||
|
||||
@ -298,7 +298,7 @@ int C67_map_regn(int r)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// mapping from tcc reg number to
|
||||
// mapping from tcc reg number to
|
||||
// C67 register to condition code field
|
||||
//
|
||||
// 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
|
||||
return (r & 2) >> 1;
|
||||
else if (r == C67_A0)
|
||||
return 0; // set to A side
|
||||
return 0; // set to A side
|
||||
else if (r == C67_B2)
|
||||
return 1; // set to B side
|
||||
return 1; // set to B side
|
||||
else if (r == C67_B3)
|
||||
return 1; // set to B side
|
||||
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)
|
||||
return 0x0; // set to FP (A15) A side
|
||||
return 0x0; // set to FP (A15) A side
|
||||
else
|
||||
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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(a) << 1) | //side of src
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(b) << 1) | //side of dst
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(b) << 1) | //side of dst
|
||||
(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
|
||||
(0 << 8) | //r (LDDW bit 0)
|
||||
(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
|
||||
(C67_map_regs(b) << 1) | //side of dst
|
||||
(0 << 0)); //parallel
|
||||
@ -877,7 +877,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
C67_g((0 << 29) | //creg
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(C67_map_regn(b) << 18) | //src2
|
||||
(C67_map_regn(b) << 18) | //src2
|
||||
(0 << 13) | //src1 NA
|
||||
(xpath << 12) | //x cross path if opposite sides
|
||||
(0x4a << 5) | //opcode
|
||||
@ -890,7 +890,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
C67_g((0 << 29) | //creg
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(C67_map_regn(b) << 18) | //src2
|
||||
(C67_map_regn(b) << 18) | //src2
|
||||
(0 << 13) | //src1 NA
|
||||
(xpath << 12) | //x cross path if opposite sides
|
||||
(0x49 << 5) | //opcode
|
||||
@ -903,7 +903,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
C67_g((0 << 29) | //creg
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(C67_map_regn(b) << 18) | //src2
|
||||
(C67_map_regn(b) << 18) | //src2
|
||||
(0 << 13) | //src1 NA
|
||||
(xpath << 12) | //x cross path if opposite sides
|
||||
(0x39 << 5) | //opcode
|
||||
@ -958,7 +958,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x3 << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -973,7 +973,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x7 << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -988,7 +988,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x7f << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1003,7 +1003,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x7b << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1018,7 +1018,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x6f << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1033,7 +1033,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x10 << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1048,7 +1048,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x18 << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1063,7 +1063,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x11 << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1078,7 +1078,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x19 << 5) | //opcode
|
||||
(0x6 << 2) | //opcode fixed
|
||||
@ -1093,7 +1093,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x1c << 7) | //opcode
|
||||
(0x0 << 2) | //opcode fixed
|
||||
@ -1108,7 +1108,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x0e << 7) | //opcode
|
||||
(0x0 << 2) | //opcode fixed
|
||||
@ -1138,7 +1138,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x37 << 6) | //opcode
|
||||
(0x8 << 2) | //opcode fixed
|
||||
@ -1153,7 +1153,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x27 << 6) | //opcode
|
||||
(0x8 << 2) | //opcode fixed
|
||||
@ -1168,7 +1168,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||
(0 << 28) | //inv
|
||||
(C67_map_regn(c) << 23) | //dst
|
||||
(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
|
||||
(0x33 << 6) | //opcode
|
||||
(0x8 << 2) | //opcode fixed
|
||||
@ -1597,7 +1597,7 @@ void load(int r, SValue * sv)
|
||||
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
|
||||
// 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.
|
||||
//
|
||||
// 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).
|
||||
|
||||
/* generate function prolog of type 't' */
|
||||
@ -2033,7 +2033,7 @@ void gfunc_prolog(CType * func_type)
|
||||
|
||||
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_PUSH(C67_A0);
|
||||
@ -2049,11 +2049,11 @@ void gfunc_epilog(void)
|
||||
C67_NOP(4); // NOP wait for load
|
||||
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
|
||||
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 +
|
||||
func_sub_sp_offset),
|
||||
-local + TotalBytesPushedOnStack);
|
||||
C67_NOP(3); // NOP
|
||||
C67_NOP(3); // NOP
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,9 @@ struct filehdr {
|
||||
#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
|
||||
#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
|
||||
#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 FILHDR struct filehdr
|
||||
|
||||
@ -68,7 +68,7 @@ typedef struct aouthdr {
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* 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 */
|
||||
/* AOUT2MAGIC: : writable text segment */
|
||||
@ -164,7 +164,7 @@ struct scnhdr {
|
||||
#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
|
||||
#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
|
||||
#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,
|
||||
loaded; reloc & lineno
|
||||
entries processed normally */
|
||||
@ -358,11 +358,11 @@ struct syment
|
||||
#define N_BTSHFT_COFF 4
|
||||
#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) || \
|
||||
((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
|
||||
#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 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)
|
||||
@ -370,7 +370,7 @@ struct syment
|
||||
#define INCREF_COFF(x) ((((x)&~N_BTMASK_COFF)<<N_TSHIFT_COFF)|(DT_PTR<<N_BTSHFT_COFF)|(x&N_BTMASK_COFF))
|
||||
#define DECREF_COFF(x) ((((x)>>N_TSHIFT_COFF)&~N_BTMASK_COFF)|((x)&N_BTMASK_COFF))
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* AUXILIARY SYMBOL ENTRY */
|
||||
/*------------------------------------------------------------------------*/
|
10
configure
vendored
10
configure
vendored
@ -66,7 +66,7 @@ case $targetos in
|
||||
esac
|
||||
|
||||
# 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.
|
||||
source_path=${0%configure}
|
||||
source_path=${source_path%/}
|
||||
@ -337,7 +337,7 @@ strip="${cross_prefix}${strip}"
|
||||
CONFTEST=./conftest$EXESUF
|
||||
|
||||
if test -z "$cross_prefix" ; then
|
||||
if ! $cc -o $CONFTEST $source_path/src/conftest.c 2>/dev/null ; then
|
||||
if ! $cc -o $CONFTEST $source_path/conftest.c 2>/dev/null ; then
|
||||
echo "configure: error: '$cc' failed to compile conftest.c."
|
||||
else
|
||||
bigendian="$($CONFTEST bigendian)"
|
||||
@ -560,7 +560,7 @@ fi
|
||||
version=`head $source_path/VERSION`
|
||||
echo "VERSION=$version" >>config.mak
|
||||
echo "#define TCC_VERSION \"$version\"" >> $TMPH
|
||||
echo "@set VERSION $version" >docs/config.texi
|
||||
echo "@set VERSION $version" > config.texi
|
||||
echo "SRC_PATH=$source_path" >>config.mak
|
||||
|
||||
if test "$source_path_used" = "yes" ; then
|
||||
@ -573,9 +573,9 @@ else
|
||||
fi
|
||||
echo 'top_builddir=$(TOP)' >>config.mak
|
||||
|
||||
diff $TMPH src/config.h >/dev/null 2>&1
|
||||
diff $TMPH config.h >/dev/null 2>&1
|
||||
if test $? -ne 0 ; then
|
||||
mv -f $TMPH src/config.h
|
||||
mv -f $TMPH config.h
|
||||
else
|
||||
echo "config.h is unchanged"
|
||||
fi
|
||||
|
@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "../tcc.h"
|
||||
#include "tcc.h"
|
||||
|
||||
/* #define NB_ASM_REGS 8 */
|
||||
#define MAX_OPERANDS 3
|
||||
@ -712,7 +712,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
||||
a32 = addr32 = 1;
|
||||
}
|
||||
#endif
|
||||
if (b & 0xff00)
|
||||
if (b & 0xff00)
|
||||
g(b >> 8);
|
||||
g(b);
|
||||
return;
|
@ -57,7 +57,7 @@ ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
|
||||
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
|
||||
|
||||
/* bits */
|
||||
|
||||
|
||||
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))
|
||||
|
||||
@ -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(repne, 0xf2)
|
||||
DEF_ASM_OP0(repnz, 0xf2)
|
||||
|
||||
|
||||
DEF_ASM_OP0(invd, 0x0f08)
|
||||
DEF_ASM_OP0(wbinvd, 0x0f09)
|
||||
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(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||
|
||||
|
||||
/* float */
|
||||
/* specific fcomp handling */
|
||||
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(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
|
||||
DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
|
||||
|
||||
|
||||
/* fp store */
|
||||
DEF_ASM_OP1(fst, 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 */
|
||||
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
|
||||
|
||||
|
||||
/* pentium pro */
|
||||
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
|
||||
#ifdef I386_ASM_16
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* X86 code generator for TCC
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||
*
|
||||
* 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_FLOAT 0x0002 /* generic float register */
|
||||
#define RC_EAX 0x0004
|
||||
#define RC_ST0 0x0008
|
||||
#define RC_ST0 0x0008
|
||||
#define RC_ECX 0x0010
|
||||
#define RC_EDX 0x0020
|
||||
#define RC_IRET RC_EAX /* function return: integer register */
|
||||
@ -89,7 +89,7 @@ enum {
|
||||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
#include "../tcc.h"
|
||||
#include "tcc.h"
|
||||
|
||||
ST_DATA const int reg_classes[NB_REGS] = {
|
||||
/* eax */ RC_INT | RC_EAX,
|
||||
@ -357,11 +357,11 @@ static void gcall_or_jmp(int is_jmp)
|
||||
/* constant case */
|
||||
if (vtop->r & VT_SYM) {
|
||||
/* relocation case */
|
||||
greloc(cur_text_section, vtop->sym,
|
||||
greloc(cur_text_section, vtop->sym,
|
||||
ind + 1, R_386_PC32);
|
||||
} else {
|
||||
/* 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);
|
||||
}
|
||||
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;
|
||||
Sym *func_sym;
|
||||
|
||||
|
||||
args_size = 0;
|
||||
for(i = 0;i < nb_args; i++) {
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
@ -610,7 +610,7 @@ ST_FUNC void gfunc_epilog(void)
|
||||
/* generate bound local allocation */
|
||||
saved_ind = ind;
|
||||
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);
|
||||
greloc(cur_text_section, sym_data,
|
||||
ind + 1, R_386_32);
|
||||
@ -637,8 +637,8 @@ ST_FUNC void gfunc_epilog(void)
|
||||
g(func_ret_sub >> 8);
|
||||
}
|
||||
/* align local size to word & save local variables */
|
||||
|
||||
v = (-loc + 3) & -4;
|
||||
|
||||
v = (-loc + 3) & -4;
|
||||
saved_ind = ind;
|
||||
ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||
#ifdef TCC_TARGET_PE
|
||||
@ -741,7 +741,7 @@ ST_FUNC void gen_opi(int op)
|
||||
r = vtop[-1].r;
|
||||
fr = vtop[0].r;
|
||||
o((opc << 3) | 0x01);
|
||||
o(0xc0 + r + fr * 8);
|
||||
o(0xc0 + r + fr * 8);
|
||||
}
|
||||
vtop--;
|
||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||
@ -911,7 +911,7 @@ ST_FUNC void gen_opf(int op)
|
||||
load(TREG_ST0, vtop);
|
||||
swapped = !swapped;
|
||||
}
|
||||
|
||||
|
||||
switch(op) {
|
||||
default:
|
||||
case '+':
|
||||
@ -972,7 +972,7 @@ ST_FUNC void gen_cvt_itof(int t)
|
||||
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
|
||||
o(0x242cdf); /* fildll (%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)) {
|
||||
/* unsigned int to float/double/long double */
|
||||
o(0x6a); /* push $0 */
|
||||
@ -1060,7 +1060,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
|
||||
vtop++;
|
||||
vtop->r = TREG_EAX | VT_BOUNDED;
|
||||
/* 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
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CIL code generator for TCC
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -112,7 +112,7 @@ static void init_outfile(void)
|
||||
{
|
||||
if (!il_outfile) {
|
||||
il_outfile = stdout;
|
||||
fprintf(il_outfile,
|
||||
fprintf(il_outfile,
|
||||
".assembly extern mscorlib\n"
|
||||
"{\n"
|
||||
".ver 1:0:2411:0\n"
|
||||
@ -149,7 +149,7 @@ static void out_opi(int op, int c)
|
||||
}
|
||||
|
||||
/* 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 bt;
|
||||
@ -301,12 +301,12 @@ void load(int r, SValue *sv)
|
||||
out_op(IL_OP_LDIND_U2);
|
||||
else
|
||||
out_op(IL_OP_LDIND_I4);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (v == VT_CONST) {
|
||||
/* XXX: handle globals */
|
||||
if (fc >= -1 && fc <= 8) {
|
||||
out_op(IL_OP_LDC_I4_M1 + fc + 1);
|
||||
out_op(IL_OP_LDC_I4_M1 + fc + 1);
|
||||
} else {
|
||||
out_opi(IL_OP_LDC_I4, fc);
|
||||
}
|
||||
@ -430,10 +430,10 @@ void gfunc_prolog(int t)
|
||||
/* XXX: cannot do better now */
|
||||
fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
|
||||
fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
|
||||
|
||||
|
||||
if (!strcmp(funcname, "main"))
|
||||
fprintf(il_outfile, " .entrypoint\n");
|
||||
|
||||
|
||||
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||
func_call = sym->r;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* CIL opcode definition
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
16
lib/Makefile
16
lib/Makefile
@ -2,9 +2,9 @@
|
||||
# Tiny C Compiler Makefile for libtcc1.a
|
||||
#
|
||||
|
||||
TOP = ../src
|
||||
TOP = ..
|
||||
include $(TOP)/Makefile
|
||||
VPATH = $(top_srcdir)/../lib $(top_srcdir)/../win32/lib
|
||||
VPATH = $(top_srcdir)/lib $(top_srcdir)/win32/lib
|
||||
|
||||
ifndef TARGET # native library
|
||||
ifdef CONFIG_WIN64
|
||||
@ -37,7 +37,7 @@ endif
|
||||
BCHECK_O = bcheck.o
|
||||
DIR = $(TARGET)
|
||||
|
||||
native : $(DIR)/libtcc1.a
|
||||
native : ../libtcc1.a
|
||||
cross : $(DIR)/libtcc1.a
|
||||
|
||||
native : TCC = $(TOP)/tcc$(EXESUF)
|
||||
@ -61,26 +61,26 @@ CFLAGS := $(filter-out -fstack-protector-strong,$(CFLAGS))
|
||||
ifeq "$(TARGET)" "i386-win"
|
||||
OBJ = $(addprefix $(DIR)/,$(WIN32_O))
|
||||
TGT = -DTCC_TARGET_I386 -DTCC_TARGET_PE
|
||||
XCC ?= $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/../include
|
||||
XCC ?= $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
|
||||
XAR ?= $(DIR)/tiny_libmaker$(EXESUF)
|
||||
PICFLAGS =
|
||||
else
|
||||
ifeq "$(TARGET)" "x86_64-win"
|
||||
OBJ = $(addprefix $(DIR)/,$(WIN64_O))
|
||||
TGT = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE
|
||||
XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/../include
|
||||
XCC = $(TCC) -B$(top_srcdir)/win32 -I$(top_srcdir)/include
|
||||
XAR ?= $(DIR)/tiny_libmaker$(EXESUF)
|
||||
PICFLAGS =
|
||||
else
|
||||
ifeq "$(TARGET)" "i386"
|
||||
OBJ = $(addprefix $(DIR)/,$(I386_O))
|
||||
TGT = -DTCC_TARGET_I386
|
||||
XCC ?= $(TCC) -B$(TOP) -I$(top_srcdir)/../include
|
||||
XCC ?= $(TCC) -B$(TOP)
|
||||
else
|
||||
ifeq "$(TARGET)" "x86_64"
|
||||
OBJ = $(addprefix $(DIR)/,$(X86_64_O))
|
||||
TGT = -DTCC_TARGET_X86_64
|
||||
XCC ?= $(TCC) -B$(TOP) -I$(top_srcdir)/../include
|
||||
XCC ?= $(TCC) -B$(TOP)
|
||||
else
|
||||
ifeq "$(TARGET)" "arm"
|
||||
OBJ = $(addprefix $(DIR)/,$(ARM_O))
|
||||
@ -110,7 +110,7 @@ endif
|
||||
|
||||
XAR ?= $(AR)
|
||||
|
||||
$(DIR)/libtcc1.a : $(OBJ) $(XAR)
|
||||
$(DIR)/libtcc1.a ../libtcc1.a : $(OBJ) $(XAR)
|
||||
$(XAR) rcs $@ $(OBJ)
|
||||
$(DIR)/%.o : %.c
|
||||
$(XCC) -c $< -o $@ $(XFLAGS)
|
||||
|
56
lib/bcheck.c
56
lib/bcheck.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Tiny C Memory and bounds checker
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2002 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -88,7 +88,7 @@ int __bound_delete_region(void *p);
|
||||
|
||||
#ifdef __attribute__
|
||||
/* an __attribute__ macro is defined in the system headers */
|
||||
#undef __attribute__
|
||||
#undef __attribute__
|
||||
#endif
|
||||
#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);
|
||||
|
||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||
e = (BoundEntry *)((char *)e +
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
e = (BoundEntry *)((char *)e +
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
||||
addr -= e->start;
|
||||
if (addr > e->size) {
|
||||
@ -236,7 +236,7 @@ BOUND_PTR_INDIR(16)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -255,7 +255,7 @@ void FASTCALL __bound_local_new(void *p1)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
GET_CALLER_FP(fp);
|
||||
@ -331,14 +331,14 @@ static void mark_invalid(size_t addr, size_t size)
|
||||
#if 0
|
||||
dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
|
||||
#endif
|
||||
|
||||
|
||||
/* first we handle full pages */
|
||||
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
|
||||
t1_end = t2_end >> BOUND_T2_BITS;
|
||||
|
||||
i = t2_start & (BOUND_T2_SIZE - 1);
|
||||
j = t2_end & (BOUND_T2_SIZE - 1);
|
||||
|
||||
|
||||
if (t1_start == t1_end) {
|
||||
page = get_page(t2_start >> BOUND_T2_BITS);
|
||||
for(; i < j; i++) {
|
||||
@ -456,7 +456,7 @@ void __bound_main_arg(void **p)
|
||||
void *start = 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);
|
||||
|
||||
__bound_new_region(start, (void *) p - start);
|
||||
@ -467,7 +467,7 @@ void __bound_exit(void)
|
||||
restore_malloc_hooks();
|
||||
}
|
||||
|
||||
static inline void add_region(BoundEntry *e,
|
||||
static inline void add_region(BoundEntry *e,
|
||||
size_t start, size_t size)
|
||||
{
|
||||
BoundEntry *e1;
|
||||
@ -496,7 +496,7 @@ void __bound_new_region(void *p, size_t size)
|
||||
|
||||
__bound_init();
|
||||
|
||||
dprintf(stderr, "%s, %s(%p, %p) start\n",
|
||||
dprintf(stderr, "%s, %s(%p, %p) start\n",
|
||||
__FILE__, __FUNCTION__, p, size);
|
||||
|
||||
start = (size_t)p;
|
||||
@ -506,9 +506,9 @@ void __bound_new_region(void *p, size_t size)
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
|
||||
@ -557,7 +557,7 @@ void __bound_new_region(void *p, size_t size)
|
||||
}
|
||||
|
||||
/* delete a region */
|
||||
static inline void delete_region(BoundEntry *e,
|
||||
static inline void delete_region(BoundEntry *e,
|
||||
void *p, size_t empty_size)
|
||||
{
|
||||
size_t addr;
|
||||
@ -612,9 +612,9 @@ int __bound_delete_region(void *p)
|
||||
|
||||
start = (size_t)p;
|
||||
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);
|
||||
|
||||
|
||||
/* find region size */
|
||||
page = __bound_t1[t1_start];
|
||||
e = (BoundEntry *)((char *)page + t2_start);
|
||||
@ -622,7 +622,7 @@ int __bound_delete_region(void *p)
|
||||
if (addr > e->size)
|
||||
e = __bound_find_region(e, p);
|
||||
/* 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;
|
||||
/* compute the size we put in invalid regions */
|
||||
if (e->is_invalid)
|
||||
@ -634,7 +634,7 @@ int __bound_delete_region(void *p)
|
||||
|
||||
/* now we can free each entry */
|
||||
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);
|
||||
|
||||
delete_region(e, p, empty_size);
|
||||
@ -690,8 +690,8 @@ static size_t get_region_size(void *p)
|
||||
BoundEntry *e;
|
||||
|
||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||
e = (BoundEntry *)((char *)e +
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
e = (BoundEntry *)((char *)e +
|
||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
||||
addr -= e->start;
|
||||
if (addr > e->size)
|
||||
@ -756,16 +756,16 @@ static void libc_free(void *ptr)
|
||||
void *__bound_malloc(size_t size, const void *caller)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
|
||||
/* we allocate one more byte to ensure the regions will be
|
||||
separated by at least one byte. With the glibc malloc, it may
|
||||
be in fact not necessary */
|
||||
ptr = libc_malloc(size + 1);
|
||||
|
||||
|
||||
if (!ptr)
|
||||
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);
|
||||
|
||||
__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 */
|
||||
ptr = memalign(size + 1, align);
|
||||
#endif
|
||||
|
||||
|
||||
install_malloc_hooks();
|
||||
|
||||
|
||||
if (!ptr)
|
||||
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);
|
||||
|
||||
__bound_new_region(ptr, size);
|
||||
@ -862,8 +862,8 @@ static void bound_dump(void)
|
||||
e = page + j;
|
||||
/* do not print invalid or empty entries */
|
||||
if (e->size != EMPTY_SIZE && e->start != 0) {
|
||||
fprintf(stderr, "%08x:",
|
||||
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
|
||||
fprintf(stderr, "%08x:",
|
||||
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
|
||||
(j << BOUND_T3_BITS));
|
||||
do {
|
||||
fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* TCC runtime library.
|
||||
Parts of this code are (c) 2002 Fabrice Bellard
|
||||
/* TCC runtime library.
|
||||
Parts of this code are (c) 2002 Fabrice Bellard
|
||||
|
||||
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
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@ -370,10 +370,10 @@ long long __divdi3(long long u, long long v)
|
||||
int c = 0;
|
||||
DWunion uu, vv;
|
||||
DWtype w;
|
||||
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c;
|
||||
uu.ll = __negdi2 (uu.ll);
|
||||
@ -393,17 +393,17 @@ long long __moddi3(long long u, long long v)
|
||||
int c = 0;
|
||||
DWunion uu, vv;
|
||||
DWtype w;
|
||||
|
||||
|
||||
uu.ll = u;
|
||||
vv.ll = v;
|
||||
|
||||
|
||||
if (uu.s.high < 0) {
|
||||
c = ~c;
|
||||
uu.ll = __negdi2 (uu.ll);
|
||||
}
|
||||
if (vv.s.high < 0)
|
||||
vv.ll = __negdi2 (vv.ll);
|
||||
|
||||
|
||||
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
|
||||
if (c)
|
||||
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)
|
||||
{
|
||||
UDWtype w;
|
||||
|
||||
|
||||
__udivmoddi4 (u, v, &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 */
|
||||
float __floatundisf(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
@ -514,7 +514,7 @@ float __floatundisf(unsigned long long a)
|
||||
|
||||
double __floatundidf(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
@ -529,7 +529,7 @@ double __floatundidf(unsigned long long a)
|
||||
|
||||
long double __floatundixf(unsigned long long a)
|
||||
{
|
||||
DWunion uu;
|
||||
DWunion uu;
|
||||
XFtype r;
|
||||
|
||||
uu.ll = a;
|
||||
@ -608,7 +608,7 @@ unsigned long long __fixunsxfdi (long double a1)
|
||||
|
||||
if (exp > 0)
|
||||
return (unsigned long long)-1;
|
||||
else if (exp >= -63)
|
||||
else if (exp >= -63)
|
||||
return l >> -exp;
|
||||
else
|
||||
return 0;
|
||||
|
@ -40,24 +40,24 @@ ST_DATA struct TCCState *tcc_state;
|
||||
#include "tccelf.c"
|
||||
#include "tccrun.c"
|
||||
#ifdef TCC_TARGET_I386
|
||||
#include "x86/i386-gen.c"
|
||||
#include "i386-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM
|
||||
#include "arm/arm-gen.c"
|
||||
#include "arm-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
#include "arm/arm64-gen.c"
|
||||
#include "arm64-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_C67
|
||||
#include "tms320c67/c67-gen.c"
|
||||
#include "c67-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#include "x86/x86_64-gen.c"
|
||||
#include "x86_64-gen.c"
|
||||
#endif
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
#include "tccasm.c"
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
#include "x86/i386-asm.c"
|
||||
#include "i386-asm.c"
|
||||
#endif
|
||||
#endif
|
||||
#ifdef TCC_TARGET_COFF
|
||||
@ -318,7 +318,7 @@ PUB_FUNC void tcc_free_debug(void *ptr)
|
||||
|
||||
mem_cur_size -= header->size;
|
||||
header->size = (size_t)-1;
|
||||
|
||||
|
||||
if (header->next)
|
||||
header->next->prev = header->prev;
|
||||
|
||||
@ -672,7 +672,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
|
||||
}
|
||||
#else
|
||||
if (! (sym->type.t & VT_STATIC))
|
||||
other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
|
||||
other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT;
|
||||
#endif
|
||||
if (tcc_state->leading_underscore && can_add_underscore) {
|
||||
buf1[0] = '_';
|
||||
@ -2101,11 +2101,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||
s->static_link = 1;
|
||||
break;
|
||||
case TCC_OPTION_std:
|
||||
/* silently ignore, a current purpose:
|
||||
allow to use a tcc as a reference compiler for "make test" */
|
||||
/* silently ignore, a current purpose:
|
||||
allow to use a tcc as a reference compiler for "make test" */
|
||||
break;
|
||||
case TCC_OPTION_shared:
|
||||
if (s->output_type)
|
||||
if (s->output_type)
|
||||
tcc_warning("-shared: some compiler action already specified (%d)", s->output_type);
|
||||
s->output_type = TCC_OUTPUT_DLL;
|
||||
break;
|
||||
@ -2124,7 +2124,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||
break;
|
||||
case TCC_OPTION_r:
|
||||
/* generate a .o merging several output files */
|
||||
if (s->output_type)
|
||||
if (s->output_type)
|
||||
tcc_warning("-r: some compiler action already specified (%d)", s->output_type);
|
||||
s->option_r = 1;
|
||||
s->output_type = TCC_OUTPUT_OBJ;
|
||||
@ -2163,7 +2163,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||
s->print_search_dirs = 1;
|
||||
break;
|
||||
case TCC_OPTION_run:
|
||||
if (s->output_type)
|
||||
if (s->output_type)
|
||||
tcc_warning("-run: some compiler action already specified (%d)", s->output_type);
|
||||
s->output_type = TCC_OUTPUT_MEMORY;
|
||||
tcc_set_options(s, optarg);
|
||||
@ -2194,7 +2194,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||
cstr_ccat(&linker_arg, '\0');
|
||||
break;
|
||||
case TCC_OPTION_E:
|
||||
if (s->output_type)
|
||||
if (s->output_type)
|
||||
tcc_warning("-E: some compiler action already specified (%d)", s->output_type);
|
||||
s->output_type = TCC_OUTPUT_PREPROCESS;
|
||||
break;
|
||||
@ -2251,13 +2251,13 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int argc, char **argv)
|
||||
}
|
||||
|
||||
if (s->output_type == 0)
|
||||
s->output_type = TCC_OUTPUT_EXE;
|
||||
s->output_type = TCC_OUTPUT_EXE;
|
||||
|
||||
if (pthread && s->output_type != TCC_OUTPUT_OBJ)
|
||||
tcc_set_options(s, "-lpthread");
|
||||
|
||||
if (s->output_type == TCC_OUTPUT_EXE)
|
||||
tcc_set_linker(s, (const char *)linker_arg.data);
|
||||
tcc_set_linker(s, (const char *)linker_arg.data);
|
||||
cstr_free(&linker_arg);
|
||||
|
||||
return optind;
|
421
src/Makefile
421
src/Makefile
@ -1,421 +0,0 @@
|
||||
#
|
||||
# Tiny C Compiler Makefile
|
||||
#
|
||||
|
||||
TOP ?= .
|
||||
include $(TOP)/../config.mak
|
||||
VPATH = $(top_srcdir)
|
||||
|
||||
CPPFLAGS += -I$(TOP) # for config.h
|
||||
|
||||
ifneq (-$(findstring gcc,$(CC))-,-gcc-)
|
||||
ifeq (-$(findstring clang,$(CC))-,-clang-)
|
||||
# make clang accept gnuisms in libtcc1.c
|
||||
CFLAGS+=-fheinous-gnu-extensions
|
||||
endif
|
||||
endif
|
||||
|
||||
CPPFLAGS_P=$(CPPFLAGS) -DCONFIG_TCC_STATIC
|
||||
CFLAGS_P=$(CFLAGS) -pg -static
|
||||
LIBS_P=
|
||||
LDFLAGS_P=$(LDFLAGS)
|
||||
|
||||
ifdef CONFIG_WIN64
|
||||
CONFIG_WIN32=yes
|
||||
endif
|
||||
|
||||
ifndef CONFIG_WIN32
|
||||
LIBS=-lm
|
||||
ifndef CONFIG_NOLDL
|
||||
LIBS+=-ldl
|
||||
endif
|
||||
endif
|
||||
|
||||
# make libtcc as static or dynamic library?
|
||||
ifdef DISABLE_STATIC
|
||||
ifndef CONFIG_WIN32
|
||||
LIBTCC=libtcc.so.1.0
|
||||
else
|
||||
LIBTCC=libtcc.dll
|
||||
LIBTCC_DLL=yes
|
||||
LIBTCC_EXTRA=libtcc.def libtcc.a
|
||||
endif
|
||||
LINK_LIBTCC=-Wl,-rpath,"$(libdir)"
|
||||
ifdef DISABLE_RPATH
|
||||
LINK_LIBTCC=
|
||||
endif
|
||||
else
|
||||
LIBTCC=libtcc.a
|
||||
LINK_LIBTCC=
|
||||
endif
|
||||
|
||||
CONFIG_$(ARCH) = yes
|
||||
NATIVE_DEFINES_$(CONFIG_i386) += -DTCC_TARGET_I386
|
||||
NATIVE_DEFINES_$(CONFIG_x86-64) += -DTCC_TARGET_X86_64
|
||||
NATIVE_DEFINES_$(CONFIG_WIN32) += -DTCC_TARGET_PE
|
||||
NATIVE_DEFINES_$(CONFIG_uClibc) += -DTCC_UCLIBC
|
||||
NATIVE_DEFINES_$(CONFIG_arm) += -DTCC_TARGET_ARM
|
||||
NATIVE_DEFINES_$(CONFIG_arm_eabihf) += -DTCC_ARM_EABI -DTCC_ARM_HARDFLOAT
|
||||
NATIVE_DEFINES_$(CONFIG_arm_eabi) += -DTCC_ARM_EABI
|
||||
NATIVE_DEFINES_$(CONFIG_arm_vfp) += -DTCC_ARM_VFP
|
||||
NATIVE_DEFINES_$(CONFIG_arm64) += -DTCC_TARGET_ARM64
|
||||
NATIVE_DEFINES += $(NATIVE_DEFINES_yes)
|
||||
|
||||
ifeq ($(TOP),.)
|
||||
|
||||
PROGS=tcc$(EXESUF)
|
||||
I386_CROSS = i386-linux-gnu-tcc$(EXESUF)
|
||||
WIN32_CROSS = i386-win-mingw32-tcc$(EXESUF)
|
||||
WIN64_CROSS = x86_64-win-mingw32-tcc$(EXESUF)
|
||||
WINCE_CROSS = arm-win-mingw32ce-tcc$(EXESUF)
|
||||
X64_CROSS = x86_64-linux-gnu-tcc$(EXESUF)
|
||||
ARM_FPA_CROSS = arm-linux-fpa-tcc$(EXESUF)
|
||||
ARM_FPA_LD_CROSS = arm-linux-fpa-ld-tcc$(EXESUF)
|
||||
ARM_VFP_CROSS = arm-linux-gnu-tcc$(EXESUF)
|
||||
ARM_EABI_CROSS = arm-linux-gnueabi-tcc$(EXESUF)
|
||||
ARM_EABIHF_CROSS = arm-linux-gnueabihf-tcc$(EXESUF)
|
||||
ARM_CROSS = $(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS)
|
||||
ARM64_CROSS = arm64-tcc$(EXESUF)
|
||||
C67_CROSS = c67-tcc$(EXESUF)
|
||||
|
||||
# Legacy symlinks for cross compilers
|
||||
$(I386_CROSS)_LINK = i386-tcc$(EXESUF)
|
||||
$(WIN32_CROSS)_LINK = i386-win-tcc$(EXESUF)
|
||||
$(WIN64_CROSS)_LINK = x86_64-win-tcc$(EXESUF)
|
||||
$(WINCE_CROSS)_LINK = arm-win-tcc$(EXESUF)
|
||||
$(X64_CROSS)_LINK = x86_64-tcc$(EXESUF)
|
||||
$(ARM_FPA_CROSS)_LINK = arm-fpa-tcc$(EXESUF)
|
||||
$(ARM_FPA_LD_CROSS)_LINK = arm-fpa-ld-tcc$(EXESUF)
|
||||
$(ARM_VFP_CROSS)_LINK = arm-vfp-tcc$(EXESUF)
|
||||
$(ARM_EABI_CROSS)_LINK = arm-eabi-tcc$(EXESUF)
|
||||
|
||||
ifeq ($(TARGETOS),Windows)
|
||||
ifeq ($(ARCH),i386)
|
||||
PROGS:=$($(WIN32_CROSS)_LINK)
|
||||
$($(WIN32_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
ifeq ($(ARCH),x86-64)
|
||||
PROGS:=$($(WIN64_CROSS)_LINK)
|
||||
$($(WIN64_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGETOS),Linux)
|
||||
ifeq ($(ARCH),i386)
|
||||
PROGS:=$($(I386_CROSS)_LINK)
|
||||
$($(I386_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
ifeq ($(ARCH),x86-64)
|
||||
PROGS:=$($(X64_CROSS)_LINK)
|
||||
$($(X64_CROSS)_LINK)_TCC = yes
|
||||
endif
|
||||
endif
|
||||
|
||||
CORE_FILES = tcc.c libtcc.c tccpp.c tccgen.c tccelf.c tccasm.c tccrun.c
|
||||
CORE_FILES += tcc.h config.h libtcc.h tcctok.h
|
||||
I386_FILES = $(CORE_FILES) x86/i386-gen.c x86/i386-asm.c x86/i386-asm.h x86/i386-tok.h
|
||||
WIN32_FILES = $(CORE_FILES) x86/i386-gen.c x86/i386-asm.c x86/i386-asm.h x86/i386-tok.h tccpe.c
|
||||
WIN64_FILES = $(CORE_FILES) x86/x86_64-gen.c x86/i386-asm.c x86/x86_64-asm.h tccpe.c
|
||||
WINCE_FILES = $(CORE_FILES) arm/arm-gen.c tccpe.c
|
||||
X86_64_FILES = $(CORE_FILES) x86/x86_64-gen.c x86/i386-asm.c x86/x86_64-asm.h
|
||||
ARM_FILES = $(CORE_FILES) arm/arm-gen.c
|
||||
ARM64_FILES = $(CORE_FILES) arm/arm64-gen.c
|
||||
C67_FILES = $(CORE_FILES) tms320c67/c67-gen.c tcccoff.c
|
||||
|
||||
ifdef CONFIG_WIN64
|
||||
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
||||
NATIVE_FILES=$(WIN64_FILES)
|
||||
PROGS_CROSS=$(WIN32_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else ifdef CONFIG_WIN32
|
||||
PROGS+=tiny_impdef$(EXESUF) tiny_libmaker$(EXESUF)
|
||||
NATIVE_FILES=$(WIN32_FILES)
|
||||
PROGS_CROSS=$(WIN64_CROSS) $(I386_CROSS) $(X64_CROSS) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/x86_64-win/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else ifeq ($(ARCH),i386)
|
||||
NATIVE_FILES=$(I386_FILES)
|
||||
PROGS_CROSS=$($(X64_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
|
||||
lib/arm64/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else ifeq ($(ARCH),x86-64)
|
||||
ifeq ($(TARGETOS),Darwin)
|
||||
NATIVE_FILES=$(X86_64_FILES)
|
||||
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
else
|
||||
NATIVE_FILES=$(X86_64_FILES)
|
||||
PROGS_CROSS=$($(I386_CROSS)_LINK) $($(WIN32_CROSS)_LINK) $($(WIN64_CROSS)_LINK) $(ARM_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a lib/x86_64/libtcc1.a \
|
||||
lib/arm64/libtcc1.a
|
||||
LIBTCC1=libtcc1.a
|
||||
endif
|
||||
else ifeq ($(ARCH),arm)
|
||||
NATIVE_FILES=$(ARM_FILES)
|
||||
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM64_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1=libtcc1.a
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
|
||||
else ifeq ($(ARCH),arm64)
|
||||
NATIVE_FILES=$(ARM64_FILES)
|
||||
PROGS_CROSS=$(I386_CROSS) $(X64_CROSS) $(WIN32_CROSS) $(WIN64_CROSS) $(ARM_CROSS) $(C67_CROSS) $(WINCE_CROSS)
|
||||
LIBTCC1=libtcc1.a
|
||||
LIBTCC1_CROSS=lib/i386-win/libtcc1.a lib/x86_64-win/libtcc1.a lib/i386/libtcc1.a
|
||||
endif
|
||||
PROGS_CROSS_LINK=$(foreach PROG_CROSS,$(PROGS_CROSS),$($(PROG_CROSS)_LINK))
|
||||
|
||||
ifeq ($(TARGETOS),Darwin)
|
||||
PROGS+=tiny_libmaker$(EXESUF)
|
||||
endif
|
||||
|
||||
TCCLIBS = $(LIBTCC1) $(LIBTCC) $(LIBTCC_EXTRA)
|
||||
TCCDOCS = tcc.1 tcc-doc.html tcc-doc.info
|
||||
|
||||
ifdef CONFIG_CROSS
|
||||
PROGS+=$(PROGS_CROSS)
|
||||
TCCLIBS+=$(LIBTCC1_CROSS)
|
||||
endif
|
||||
|
||||
all: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||
|
||||
# Host Tiny C Compiler
|
||||
tcc$(EXESUF): tcc.o $(LIBTCC)
|
||||
$(CC) -o $@ $^ $(LIBS) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LINK_LIBTCC)
|
||||
|
||||
# Cross Tiny C Compilers
|
||||
%-tcc$(EXESUF): tcc.c
|
||||
$(CC) -o $@ $< -DONE_SOURCE $(if $($@_TCC),$(NATIVE_DEFINES),$(DEFINES)) $(CPPFLAGS) $(CFLAGS) $(LIBS) $(LDFLAGS)
|
||||
$(if $($@_LINK),ln -sf $@ $($@_LINK))
|
||||
$(if $($@_TCC),ln -sf $@ tcc$(EXESUF))
|
||||
|
||||
# profiling version
|
||||
tcc_p$(EXESUF): $(NATIVE_FILES)
|
||||
$(CC) -o $@ $< -DONE_SOURCE $(NATIVE_DEFINES) $(CPPFLAGS_P) $(CFLAGS_P) $(LIBS_P) $(LDFLAGS_P)
|
||||
|
||||
$(I386_CROSS) $($(I386_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386
|
||||
$(X64_CROSS) $($(X64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64
|
||||
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): DEFINES = -DTCC_TARGET_I386 -DTCC_TARGET_PE \
|
||||
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
|
||||
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/32;{B}/lib\""
|
||||
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): DEFINES = -DTCC_TARGET_X86_64 -DTCC_TARGET_PE \
|
||||
-DCONFIG_TCCDIR="\"$(tccdir)/win32\"" \
|
||||
-DCONFIG_TCC_LIBPATHS="\"{B}/lib/64;{B}/lib\""
|
||||
$(WINCE_CROSS): DEFINES = -DTCC_TARGET_PE
|
||||
$(C67_CROSS): DEFINES = -DTCC_TARGET_C67
|
||||
$(ARM_FPA_CROSS): DEFINES = -DTCC_TARGET_ARM
|
||||
$(ARM_FPA_LD_CROSS)$(EXESUF): DEFINES = -DTCC_TARGET_ARM -DLDOUBLE_SIZE=12
|
||||
$(ARM_VFP_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_VFP
|
||||
$(ARM_EABI_CROSS): DEFINES = -DTCC_TARGET_ARM -DTCC_ARM_EABI -DTCC_ARM_VFP
|
||||
$(ARM64_CROSS): DEFINES = -DTCC_TARGET_ARM64
|
||||
|
||||
$(I386_CROSS) $($(I386_CROSS)_LINK): $(I386_FILES)
|
||||
$(X64_CROSS) $($(X64_CROSS)_LINK): $(X86_64_FILES)
|
||||
$(WIN32_CROSS) $($(WIN32_CROSS)_LINK): $(WIN32_FILES)
|
||||
$(WIN64_CROSS) $($(WIN64_CROSS)_LINK): $(WIN64_FILES)
|
||||
$(WINCE_CROSS) $($(WINCE_CROSS)_LINK): $(WINCE_FILES)
|
||||
$(C67_CROSS) $($(C67_CROSS)_LINK): $(C67_FILES)
|
||||
$(ARM_FPA_CROSS) $(ARM_FPA_LD_CROSS) $(ARM_VFP_CROSS) $(ARM_EABI_CROSS): $(ARM_FILES)
|
||||
$($(ARM_FPA_CROSS)_LINK) $($(ARM_FPA_LD_CROSS)_LINK) $($(ARM_VFP_CROSS)_LINK) $($(ARM_EABI_CROSS)_LINK): $(ARM_FILES)
|
||||
$(ARM64_CROSS): $(ARM64_FILES)
|
||||
|
||||
# libtcc generation and test
|
||||
ifndef ONE_SOURCE
|
||||
LIBTCC_OBJ = $(filter-out tcc.o,$(patsubst %.c,%.o,$(filter %.c,$(NATIVE_FILES))))
|
||||
LIBTCC_INC = $(filter %.h,$(CORE_FILES)) $(filter-out $(CORE_FILES),$(NATIVE_FILES))
|
||||
else
|
||||
LIBTCC_OBJ = libtcc.o
|
||||
LIBTCC_INC = $(NATIVE_FILES)
|
||||
libtcc.o : NATIVE_DEFINES += -DONE_SOURCE
|
||||
endif
|
||||
|
||||
$(LIBTCC_OBJ) tcc.o : %.o : %.c $(LIBTCC_INC)
|
||||
$(CC) -o $@ -c $< $(NATIVE_DEFINES) $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
ifndef LIBTCC_DLL
|
||||
libtcc.a: $(LIBTCC_OBJ)
|
||||
$(AR) rcs $@ $^
|
||||
endif
|
||||
|
||||
libtcc.so.1.0: $(LIBTCC_OBJ)
|
||||
$(CC) -shared -Wl,-soname,$@ -o $@ $^ $(LDFLAGS)
|
||||
|
||||
libtcc.so.1.0: CFLAGS+=-fPIC
|
||||
|
||||
ifdef LIBTCC_DLL
|
||||
libtcc.dll libtcc.def libtcc.a: $(LIBTCC_OBJ)
|
||||
$(CC) -shared $^ -o $@ $(LDFLAGS) -Wl,--output-def,libtcc.def,--out-implib,libtcc.a
|
||||
endif
|
||||
|
||||
# windows utilities
|
||||
tiny_impdef$(EXESUF): ../win32/tools/tiny_impdef.c
|
||||
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
tiny_libmaker$(EXESUF): ../win32/tools/tiny_libmaker.c
|
||||
$(CC) -o $@ $< $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
|
||||
|
||||
# TinyCC runtime libraries
|
||||
libtcc1.a : FORCE
|
||||
$(MAKE) -C ../lib native
|
||||
if test ! -d $(ARCH); then mkdir $(ARCH); fi
|
||||
if test ! -L $(ARCH)/$@; then ln -sf ../$@ $(ARCH)/$@; fi
|
||||
lib/%/libtcc1.a : FORCE $(PROGS_CROSS)
|
||||
$(MAKE) -C ../lib cross TARGET=$*
|
||||
|
||||
FORCE:
|
||||
|
||||
# install
|
||||
TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h
|
||||
INSTALL=install
|
||||
ifdef STRIP_BINARIES
|
||||
INSTALLBIN=$(INSTALL) -s
|
||||
else
|
||||
INSTALLBIN=$(INSTALL)
|
||||
endif
|
||||
|
||||
install-strip: install
|
||||
strip $(foreach PROG,$(PROGS),"$(bindir)"/$(PROG))
|
||||
|
||||
ifndef CONFIG_WIN32
|
||||
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||
mkdir -p "$(bindir)"
|
||||
$(INSTALLBIN) -m755 $(PROGS) "$(bindir)"
|
||||
cp -P tcc$(EXESUF) "$(bindir)"
|
||||
mkdir -p "$(mandir)/man1"
|
||||
-$(INSTALL) -m644 tcc.1 "$(mandir)/man1"
|
||||
mkdir -p "$(infodir)"
|
||||
-$(INSTALL) -m644 tcc-doc.info "$(infodir)"
|
||||
mkdir -p "$(tccdir)"
|
||||
mkdir -p "$(tccdir)/include"
|
||||
ifneq ($(LIBTCC1),)
|
||||
mkdir -p "$(tccdir)/$(ARCH)"
|
||||
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)/$(ARCH)"
|
||||
endif
|
||||
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
||||
mkdir -p "$(libdir)"
|
||||
$(INSTALL) -m644 $(LIBTCC) "$(libdir)"
|
||||
ifdef DISABLE_STATIC
|
||||
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so.1"
|
||||
ln -sf "$(ln_libdir)/libtcc.so.1.0" "$(libdir)/libtcc.so"
|
||||
endif
|
||||
mkdir -p "$(includedir)"
|
||||
$(INSTALL) -m644 $(top_srcdir)/libtcc.h "$(includedir)"
|
||||
mkdir -p "$(docdir)"
|
||||
-$(INSTALL) -m644 tcc-doc.html "$(docdir)"
|
||||
ifdef CONFIG_CROSS
|
||||
mkdir -p "$(tccdir)/win32/lib/32"
|
||||
mkdir -p "$(tccdir)/win32/lib/64"
|
||||
mkdir -p "$(tccdir)/i386"
|
||||
mkdir -p "$(tccdir)/x86-64"
|
||||
ifneq ($(HOST_OS),Darwin)
|
||||
mkdir -p "$(tccdir)/arm64"
|
||||
$(INSTALL) -m644 lib/arm64/libtcc1.a "$(tccdir)/arm64"
|
||||
endif
|
||||
$(INSTALL) -m644 lib/i386/libtcc1.a "$(tccdir)/i386"
|
||||
$(INSTALL) -m644 lib/x86_64/libtcc1.a "$(tccdir)/x86-64"
|
||||
$(INSTALL) -m644 $(top_srcdir)/win32/lib/*.def "$(tccdir)/win32/lib"
|
||||
$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/win32/lib/32"
|
||||
$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/win32/lib/64"
|
||||
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/win32/include"
|
||||
cp -r "$(tccdir)/include" "$(tccdir)/win32"
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
|
||||
rm -fv "$(bindir)/tcc$(EXESUF)"
|
||||
rm -fv $(foreach P,$(LIBTCC1),"$(tccdir)/$P")
|
||||
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
|
||||
rm -fv "$(mandir)/man1/tcc.1" "$(infodir)/tcc-doc.info"
|
||||
rm -fv "$(libdir)/$(LIBTCC)" "$(includedir)/libtcc.h"
|
||||
rm -fv "$(libdir)/libtcc.so*"
|
||||
rm -rv "$(tccdir)"
|
||||
rm -rv "$(docdir)"
|
||||
else
|
||||
# on windows
|
||||
install: $(PROGS) $(TCCLIBS) $(TCCDOCS)
|
||||
mkdir -p "$(tccdir)"
|
||||
mkdir -p "$(tccdir)/lib"
|
||||
mkdir -p "$(tccdir)/include"
|
||||
mkdir -p "$(tccdir)/examples"
|
||||
mkdir -p "$(tccdir)/doc"
|
||||
mkdir -p "$(tccdir)/libtcc"
|
||||
$(INSTALLBIN) -m755 $(PROGS) "$(tccdir)"
|
||||
$(INSTALLBIN) -m755 tcc.exe "$(tccdir)"
|
||||
$(INSTALL) -m644 $(LIBTCC1) $(top_srcdir)/win32/lib/*.def "$(tccdir)/lib"
|
||||
cp -r $(top_srcdir)/win32/include/. "$(tccdir)/include"
|
||||
cp -r $(top_srcdir)/win32/examples/. "$(tccdir)/examples"
|
||||
$(INSTALL) -m644 $(addprefix $(top_srcdir)/include/,$(TCC_INCLUDES)) $(top_srcdir)/tcclib.h "$(tccdir)/include"
|
||||
$(INSTALL) -m644 tcc-doc.html $(top_srcdir)/win32/tcc-win32.txt "$(tccdir)/doc"
|
||||
$(INSTALL) -m644 $(top_srcdir)/libtcc.h $(LIBTCC_EXTRA) "$(tccdir)/libtcc"
|
||||
$(INSTALL) -m644 $(LIBTCC) "$(tccdir)"
|
||||
ifdef CONFIG_CROSS
|
||||
mkdir -p "$(tccdir)/lib/32"
|
||||
mkdir -p "$(tccdir)/lib/64"
|
||||
-$(INSTALL) -m644 lib/i386-win/libtcc1.a "$(tccdir)/lib/32"
|
||||
-$(INSTALL) -m644 lib/x86_64-win/libtcc1.a "$(tccdir)/lib/64"
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
rm -rfv "$(tccdir)/*"
|
||||
endif
|
||||
|
||||
# documentation and man page
|
||||
tcc-doc.html: ../docs/tcc-doc.texi
|
||||
-makeinfo --no-split --html --number-sections -o $@ $<
|
||||
|
||||
tcc.1: ../docs/tcc-doc.texi
|
||||
-$(top_srcdir)/../docs/texi2pod.pl $< tcc.pod
|
||||
-pod2man --section=1 --center="Tiny C Compiler" --release=`cat $(top_srcdir)/../VERSION` tcc.pod > $@
|
||||
|
||||
tcc-doc.info: ../docs/tcc-doc.texi
|
||||
-makeinfo $<
|
||||
|
||||
# in tests subdir
|
||||
export LIBTCC1
|
||||
|
||||
%est:
|
||||
$(MAKE) -C ../tests $@ 'PROGS_CROSS=$(PROGS_CROSS)'
|
||||
|
||||
clean:
|
||||
rm -vf $(PROGS) tcc_p$(EXESUF) tcc.pod *~ *.o *.a *.so* *.out *.log \
|
||||
*.exe a.out tags TAGS libtcc_test$(EXESUF) tcc$(EXESUF)
|
||||
-rm -r $(ARCH) arm64
|
||||
ifeq ($(HOST_OS),Linux)
|
||||
-rm -r ./C:
|
||||
endif
|
||||
-rm *-tcc$(EXESUF)
|
||||
$(MAKE) -C ../tests $@
|
||||
ifneq ($(LIBTCC1),)
|
||||
$(MAKE) -C ../lib $@
|
||||
endif
|
||||
|
||||
distclean: clean
|
||||
rm -vf config.h config.mak config.texi tcc.1 tcc-doc.info tcc-doc.html
|
||||
|
||||
config.mak:
|
||||
@echo "Please run ./configure."
|
||||
@exit 1
|
||||
|
||||
tags:
|
||||
ctags $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
|
||||
|
||||
TAGS:
|
||||
ctags -e $(top_srcdir)/*.[ch] $(top_srcdir)/include/*.h $(top_srcdir)/lib/*.[chS]
|
||||
|
||||
# create release tarball from *current* git branch (including tcc-doc.html
|
||||
# and converting two files to CRLF)
|
||||
TCC-VERSION := tcc-$(shell cat $(top_srcdir)/../VERSION)
|
||||
tar: tcc-doc.html
|
||||
mkdir $(TCC-VERSION)
|
||||
( cd $(TCC-VERSION) && git --git-dir ../.git checkout -f )
|
||||
cp tcc-doc.html $(TCC-VERSION)
|
||||
for f in tcc-win32.txt build-tcc.bat ; do \
|
||||
cat win32/$$f | sed 's,\(.*\),\1\r,g' > $(TCC-VERSION)/win32/$$f ; \
|
||||
done
|
||||
tar cjf $(TCC-VERSION).tar.bz2 $(TCC-VERSION)
|
||||
rm -rf $(TCC-VERSION)
|
||||
git reset
|
||||
|
||||
.PHONY: all clean tar tags TAGS distclean install uninstall FORCE
|
||||
|
||||
endif # ifeq ($(TOP),.)
|
2162
src/arm/arm-gen.c
2162
src/arm/arm-gen.c
File diff suppressed because it is too large
Load Diff
924
src/tcccoff.c
924
src/tcccoff.c
@ -1,924 +0,0 @@
|
||||
/*
|
||||
* COFF file handling for TCC
|
||||
*
|
||||
* Copyright (c) 2003, 2004 TK
|
||||
* Copyright (c) 2004 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "tcc.h"
|
||||
|
||||
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
|
||||
#define MAX_STR_TABLE 1000000
|
||||
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
|
||||
|
||||
SCNHDR section_header[MAXNSCNS];
|
||||
|
||||
#define MAX_FUNCS 1000
|
||||
#define MAX_FUNC_NAME_LENGTH 128
|
||||
|
||||
int nFuncs;
|
||||
char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
|
||||
char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
|
||||
int LineNoFilePtr[MAX_FUNCS];
|
||||
int EndAddress[MAX_FUNCS];
|
||||
int LastLineNo[MAX_FUNCS];
|
||||
int FuncEntries[MAX_FUNCS];
|
||||
|
||||
int OutputTheSection(Section* sect);
|
||||
short int GetCoffFlags(const char* s);
|
||||
void SortSymbolTable(void);
|
||||
Section* FindSection(TCCState* s1, const char* sname);
|
||||
|
||||
int C67_main_entry_point;
|
||||
|
||||
int FindCoffSymbolIndex(const char* func_name);
|
||||
int nb_syms;
|
||||
|
||||
typedef struct {
|
||||
long tag;
|
||||
long size;
|
||||
long fileptr;
|
||||
long nextsym;
|
||||
short int dummy;
|
||||
} AUXFUNC;
|
||||
|
||||
typedef struct {
|
||||
long regmask;
|
||||
unsigned short lineno;
|
||||
unsigned short nentries;
|
||||
int localframe;
|
||||
int nextentry;
|
||||
short int dummy;
|
||||
} AUXBF;
|
||||
|
||||
typedef struct {
|
||||
long dummy;
|
||||
unsigned short lineno;
|
||||
unsigned short dummy1;
|
||||
int dummy2;
|
||||
int dummy3;
|
||||
unsigned short dummy4;
|
||||
} AUXEF;
|
||||
|
||||
ST_FUNC int tcc_output_coff(TCCState* s1, FILE* f)
|
||||
{
|
||||
Section* tcc_sect;
|
||||
SCNHDR* coff_sec;
|
||||
int file_pointer;
|
||||
char* Coff_str_table, *pCoff_str_table;
|
||||
int CoffTextSectionNo, coff_nb_syms;
|
||||
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
|
||||
Section* stext, *sdata, *sbss;
|
||||
int i, NSectionsToOutput = 0;
|
||||
|
||||
Coff_str_table = pCoff_str_table = NULL;
|
||||
|
||||
stext = FindSection(s1, ".text");
|
||||
sdata = FindSection(s1, ".data");
|
||||
sbss = FindSection(s1, ".bss");
|
||||
|
||||
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
|
||||
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
|
||||
|
||||
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
|
||||
file_hdr.f_timdat = 0; /* time & date stamp */
|
||||
file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
|
||||
file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
|
||||
file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
|
||||
|
||||
o_filehdr.magic = 0x0108; /* see magic.h */
|
||||
o_filehdr.vstamp = 0x0190; /* version stamp */
|
||||
o_filehdr.tsize =
|
||||
stext->data_offset; /* text size in bytes, padded to FW bdry */
|
||||
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
|
||||
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
|
||||
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
|
||||
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
|
||||
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
|
||||
|
||||
// create all the section headers
|
||||
|
||||
file_pointer = FILHSZ + sizeof(AOUTHDR);
|
||||
|
||||
CoffTextSectionNo = -1;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
NSectionsToOutput++;
|
||||
|
||||
if (CoffTextSectionNo == -1 && tcc_sect == stext)
|
||||
CoffTextSectionNo = NSectionsToOutput; // rem which coff sect
|
||||
// number the .text sect
|
||||
// is
|
||||
|
||||
strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
|
||||
|
||||
coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
|
||||
coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
|
||||
coff_sec->s_size = tcc_sect->data_offset; /* section size */
|
||||
coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
|
||||
coff_sec->s_relptr = 0; /* file ptr to relocation */
|
||||
coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
|
||||
coff_sec->s_nreloc = 0; /* number of relocation entries */
|
||||
coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
|
||||
coff_sec->s_reserved = 0; /* reserved byte */
|
||||
coff_sec->s_page = 0; /* memory page id */
|
||||
|
||||
file_pointer += sizeof(SCNHDR);
|
||||
}
|
||||
}
|
||||
|
||||
file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the raw data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put raw data
|
||||
coff_sec->s_scnptr =
|
||||
file_pointer; /* file ptr to raw data for section */
|
||||
file_pointer += coff_sec->s_size;
|
||||
}
|
||||
}
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the relocation data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put relocations data
|
||||
if (coff_sec->s_nreloc > 0) {
|
||||
coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
|
||||
file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the line number data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
coff_sec->s_nlnno = 0;
|
||||
coff_sec->s_lnnoptr = 0;
|
||||
|
||||
if (s1->do_debug && tcc_sect == stext) {
|
||||
// count how many line nos data
|
||||
|
||||
// also find association between source file name and function
|
||||
// so we can sort the symbol table
|
||||
|
||||
Stab_Sym* sym, *sym_end;
|
||||
char func_name[MAX_FUNC_NAME_LENGTH],
|
||||
last_func_name[MAX_FUNC_NAME_LENGTH];
|
||||
unsigned long func_addr, last_pc, pc;
|
||||
const char* incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num;
|
||||
const char* str, *p;
|
||||
|
||||
coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
|
||||
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
incl_index = 0;
|
||||
last_func_name[0] = '\0';
|
||||
last_pc = 0xffffffff;
|
||||
last_line_num = 1;
|
||||
sym = (Stab_Sym*)stab_section->data + 1;
|
||||
sym_end =
|
||||
(Stab_Sym*)(stab_section->data + stab_section->data_offset);
|
||||
|
||||
nFuncs = 0;
|
||||
while (sym < sym_end) {
|
||||
switch (sym->n_type) {
|
||||
/* function start or end */
|
||||
case N_FUN:
|
||||
if (sym->n_strx == 0) {
|
||||
// end of function
|
||||
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
|
||||
pc = sym->n_value + func_addr;
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
EndAddress[nFuncs] = pc;
|
||||
FuncEntries[nFuncs] =
|
||||
(file_pointer - LineNoFilePtr[nFuncs]) / LINESZ - 1;
|
||||
LastLineNo[nFuncs++] = last_line_num + 1;
|
||||
} else {
|
||||
// beginning of function
|
||||
|
||||
LineNoFilePtr[nFuncs] = file_pointer;
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
|
||||
str = (const char*)stabstr_section->data + sym->n_strx;
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (!p) {
|
||||
pstrcpy(func_name, sizeof(func_name), str);
|
||||
pstrcpy(Func[nFuncs], sizeof(func_name), str);
|
||||
} else {
|
||||
len = p - str;
|
||||
if (len > sizeof(func_name) - 1)
|
||||
len = sizeof(func_name) - 1;
|
||||
memcpy(func_name, str, len);
|
||||
memcpy(Func[nFuncs], str, len);
|
||||
func_name[len] = '\0';
|
||||
}
|
||||
|
||||
// save the file that it came in so we can sort later
|
||||
pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
|
||||
incl_files[incl_index - 1]);
|
||||
|
||||
func_addr = sym->n_value;
|
||||
}
|
||||
break;
|
||||
|
||||
/* line number info */
|
||||
case N_SLINE:
|
||||
pc = sym->n_value + func_addr;
|
||||
|
||||
last_pc = pc;
|
||||
last_line_num = sym->n_desc;
|
||||
|
||||
/* XXX: slow! */
|
||||
strcpy(last_func_name, func_name);
|
||||
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
break;
|
||||
/* include files */
|
||||
case N_BINCL:
|
||||
str = (const char*)stabstr_section->data + sym->n_strx;
|
||||
add_incl:
|
||||
if (incl_index < INCLUDE_STACK_SIZE) {
|
||||
incl_files[incl_index++] = str;
|
||||
}
|
||||
break;
|
||||
case N_EINCL:
|
||||
if (incl_index > 1)
|
||||
incl_index--;
|
||||
break;
|
||||
case N_SO:
|
||||
if (sym->n_strx == 0) {
|
||||
incl_index = 0; /* end of translation unit */
|
||||
} else {
|
||||
str = (const char*)stabstr_section->data + sym->n_strx;
|
||||
/* do not add path */
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[len - 1] != '/')
|
||||
goto add_incl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sym++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
|
||||
|
||||
if (s1->do_debug)
|
||||
file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
|
||||
else
|
||||
file_hdr.f_nsyms = 0;
|
||||
|
||||
file_pointer += file_hdr.f_nsyms * SYMNMLEN;
|
||||
|
||||
// OK now we are all set to write the file
|
||||
|
||||
fwrite(&file_hdr, FILHSZ, 1, f);
|
||||
fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
|
||||
|
||||
// write section headers
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
fwrite(coff_sec, sizeof(SCNHDR), 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write raw data
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write relocation data
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put relocations data
|
||||
if (coff_sec->s_nreloc > 0) {
|
||||
fwrite(tcc_sect->reloc,
|
||||
coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// group the symbols in order of filename, func1, func2, etc
|
||||
// finally global symbols
|
||||
|
||||
if (s1->do_debug)
|
||||
SortSymbolTable();
|
||||
|
||||
// write line no data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (s1->do_debug && tcc_sect == stext) {
|
||||
// count how many line nos data
|
||||
|
||||
Stab_Sym* sym, *sym_end;
|
||||
char func_name[128], last_func_name[128];
|
||||
unsigned long func_addr, last_pc, pc;
|
||||
const char* incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num;
|
||||
const char* str, *p;
|
||||
|
||||
LINENO CoffLineNo;
|
||||
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
incl_index = 0;
|
||||
last_func_name[0] = '\0';
|
||||
last_pc = 0;
|
||||
last_line_num = 1;
|
||||
sym = (Stab_Sym*)stab_section->data + 1;
|
||||
sym_end =
|
||||
(Stab_Sym*)(stab_section->data + stab_section->data_offset);
|
||||
|
||||
while (sym < sym_end) {
|
||||
switch (sym->n_type) {
|
||||
/* function start or end */
|
||||
case N_FUN:
|
||||
if (sym->n_strx == 0) {
|
||||
// end of function
|
||||
|
||||
CoffLineNo.l_addr.l_paddr = last_pc;
|
||||
CoffLineNo.l_lnno = last_line_num + 1;
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
|
||||
pc = sym->n_value + func_addr;
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
} else {
|
||||
// beginning of function
|
||||
|
||||
str = (const char*)stabstr_section->data + sym->n_strx;
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (!p) {
|
||||
pstrcpy(func_name, sizeof(func_name), str);
|
||||
} else {
|
||||
len = p - str;
|
||||
if (len > sizeof(func_name) - 1)
|
||||
len = sizeof(func_name) - 1;
|
||||
memcpy(func_name, str, len);
|
||||
func_name[len] = '\0';
|
||||
}
|
||||
func_addr = sym->n_value;
|
||||
last_pc = func_addr;
|
||||
last_line_num = -1;
|
||||
|
||||
// output a function begin
|
||||
|
||||
CoffLineNo.l_addr.l_symndx =
|
||||
FindCoffSymbolIndex(func_name);
|
||||
CoffLineNo.l_lnno = 0;
|
||||
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
}
|
||||
break;
|
||||
|
||||
/* line number info */
|
||||
case N_SLINE:
|
||||
pc = sym->n_value + func_addr;
|
||||
|
||||
/* XXX: slow! */
|
||||
strcpy(last_func_name, func_name);
|
||||
|
||||
// output a line reference
|
||||
|
||||
CoffLineNo.l_addr.l_paddr = last_pc;
|
||||
|
||||
if (last_line_num == -1) {
|
||||
CoffLineNo.l_lnno = sym->n_desc;
|
||||
} else {
|
||||
CoffLineNo.l_lnno = last_line_num + 1;
|
||||
}
|
||||
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
|
||||
last_pc = pc;
|
||||
last_line_num = sym->n_desc;
|
||||
|
||||
break;
|
||||
|
||||
/* include files */
|
||||
case N_BINCL:
|
||||
str = (const char*)stabstr_section->data + sym->n_strx;
|
||||
add_incl2:
|
||||
if (incl_index < INCLUDE_STACK_SIZE) {
|
||||
incl_files[incl_index++] = str;
|
||||
}
|
||||
break;
|
||||
case N_EINCL:
|
||||
if (incl_index > 1)
|
||||
incl_index--;
|
||||
break;
|
||||
case N_SO:
|
||||
if (sym->n_strx == 0) {
|
||||
incl_index = 0; /* end of translation unit */
|
||||
} else {
|
||||
str = (const char*)stabstr_section->data + sym->n_strx;
|
||||
/* do not add path */
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[len - 1] != '/')
|
||||
goto add_incl2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sym++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write symbol table
|
||||
if (s1->do_debug) {
|
||||
int k;
|
||||
struct syment csym;
|
||||
AUXFUNC auxfunc;
|
||||
AUXBF auxbf;
|
||||
AUXEF auxef;
|
||||
int i;
|
||||
Elf32_Sym* p;
|
||||
const char* name;
|
||||
int nstr;
|
||||
int n = 0;
|
||||
|
||||
Coff_str_table = (char*)tcc_malloc(MAX_STR_TABLE);
|
||||
pCoff_str_table = Coff_str_table;
|
||||
nstr = 0;
|
||||
|
||||
p = (Elf32_Sym*)symtab_section->data;
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
|
||||
name = symtab_section->link->data + p->st_name;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
csym._n._n_name[k] = 0;
|
||||
|
||||
if (strlen(name) <= 8) {
|
||||
strcpy(csym._n._n_name, name);
|
||||
} else {
|
||||
if (pCoff_str_table - Coff_str_table + strlen(name) >
|
||||
MAX_STR_TABLE - 1)
|
||||
tcc_error("String table too large");
|
||||
|
||||
csym._n._n_n._n_zeroes = 0;
|
||||
csym._n._n_n._n_offset = pCoff_str_table - Coff_str_table + 4;
|
||||
|
||||
strcpy(pCoff_str_table, name);
|
||||
pCoff_str_table += strlen(name) + 1; // skip over null
|
||||
nstr++;
|
||||
}
|
||||
|
||||
if (p->st_info == 4) {
|
||||
// put a filename symbol
|
||||
csym.n_value = 33; // ?????
|
||||
csym.n_scnum = N_DEBUG;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FILE;
|
||||
csym.n_numaux = 0;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
n++;
|
||||
|
||||
} else if (p->st_info == 0x12) {
|
||||
// find the function data
|
||||
|
||||
for (k = 0; k < nFuncs; k++) {
|
||||
if (strcmp(name, Func[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k >= nFuncs) {
|
||||
tcc_error("debug info can't find function: %s", name);
|
||||
}
|
||||
// put a Function Name
|
||||
|
||||
csym.n_value = p->st_value; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
|
||||
csym.n_sclass = C_EXT;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxfunc.tag = 0;
|
||||
auxfunc.size = EndAddress[k] - p->st_value;
|
||||
auxfunc.fileptr = LineNoFilePtr[k];
|
||||
auxfunc.nextsym = n + 6; // tktk
|
||||
auxfunc.dummy = 0;
|
||||
fwrite(&auxfunc, 18, 1, f);
|
||||
|
||||
// put a .bf
|
||||
|
||||
strcpy(csym._n._n_name, ".bf");
|
||||
csym.n_value = p->st_value; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FCN;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxbf.regmask = 0;
|
||||
auxbf.lineno = 0;
|
||||
auxbf.nentries = FuncEntries[k];
|
||||
auxbf.localframe = 0;
|
||||
auxbf.nextentry = n + 6;
|
||||
auxbf.dummy = 0;
|
||||
fwrite(&auxbf, 18, 1, f);
|
||||
|
||||
// put a .ef
|
||||
|
||||
strcpy(csym._n._n_name, ".ef");
|
||||
csym.n_value = EndAddress[k]; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FCN;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxef.dummy = 0;
|
||||
auxef.lineno = LastLineNo[k];
|
||||
auxef.dummy1 = 0;
|
||||
auxef.dummy2 = 0;
|
||||
auxef.dummy3 = 0;
|
||||
auxef.dummy4 = 0;
|
||||
fwrite(&auxef, 18, 1, f);
|
||||
|
||||
n += 6;
|
||||
|
||||
} else {
|
||||
// try an put some type info
|
||||
|
||||
if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
|
||||
csym.n_type = T_DOUBLE; // int
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
|
||||
csym.n_type = T_FLOAT;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_INT) {
|
||||
csym.n_type = T_INT; // int
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
|
||||
csym.n_type = T_SHORT;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
|
||||
csym.n_type = T_CHAR;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else {
|
||||
csym.n_type = T_INT; // just mark as a label
|
||||
csym.n_sclass = C_LABEL;
|
||||
}
|
||||
|
||||
csym.n_value = p->st_value;
|
||||
csym.n_scnum = 2;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
auxfunc.tag = 0;
|
||||
auxfunc.size = 0x20;
|
||||
auxfunc.fileptr = 0;
|
||||
auxfunc.nextsym = 0;
|
||||
auxfunc.dummy = 0;
|
||||
fwrite(&auxfunc, 18, 1, f);
|
||||
n++;
|
||||
n++;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->do_debug) {
|
||||
// write string table
|
||||
|
||||
// first write the size
|
||||
i = pCoff_str_table - Coff_str_table;
|
||||
fwrite(&i, 4, 1, f);
|
||||
|
||||
// then write the strings
|
||||
fwrite(Coff_str_table, i, 1, f);
|
||||
|
||||
tcc_free(Coff_str_table);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// group the symbols in order of filename, func1, func2, etc
|
||||
// finally global symbols
|
||||
|
||||
void SortSymbolTable(void)
|
||||
{
|
||||
int i, j, k, n = 0;
|
||||
Elf32_Sym* p, *p2, *NewTable;
|
||||
char* name, *name2;
|
||||
|
||||
NewTable = (Elf32_Sym*)tcc_malloc(nb_syms * sizeof(Elf32_Sym));
|
||||
|
||||
p = (Elf32_Sym*)symtab_section->data;
|
||||
|
||||
// find a file symbol, copy it over
|
||||
// then scan the whole symbol list and copy any function
|
||||
// symbols that match the file association
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
if (p->st_info == 4) {
|
||||
name = (char*)symtab_section->link->data + p->st_name;
|
||||
|
||||
// this is a file symbol, copy it over
|
||||
|
||||
NewTable[n++] = *p;
|
||||
|
||||
p2 = (Elf32_Sym*)symtab_section->data;
|
||||
|
||||
for (j = 0; j < nb_syms; j++) {
|
||||
if (p2->st_info == 0x12) {
|
||||
// this is a func symbol
|
||||
|
||||
name2 = (char*)symtab_section->link->data + p2->st_name;
|
||||
|
||||
// find the function data index
|
||||
|
||||
for (k = 0; k < nFuncs; k++) {
|
||||
if (strcmp(name2, Func[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k >= nFuncs) {
|
||||
tcc_error("debug (sort) info can't find function: %s",
|
||||
name2);
|
||||
}
|
||||
|
||||
if (strcmp(AssociatedFile[k], name) == 0) {
|
||||
// yes they match copy it over
|
||||
|
||||
NewTable[n++] = *p2;
|
||||
}
|
||||
}
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
// now all the filename and func symbols should have been copied over
|
||||
// copy all the rest over (all except file and funcs)
|
||||
|
||||
p = (Elf32_Sym*)symtab_section->data;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
if (p->st_info != 4 && p->st_info != 0x12) {
|
||||
NewTable[n++] = *p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (n != nb_syms)
|
||||
tcc_error("Internal Compiler error, debug info");
|
||||
|
||||
// copy it all back
|
||||
|
||||
p = (Elf32_Sym*)symtab_section->data;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
*p++ = NewTable[i];
|
||||
}
|
||||
|
||||
tcc_free(NewTable);
|
||||
}
|
||||
|
||||
int FindCoffSymbolIndex(const char* func_name)
|
||||
{
|
||||
int i, n = 0;
|
||||
Elf32_Sym* p;
|
||||
char* name;
|
||||
|
||||
p = (Elf32_Sym*)symtab_section->data;
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
|
||||
name = (char*)symtab_section->link->data + p->st_name;
|
||||
|
||||
if (p->st_info == 4) {
|
||||
// put a filename symbol
|
||||
n++;
|
||||
} else if (p->st_info == 0x12) {
|
||||
|
||||
if (strcmp(func_name, name) == 0)
|
||||
return n;
|
||||
|
||||
n += 6;
|
||||
|
||||
// put a Function Name
|
||||
|
||||
// now put aux info
|
||||
|
||||
// put a .bf
|
||||
|
||||
// now put aux info
|
||||
|
||||
// put a .ef
|
||||
|
||||
// now put aux info
|
||||
|
||||
} else {
|
||||
n += 2;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return n; // total number of symbols
|
||||
}
|
||||
|
||||
int OutputTheSection(Section* sect)
|
||||
{
|
||||
const char* s = sect->name;
|
||||
|
||||
if (!strcmp(s, ".text"))
|
||||
return 1;
|
||||
else if (!strcmp(s, ".data"))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
short int GetCoffFlags(const char* s)
|
||||
{
|
||||
if (!strcmp(s, ".text"))
|
||||
return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
|
||||
else if (!strcmp(s, ".data"))
|
||||
return STYP_DATA;
|
||||
else if (!strcmp(s, ".bss"))
|
||||
return STYP_BSS;
|
||||
else if (!strcmp(s, ".stack"))
|
||||
return STYP_BSS | STYP_ALIGN | 0x200;
|
||||
else if (!strcmp(s, ".cinit"))
|
||||
return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Section* FindSection(TCCState* s1, const char* sname)
|
||||
{
|
||||
Section* s;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
|
||||
if (!strcmp(sname, s->name))
|
||||
return s;
|
||||
}
|
||||
|
||||
tcc_error("could not find section %s", sname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ST_FUNC int tcc_load_coff(TCCState* s1, int fd)
|
||||
{
|
||||
// tktk TokenSym *ts;
|
||||
|
||||
FILE* f;
|
||||
unsigned int str_size;
|
||||
char* Coff_str_table, *name;
|
||||
int i, k;
|
||||
struct syment csym;
|
||||
char name2[9];
|
||||
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
|
||||
|
||||
f = fdopen(fd, "rb");
|
||||
if (!f) {
|
||||
tcc_error("Unable to open .out file for input");
|
||||
}
|
||||
|
||||
if (fread(&file_hdr, FILHSZ, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
// first read the string table
|
||||
|
||||
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
if (fread(&str_size, sizeof(int), 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
Coff_str_table = (char*)tcc_malloc(str_size);
|
||||
|
||||
if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
// read/process all the symbols
|
||||
|
||||
// seek back to symbols
|
||||
|
||||
if (fseek(f, file_hdr.f_symptr, SEEK_SET))
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
for (i = 0; i < file_hdr.f_nsyms; i++) {
|
||||
if (fread(&csym, SYMESZ, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
if (csym._n._n_n._n_zeroes == 0) {
|
||||
name = Coff_str_table + csym._n._n_n._n_offset - 4;
|
||||
} else {
|
||||
name = csym._n._n_name;
|
||||
|
||||
if (name[7] != 0) {
|
||||
for (k = 0; k < 8; k++)
|
||||
name2[k] = name[k];
|
||||
|
||||
name2[8] = 0;
|
||||
|
||||
name = name2;
|
||||
}
|
||||
}
|
||||
// if (strcmp("_DAC_Buffer",name)==0) // tktk
|
||||
// name[0]=0;
|
||||
|
||||
if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) ||
|
||||
((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) ||
|
||||
(csym.n_type == 0x4 && csym.n_sclass == 0x2) ||
|
||||
(csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
|
||||
(csym.n_type == 0x18 &&
|
||||
csym.n_sclass == 0x2) || // pointer to structure
|
||||
(csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
|
||||
(csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
|
||||
{
|
||||
// strip off any leading underscore (except for other main routine)
|
||||
|
||||
if (name[0] == '_' && strcmp(name, "_main") != 0)
|
||||
name++;
|
||||
|
||||
tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
|
||||
}
|
||||
// skip any aux records
|
||||
|
||||
if (csym.n_numaux == 1) {
|
||||
if (fread(&csym, SYMESZ, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -99,9 +99,9 @@ the @code{main()} of a.c.
|
||||
|
||||
@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
|
||||
as first argument to the @code{main()} of the resulting program.
|
||||
@ignore
|
||||
Because multiple C files are specified, @option{--} are necessary to clearly
|
||||
as first argument to the @code{main()} of the resulting program.
|
||||
@ignore
|
||||
Because multiple C files are specified, @option{--} are necessary to clearly
|
||||
separate the program arguments from the TCC options.
|
||||
@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
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
int main()
|
||||
@{
|
||||
printf("Hello World\n");
|
||||
return 0;
|
||||
@}
|
||||
@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:
|
||||
|
||||
@example
|
||||
@ -271,7 +271,7 @@ Make string constants be of type @code{const char *} instead of @code{char
|
||||
@item -Werror
|
||||
Abort compilation if warnings are issued.
|
||||
|
||||
@item -Wall
|
||||
@item -Wall
|
||||
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
|
||||
@option{-Wwrite-strings}.
|
||||
|
||||
@ -451,7 +451,7 @@ function name.
|
||||
|
||||
int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
|
||||
@end example
|
||||
|
||||
|
||||
@item Compound initializers are supported:
|
||||
@example
|
||||
int *p = (int [])@{ 1, 2, 3 @};
|
||||
@ -465,7 +465,7 @@ works for structures and strings.
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
is the same as writing
|
||||
is the same as writing
|
||||
@example
|
||||
double d = 4771840.0;
|
||||
@end example
|
||||
@ -481,12 +481,12 @@ TCC implements some GNU C extensions:
|
||||
|
||||
@itemize
|
||||
|
||||
@item array designators can be used without '=':
|
||||
@item array designators can be used without '=':
|
||||
@example
|
||||
int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
|
||||
@end example
|
||||
|
||||
@item Structure field designators can be a label:
|
||||
@item Structure field designators can be a label:
|
||||
@example
|
||||
struct @{ int x, y; @} st = @{ x: 1, y: 1@};
|
||||
@end example
|
||||
@ -555,7 +555,7 @@ Here are some examples:
|
||||
align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
|
||||
|
||||
@example
|
||||
int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
|
||||
int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
|
||||
@{
|
||||
return a + b;
|
||||
@}
|
||||
@ -572,17 +572,17 @@ generate function @code{my_add} in section @code{.mycodesection}.
|
||||
dprintf("one arg %d\n", 1);
|
||||
@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
|
||||
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.
|
||||
|
||||
@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.
|
||||
|
||||
@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
|
||||
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
|
||||
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.
|
||||
|
||||
@item @code{#pragma pack} is supported for win32 compatibility.
|
||||
@ -681,7 +681,7 @@ same as C.
|
||||
@item +, -
|
||||
@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
|
||||
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.
|
||||
@ -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 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'
|
||||
(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
|
||||
|
||||
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
|
||||
@file{libtcc_test.c} to have a very simple example.
|
||||
@ -941,10 +941,10 @@ except:
|
||||
|
||||
@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.
|
||||
|
||||
@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.
|
||||
|
||||
@end itemize
|
||||
@ -1156,7 +1156,7 @@ stack.
|
||||
@item VT_CMP
|
||||
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
|
||||
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
|
||||
put in a normal register.
|
||||
@ -1176,7 +1176,7 @@ taken.
|
||||
@item VT_LVAL
|
||||
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
|
||||
the wanted value.
|
||||
the wanted value.
|
||||
|
||||
Understanding the use @code{VT_LVAL} is very important if you want to
|
||||
understand how TCC works.
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TCC - Tiny C Compiler
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TCC - Tiny C Compiler
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -293,20 +293,20 @@
|
||||
|
||||
#define TARGET_DEFS_ONLY
|
||||
#ifdef TCC_TARGET_I386
|
||||
# include "x86/i386-gen.c"
|
||||
# include "i386-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
# include "x86/x86_64-gen.c"
|
||||
# include "x86_64-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM
|
||||
# include "arm/arm-gen.c"
|
||||
# include "arm-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
# include "arm/arm64-gen.c"
|
||||
# include "arm64-gen.c"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_C67
|
||||
# include "coff.h"
|
||||
# include "tms320c67c67-gen.c"
|
||||
# include "c67-gen.c"
|
||||
#endif
|
||||
#undef TARGET_DEFS_ONLY
|
||||
|
||||
@ -605,7 +605,7 @@ struct TCCState {
|
||||
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 */
|
||||
int dollars_in_identifiers; /* allows '$' char in indentifiers */
|
||||
|
||||
|
||||
/* warning switches */
|
||||
int warn_write_strings;
|
||||
int warn_unsupported;
|
||||
@ -631,7 +631,7 @@ struct TCCState {
|
||||
|
||||
char *init_symbol; /* symbols to call at load-time (not used currently) */
|
||||
char *fini_symbol; /* symbols to call at unload-time (not used currently) */
|
||||
|
||||
|
||||
#ifdef TCC_TARGET_I386
|
||||
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
|
||||
#endif
|
||||
@ -885,7 +885,7 @@ struct TCCState {
|
||||
|
||||
#define TOK_SHL 0x01 /* shift left */
|
||||
#define TOK_SAR 0x02 /* signed shift right */
|
||||
|
||||
|
||||
/* assignement operators : normal operator or 0x80 */
|
||||
#define TOK_A_MOD 0xa5
|
||||
#define TOK_A_AND 0xa6
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* GAS like assembler for TCC
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@ -92,10 +92,10 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
|
||||
break;
|
||||
case TOK_CCHAR:
|
||||
case TOK_LCHAR:
|
||||
pe->v = tokc.i;
|
||||
pe->sym = NULL;
|
||||
next();
|
||||
break;
|
||||
pe->v = tokc.i;
|
||||
pe->sym = NULL;
|
||||
next();
|
||||
break;
|
||||
case '(':
|
||||
next();
|
||||
asm_expr(s1, pe);
|
||||
@ -125,7 +125,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
||||
{
|
||||
int op;
|
||||
@ -134,7 +134,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
||||
asm_expr_unary(s1, pe);
|
||||
for(;;) {
|
||||
op = tok;
|
||||
if (op != '*' && op != '/' && op != '%' &&
|
||||
if (op != '*' && op != '/' && op != '%' &&
|
||||
op != TOK_SHL && op != TOK_SAR)
|
||||
break;
|
||||
next();
|
||||
@ -145,14 +145,14 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
||||
case '*':
|
||||
pe->v *= e2.v;
|
||||
break;
|
||||
case '/':
|
||||
case '/':
|
||||
if (e2.v == 0) {
|
||||
div_error:
|
||||
tcc_error("division by zero");
|
||||
}
|
||||
pe->v /= e2.v;
|
||||
break;
|
||||
case '%':
|
||||
case '%':
|
||||
if (e2.v == 0)
|
||||
goto div_error;
|
||||
pe->v %= e2.v;
|
||||
@ -186,7 +186,7 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe)
|
||||
case '&':
|
||||
pe->v &= e2.v;
|
||||
break;
|
||||
case '|':
|
||||
case '|':
|
||||
pe->v |= e2.v;
|
||||
break;
|
||||
default:
|
||||
@ -224,7 +224,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
|
||||
} else if (pe->sym && !e2.sym) {
|
||||
/* OK */
|
||||
} else if (pe->sym && e2.sym) {
|
||||
if (pe->sym == e2.sym) {
|
||||
if (pe->sym == e2.sym) {
|
||||
/* OK */
|
||||
} else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
|
||||
/* 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) {
|
||||
/* the label is already defined */
|
||||
if (!is_local) {
|
||||
tcc_error("assembler label '%s' already defined",
|
||||
tcc_error("assembler label '%s' already defined",
|
||||
get_tok_str(label, NULL));
|
||||
} else {
|
||||
/* redefinition of local labels is possible */
|
||||
@ -492,25 +492,25 @@ static void asm_parse_directive(TCCState *s1)
|
||||
case TOK_ASM_global:
|
||||
case TOK_ASM_weak:
|
||||
case TOK_ASM_hidden:
|
||||
tok1 = tok;
|
||||
do {
|
||||
Sym *sym;
|
||||
tok1 = tok;
|
||||
do {
|
||||
Sym *sym;
|
||||
|
||||
next();
|
||||
sym = label_find(tok);
|
||||
if (!sym) {
|
||||
sym = label_push(&s1->asm_labels, tok, 0);
|
||||
sym->type.t = VT_VOID;
|
||||
}
|
||||
if (tok1 != TOK_ASM_hidden)
|
||||
sym->type.t &= ~VT_STATIC;
|
||||
if (tok1 == TOK_ASM_weak)
|
||||
sym->type.t |= VT_WEAK;
|
||||
else if (tok1 == TOK_ASM_hidden)
|
||||
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
|
||||
next();
|
||||
} while (tok == ',');
|
||||
break;
|
||||
next();
|
||||
sym = label_find(tok);
|
||||
if (!sym) {
|
||||
sym = label_push(&s1->asm_labels, tok, 0);
|
||||
sym->type.t = VT_VOID;
|
||||
}
|
||||
if (tok1 != TOK_ASM_hidden)
|
||||
sym->type.t &= ~VT_STATIC;
|
||||
if (tok1 == TOK_ASM_weak)
|
||||
sym->type.t |= VT_WEAK;
|
||||
else if (tok1 == TOK_ASM_hidden)
|
||||
sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT;
|
||||
next();
|
||||
} while (tok == ',');
|
||||
break;
|
||||
case TOK_ASM_string:
|
||||
case TOK_ASM_ascii:
|
||||
case TOK_ASM_asciz:
|
||||
@ -536,24 +536,24 @@ static void asm_parse_directive(TCCState *s1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASM_text:
|
||||
case TOK_ASM_data:
|
||||
case TOK_ASM_bss:
|
||||
{
|
||||
{
|
||||
char sname[64];
|
||||
tok1 = tok;
|
||||
n = 0;
|
||||
next();
|
||||
if (tok != ';' && tok != TOK_LINEFEED) {
|
||||
n = asm_int_expr(s1);
|
||||
next();
|
||||
n = asm_int_expr(s1);
|
||||
next();
|
||||
}
|
||||
sprintf(sname, (n?".%s%d":".%s"), get_tok_str(tok1, NULL), n);
|
||||
use_section(s1, sname);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASM_file:
|
||||
{
|
||||
char filename[512];
|
||||
@ -591,7 +591,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||
}
|
||||
break;
|
||||
case TOK_ASM_size:
|
||||
{
|
||||
{
|
||||
Sym *sym;
|
||||
|
||||
next();
|
||||
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||
}
|
||||
break;
|
||||
case TOK_ASM_type:
|
||||
{
|
||||
{
|
||||
Sym *sym;
|
||||
const char *newtype;
|
||||
|
||||
@ -637,7 +637,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
|
||||
}
|
||||
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);
|
||||
|
||||
next();
|
||||
@ -669,7 +669,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||
}
|
||||
break;
|
||||
case TOK_ASM_previous:
|
||||
{
|
||||
{
|
||||
Section *sec;
|
||||
next();
|
||||
if (!last_text_section)
|
||||
@ -830,7 +830,7 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
|
||||
|
||||
cur_text_section->data_offset = ind;
|
||||
|
||||
free_defines(define_start);
|
||||
free_defines(define_start);
|
||||
|
||||
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
|
||||
syntax). return -1 if not found. Return in *pp in char after the
|
||||
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)
|
||||
{
|
||||
int index;
|
||||
@ -901,7 +901,7 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
|
||||
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,
|
||||
CString *out_str, CString *in_str)
|
||||
{
|
||||
@ -1052,12 +1052,12 @@ ST_FUNC void asm_instr(void)
|
||||
token after the assembler parsing */
|
||||
if (tok != ';')
|
||||
expect("';'");
|
||||
|
||||
|
||||
/* save all values in the memory */
|
||||
save_regs(0);
|
||||
|
||||
/* compute constraints */
|
||||
asm_compute_constraints(operands, nb_operands, nb_outputs,
|
||||
asm_compute_constraints(operands, nb_operands, nb_outputs,
|
||||
clobber_regs, &out_reg);
|
||||
|
||||
/* substitute the operands in the asm string. No substitution is
|
||||
@ -1076,8 +1076,8 @@ ST_FUNC void asm_instr(void)
|
||||
#endif
|
||||
|
||||
/* generate loads */
|
||||
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
||||
clobber_regs, out_reg);
|
||||
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
||||
clobber_regs, out_reg);
|
||||
|
||||
/* assemble the string with tcc internal assembler */
|
||||
tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
|
||||
@ -1086,9 +1086,9 @@ ST_FUNC void asm_instr(void)
|
||||
next();
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
/* free everything */
|
||||
for(i=0;i<nb_operands;i++) {
|
||||
ASMOperand *op;
|
||||
@ -1110,7 +1110,7 @@ ST_FUNC void asm_global_instr(void)
|
||||
token after the assembler parsing */
|
||||
if (tok != ';')
|
||||
expect("';'");
|
||||
|
||||
|
||||
#ifdef ASM_DEBUG
|
||||
printf("asm_global: \"%s\"\n", (char *)astr.data);
|
||||
#endif
|
||||
@ -1119,7 +1119,7 @@ ST_FUNC void asm_global_instr(void)
|
||||
|
||||
/* assemble the string with tcc internal assembler */
|
||||
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
|
||||
|
||||
|
||||
cur_text_section->data_offset = ind;
|
||||
|
||||
/* restore the current C token */
|
948
tcccoff.c
Normal file
948
tcccoff.c
Normal file
@ -0,0 +1,948 @@
|
||||
/*
|
||||
* COFF file handling for TCC
|
||||
*
|
||||
* Copyright (c) 2003, 2004 TK
|
||||
* Copyright (c) 2004 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "tcc.h"
|
||||
|
||||
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
|
||||
#define MAX_STR_TABLE 1000000
|
||||
AOUTHDR o_filehdr; /* OPTIONAL (A.OUT) FILE HEADER */
|
||||
|
||||
SCNHDR section_header[MAXNSCNS];
|
||||
|
||||
#define MAX_FUNCS 1000
|
||||
#define MAX_FUNC_NAME_LENGTH 128
|
||||
|
||||
int nFuncs;
|
||||
char Func[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
|
||||
char AssociatedFile[MAX_FUNCS][MAX_FUNC_NAME_LENGTH];
|
||||
int LineNoFilePtr[MAX_FUNCS];
|
||||
int EndAddress[MAX_FUNCS];
|
||||
int LastLineNo[MAX_FUNCS];
|
||||
int FuncEntries[MAX_FUNCS];
|
||||
|
||||
int OutputTheSection(Section * sect);
|
||||
short int GetCoffFlags(const char *s);
|
||||
void SortSymbolTable(void);
|
||||
Section *FindSection(TCCState * s1, const char *sname);
|
||||
|
||||
int C67_main_entry_point;
|
||||
|
||||
int FindCoffSymbolIndex(const char *func_name);
|
||||
int nb_syms;
|
||||
|
||||
typedef struct {
|
||||
long tag;
|
||||
long size;
|
||||
long fileptr;
|
||||
long nextsym;
|
||||
short int dummy;
|
||||
} AUXFUNC;
|
||||
|
||||
typedef struct {
|
||||
long regmask;
|
||||
unsigned short lineno;
|
||||
unsigned short nentries;
|
||||
int localframe;
|
||||
int nextentry;
|
||||
short int dummy;
|
||||
} AUXBF;
|
||||
|
||||
typedef struct {
|
||||
long dummy;
|
||||
unsigned short lineno;
|
||||
unsigned short dummy1;
|
||||
int dummy2;
|
||||
int dummy3;
|
||||
unsigned short dummy4;
|
||||
} AUXEF;
|
||||
|
||||
ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
|
||||
{
|
||||
Section *tcc_sect;
|
||||
SCNHDR *coff_sec;
|
||||
int file_pointer;
|
||||
char *Coff_str_table, *pCoff_str_table;
|
||||
int CoffTextSectionNo, coff_nb_syms;
|
||||
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
|
||||
Section *stext, *sdata, *sbss;
|
||||
int i, NSectionsToOutput = 0;
|
||||
|
||||
Coff_str_table = pCoff_str_table = NULL;
|
||||
|
||||
stext = FindSection(s1, ".text");
|
||||
sdata = FindSection(s1, ".data");
|
||||
sbss = FindSection(s1, ".bss");
|
||||
|
||||
nb_syms = symtab_section->data_offset / sizeof(Elf32_Sym);
|
||||
coff_nb_syms = FindCoffSymbolIndex("XXXXXXXXXX1");
|
||||
|
||||
file_hdr.f_magic = COFF_C67_MAGIC; /* magic number */
|
||||
file_hdr.f_timdat = 0; /* time & date stamp */
|
||||
file_hdr.f_opthdr = sizeof(AOUTHDR); /* sizeof(optional hdr) */
|
||||
file_hdr.f_flags = 0x1143; /* flags (copied from what code composer does) */
|
||||
file_hdr.f_TargetID = 0x99; /* for C6x = 0x0099 */
|
||||
|
||||
o_filehdr.magic = 0x0108; /* see magic.h */
|
||||
o_filehdr.vstamp = 0x0190; /* version stamp */
|
||||
o_filehdr.tsize = stext->data_offset; /* text size in bytes, padded to FW bdry */
|
||||
o_filehdr.dsize = sdata->data_offset; /* initialized data " " */
|
||||
o_filehdr.bsize = sbss->data_offset; /* uninitialized data " " */
|
||||
o_filehdr.entrypt = C67_main_entry_point; /* entry pt. */
|
||||
o_filehdr.text_start = stext->sh_addr; /* base of text used for this file */
|
||||
o_filehdr.data_start = sdata->sh_addr; /* base of data used for this file */
|
||||
|
||||
|
||||
// create all the section headers
|
||||
|
||||
file_pointer = FILHSZ + sizeof(AOUTHDR);
|
||||
|
||||
CoffTextSectionNo = -1;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
NSectionsToOutput++;
|
||||
|
||||
if (CoffTextSectionNo == -1 && tcc_sect == stext)
|
||||
CoffTextSectionNo = NSectionsToOutput; // rem which coff sect number the .text sect is
|
||||
|
||||
strcpy(coff_sec->s_name, tcc_sect->name); /* section name */
|
||||
|
||||
coff_sec->s_paddr = tcc_sect->sh_addr; /* physical address */
|
||||
coff_sec->s_vaddr = tcc_sect->sh_addr; /* virtual address */
|
||||
coff_sec->s_size = tcc_sect->data_offset; /* section size */
|
||||
coff_sec->s_scnptr = 0; /* file ptr to raw data for section */
|
||||
coff_sec->s_relptr = 0; /* file ptr to relocation */
|
||||
coff_sec->s_lnnoptr = 0; /* file ptr to line numbers */
|
||||
coff_sec->s_nreloc = 0; /* number of relocation entries */
|
||||
coff_sec->s_flags = GetCoffFlags(coff_sec->s_name); /* flags */
|
||||
coff_sec->s_reserved = 0; /* reserved byte */
|
||||
coff_sec->s_page = 0; /* memory page id */
|
||||
|
||||
file_pointer += sizeof(SCNHDR);
|
||||
}
|
||||
}
|
||||
|
||||
file_hdr.f_nscns = NSectionsToOutput; /* number of sections */
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the raw data
|
||||
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put raw data
|
||||
coff_sec->s_scnptr = file_pointer; /* file ptr to raw data for section */
|
||||
file_pointer += coff_sec->s_size;
|
||||
}
|
||||
}
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the relocation data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put relocations data
|
||||
if (coff_sec->s_nreloc > 0) {
|
||||
coff_sec->s_relptr = file_pointer; /* file ptr to relocation */
|
||||
file_pointer += coff_sec->s_nreloc * sizeof(struct reloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now loop through and determine file pointer locations
|
||||
// for the line number data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
coff_sec->s_nlnno = 0;
|
||||
coff_sec->s_lnnoptr = 0;
|
||||
|
||||
if (s1->do_debug && tcc_sect == stext) {
|
||||
// count how many line nos data
|
||||
|
||||
// also find association between source file name and function
|
||||
// so we can sort the symbol table
|
||||
|
||||
|
||||
Stab_Sym *sym, *sym_end;
|
||||
char func_name[MAX_FUNC_NAME_LENGTH],
|
||||
last_func_name[MAX_FUNC_NAME_LENGTH];
|
||||
unsigned long func_addr, last_pc, pc;
|
||||
const char *incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num;
|
||||
const char *str, *p;
|
||||
|
||||
coff_sec->s_lnnoptr = file_pointer; /* file ptr to linno */
|
||||
|
||||
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
incl_index = 0;
|
||||
last_func_name[0] = '\0';
|
||||
last_pc = 0xffffffff;
|
||||
last_line_num = 1;
|
||||
sym = (Stab_Sym *) stab_section->data + 1;
|
||||
sym_end =
|
||||
(Stab_Sym *) (stab_section->data +
|
||||
stab_section->data_offset);
|
||||
|
||||
nFuncs = 0;
|
||||
while (sym < sym_end) {
|
||||
switch (sym->n_type) {
|
||||
/* function start or end */
|
||||
case N_FUN:
|
||||
if (sym->n_strx == 0) {
|
||||
// end of function
|
||||
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
|
||||
pc = sym->n_value + func_addr;
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
EndAddress[nFuncs] = pc;
|
||||
FuncEntries[nFuncs] =
|
||||
(file_pointer -
|
||||
LineNoFilePtr[nFuncs]) / LINESZ - 1;
|
||||
LastLineNo[nFuncs++] = last_line_num + 1;
|
||||
} else {
|
||||
// beginning of function
|
||||
|
||||
LineNoFilePtr[nFuncs] = file_pointer;
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (!p) {
|
||||
pstrcpy(func_name, sizeof(func_name), str);
|
||||
pstrcpy(Func[nFuncs], sizeof(func_name), str);
|
||||
} else {
|
||||
len = p - str;
|
||||
if (len > sizeof(func_name) - 1)
|
||||
len = sizeof(func_name) - 1;
|
||||
memcpy(func_name, str, len);
|
||||
memcpy(Func[nFuncs], str, len);
|
||||
func_name[len] = '\0';
|
||||
}
|
||||
|
||||
// save the file that it came in so we can sort later
|
||||
pstrcpy(AssociatedFile[nFuncs], sizeof(func_name),
|
||||
incl_files[incl_index - 1]);
|
||||
|
||||
func_addr = sym->n_value;
|
||||
}
|
||||
break;
|
||||
|
||||
/* line number info */
|
||||
case N_SLINE:
|
||||
pc = sym->n_value + func_addr;
|
||||
|
||||
last_pc = pc;
|
||||
last_line_num = sym->n_desc;
|
||||
|
||||
/* XXX: slow! */
|
||||
strcpy(last_func_name, func_name);
|
||||
|
||||
coff_sec->s_nlnno++;
|
||||
file_pointer += LINESZ;
|
||||
break;
|
||||
/* include files */
|
||||
case N_BINCL:
|
||||
str =
|
||||
(const char *) stabstr_section->data + sym->n_strx;
|
||||
add_incl:
|
||||
if (incl_index < INCLUDE_STACK_SIZE) {
|
||||
incl_files[incl_index++] = str;
|
||||
}
|
||||
break;
|
||||
case N_EINCL:
|
||||
if (incl_index > 1)
|
||||
incl_index--;
|
||||
break;
|
||||
case N_SO:
|
||||
if (sym->n_strx == 0) {
|
||||
incl_index = 0; /* end of translation unit */
|
||||
} else {
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
/* do not add path */
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[len - 1] != '/')
|
||||
goto add_incl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sym++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
file_hdr.f_symptr = file_pointer; /* file pointer to symtab */
|
||||
|
||||
if (s1->do_debug)
|
||||
file_hdr.f_nsyms = coff_nb_syms; /* number of symtab entries */
|
||||
else
|
||||
file_hdr.f_nsyms = 0;
|
||||
|
||||
file_pointer += file_hdr.f_nsyms * SYMNMLEN;
|
||||
|
||||
// OK now we are all set to write the file
|
||||
|
||||
|
||||
fwrite(&file_hdr, FILHSZ, 1, f);
|
||||
fwrite(&o_filehdr, sizeof(o_filehdr), 1, f);
|
||||
|
||||
// write section headers
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
fwrite(coff_sec, sizeof(SCNHDR), 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write raw data
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
fwrite(tcc_sect->data, tcc_sect->data_offset, 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
// write relocation data
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (OutputTheSection(tcc_sect)) {
|
||||
// put relocations data
|
||||
if (coff_sec->s_nreloc > 0) {
|
||||
fwrite(tcc_sect->reloc,
|
||||
coff_sec->s_nreloc * sizeof(struct reloc), 1, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// group the symbols in order of filename, func1, func2, etc
|
||||
// finally global symbols
|
||||
|
||||
if (s1->do_debug)
|
||||
SortSymbolTable();
|
||||
|
||||
// write line no data
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
coff_sec = §ion_header[i];
|
||||
tcc_sect = s1->sections[i];
|
||||
|
||||
if (s1->do_debug && tcc_sect == stext) {
|
||||
// count how many line nos data
|
||||
|
||||
|
||||
Stab_Sym *sym, *sym_end;
|
||||
char func_name[128], last_func_name[128];
|
||||
unsigned long func_addr, last_pc, pc;
|
||||
const char *incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num;
|
||||
const char *str, *p;
|
||||
|
||||
LINENO CoffLineNo;
|
||||
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
incl_index = 0;
|
||||
last_func_name[0] = '\0';
|
||||
last_pc = 0;
|
||||
last_line_num = 1;
|
||||
sym = (Stab_Sym *) stab_section->data + 1;
|
||||
sym_end =
|
||||
(Stab_Sym *) (stab_section->data +
|
||||
stab_section->data_offset);
|
||||
|
||||
while (sym < sym_end) {
|
||||
switch (sym->n_type) {
|
||||
/* function start or end */
|
||||
case N_FUN:
|
||||
if (sym->n_strx == 0) {
|
||||
// end of function
|
||||
|
||||
CoffLineNo.l_addr.l_paddr = last_pc;
|
||||
CoffLineNo.l_lnno = last_line_num + 1;
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
|
||||
pc = sym->n_value + func_addr;
|
||||
func_name[0] = '\0';
|
||||
func_addr = 0;
|
||||
} else {
|
||||
// beginning of function
|
||||
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
|
||||
|
||||
p = strchr(str, ':');
|
||||
if (!p) {
|
||||
pstrcpy(func_name, sizeof(func_name), str);
|
||||
} else {
|
||||
len = p - str;
|
||||
if (len > sizeof(func_name) - 1)
|
||||
len = sizeof(func_name) - 1;
|
||||
memcpy(func_name, str, len);
|
||||
func_name[len] = '\0';
|
||||
}
|
||||
func_addr = sym->n_value;
|
||||
last_pc = func_addr;
|
||||
last_line_num = -1;
|
||||
|
||||
// output a function begin
|
||||
|
||||
CoffLineNo.l_addr.l_symndx =
|
||||
FindCoffSymbolIndex(func_name);
|
||||
CoffLineNo.l_lnno = 0;
|
||||
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
}
|
||||
break;
|
||||
|
||||
/* line number info */
|
||||
case N_SLINE:
|
||||
pc = sym->n_value + func_addr;
|
||||
|
||||
|
||||
/* XXX: slow! */
|
||||
strcpy(last_func_name, func_name);
|
||||
|
||||
// output a line reference
|
||||
|
||||
CoffLineNo.l_addr.l_paddr = last_pc;
|
||||
|
||||
if (last_line_num == -1) {
|
||||
CoffLineNo.l_lnno = sym->n_desc;
|
||||
} else {
|
||||
CoffLineNo.l_lnno = last_line_num + 1;
|
||||
}
|
||||
|
||||
fwrite(&CoffLineNo, 6, 1, f);
|
||||
|
||||
last_pc = pc;
|
||||
last_line_num = sym->n_desc;
|
||||
|
||||
break;
|
||||
|
||||
/* include files */
|
||||
case N_BINCL:
|
||||
str =
|
||||
(const char *) stabstr_section->data + sym->n_strx;
|
||||
add_incl2:
|
||||
if (incl_index < INCLUDE_STACK_SIZE) {
|
||||
incl_files[incl_index++] = str;
|
||||
}
|
||||
break;
|
||||
case N_EINCL:
|
||||
if (incl_index > 1)
|
||||
incl_index--;
|
||||
break;
|
||||
case N_SO:
|
||||
if (sym->n_strx == 0) {
|
||||
incl_index = 0; /* end of translation unit */
|
||||
} else {
|
||||
str =
|
||||
(const char *) stabstr_section->data +
|
||||
sym->n_strx;
|
||||
/* do not add path */
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[len - 1] != '/')
|
||||
goto add_incl2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
sym++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write symbol table
|
||||
if (s1->do_debug) {
|
||||
int k;
|
||||
struct syment csym;
|
||||
AUXFUNC auxfunc;
|
||||
AUXBF auxbf;
|
||||
AUXEF auxef;
|
||||
int i;
|
||||
Elf32_Sym *p;
|
||||
const char *name;
|
||||
int nstr;
|
||||
int n = 0;
|
||||
|
||||
Coff_str_table = (char *) tcc_malloc(MAX_STR_TABLE);
|
||||
pCoff_str_table = Coff_str_table;
|
||||
nstr = 0;
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
|
||||
name = symtab_section->link->data + p->st_name;
|
||||
|
||||
for (k = 0; k < 8; k++)
|
||||
csym._n._n_name[k] = 0;
|
||||
|
||||
if (strlen(name) <= 8) {
|
||||
strcpy(csym._n._n_name, name);
|
||||
} else {
|
||||
if (pCoff_str_table - Coff_str_table + strlen(name) >
|
||||
MAX_STR_TABLE - 1)
|
||||
tcc_error("String table too large");
|
||||
|
||||
csym._n._n_n._n_zeroes = 0;
|
||||
csym._n._n_n._n_offset =
|
||||
pCoff_str_table - Coff_str_table + 4;
|
||||
|
||||
strcpy(pCoff_str_table, name);
|
||||
pCoff_str_table += strlen(name) + 1; // skip over null
|
||||
nstr++;
|
||||
}
|
||||
|
||||
if (p->st_info == 4) {
|
||||
// put a filename symbol
|
||||
csym.n_value = 33; // ?????
|
||||
csym.n_scnum = N_DEBUG;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FILE;
|
||||
csym.n_numaux = 0;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
n++;
|
||||
|
||||
} else if (p->st_info == 0x12) {
|
||||
// find the function data
|
||||
|
||||
for (k = 0; k < nFuncs; k++) {
|
||||
if (strcmp(name, Func[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k >= nFuncs) {
|
||||
tcc_error("debug info can't find function: %s", name);
|
||||
}
|
||||
// put a Function Name
|
||||
|
||||
csym.n_value = p->st_value; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = MKTYPE(T_INT, DT_FCN, 0, 0, 0, 0, 0);
|
||||
csym.n_sclass = C_EXT;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxfunc.tag = 0;
|
||||
auxfunc.size = EndAddress[k] - p->st_value;
|
||||
auxfunc.fileptr = LineNoFilePtr[k];
|
||||
auxfunc.nextsym = n + 6; // tktk
|
||||
auxfunc.dummy = 0;
|
||||
fwrite(&auxfunc, 18, 1, f);
|
||||
|
||||
// put a .bf
|
||||
|
||||
strcpy(csym._n._n_name, ".bf");
|
||||
csym.n_value = p->st_value; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FCN;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxbf.regmask = 0;
|
||||
auxbf.lineno = 0;
|
||||
auxbf.nentries = FuncEntries[k];
|
||||
auxbf.localframe = 0;
|
||||
auxbf.nextentry = n + 6;
|
||||
auxbf.dummy = 0;
|
||||
fwrite(&auxbf, 18, 1, f);
|
||||
|
||||
// put a .ef
|
||||
|
||||
strcpy(csym._n._n_name, ".ef");
|
||||
csym.n_value = EndAddress[k]; // physical address
|
||||
csym.n_scnum = CoffTextSectionNo;
|
||||
csym.n_type = 0;
|
||||
csym.n_sclass = C_FCN;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
// now put aux info
|
||||
|
||||
auxef.dummy = 0;
|
||||
auxef.lineno = LastLineNo[k];
|
||||
auxef.dummy1 = 0;
|
||||
auxef.dummy2 = 0;
|
||||
auxef.dummy3 = 0;
|
||||
auxef.dummy4 = 0;
|
||||
fwrite(&auxef, 18, 1, f);
|
||||
|
||||
n += 6;
|
||||
|
||||
} else {
|
||||
// try an put some type info
|
||||
|
||||
if ((p->st_other & VT_BTYPE) == VT_DOUBLE) {
|
||||
csym.n_type = T_DOUBLE; // int
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_FLOAT) {
|
||||
csym.n_type = T_FLOAT;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_INT) {
|
||||
csym.n_type = T_INT; // int
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_SHORT) {
|
||||
csym.n_type = T_SHORT;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else if ((p->st_other & VT_BTYPE) == VT_BYTE) {
|
||||
csym.n_type = T_CHAR;
|
||||
csym.n_sclass = C_EXT;
|
||||
} else {
|
||||
csym.n_type = T_INT; // just mark as a label
|
||||
csym.n_sclass = C_LABEL;
|
||||
}
|
||||
|
||||
|
||||
csym.n_value = p->st_value;
|
||||
csym.n_scnum = 2;
|
||||
csym.n_numaux = 1;
|
||||
fwrite(&csym, 18, 1, f);
|
||||
|
||||
auxfunc.tag = 0;
|
||||
auxfunc.size = 0x20;
|
||||
auxfunc.fileptr = 0;
|
||||
auxfunc.nextsym = 0;
|
||||
auxfunc.dummy = 0;
|
||||
fwrite(&auxfunc, 18, 1, f);
|
||||
n++;
|
||||
n++;
|
||||
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (s1->do_debug) {
|
||||
// write string table
|
||||
|
||||
// first write the size
|
||||
i = pCoff_str_table - Coff_str_table;
|
||||
fwrite(&i, 4, 1, f);
|
||||
|
||||
// then write the strings
|
||||
fwrite(Coff_str_table, i, 1, f);
|
||||
|
||||
tcc_free(Coff_str_table);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// group the symbols in order of filename, func1, func2, etc
|
||||
// finally global symbols
|
||||
|
||||
void SortSymbolTable(void)
|
||||
{
|
||||
int i, j, k, n = 0;
|
||||
Elf32_Sym *p, *p2, *NewTable;
|
||||
char *name, *name2;
|
||||
|
||||
NewTable = (Elf32_Sym *) tcc_malloc(nb_syms * sizeof(Elf32_Sym));
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
|
||||
// find a file symbol, copy it over
|
||||
// then scan the whole symbol list and copy any function
|
||||
// symbols that match the file association
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
if (p->st_info == 4) {
|
||||
name = (char *) symtab_section->link->data + p->st_name;
|
||||
|
||||
// this is a file symbol, copy it over
|
||||
|
||||
NewTable[n++] = *p;
|
||||
|
||||
p2 = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
for (j = 0; j < nb_syms; j++) {
|
||||
if (p2->st_info == 0x12) {
|
||||
// this is a func symbol
|
||||
|
||||
name2 =
|
||||
(char *) symtab_section->link->data + p2->st_name;
|
||||
|
||||
// find the function data index
|
||||
|
||||
for (k = 0; k < nFuncs; k++) {
|
||||
if (strcmp(name2, Func[k]) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (k >= nFuncs) {
|
||||
tcc_error("debug (sort) info can't find function: %s", name2);
|
||||
}
|
||||
|
||||
if (strcmp(AssociatedFile[k], name) == 0) {
|
||||
// yes they match copy it over
|
||||
|
||||
NewTable[n++] = *p2;
|
||||
}
|
||||
}
|
||||
p2++;
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
// now all the filename and func symbols should have been copied over
|
||||
// copy all the rest over (all except file and funcs)
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
if (p->st_info != 4 && p->st_info != 0x12) {
|
||||
NewTable[n++] = *p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
if (n != nb_syms)
|
||||
tcc_error("Internal Compiler error, debug info");
|
||||
|
||||
// copy it all back
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
*p++ = NewTable[i];
|
||||
}
|
||||
|
||||
tcc_free(NewTable);
|
||||
}
|
||||
|
||||
|
||||
int FindCoffSymbolIndex(const char *func_name)
|
||||
{
|
||||
int i, n = 0;
|
||||
Elf32_Sym *p;
|
||||
char *name;
|
||||
|
||||
p = (Elf32_Sym *) symtab_section->data;
|
||||
|
||||
for (i = 0; i < nb_syms; i++) {
|
||||
|
||||
name = (char *) symtab_section->link->data + p->st_name;
|
||||
|
||||
if (p->st_info == 4) {
|
||||
// put a filename symbol
|
||||
n++;
|
||||
} else if (p->st_info == 0x12) {
|
||||
|
||||
if (strcmp(func_name, name) == 0)
|
||||
return n;
|
||||
|
||||
n += 6;
|
||||
|
||||
// put a Function Name
|
||||
|
||||
// now put aux info
|
||||
|
||||
// put a .bf
|
||||
|
||||
// now put aux info
|
||||
|
||||
// put a .ef
|
||||
|
||||
// now put aux info
|
||||
|
||||
} else {
|
||||
n += 2;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return n; // total number of symbols
|
||||
}
|
||||
|
||||
int OutputTheSection(Section * sect)
|
||||
{
|
||||
const char *s = sect->name;
|
||||
|
||||
if (!strcmp(s, ".text"))
|
||||
return 1;
|
||||
else if (!strcmp(s, ".data"))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
short int GetCoffFlags(const char *s)
|
||||
{
|
||||
if (!strcmp(s, ".text"))
|
||||
return STYP_TEXT | STYP_DATA | STYP_ALIGN | 0x400;
|
||||
else if (!strcmp(s, ".data"))
|
||||
return STYP_DATA;
|
||||
else if (!strcmp(s, ".bss"))
|
||||
return STYP_BSS;
|
||||
else if (!strcmp(s, ".stack"))
|
||||
return STYP_BSS | STYP_ALIGN | 0x200;
|
||||
else if (!strcmp(s, ".cinit"))
|
||||
return STYP_COPY | STYP_DATA | STYP_ALIGN | 0x200;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Section *FindSection(TCCState * s1, const char *sname)
|
||||
{
|
||||
Section *s;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < s1->nb_sections; i++) {
|
||||
s = s1->sections[i];
|
||||
|
||||
if (!strcmp(sname, s->name))
|
||||
return s;
|
||||
}
|
||||
|
||||
tcc_error("could not find section %s", sname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ST_FUNC int tcc_load_coff(TCCState * s1, int fd)
|
||||
{
|
||||
// tktk TokenSym *ts;
|
||||
|
||||
FILE *f;
|
||||
unsigned int str_size;
|
||||
char *Coff_str_table, *name;
|
||||
int i, k;
|
||||
struct syment csym;
|
||||
char name2[9];
|
||||
FILHDR file_hdr; /* FILE HEADER STRUCTURE */
|
||||
|
||||
f = fdopen(fd, "rb");
|
||||
if (!f) {
|
||||
tcc_error("Unable to open .out file for input");
|
||||
}
|
||||
|
||||
if (fread(&file_hdr, FILHSZ, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
if (fread(&o_filehdr, sizeof(o_filehdr), 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
// first read the string table
|
||||
|
||||
if (fseek(f, file_hdr.f_symptr + file_hdr.f_nsyms * SYMESZ, SEEK_SET))
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
if (fread(&str_size, sizeof(int), 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
|
||||
Coff_str_table = (char *) tcc_malloc(str_size);
|
||||
|
||||
if (fread(Coff_str_table, str_size - 4, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
// read/process all the symbols
|
||||
|
||||
// seek back to symbols
|
||||
|
||||
if (fseek(f, file_hdr.f_symptr, SEEK_SET))
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
for (i = 0; i < file_hdr.f_nsyms; i++) {
|
||||
if (fread(&csym, SYMESZ, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
|
||||
if (csym._n._n_n._n_zeroes == 0) {
|
||||
name = Coff_str_table + csym._n._n_n._n_offset - 4;
|
||||
} else {
|
||||
name = csym._n._n_name;
|
||||
|
||||
if (name[7] != 0) {
|
||||
for (k = 0; k < 8; k++)
|
||||
name2[k] = name[k];
|
||||
|
||||
name2[8] = 0;
|
||||
|
||||
name = name2;
|
||||
}
|
||||
}
|
||||
// if (strcmp("_DAC_Buffer",name)==0) // tktk
|
||||
// name[0]=0;
|
||||
|
||||
if (((csym.n_type & 0x30) == 0x20 && csym.n_sclass == 0x2) || ((csym.n_type & 0x30) == 0x30 && csym.n_sclass == 0x2) || (csym.n_type == 0x4 && csym.n_sclass == 0x2) || (csym.n_type == 0x8 && csym.n_sclass == 0x2) || // structures
|
||||
(csym.n_type == 0x18 && csym.n_sclass == 0x2) || // pointer to structure
|
||||
(csym.n_type == 0x7 && csym.n_sclass == 0x2) || // doubles
|
||||
(csym.n_type == 0x6 && csym.n_sclass == 0x2)) // floats
|
||||
{
|
||||
// strip off any leading underscore (except for other main routine)
|
||||
|
||||
if (name[0] == '_' && strcmp(name, "_main") != 0)
|
||||
name++;
|
||||
|
||||
tcc_add_symbol(s1, name, (void*)(uintptr_t)csym.n_value);
|
||||
}
|
||||
// skip any aux records
|
||||
|
||||
if (csym.n_numaux == 1) {
|
||||
if (fread(&csym, SYMESZ, 1, f) != 1)
|
||||
tcc_error("error reading .out file for input");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -451,7 +451,7 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve)
|
||||
if (addr) {
|
||||
sym->st_value = (addr_t)addr;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
|
||||
printf ("relocate_sym: %s -> 0x%lx\n", name, sym->st_value);
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
@ -580,10 +580,10 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
{
|
||||
int x, is_thumb, is_call, h, blx_avail, is_bl, th_ko;
|
||||
x = (*(int *) ptr) & 0xffffff;
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
val = s1->plt->sh_addr;
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
val = s1->plt->sh_addr;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
|
||||
printf ("reloc %d: x=0x%x val=0x%x ", type, x, val);
|
||||
#endif
|
||||
(*(int *)ptr) &= 0xff000000;
|
||||
if (x & 0x800000)
|
||||
@ -595,8 +595,8 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
is_call = (type == R_ARM_CALL || (type == R_ARM_PC24 && is_bl));
|
||||
x += val - addr;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf (" newx=0x%x name=%s\n", x,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
printf (" newx=0x%x name=%s\n", x,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
h = x & 2;
|
||||
th_ko = (x & 3) && (!blx_avail || !is_call);
|
||||
@ -797,21 +797,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
break;
|
||||
case R_AARCH64_JUMP26:
|
||||
case R_AARCH64_CALL26:
|
||||
/* This check must match the one in build_got_entries, testing
|
||||
if we really need a PLT slot. */
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
/* We've put the PLT slot offset into r_addend when generating
|
||||
it, and that's what we must use as relocation value (adjusted
|
||||
by section offset of course). */
|
||||
val = s1->plt->sh_addr + rel->r_addend;
|
||||
/* This check must match the one in build_got_entries, testing
|
||||
if we really need a PLT slot. */
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
/* We've put the PLT slot offset into r_addend when generating
|
||||
it, and that's what we must use as relocation value (adjusted
|
||||
by section offset of course). */
|
||||
val = s1->plt->sh_addr + rel->r_addend;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
|
||||
{
|
||||
{
|
||||
tcc_error("R_AARCH64_(JUMP|CALL)26 relocation failed (val=%lx, addr=%lx)", addr, val);
|
||||
}
|
||||
}
|
||||
*(uint32_t *)ptr = 0x14000000 | (type == R_AARCH64_CALL26) << 31 |
|
||||
((val - addr) >> 2 & 0x3ffffff);
|
||||
break;
|
||||
@ -836,9 +836,9 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
case R_AARCH64_JUMP_SLOT:
|
||||
/* They don't need addend */
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
|
||||
val - rel->r_addend,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr,
|
||||
val - rel->r_addend,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
*(addr_t *)ptr = val - rel->r_addend;
|
||||
break;
|
||||
@ -879,12 +879,12 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
qrel->r_offset = rel->r_offset;
|
||||
if (esym_index) {
|
||||
qrel->r_info = ELFW(R_INFO)(esym_index, R_X86_64_64);
|
||||
qrel->r_addend = rel->r_addend;
|
||||
qrel->r_addend = rel->r_addend;
|
||||
qrel++;
|
||||
break;
|
||||
} else {
|
||||
qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
|
||||
qrel->r_addend = *(long long *)ptr + val;
|
||||
qrel->r_info = ELFW(R_INFO)(0, R_X86_64_RELATIVE);
|
||||
qrel->r_addend = *(long long *)ptr + val;
|
||||
qrel++;
|
||||
}
|
||||
}
|
||||
@ -917,21 +917,21 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s)
|
||||
goto plt32pc32;
|
||||
|
||||
case R_X86_64_PLT32:
|
||||
/* We've put the PLT slot offset into r_addend when generating
|
||||
it, and that's what we must use as relocation value (adjusted
|
||||
by section offset of course). */
|
||||
val = s1->plt->sh_addr + rel->r_addend;
|
||||
/* fallthrough. */
|
||||
/* We've put the PLT slot offset into r_addend when generating
|
||||
it, and that's what we must use as relocation value (adjusted
|
||||
by section offset of course). */
|
||||
val = s1->plt->sh_addr + rel->r_addend;
|
||||
/* fallthrough. */
|
||||
|
||||
plt32pc32:
|
||||
{
|
||||
long long diff;
|
||||
diff = (long long)val - addr;
|
||||
if (diff < -2147483648LL || diff > 2147483647LL) {
|
||||
tcc_error("internal error: relocation failed");
|
||||
}
|
||||
*(int *)ptr += diff;
|
||||
plt32pc32:
|
||||
{
|
||||
long long diff;
|
||||
diff = (long long)val - addr;
|
||||
if (diff < -2147483648LL || diff > 2147483647LL) {
|
||||
tcc_error("internal error: relocation failed");
|
||||
}
|
||||
*(int *)ptr += diff;
|
||||
}
|
||||
break;
|
||||
case R_X86_64_GLOB_DAT:
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
@ -1080,8 +1080,8 @@ static void build_got(TCCState *s1)
|
||||
and 'info' can be modifed if more precise info comes from the DLL.
|
||||
Returns offset of GOT or PLT slot. */
|
||||
static unsigned long put_got_entry(TCCState *s1,
|
||||
int reloc_type, unsigned long size, int info,
|
||||
int sym_index)
|
||||
int reloc_type, unsigned long size, int info,
|
||||
int sym_index)
|
||||
{
|
||||
int index, need_plt_entry;
|
||||
const char *name;
|
||||
@ -1107,18 +1107,18 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
#endif
|
||||
|
||||
if (need_plt_entry && !s1->plt) {
|
||||
/* add PLT */
|
||||
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
|
||||
SHF_ALLOC | SHF_EXECINSTR);
|
||||
s1->plt->sh_entsize = 4;
|
||||
/* add PLT */
|
||||
s1->plt = new_section(s1, ".plt", SHT_PROGBITS,
|
||||
SHF_ALLOC | SHF_EXECINSTR);
|
||||
s1->plt->sh_entsize = 4;
|
||||
}
|
||||
|
||||
/* If a got/plt entry already exists for that symbol, no need to add one */
|
||||
if (sym_index < s1->nb_sym_attrs) {
|
||||
if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
|
||||
return s1->sym_attrs[sym_index].plt_offset;
|
||||
else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
|
||||
return s1->sym_attrs[sym_index].got_offset;
|
||||
if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset)
|
||||
return s1->sym_attrs[sym_index].plt_offset;
|
||||
else if (!need_plt_entry && s1->sym_attrs[sym_index].got_offset)
|
||||
return s1->sym_attrs[sym_index].got_offset;
|
||||
}
|
||||
|
||||
symattr = alloc_sym_attr(s1, sym_index);
|
||||
@ -1135,7 +1135,7 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
Section *plt;
|
||||
uint8_t *p;
|
||||
int modrm;
|
||||
unsigned long relofs;
|
||||
unsigned long relofs;
|
||||
|
||||
#if defined(TCC_OUTPUT_DLL_WITH_PLT)
|
||||
modrm = 0x25;
|
||||
@ -1160,10 +1160,10 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
put32(p + 8, PTR_SIZE * 2);
|
||||
}
|
||||
|
||||
/* The PLT slot refers to the relocation entry it needs
|
||||
via offset. The reloc entry is created below, so its
|
||||
offset is the current data_offset. */
|
||||
relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
|
||||
/* The PLT slot refers to the relocation entry it needs
|
||||
via offset. The reloc entry is created below, so its
|
||||
offset is the current data_offset. */
|
||||
relofs = s1->got->reloc ? s1->got->reloc->data_offset : 0;
|
||||
symattr->plt_offset = plt->data_offset;
|
||||
p = section_ptr_add(plt, 16);
|
||||
p[0] = 0xff; /* jmp *(got + x) */
|
||||
@ -1171,20 +1171,20 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
put32(p + 2, s1->got->data_offset);
|
||||
p[6] = 0x68; /* push $xxx */
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
/* On x86-64, the relocation is referred to by _index_. */
|
||||
put32(p + 7, relofs / sizeof (ElfW_Rel));
|
||||
/* On x86-64, the relocation is referred to by _index_. */
|
||||
put32(p + 7, relofs / sizeof (ElfW_Rel));
|
||||
#else
|
||||
put32(p + 7, relofs);
|
||||
#endif
|
||||
p[11] = 0xe9; /* jmp plt_start */
|
||||
put32(p + 12, -(plt->data_offset));
|
||||
|
||||
/* If this was an UNDEF symbol set the offset in the
|
||||
dynsymtab to the PLT slot, so that PC32 relocs to it
|
||||
can be resolved. */
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
offset = plt->data_offset - 16;
|
||||
}
|
||||
/* If this was an UNDEF symbol set the offset in the
|
||||
dynsymtab to the PLT slot, so that PC32 relocs to it
|
||||
can be resolved. */
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
offset = plt->data_offset - 16;
|
||||
}
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
if (need_plt_entry) {
|
||||
Section *plt;
|
||||
@ -1220,9 +1220,9 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
|
||||
/* the symbol is modified so that it will be relocated to
|
||||
the PLT */
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
offset = plt->data_offset - 16;
|
||||
}
|
||||
}
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
if (need_plt_entry) {
|
||||
Section *plt;
|
||||
@ -1250,29 +1250,29 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
if (s1->dynsym) {
|
||||
/* XXX This might generate multiple syms for name. */
|
||||
/* XXX This might generate multiple syms for name. */
|
||||
index = put_elf_sym(s1->dynsym, offset,
|
||||
size, info, 0, sym->st_shndx, name);
|
||||
/* Create the relocation (it's against the GOT for PLT
|
||||
and GOT relocs). */
|
||||
and GOT relocs). */
|
||||
put_elf_reloc(s1->dynsym, s1->got,
|
||||
s1->got->data_offset,
|
||||
reloc_type, index);
|
||||
} else {
|
||||
/* Without .dynsym (i.e. static link or memory output) we
|
||||
still need relocs against the generated got, so as to fill
|
||||
the entries with the symbol values (determined later). */
|
||||
put_elf_reloc(symtab_section, s1->got,
|
||||
s1->got->data_offset,
|
||||
reloc_type, sym_index);
|
||||
/* Without .dynsym (i.e. static link or memory output) we
|
||||
still need relocs against the generated got, so as to fill
|
||||
the entries with the symbol values (determined later). */
|
||||
put_elf_reloc(symtab_section, s1->got,
|
||||
s1->got->data_offset,
|
||||
reloc_type, sym_index);
|
||||
}
|
||||
/* And now create the GOT slot itself. */
|
||||
ptr = section_ptr_add(s1->got, PTR_SIZE);
|
||||
*ptr = 0;
|
||||
if (need_plt_entry)
|
||||
return symattr->plt_offset;
|
||||
return symattr->plt_offset;
|
||||
else
|
||||
return symattr->got_offset;
|
||||
return symattr->got_offset;
|
||||
}
|
||||
|
||||
/* build GOT and PLT entries */
|
||||
@ -1324,8 +1324,8 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||
build_got(s1);
|
||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
|
||||
&& sym->st_shndx == SHN_UNDEF) {
|
||||
if (type != R_ARM_GOTOFF && type != R_ARM_GOTPC
|
||||
&& sym->st_shndx == SHN_UNDEF) {
|
||||
unsigned long ofs;
|
||||
/* look at the symbol got offset. If none, then add one */
|
||||
if (type == R_ARM_GOT32)
|
||||
@ -1333,27 +1333,27 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||
else
|
||||
reloc_type = R_ARM_JUMP_SLOT;
|
||||
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
||||
sym->st_info, sym_index);
|
||||
sym->st_info, sym_index);
|
||||
#ifdef DEBUG_RELOC
|
||||
printf("maybegot: %s, %d, %d --> ofs=0x%x\n",
|
||||
(char *) symtab_section->link->data + sym->st_name,
|
||||
type, sym->st_shndx, ofs);
|
||||
printf ("maybegot: %s, %d, %d --> ofs=0x%x\n",
|
||||
(char *) symtab_section->link->data + sym->st_name,
|
||||
type, sym->st_shndx, ofs);
|
||||
#endif
|
||||
if (type != R_ARM_GOT32) {
|
||||
addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
|
||||
+ rel->r_offset);
|
||||
/* x must be signed! */
|
||||
int x = *ptr & 0xffffff;
|
||||
x = (x << 8) >> 8;
|
||||
x <<= 2;
|
||||
x += ofs;
|
||||
x >>= 2;
|
||||
if (type != R_ARM_GOT32) {
|
||||
addr_t *ptr = (addr_t*)(s1->sections[s->sh_info]->data
|
||||
+ rel->r_offset);
|
||||
/* x must be signed! */
|
||||
int x = *ptr & 0xffffff;
|
||||
x = (x << 8) >> 8;
|
||||
x <<= 2;
|
||||
x += ofs;
|
||||
x >>= 2;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
|
||||
(*ptr & 0xff000000) | x, x);
|
||||
printf ("insn=0x%x --> 0x%x (x==0x%x)\n", *ptr,
|
||||
(*ptr & 0xff000000) | x, x);
|
||||
#endif
|
||||
*ptr = (*ptr & 0xff000000) | x;
|
||||
}
|
||||
*ptr = (*ptr & 0xff000000) | x;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case R_ARM_THM_JUMP24:
|
||||
@ -1397,22 +1397,22 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||
sym_index);
|
||||
break;
|
||||
|
||||
case R_AARCH64_JUMP26:
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_JUMP26:
|
||||
case R_AARCH64_CALL26:
|
||||
if (!s1->got)
|
||||
build_got(s1);
|
||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
if (sym->st_shndx == SHN_UNDEF) {
|
||||
unsigned long ofs;
|
||||
reloc_type = R_AARCH64_JUMP_SLOT;
|
||||
unsigned long ofs;
|
||||
reloc_type = R_AARCH64_JUMP_SLOT;
|
||||
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
||||
sym->st_info, sym_index);
|
||||
/* We store the place of the generated PLT slot
|
||||
in our addend. */
|
||||
rel->r_addend += ofs;
|
||||
sym->st_info, sym_index);
|
||||
/* We store the place of the generated PLT slot
|
||||
in our addend. */
|
||||
rel->r_addend += ofs;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
#elif defined(TCC_TARGET_C67)
|
||||
case R_C60_GOT32:
|
||||
case R_C60_GOTOFF:
|
||||
@ -1439,29 +1439,29 @@ ST_FUNC void build_got_entries(TCCState *s1)
|
||||
case R_X86_64_PLT32:
|
||||
sym_index = ELFW(R_SYM)(rel->r_info);
|
||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
if (type == R_X86_64_PLT32 &&
|
||||
ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
|
||||
{
|
||||
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
|
||||
break;
|
||||
}
|
||||
if (type == R_X86_64_PLT32 &&
|
||||
ELFW(ST_VISIBILITY)(sym->st_other) != STV_DEFAULT)
|
||||
{
|
||||
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PC32);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!s1->got)
|
||||
build_got(s1);
|
||||
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL ||
|
||||
type == R_X86_64_PLT32) {
|
||||
unsigned long ofs;
|
||||
unsigned long ofs;
|
||||
/* look at the symbol got offset. If none, then add one */
|
||||
if (type == R_X86_64_GOT32 || type == R_X86_64_GOTPCREL)
|
||||
reloc_type = R_X86_64_GLOB_DAT;
|
||||
else
|
||||
reloc_type = R_X86_64_JUMP_SLOT;
|
||||
reloc_type = R_X86_64_JUMP_SLOT;
|
||||
ofs = put_got_entry(s1, reloc_type, sym->st_size,
|
||||
sym->st_info, sym_index);
|
||||
if (type == R_X86_64_PLT32)
|
||||
/* We store the place of the generated PLT slot
|
||||
in our addend. */
|
||||
rel->r_addend += ofs;
|
||||
sym->st_info, sym_index);
|
||||
if (type == R_X86_64_PLT32)
|
||||
/* We store the place of the generated PLT slot
|
||||
in our addend. */
|
||||
rel->r_addend += ofs;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
@ -1546,21 +1546,21 @@ static int tcc_add_support(TCCState *s1, const char *filename)
|
||||
snprintf(buf, sizeof(buf), "%s/%s/%s", s1->tcc_lib_path,
|
||||
/* an cpu specific path inside tcc_lib_path, mainly for keeping libtcc1.a */
|
||||
#ifdef TCC_TARGET_I386
|
||||
"i386"
|
||||
"i386"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
"x86_64"
|
||||
"x86-64"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM
|
||||
"arm"
|
||||
"arm"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
"arm64"
|
||||
"arm64"
|
||||
#endif
|
||||
#ifdef TCC_TARGET_C67
|
||||
"C67"
|
||||
"C67"
|
||||
#endif
|
||||
, filename);
|
||||
,filename);
|
||||
|
||||
return tcc_add_file(s1, buf, TCC_FILETYPE_BINARY);
|
||||
}
|
||||
@ -1587,17 +1587,17 @@ ST_FUNC void tcc_add_bcheck(TCCState *s1)
|
||||
when __bound_ptr_add, __bound_new_region,
|
||||
__bound_delete_region called */
|
||||
|
||||
int sym_index = find_elf_sym(symtab_section, "__bound_init");
|
||||
if (sym_index) {
|
||||
Section *init_section = find_section(s1, ".init");
|
||||
unsigned char *pinit = section_ptr_add(init_section, 5);
|
||||
pinit[0] = 0xe8;
|
||||
put32(pinit + 1, -4);
|
||||
put_elf_reloc(symtab_section, init_section,
|
||||
init_section->data_offset - 4, R_386_PC32, sym_index);
|
||||
}
|
||||
else
|
||||
tcc_warning("__bound_init not defined");
|
||||
int sym_index = find_elf_sym(symtab_section, "__bound_init");
|
||||
if (sym_index) {
|
||||
Section *init_section = find_section(s1, ".init");
|
||||
unsigned char *pinit = section_ptr_add(init_section, 5);
|
||||
pinit[0] = 0xe8;
|
||||
put32(pinit + 1, -4);
|
||||
put_elf_reloc(symtab_section, init_section,
|
||||
init_section->data_offset - 4, R_386_PC32, sym_index);
|
||||
}
|
||||
else
|
||||
tcc_warning("__bound_init not defined");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1905,11 +1905,11 @@ static void export_global_syms(TCCState *s1)
|
||||
s1->symtab_to_dynsym = tcc_mallocz(sizeof(int) * nb_syms);
|
||||
for_each_elem(symtab_section, 1, sym, ElfW(Sym)) {
|
||||
if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
|
||||
name = (char *) symtab_section->link->data + sym->st_name;
|
||||
dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
|
||||
sym->st_info, 0, sym->st_shndx, name);
|
||||
index = sym - (ElfW(Sym) *) symtab_section->data;
|
||||
s1->symtab_to_dynsym[index] = dynindex;
|
||||
name = (char *) symtab_section->link->data + sym->st_name;
|
||||
dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size,
|
||||
sym->st_info, 0, sym->st_shndx, name);
|
||||
index = sym - (ElfW(Sym) *) symtab_section->data;
|
||||
s1->symtab_to_dynsym[index] = dynindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2179,15 +2179,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||
file_offset += s->sh_size;
|
||||
}
|
||||
}
|
||||
if (j == 0) {
|
||||
/* Make the first PT_LOAD segment include the program
|
||||
headers itself (and the ELF header as well), it'll
|
||||
come out with same memory use but will make various
|
||||
tools like binutils strip work better. */
|
||||
ph->p_offset &= ~(ph->p_align - 1);
|
||||
ph->p_vaddr &= ~(ph->p_align - 1);
|
||||
ph->p_paddr &= ~(ph->p_align - 1);
|
||||
}
|
||||
if (j == 0) {
|
||||
/* Make the first PT_LOAD segment include the program
|
||||
headers itself (and the ELF header as well), it'll
|
||||
come out with same memory use but will make various
|
||||
tools like binutils strip work better. */
|
||||
ph->p_offset &= ~(ph->p_align - 1);
|
||||
ph->p_vaddr &= ~(ph->p_align - 1);
|
||||
ph->p_paddr &= ~(ph->p_align - 1);
|
||||
}
|
||||
ph->p_filesz = file_offset - ph->p_offset;
|
||||
ph->p_memsz = addr - ph->p_vaddr;
|
||||
ph++;
|
||||
@ -2662,10 +2662,10 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||
for_each_elem(s1->dynsym, 1, sym, ElfW(Sym)) {
|
||||
if (sym->st_shndx == SHN_UNDEF) {
|
||||
/* relocate to PLT if symbol corresponds to a PLT entry,
|
||||
but not if it's a weak symbol */
|
||||
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
||||
sym->st_value = 0;
|
||||
else if (sym->st_value)
|
||||
but not if it's a weak symbol */
|
||||
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
||||
sym->st_value = 0;
|
||||
else if (sym->st_value)
|
||||
sym->st_value += s1->plt->sh_addr;
|
||||
} else if (sym->st_shndx < SHN_LORESERVE) {
|
||||
/* do symbol relocation */
|
||||
@ -2690,14 +2690,14 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||
/* Create the ELF file with name 'filename' */
|
||||
ret = tcc_write_elf_file(s1, filename, phnum, phdr, file_offset, sec_order);
|
||||
if (s1->do_strip) {
|
||||
int rc;
|
||||
const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers
|
||||
const char *null_dev = " 2> /dev/null";
|
||||
char buf[1050];
|
||||
snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev);
|
||||
rc = system(buf);
|
||||
if (rc)
|
||||
system(buf+1); // call a strip utility from binutils
|
||||
int rc;
|
||||
const char *strip_cmd = "sstrip "; // super strip utility from ELFkickers
|
||||
const char *null_dev = " 2> /dev/null";
|
||||
char buf[1050];
|
||||
snprintf(buf, sizeof(buf), "%s%s%s", strip_cmd, filename, null_dev);
|
||||
rc = system(buf);
|
||||
if (rc)
|
||||
system(buf+1); // call a strip utility from binutils
|
||||
}
|
||||
the_end:
|
||||
tcc_free(s1->symtab_to_dynsym);
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
* 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
|
||||
#define _TCCLIB_H
|
@ -398,22 +398,22 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
|
||||
s = pe_export_name(s1, sym);
|
||||
if (n) {
|
||||
/* second try: */
|
||||
if (sym->st_other & ST_PE_STDCALL) {
|
||||
/* try w/0 stdcall deco (windows API convention) */
|
||||
p = strrchr(s, '@');
|
||||
if (!p || s[0] != '_')
|
||||
break;
|
||||
strcpy(buffer, s+1)[p-s-1] = 0;
|
||||
} else if (s[0] != '_') { /* try non-ansi function */
|
||||
buffer[0] = '_', strcpy(buffer + 1, s);
|
||||
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
|
||||
strcpy(buffer, s + 6);
|
||||
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
|
||||
strcpy(buffer, s + 6);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
s = buffer;
|
||||
if (sym->st_other & ST_PE_STDCALL) {
|
||||
/* try w/0 stdcall deco (windows API convention) */
|
||||
p = strrchr(s, '@');
|
||||
if (!p || s[0] != '_')
|
||||
break;
|
||||
strcpy(buffer, s+1)[p-s-1] = 0;
|
||||
} else if (s[0] != '_') { /* try non-ansi function */
|
||||
buffer[0] = '_', strcpy(buffer + 1, s);
|
||||
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
|
||||
strcpy(buffer, s + 6);
|
||||
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
|
||||
strcpy(buffer, s + 6);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
s = buffer;
|
||||
}
|
||||
sym_index = find_elf_sym(s1->dynsymtab_section, s);
|
||||
// printf("find (%d) %d %s\n", n, sym_index, s);
|
||||
@ -1266,7 +1266,7 @@ static int pe_check_symbols(struct pe_info *pe)
|
||||
put_elf_reloc(symtab_section, text_section,
|
||||
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
|
||||
#else
|
||||
put_elf_reloc(symtab_section, text_section,
|
||||
put_elf_reloc(symtab_section, text_section,
|
||||
offset + 2, R_XXX_THUNKFIX, is->iat_index);
|
||||
#endif
|
||||
is->thk_offset = offset;
|
||||
@ -1636,7 +1636,7 @@ quit:
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
#define TINY_IMPDEF_GET_EXPORT_NAMES_ONLY
|
||||
#include "../win32/tools/tiny_impdef.c"
|
||||
#include "win32/tools/tiny_impdef.c"
|
||||
|
||||
static int pe_load_dll(TCCState *s1, const char *dllname, int fd)
|
||||
{
|
||||
@ -1841,13 +1841,13 @@ ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
|
||||
pe.subsystem = s1->pe_subsystem;
|
||||
|
||||
/* set default file/section alignment */
|
||||
if (pe.subsystem == 1) {
|
||||
pe.section_align = 0x20;
|
||||
pe.file_align = 0x20;
|
||||
} else {
|
||||
pe.section_align = 0x1000;
|
||||
pe.file_align = 0x200;
|
||||
}
|
||||
if (pe.subsystem == 1) {
|
||||
pe.section_align = 0x20;
|
||||
pe.file_align = 0x20;
|
||||
} else {
|
||||
pe.section_align = 0x1000;
|
||||
pe.file_align = 0x200;
|
||||
}
|
||||
|
||||
if (s1->section_align != 0)
|
||||
pe.section_align = s1->section_align;
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* TCC - Tiny C Compiler
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||
*
|
||||
* 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 const char tcc_keywords[] =
|
||||
static const char tcc_keywords[] =
|
||||
#define DEF(id, str) str "\0"
|
||||
#include "tcctok.h"
|
||||
#undef DEF
|
||||
@ -221,7 +221,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
|
||||
TokenSym *ts, **ptable;
|
||||
int i;
|
||||
|
||||
if (tok_ident >= SYM_FIRST_ANOM)
|
||||
if (tok_ident >= SYM_FIRST_ANOM)
|
||||
tcc_error("memory full (symbols)");
|
||||
|
||||
/* expand token table if needed */
|
||||
@ -255,7 +255,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len)
|
||||
TokenSym *ts, **pts;
|
||||
int i;
|
||||
unsigned int h;
|
||||
|
||||
|
||||
h = TOK_HASH_INIT;
|
||||
for(i=0;i<len;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)
|
||||
{
|
||||
inp();
|
||||
if (ch == '\\')
|
||||
if (ch == '\\')
|
||||
handle_stray();
|
||||
}
|
||||
|
||||
@ -557,7 +557,7 @@ static uint8_t *parse_line_comment(uint8_t *p)
|
||||
ST_FUNC uint8_t *parse_comment(uint8_t *p)
|
||||
{
|
||||
int c;
|
||||
|
||||
|
||||
p++;
|
||||
for(;;) {
|
||||
/* fast skip loop */
|
||||
@ -635,13 +635,13 @@ static inline void skip_spaces(void)
|
||||
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 (*spc)
|
||||
if (*spc)
|
||||
return 1;
|
||||
*spc = 1;
|
||||
} else
|
||||
} else
|
||||
*spc = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -774,7 +774,7 @@ redo_start:
|
||||
file->buf_ptr = p;
|
||||
next_nomacro();
|
||||
p = file->buf_ptr;
|
||||
if (a == 0 &&
|
||||
if (a == 0 &&
|
||||
(tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
|
||||
goto the_end;
|
||||
if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
|
||||
@ -786,7 +786,7 @@ redo_start:
|
||||
else if (tok == TOK_LINEFEED)
|
||||
goto redo_start;
|
||||
} else if (parse_flags & PARSE_FLAG_ASM_FILE)
|
||||
p = parse_line_comment(p);
|
||||
p = parse_line_comment(p);
|
||||
break;
|
||||
_default:
|
||||
default:
|
||||
@ -930,7 +930,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
|
||||
cstr->size = cv->cstr->size;
|
||||
cstr->data_allocated = NULL;
|
||||
cstr->size_allocated = cstr->size;
|
||||
memcpy((char *)cstr + sizeof(CString),
|
||||
memcpy((char *)cstr + sizeof(CString),
|
||||
cv->cstr->data, cstr->size);
|
||||
len += nb_words;
|
||||
}
|
||||
@ -1253,14 +1253,14 @@ static int expr_preprocess(void)
|
||||
{
|
||||
int c, t;
|
||||
TokenString str;
|
||||
|
||||
|
||||
tok_str_new(&str);
|
||||
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
|
||||
next(); /* do macro subst */
|
||||
if (tok == TOK_DEFINED) {
|
||||
next_nomacro();
|
||||
t = tok;
|
||||
if (t == '(')
|
||||
if (t == '(')
|
||||
next_nomacro();
|
||||
c = define_find(tok) != 0;
|
||||
if (t == '(')
|
||||
@ -1786,7 +1786,7 @@ _line_num:
|
||||
total_lines += file->line_num - n;
|
||||
file->line_num = n;
|
||||
if (s1->do_debug)
|
||||
put_stabs(file->filename, N_BINCL, 0, 0, 0);
|
||||
put_stabs(file->filename, N_BINCL, 0, 0, 0);
|
||||
break;
|
||||
case TOK_ERROR:
|
||||
case TOK_WARNING:
|
||||
@ -1914,7 +1914,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
|
||||
break;
|
||||
case '\'':
|
||||
case '\"':
|
||||
case '\\':
|
||||
case '\\':
|
||||
case '?':
|
||||
break;
|
||||
default:
|
||||
@ -2070,7 +2070,7 @@ static void parse_number(const char *p)
|
||||
*q = '\0';
|
||||
if (b == 16)
|
||||
shift = 4;
|
||||
else
|
||||
else
|
||||
shift = 1;
|
||||
bn_zero(bn);
|
||||
q = token_buf;
|
||||
@ -2126,7 +2126,7 @@ static void parse_number(const char *p)
|
||||
ch = *p++;
|
||||
}
|
||||
exp_val = exp_val * s;
|
||||
|
||||
|
||||
/* now we can generate the number */
|
||||
/* XXX: should patch directly float number */
|
||||
d = (double)bn[1] * 4294967296.0 + (double)bn[0];
|
||||
@ -2272,7 +2272,7 @@ static void parse_number(const char *p)
|
||||
if (n & 0xffffffff00000000LL || must_64bit) {
|
||||
tok = TOK_CLLONG;
|
||||
n1 = n >> 32;
|
||||
} else {
|
||||
} else {
|
||||
tok = TOK_CINT;
|
||||
n1 = n;
|
||||
}
|
||||
@ -2363,7 +2363,7 @@ static inline void next_nomacro1(void)
|
||||
} else {
|
||||
tok_flags &= ~TOK_FLAG_EOF;
|
||||
/* pop include file */
|
||||
|
||||
|
||||
/* test if previous '#endif' was after a #ifdef at
|
||||
start of file */
|
||||
if (tok_flags & TOK_FLAG_ENDIF) {
|
||||
@ -2400,7 +2400,7 @@ maybe_newline:
|
||||
case '#':
|
||||
/* XXX: simplify */
|
||||
PEEKC(c, p);
|
||||
if ((tok_flags & TOK_FLAG_BOL) &&
|
||||
if ((tok_flags & TOK_FLAG_BOL) &&
|
||||
(parse_flags & PARSE_FLAG_PREPROCESS)) {
|
||||
file->buf_ptr = p;
|
||||
preprocess(tok_flags & TOK_FLAG_BOF);
|
||||
@ -2420,7 +2420,7 @@ maybe_newline:
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* dollar is allowed to start identifiers when not parsing asm */
|
||||
case '$':
|
||||
if (!(isidnum_table[c - CH_EOF] & IS_ID)
|
||||
@ -2433,14 +2433,14 @@ maybe_newline:
|
||||
case 'm': case 'n': case 'o': case 'p':
|
||||
case 'q': case 'r': case 's': case 't':
|
||||
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 '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 'Q': case 'R': case 'S': case 'T':
|
||||
case 'U': case 'V': case 'W': case 'X':
|
||||
case 'Y': case 'Z':
|
||||
case 'Y': case 'Z':
|
||||
case '_':
|
||||
parse_ident_fast:
|
||||
p1 = p;
|
||||
@ -2538,7 +2538,7 @@ maybe_newline:
|
||||
} else if (c == '.') {
|
||||
PEEKC(c, p);
|
||||
if (c != '.')
|
||||
expect("'.'");
|
||||
expect("'.'");
|
||||
PEEKC(c, p);
|
||||
tok = TOK_DOTS;
|
||||
} else {
|
||||
@ -2594,7 +2594,7 @@ maybe_newline:
|
||||
tok = TOK_GT;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '&':
|
||||
PEEKC(c, p);
|
||||
if (c == '&') {
|
||||
@ -2607,7 +2607,7 @@ maybe_newline:
|
||||
tok = '&';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '|':
|
||||
PEEKC(c, p);
|
||||
if (c == '|') {
|
||||
@ -2633,7 +2633,7 @@ maybe_newline:
|
||||
tok = '+';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '-':
|
||||
PEEKC(c, p);
|
||||
if (c == '-') {
|
||||
@ -2655,7 +2655,7 @@ maybe_newline:
|
||||
PARSE2('*', '*', '=', TOK_A_MUL)
|
||||
PARSE2('%', '%', '=', TOK_A_MOD)
|
||||
PARSE2('^', '^', '=', TOK_A_XOR)
|
||||
|
||||
|
||||
/* comments or operator */
|
||||
case '/':
|
||||
PEEKC(c, p);
|
||||
@ -2675,7 +2675,7 @@ maybe_newline:
|
||||
tok = '/';
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
/* simple tokens */
|
||||
case '(':
|
||||
case ')':
|
||||
@ -2730,7 +2730,7 @@ ST_FUNC void next_nomacro(void)
|
||||
next_nomacro_spc();
|
||||
} while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void macro_subst(
|
||||
TokenString *tok_str,
|
||||
@ -2924,7 +2924,7 @@ static int macro_subst_tok(
|
||||
CValue cval;
|
||||
CString cstr;
|
||||
char buf[32];
|
||||
|
||||
|
||||
/* if symbol is a macro, prepare substitution */
|
||||
/* special macros */
|
||||
if (tok == TOK___LINE__) {
|
||||
@ -2942,10 +2942,10 @@ static int macro_subst_tok(
|
||||
time(&ti);
|
||||
tm = localtime(&ti);
|
||||
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);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
|
||||
snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
}
|
||||
cstrval = buf;
|
||||
@ -3010,8 +3010,8 @@ static int macro_subst_tok(
|
||||
tok_str_new(&str);
|
||||
parlevel = spc = 0;
|
||||
/* NOTE: non zero sa->t indicates VA_ARGS */
|
||||
while ((parlevel > 0 ||
|
||||
(tok != ')' &&
|
||||
while ((parlevel > 0 ||
|
||||
(tok != ')' &&
|
||||
(tok != ',' || sa->type.t)))) {
|
||||
if (tok == TOK_EOF || tok == 0)
|
||||
break;
|
||||
@ -3143,7 +3143,7 @@ static inline int *macro_twosharps(const int *ptr0)
|
||||
/* given 'a##b', remove nosubsts preceding 'b' */
|
||||
while ((t1 = *++ptr) == TOK_NOSUBST)
|
||||
;
|
||||
if (t1 && t1 != TOK_TWOSHARPS
|
||||
if (t1 && t1 != TOK_TWOSHARPS
|
||||
&& t1 != ':') /* 'a##:' don't build a new token */
|
||||
{
|
||||
TOK_GET(&t1, &ptr, &cv1);
|
||||
@ -3181,7 +3181,7 @@ static void macro_subst(
|
||||
int t, spc, nosubst;
|
||||
CValue cval;
|
||||
int *macro_str1 = NULL;
|
||||
|
||||
|
||||
/* first scan for '##' operator handling */
|
||||
ptr = macro_str;
|
||||
spc = nosubst = 0;
|
||||
@ -3334,7 +3334,7 @@ ST_FUNC void preprocess_new(void)
|
||||
: 0;
|
||||
|
||||
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
||||
|
||||
|
||||
tok_ident = TOK_IDENT;
|
||||
p = tcc_keywords;
|
||||
while (*p) {
|
@ -127,7 +127,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
for (i=0; i<argc; ++i)
|
||||
bound_new_region(argv[i], strlen(argv[i]));
|
||||
|
||||
errno = 0; /* clean errno value */
|
||||
errno = 0; /* clean errno value */
|
||||
ret = (*prog_main)(argc, argv);
|
||||
|
||||
/* unmark argv area */
|
||||
@ -139,7 +139,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
errno = 0; /* clean errno value */
|
||||
errno = 0; /* clean errno value */
|
||||
ret = (*prog_main)(argc, argv);
|
||||
}
|
||||
return ret;
|
||||
@ -652,7 +652,7 @@ static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
|
||||
if (rt_bound_error_msg && *rt_bound_error_msg)
|
||||
rt_error(uc, *rt_bound_error_msg);
|
||||
else
|
||||
rt_error(uc, "access violation");
|
||||
rt_error(uc, "access violation");
|
||||
break;
|
||||
case EXCEPTION_STACK_OVERFLOW:
|
||||
rt_error(uc, "stack overflow");
|
||||
@ -697,12 +697,12 @@ static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
|
||||
fp = uc->Ebp;
|
||||
#endif
|
||||
if (level > 0) {
|
||||
for(i = 1; i < level; i++) {
|
||||
/* XXX: check address validity with program info */
|
||||
if (fp <= 0x1000 || fp >= 0xc0000000)
|
||||
return -1;
|
||||
fp = ((addr_t*)fp)[0];
|
||||
}
|
||||
for(i=1;i<level;i++) {
|
||||
/* XXX: check address validity with program info */
|
||||
if (fp <= 0x1000 || fp >= 0xc0000000)
|
||||
return -1;
|
||||
fp = ((addr_t*)fp)[0];
|
||||
}
|
||||
pc = ((addr_t*)fp)[1];
|
||||
}
|
||||
*paddr = pc;
|
@ -36,7 +36,7 @@
|
||||
DEF(TOK_RESTRICT2, "__restrict")
|
||||
DEF(TOK_RESTRICT3, "__restrict__")
|
||||
DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
|
||||
|
||||
|
||||
DEF(TOK_FLOAT, "float")
|
||||
DEF(TOK_DOUBLE, "double")
|
||||
DEF(TOK_BOOL, "_Bool")
|
||||
@ -331,5 +331,5 @@
|
||||
#endif
|
||||
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
#include "x86/i386-tok.h"
|
||||
#include "i386-tok.h"
|
||||
#endif
|
@ -2,7 +2,7 @@
|
||||
# Tiny C Compiler Makefile - tests
|
||||
#
|
||||
|
||||
TOP = ../src
|
||||
TOP = ..
|
||||
include $(TOP)/Makefile
|
||||
SRCDIR = $(top_srcdir)/tests
|
||||
VPATH = $(SRCDIR) $(top_srcdir)
|
||||
@ -60,11 +60,11 @@ ifeq ($(TARGETOS),Darwin)
|
||||
endif
|
||||
|
||||
# run local version of tcc with local libraries and includes
|
||||
TCCFLAGS = -B$(TOP)/../lib -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/../include -L$(TOP)
|
||||
TCCFLAGS = -B$(TOP) -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include -L$(TOP)
|
||||
ifdef CONFIG_WIN32
|
||||
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir) -I$(top_srcdir)/../include -L$(TOP)
|
||||
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir) -I$(top_srcdir)/include -L$(TOP)
|
||||
endif
|
||||
XTCCFLAGS = -B$(TOP)/../lib -B$(top_srcdir)/win32 -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/../include
|
||||
XTCCFLAGS = -B$(TOP) -B$(top_srcdir)/win32 -I$(TOP) -I$(top_srcdir) -I$(top_srcdir)/include
|
||||
|
||||
TCC = $(TOP)/tcc $(TCCFLAGS)
|
||||
RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(top_srcdir)/tcc.c $(TCCFLAGS)
|
||||
@ -73,7 +73,7 @@ DISAS = objdump -d
|
||||
|
||||
# libtcc test
|
||||
ifdef LIBTCC1
|
||||
LIBTCC1:=$(TOP)/lib/$(LIBTCC1)
|
||||
LIBTCC1:=$(TOP)/$(LIBTCC1)
|
||||
endif
|
||||
|
||||
all test : $(TESTS)
|
||||
|
@ -41,7 +41,7 @@ static int run_callback(const char *src, callback_type callback) {
|
||||
TCCState *s;
|
||||
int result;
|
||||
void *ptr;
|
||||
|
||||
|
||||
s = tcc_new();
|
||||
if (!s)
|
||||
return -1;
|
||||
@ -54,14 +54,14 @@ static int run_callback(const char *src, callback_type callback) {
|
||||
return -1;
|
||||
if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
ptr = tcc_get_symbol(s, "f");
|
||||
if (!ptr)
|
||||
return -1;
|
||||
result = callback(ptr);
|
||||
|
||||
|
||||
tcc_delete(s);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
|
||||
|
||||
/*
|
||||
* ret_2float_test:
|
||||
*
|
||||
*
|
||||
* On x86-64, a struct with 2 floats should be packed into a single
|
||||
* SSE register (VT_DOUBLE is used for this purpose).
|
||||
*/
|
||||
@ -117,7 +117,7 @@ static int ret_2float_test(void) {
|
||||
|
||||
/*
|
||||
* ret_2double_test:
|
||||
*
|
||||
*
|
||||
* On x86-64, a struct with 2 doubles should be passed in two SSE
|
||||
* registers.
|
||||
*/
|
||||
@ -281,7 +281,7 @@ static int reg_pack_test(void) {
|
||||
" reg_pack_test_type r = {a.x*5, a.y*3};\n"
|
||||
" return r;\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
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"
|
||||
" return r;\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
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"
|
||||
" return r;\n"
|
||||
"}\n";
|
||||
|
||||
|
||||
return run_callback(src, sret_test_callback);
|
||||
}
|
||||
|
||||
/*
|
||||
* one_member_union_test:
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
@ -399,7 +399,7 @@ static int one_member_union_test(void) {
|
||||
|
||||
/*
|
||||
* two_member_union_test:
|
||||
*
|
||||
*
|
||||
* 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;
|
||||
@ -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 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) {
|
||||
many_struct_test_function_type f = (many_struct_test_function_type)ptr;
|
||||
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 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) {
|
||||
many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
|
||||
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) {
|
||||
const char *src =
|
||||
const char *src =
|
||||
"long double f(long double a, int b, long double c, int d, long double e) {\n"
|
||||
" return a + c + e;\n"
|
||||
"}\n";
|
||||
@ -621,7 +621,7 @@ int main(int argc, char **argv) {
|
||||
int i;
|
||||
const char *testname = NULL;
|
||||
int retval = EXIT_SUCCESS;
|
||||
|
||||
|
||||
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (!memcmp(argv[i], "run_test=", 9))
|
||||
|
@ -2,7 +2,7 @@
|
||||
# credits: 01..13.c from the pcc cpp-tests suite
|
||||
#
|
||||
|
||||
TCC = ../../src/tcc
|
||||
TCC = ../../tcc
|
||||
TESTS = $(patsubst %.c,%.test,$(wildcard *.c))
|
||||
|
||||
all test : $(TESTS)
|
||||
|
116
tests/tcctest.c
116
tests/tcctest.c
@ -320,7 +320,7 @@ void macro_test(void)
|
||||
#line 200
|
||||
printf("__LINE__=%d __FILE__=%s\n",
|
||||
__LINE__, __FILE__);
|
||||
#line 203 "test"
|
||||
#line 203 "test"
|
||||
printf("__LINE__=%d __FILE__=%s\n",
|
||||
__LINE__, __FILE__);
|
||||
#line 227 "tcctest.c"
|
||||
@ -348,7 +348,7 @@ void macro_test(void)
|
||||
glue(a <, <= 2);
|
||||
printf("a=%d\n", a);
|
||||
}
|
||||
|
||||
|
||||
/* macro function with argument outside the macro string */
|
||||
#define MF_s MF_hello
|
||||
#define MF_hello(msg) printf("%s\n",msg)
|
||||
@ -357,7 +357,7 @@ void macro_test(void)
|
||||
|
||||
MF_s("hi");
|
||||
MF_t("hi");
|
||||
|
||||
|
||||
/* test macro substituion inside args (should not eat stream) */
|
||||
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)));
|
||||
|
||||
#define WRAP(x) x
|
||||
|
||||
|
||||
#define print_num(x) print_num(__FILE__,__LINE__,x)
|
||||
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. */
|
||||
typedef_and_label:
|
||||
s_loop:
|
||||
if (i >= 10)
|
||||
if (i >= 10)
|
||||
goto s_end;
|
||||
printf("%d", i);
|
||||
i++;
|
||||
@ -688,7 +688,7 @@ int main(int argc, char **argv)
|
||||
callsave_test();
|
||||
builtin_frame_address_test();
|
||||
intdiv_test();
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tab[3];
|
||||
@ -797,10 +797,10 @@ void expr_test()
|
||||
printf("%d\n", ~12);
|
||||
printf("%d\n", -12);
|
||||
printf("%d\n", +12);
|
||||
printf("%d %d %d %d\n",
|
||||
isid('a'),
|
||||
isid('g'),
|
||||
isid('T'),
|
||||
printf("%d %d %d %d\n",
|
||||
isid('a'),
|
||||
isid('g'),
|
||||
isid('T'),
|
||||
isid('('));
|
||||
}
|
||||
|
||||
@ -984,7 +984,7 @@ void struct_test()
|
||||
sizeof(struct aligntest3), __alignof__(struct aligntest3));
|
||||
printf("aligntest4 sizeof=%d alignof=%d\n",
|
||||
sizeof(struct aligntest4), __alignof__(struct aligntest4));
|
||||
|
||||
|
||||
/* empty structures (GCC extension) */
|
||||
printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
|
||||
printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
|
||||
@ -999,17 +999,17 @@ void char_short_test()
|
||||
|
||||
var1 = 0x01020304;
|
||||
var2 = 0xfffefdfc;
|
||||
printf("s8=%d %d\n",
|
||||
printf("s8=%d %d\n",
|
||||
*(char *)&var1, *(char *)&var2);
|
||||
printf("u8=%d %d\n",
|
||||
printf("u8=%d %d\n",
|
||||
*(unsigned char *)&var1, *(unsigned char *)&var2);
|
||||
printf("s16=%d %d\n",
|
||||
printf("s16=%d %d\n",
|
||||
*(short *)&var1, *(short *)&var2);
|
||||
printf("u16=%d %d\n",
|
||||
printf("u16=%d %d\n",
|
||||
*(unsigned short *)&var1, *(unsigned short *)&var2);
|
||||
printf("s32=%d %d\n",
|
||||
printf("s32=%d %d\n",
|
||||
*(int *)&var1, *(int *)&var2);
|
||||
printf("u32=%d %d\n",
|
||||
printf("u32=%d %d\n",
|
||||
*(unsigned int *)&var1, *(unsigned int *)&var2);
|
||||
*(char *)&var1 = 0x08;
|
||||
printf("var1=%x\n", var1);
|
||||
@ -1099,7 +1099,7 @@ void bool_test()
|
||||
static int v1 = 34 ? : -1; /* constant case */
|
||||
static int v2 = 0 ? : -1; /* constant case */
|
||||
int a = 30;
|
||||
|
||||
|
||||
printf("%d %d\n", v1, v2);
|
||||
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];
|
||||
|
||||
//int cinit1; /* a global variable can be defined several times without error ! */
|
||||
int cinit1;
|
||||
int cinit1;
|
||||
int cinit1;
|
||||
int cinit1;
|
||||
int cinit1 = 0;
|
||||
int *cinit2 = (int []){3, 2, 1};
|
||||
|
||||
@ -1157,7 +1157,7 @@ void compound_literal_test(void)
|
||||
|
||||
for(i=0;i<3;i++) {
|
||||
p = (int []){1, 2, 4 + i};
|
||||
printf("%d %d %d\n",
|
||||
printf("%d %d %d\n",
|
||||
p[0],
|
||||
p[1],
|
||||
p[2]);
|
||||
@ -1188,7 +1188,7 @@ kr_test()
|
||||
void num(int n)
|
||||
{
|
||||
char *tab, *p;
|
||||
tab = (char*)malloc(20);
|
||||
tab = (char*)malloc(20);
|
||||
p = tab;
|
||||
while (1) {
|
||||
*p = 48 + (n % 10);
|
||||
@ -1231,7 +1231,7 @@ void struct_assign_test(void)
|
||||
struct structa1 lsta1, lsta2;
|
||||
int i;
|
||||
} s, *ps;
|
||||
|
||||
|
||||
ps = &s;
|
||||
ps->i = 4;
|
||||
#if 0
|
||||
@ -1247,7 +1247,7 @@ void struct_assign_test(void)
|
||||
s.lsta2.f2 = 2;
|
||||
#endif
|
||||
struct_assign_test1(ps->lsta2, 3, 4.5);
|
||||
|
||||
|
||||
printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
|
||||
ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
|
||||
printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
|
||||
@ -1300,9 +1300,9 @@ void cast_test()
|
||||
printf("%d\n", a);
|
||||
a = (scast = 65536) + 1;
|
||||
printf("%d\n", a);
|
||||
|
||||
|
||||
printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
|
||||
|
||||
|
||||
/* test cast from unsigned to signed short to int */
|
||||
b = 0xf000;
|
||||
d = (short)b;
|
||||
@ -1310,7 +1310,7 @@ void cast_test()
|
||||
b = 0xf0f0;
|
||||
d = (char)b;
|
||||
printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
|
||||
|
||||
|
||||
/* test implicit int casting for array accesses */
|
||||
c = 0;
|
||||
tab[1] = 2;
|
||||
@ -1352,7 +1352,7 @@ char sinit8[] = "hello" "trala";
|
||||
|
||||
struct structinit1 sinit9 = { 1, 2, 3 };
|
||||
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
|
||||
.farray[0] = 10,
|
||||
.farray[1] = 11,
|
||||
@ -1437,36 +1437,36 @@ void init_test(void)
|
||||
int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
|
||||
struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
|
||||
int linit17 = sizeof(linit17);
|
||||
|
||||
|
||||
printf("init_test:\n");
|
||||
|
||||
printf("sinit1=%d\n", sinit1);
|
||||
printf("sinit2=%d\n", sinit2);
|
||||
printf("sinit3=%d %d %d %d\n",
|
||||
printf("sinit3=%d %d %d %d\n",
|
||||
sizeof(sinit3),
|
||||
sinit3[0],
|
||||
sinit3[1],
|
||||
sinit3[2]
|
||||
);
|
||||
printf("sinit6=%d\n", sizeof(sinit6));
|
||||
printf("sinit7=%d %d %d %d\n",
|
||||
printf("sinit7=%d %d %d %d\n",
|
||||
sizeof(sinit7),
|
||||
sinit7[0],
|
||||
sinit7[1],
|
||||
sinit7[2]
|
||||
);
|
||||
printf("sinit8=%s\n", sinit8);
|
||||
printf("sinit9=%d %d %d\n",
|
||||
printf("sinit9=%d %d %d\n",
|
||||
sinit9.f1,
|
||||
sinit9.f2,
|
||||
sinit9.f3
|
||||
);
|
||||
printf("sinit10=%d %d %d\n",
|
||||
printf("sinit10=%d %d %d\n",
|
||||
sinit10.f1,
|
||||
sinit10.f2,
|
||||
sinit10.f3
|
||||
);
|
||||
printf("sinit11=%d %d %d %d %d %d\n",
|
||||
printf("sinit11=%d %d %d %d %d %d\n",
|
||||
sinit11.f1,
|
||||
sinit11.f2,
|
||||
sinit11.f3,
|
||||
@ -1477,7 +1477,7 @@ void init_test(void)
|
||||
|
||||
for(i=0;i<3;i++)
|
||||
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]);
|
||||
printf("linit1=%d\n", linit1);
|
||||
printf("linit2=%d\n", linit2);
|
||||
@ -1486,7 +1486,7 @@ void init_test(void)
|
||||
|
||||
printf("sinit12=%s\n", sinit12);
|
||||
printf("sinit13=%d %s %s %s\n",
|
||||
sizeof(sinit13),
|
||||
sizeof(sinit13),
|
||||
sinit13[0],
|
||||
sinit13[1],
|
||||
sinit13[2]);
|
||||
@ -1500,7 +1500,7 @@ void init_test(void)
|
||||
printf("\n");
|
||||
for(i=0;i<10;i++) printf(" %d", linit15[i]);
|
||||
printf("\n");
|
||||
printf("%d %d %d %d\n",
|
||||
printf("%d %d %d %d\n",
|
||||
linit16.a1,
|
||||
linit16.a2,
|
||||
linit16.a3,
|
||||
@ -1599,13 +1599,13 @@ void bitfield_test(void)
|
||||
printf("%d %d\n", sa, ca);
|
||||
|
||||
st1.f1 = 7;
|
||||
if (st1.f1 == -1)
|
||||
if (st1.f1 == -1)
|
||||
printf("st1.f1 == -1\n");
|
||||
else
|
||||
else
|
||||
printf("st1.f1 != -1\n");
|
||||
if (st1.f2 == -1)
|
||||
if (st1.f2 == -1)
|
||||
printf("st1.f2 == -1\n");
|
||||
else
|
||||
else
|
||||
printf("st1.f2 != -1\n");
|
||||
|
||||
/* 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);
|
||||
|
||||
|
||||
if (b != 0) {
|
||||
printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
|
||||
a / b,
|
||||
@ -1856,7 +1856,7 @@ void lloptest(long long a, long long b)
|
||||
a > b,
|
||||
a >= b,
|
||||
a <= b);
|
||||
|
||||
|
||||
printf("utest: %d %d %d %d %d %d\n",
|
||||
ua == ub,
|
||||
ua != ub,
|
||||
@ -1932,7 +1932,7 @@ long long llfunc1(int a)
|
||||
}
|
||||
|
||||
struct S {
|
||||
int id;
|
||||
int id;
|
||||
char item;
|
||||
};
|
||||
|
||||
@ -1953,8 +1953,8 @@ void longlong_test(void)
|
||||
a = ia;
|
||||
b = ua;
|
||||
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
|
||||
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
|
||||
(long long)1,
|
||||
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
|
||||
(long long)1,
|
||||
(long long)-2,
|
||||
1LL,
|
||||
0x1234567812345679);
|
||||
@ -2049,7 +2049,7 @@ void vprintf1(const char *fmt, ...)
|
||||
|
||||
va_start(aq, fmt);
|
||||
va_copy(ap, aq);
|
||||
|
||||
|
||||
p = fmt;
|
||||
for(;;) {
|
||||
c = *p;
|
||||
@ -2250,10 +2250,10 @@ void c99_vla_test(int size1, int size2)
|
||||
int tab1[size][2], tab2[10][2];
|
||||
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. */
|
||||
size = size-1;
|
||||
|
||||
|
||||
printf("Test C99 VLA 1 (sizeof): ");
|
||||
printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
|
||||
tab1_ptr = tab1;
|
||||
@ -2325,7 +2325,7 @@ void sizeof_test(void)
|
||||
t <<= 16;
|
||||
t <<= 16;
|
||||
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. */
|
||||
t2 = t & -sizeof(uintptr_t);
|
||||
printf ("%lu %lu\n", t, t2);
|
||||
@ -2358,15 +2358,15 @@ void statement_expr_test(void)
|
||||
|
||||
a = 0;
|
||||
for(i=0;i<10;i++) {
|
||||
a += 1 +
|
||||
( { int b, j;
|
||||
b = 0;
|
||||
for(j=0;j<5;j++)
|
||||
b += j; b;
|
||||
a += 1 +
|
||||
( { int b, j;
|
||||
b = 0;
|
||||
for(j=0;j<5;j++)
|
||||
b += j; b;
|
||||
} );
|
||||
}
|
||||
printf("a=%d\n", a);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void local_label_test(void)
|
||||
@ -2589,7 +2589,7 @@ void builtin_test(void)
|
||||
COMPAT_TYPE(char *, signed char *);
|
||||
COMPAT_TYPE(char *, char *);
|
||||
/* space is needed because tcc preprocessor introduces a space between each token */
|
||||
COMPAT_TYPE(char * *, void *);
|
||||
COMPAT_TYPE(char * *, void *);
|
||||
#endif
|
||||
printf("res = %d\n", __builtin_constant_p(1));
|
||||
printf("res = %d\n", __builtin_constant_p(1 + 2));
|
||||
@ -2640,7 +2640,7 @@ void __attribute__((weak)) weak_test(void)
|
||||
printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
|
||||
printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
|
||||
printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
|
||||
|
||||
|
||||
printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
|
||||
printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
|
||||
printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
|
||||
|
@ -1,4 +1,4 @@
|
||||
TOP = ../../src
|
||||
TOP = ../..
|
||||
include $(TOP)/Makefile
|
||||
|
||||
# clear CFLAGS and LDFLAGS
|
||||
@ -6,9 +6,9 @@ CFLAGS :=
|
||||
LDFLAGS :=
|
||||
|
||||
ifdef CONFIG_WIN32
|
||||
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir)/../include -L$(TOP)
|
||||
TCCFLAGS = -B$(top_srcdir)/win32 -I$(top_srcdir)/include -L$(TOP)
|
||||
else
|
||||
TCCFLAGS = -B$(TOP)/../lib -I$(top_srcdir)/../include -lm
|
||||
TCCFLAGS = -B$(TOP) -I$(top_srcdir)/include -lm
|
||||
endif
|
||||
|
||||
ifeq ($(TARGETOS),Darwin)
|
||||
|
2
docs/texi2pod.pl → texi2pod.pl
Normal file → Executable file
2
docs/texi2pod.pl → texi2pod.pl
Normal file → Executable file
@ -229,7 +229,7 @@ while(<$inf>) {
|
||||
$inf = gensym();
|
||||
|
||||
# Try cwd and $ibase.
|
||||
open($inf, "<" . $1)
|
||||
open($inf, "<" . $1)
|
||||
or open($inf, "<" . $ibase . "/" . $1)
|
||||
or die "cannot open $1 or $ibase/$1: $!\n";
|
||||
next;
|
@ -21,7 +21,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "../../src/elf.h"
|
||||
#include "../../elf.h"
|
||||
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
# define ELFCLASSW ELFCLASS64
|
||||
|
@ -136,7 +136,7 @@ enum {
|
||||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
#include "../tcc.h"
|
||||
#include "tcc.h"
|
||||
#include <assert.h>
|
||||
|
||||
ST_DATA const int reg_classes[NB_REGS] = {
|
||||
@ -477,17 +477,18 @@ void load(int r, SValue *sv)
|
||||
gen_modrm(r, VT_LOCAL, sv->sym, fc);
|
||||
} else if (v == VT_CMP) {
|
||||
orex(0,r,0,0);
|
||||
if ((fc & ~0x100) != TOK_NE)
|
||||
oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
|
||||
else
|
||||
oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
|
||||
if (fc & 0x100) {
|
||||
/* This was a float compare. If the parity bit is
|
||||
* set the result was unordered, meaning false for everything
|
||||
* except TOK_NE, and true for TOK_NE. */
|
||||
fc &= ~0x100;
|
||||
o(0x037a + (REX_BASE(r) << 8));
|
||||
}
|
||||
if ((fc & ~0x100) != TOK_NE)
|
||||
oad(0xb8 + REG_VALUE(r), 0); /* mov $0, r */
|
||||
else
|
||||
oad(0xb8 + REG_VALUE(r), 1); /* mov $1, r */
|
||||
if (fc & 0x100)
|
||||
{
|
||||
/* This was a float compare. If the parity bit is
|
||||
set the result was unordered, meaning false for everything
|
||||
except TOK_NE, and true for TOK_NE. */
|
||||
fc &= ~0x100;
|
||||
o(0x037a + (REX_BASE(r) << 8));
|
||||
}
|
||||
orex(0,r,0, 0x0f); /* setxx %br */
|
||||
o(fc);
|
||||
o(0xc0 + REG_VALUE(r));
|
||||
@ -618,7 +619,7 @@ static void gcall_or_jmp(int is_jmp)
|
||||
{
|
||||
int r;
|
||||
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST &&
|
||||
((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) {
|
||||
((vtop->r & VT_SYM) || (vtop->c.ll-4) == (int)(vtop->c.ll-4))) {
|
||||
/* constant case */
|
||||
if (vtop->r & VT_SYM) {
|
||||
/* relocation case */
|
||||
@ -680,7 +681,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
|
||||
|
||||
|
||||
/* 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
|
||||
@ -822,7 +823,7 @@ void gfunc_call(int nb_args)
|
||||
struct_size = args_size;
|
||||
for(i = 0; i < nb_args; i++) {
|
||||
SValue *sv;
|
||||
|
||||
|
||||
--arg;
|
||||
sv = &vtop[-i];
|
||||
bt = (sv->type.t & VT_BTYPE);
|
||||
@ -896,7 +897,7 @@ void gfunc_call(int nb_args)
|
||||
vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
|
||||
: size > 1 ? VT_SHORT : VT_BYTE;
|
||||
}
|
||||
|
||||
|
||||
r = gv(RC_INT);
|
||||
if (arg >= REGN) {
|
||||
gen_offs_sp(0x89, r, arg*8);
|
||||
@ -910,7 +911,7 @@ void gfunc_call(int nb_args)
|
||||
vtop--;
|
||||
}
|
||||
save_regs(0);
|
||||
|
||||
|
||||
/* Copy R10 and R11 into RCX and RDX, respectively */
|
||||
if (nb_args > 0) {
|
||||
o(0xd1894c); /* mov %r10, %rcx */
|
||||
@ -918,7 +919,7 @@ void gfunc_call(int nb_args)
|
||||
o(0xda894c); /* mov %r11, %rdx */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gcall_or_jmp(0);
|
||||
vtop--;
|
||||
}
|
||||
@ -1071,10 +1072,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
|
||||
{
|
||||
X86_64_Mode mode;
|
||||
Sym *f;
|
||||
|
||||
|
||||
switch (ty->t & VT_BTYPE) {
|
||||
case VT_VOID: return x86_64_mode_none;
|
||||
|
||||
|
||||
case VT_INT:
|
||||
case VT_BYTE:
|
||||
case VT_SHORT:
|
||||
@ -1083,12 +1084,12 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
|
||||
case VT_PTR:
|
||||
case VT_FUNC:
|
||||
case VT_ENUM: return x86_64_mode_integer;
|
||||
|
||||
|
||||
case VT_FLOAT:
|
||||
case VT_DOUBLE: return x86_64_mode_sse;
|
||||
|
||||
|
||||
case VT_LDOUBLE: return x86_64_mode_x87;
|
||||
|
||||
|
||||
case VT_STRUCT:
|
||||
f = ty->ref;
|
||||
|
||||
@ -1097,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)
|
||||
mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end));
|
||||
}
|
||||
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@ -1304,7 +1305,7 @@ void gfunc_call(int nb_args)
|
||||
args_size = 0;
|
||||
while (run_start != nb_args) {
|
||||
int run_gen_reg = gen_reg, run_sse_reg = sse_reg;
|
||||
|
||||
|
||||
run_end = nb_args;
|
||||
stack_adjust = 0;
|
||||
for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) {
|
||||
@ -1318,10 +1319,10 @@ void gfunc_call(int nb_args)
|
||||
stack_adjust += size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gen_reg = run_gen_reg;
|
||||
sse_reg = run_sse_reg;
|
||||
|
||||
|
||||
/* adjust stack to align SSE boundary */
|
||||
if (stack_adjust &= 15) {
|
||||
/* fetch cpu flag before the following sub will change the value */
|
||||
@ -1333,7 +1334,7 @@ void gfunc_call(int nb_args)
|
||||
oad(0xec81, stack_adjust); /* sub $xxx, %rsp */
|
||||
args_size += stack_adjust;
|
||||
}
|
||||
|
||||
|
||||
for(i = run_start; i < run_end;) {
|
||||
int arg_stored = regargs_nregs(®_args[i]) == 0;
|
||||
SValue tmp;
|
||||
@ -1343,7 +1344,7 @@ void gfunc_call(int nb_args)
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Swap argument to top, it will possibly be changed here,
|
||||
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
|
||||
@ -1351,7 +1352,7 @@ void gfunc_call(int nb_args)
|
||||
tmp = vtop[0];
|
||||
vtop[0] = vtop[-i];
|
||||
vtop[-i] = tmp;
|
||||
|
||||
|
||||
classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args);
|
||||
|
||||
switch (vtop->type.t & VT_BTYPE) {
|
||||
@ -1368,11 +1369,11 @@ void gfunc_call(int nb_args)
|
||||
vstore();
|
||||
args_size += size;
|
||||
break;
|
||||
|
||||
|
||||
case VT_LDOUBLE:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
|
||||
case VT_FLOAT:
|
||||
case VT_DOUBLE:
|
||||
r = gv(RC_FLOAT);
|
||||
@ -1383,7 +1384,7 @@ void gfunc_call(int nb_args)
|
||||
o(0x24);
|
||||
args_size += size;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
/* simple type */
|
||||
/* XXX: implicit cast ? */
|
||||
@ -1416,7 +1417,7 @@ void gfunc_call(int nb_args)
|
||||
break;
|
||||
|
||||
vrotb(i+1);
|
||||
|
||||
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||
gv(RC_ST0);
|
||||
oad(0xec8148, size); /* sub $xxx, %rsp */
|
||||
@ -1439,7 +1440,7 @@ void gfunc_call(int nb_args)
|
||||
vstore();
|
||||
args_size += size;
|
||||
}
|
||||
|
||||
|
||||
vpop();
|
||||
memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args);
|
||||
--nb_args;
|
||||
@ -1697,14 +1698,14 @@ void gfunc_prolog(CType *func_type)
|
||||
addr += size;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case x86_64_mode_memory:
|
||||
case x86_64_mode_x87:
|
||||
addr = (addr + align - 1) & -align;
|
||||
param_addr = addr;
|
||||
addr += size;
|
||||
break;
|
||||
default: break; /* nothing to be done for x86_64_mode_none */
|
||||
default: break; /* nothing to be done for x86_64_mode_none */
|
||||
}
|
||||
sym_push(sym->v & ~SYM_FIELD, type,
|
||||
VT_LOCAL | VT_LVAL, param_addr);
|
||||
@ -1716,8 +1717,8 @@ void gfunc_prolog(CType *func_type)
|
||||
func_bound_offset = lbounds_section->data_offset;
|
||||
func_bound_ind = ind;
|
||||
oad(0xb8, 0); /* lbound section pointer */
|
||||
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
||||
oad(0xb8, 0); /* call to function */
|
||||
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
||||
oad(0xb8, 0); /* call to function */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1729,7 +1730,7 @@ void gfunc_epilog(void)
|
||||
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (tcc_state->do_bounds_check
|
||||
&& func_bound_offset != lbounds_section->data_offset)
|
||||
&& func_bound_offset != lbounds_section->data_offset)
|
||||
{
|
||||
addr_t saved_ind;
|
||||
addr_t *bounds_ptr;
|
||||
@ -1753,7 +1754,7 @@ void gfunc_epilog(void)
|
||||
o(0x5250); /* save returned value, if any */
|
||||
greloc(cur_text_section, sym_data, ind + 1, R_386_32);
|
||||
oad(0xb8, 0); /* mov xxx, %rax */
|
||||
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
||||
o(0xc78948); /* mov %rax,%rdi ## first arg in %rdi, this must be ptr */
|
||||
gen_static_call(TOK___bound_local_delete);
|
||||
o(0x585a); /* restore returned value, if any */
|
||||
}
|
||||
@ -1805,23 +1806,24 @@ int gtst(int inv, int t)
|
||||
v = vtop->r & VT_VALMASK;
|
||||
if (v == VT_CMP) {
|
||||
/* fast case : can jump directly since flags are set */
|
||||
if (vtop->c.i & 0x100)
|
||||
{
|
||||
/* This was a float compare. If the parity flag is set
|
||||
the result was unordered. For anything except != this
|
||||
means false and we don't jump (anding both conditions).
|
||||
For != this means true (oring both).
|
||||
Take care about inverting the test. We need to jump
|
||||
to our target if the result was unordered and test wasn't NE,
|
||||
otherwise if unordered we don't want to jump. */
|
||||
vtop->c.i &= ~0x100;
|
||||
if (!inv == (vtop->c.i != TOK_NE))
|
||||
o(0x067a); /* jp +6 */
|
||||
else {
|
||||
g(0x0f);
|
||||
t = psym(0x8a, t); /* jp t */
|
||||
}
|
||||
}
|
||||
if (vtop->c.i & 0x100)
|
||||
{
|
||||
/* This was a float compare. If the parity flag is set
|
||||
the result was unordered. For anything except != this
|
||||
means false and we don't jump (anding both conditions).
|
||||
For != this means true (oring both).
|
||||
Take care about inverting the test. We need to jump
|
||||
to our target if the result was unordered and test wasn't NE,
|
||||
otherwise if unordered we don't want to jump. */
|
||||
vtop->c.i &= ~0x100;
|
||||
if (!inv == (vtop->c.i != TOK_NE))
|
||||
o(0x067a); /* jp +6 */
|
||||
else
|
||||
{
|
||||
g(0x0f);
|
||||
t = psym(0x8a, t); /* jp t */
|
||||
}
|
||||
}
|
||||
g(0x0f);
|
||||
t = psym((vtop->c.i - 16) ^ inv, t);
|
||||
} else if (v == VT_JMP || v == VT_JMPI) {
|
||||
@ -2102,7 +2104,7 @@ void gen_opf(int op)
|
||||
vswap();
|
||||
}
|
||||
assert(!(vtop[-1].r & VT_LVAL));
|
||||
|
||||
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||
o(0x66);
|
||||
if (op == TOK_EQ || op == TOK_NE)
|
||||
@ -2139,7 +2141,7 @@ void gen_opf(int op)
|
||||
ft = vtop->type.t;
|
||||
fc = vtop->c.ul;
|
||||
assert((ft & VT_BTYPE) != VT_LDOUBLE);
|
||||
|
||||
|
||||
r = vtop->r;
|
||||
/* if saved lvalue, then we must reload it */
|
||||
if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
|
||||
@ -2151,14 +2153,14 @@ void gen_opf(int op)
|
||||
load(r, &v1);
|
||||
fc = 0;
|
||||
}
|
||||
|
||||
|
||||
assert(!(vtop[-1].r & VT_LVAL));
|
||||
if (swapped) {
|
||||
assert(vtop->r & VT_LVAL);
|
||||
gv(RC_FLOAT);
|
||||
vswap();
|
||||
}
|
||||
|
||||
|
||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||
o(0xf2);
|
||||
} else {
|
||||
@ -2166,7 +2168,7 @@ void gen_opf(int op)
|
||||
}
|
||||
o(0x0f);
|
||||
o(0x58 + a);
|
||||
|
||||
|
||||
if (vtop->r & VT_LVAL) {
|
||||
gen_modrm(vtop[-1].r, r, vtop->sym, fc);
|
||||
} else {
|
||||
@ -2229,7 +2231,7 @@ void gen_cvt_ftof(int t)
|
||||
ft = vtop->type.t;
|
||||
bt = ft & VT_BTYPE;
|
||||
tbt = t & VT_BTYPE;
|
||||
|
||||
|
||||
if (bt == VT_FLOAT) {
|
||||
gv(RC_FLOAT);
|
||||
if (tbt == VT_DOUBLE) {
|
Loading…
Reference in New Issue
Block a user