Trim trailing spaces everywhere.
This commit is contained in:
parent
5e67f24e6b
commit
41031221c8
27 changed files with 430 additions and 430 deletions
|
|
@ -154,7 +154,7 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
|
||||||
foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS})
|
foreach(make_tcc_def ${TCC_NATIVE_DEFINITIONS})
|
||||||
set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def})
|
set(TCC_NATIVE_FLAGS ${TCC_NATIVE_FLAGS} -D${make_tcc_def})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if (TCC_BUILD_NATIVE)
|
if (TCC_BUILD_NATIVE)
|
||||||
add_library(libtcc
|
add_library(libtcc
|
||||||
libtcc.c
|
libtcc.c
|
||||||
|
|
@ -179,7 +179,7 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
|
||||||
endif()
|
endif()
|
||||||
install(TARGETS tcc libtcc RUNTIME DESTINATION ${EXE_PATH} LIBRARY DESTINATION ${NATIVE_LIB_PATH} ARCHIVE DESTINATION ${NATIVE_LIB_PATH})
|
install(TARGETS tcc libtcc RUNTIME DESTINATION ${EXE_PATH} LIBRARY DESTINATION ${NATIVE_LIB_PATH} ARCHIVE DESTINATION ${NATIVE_LIB_PATH})
|
||||||
set_target_properties(tcc libtcc PROPERTIES COMPILE_DEFINITIONS "${TCC_NATIVE_DEFINITIONS}")
|
set_target_properties(tcc libtcc PROPERTIES COMPILE_DEFINITIONS "${TCC_NATIVE_DEFINITIONS}")
|
||||||
|
|
||||||
if("${libtcc_sources}" STRGREATER "")
|
if("${libtcc_sources}" STRGREATER "")
|
||||||
make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}")
|
make_libtcc1("" tcc "${libtcc_ar}" "${TCC_NATIVE_DEFINITIONS}" "${libtcc_includes}" "${libtcc_sources}")
|
||||||
endif()
|
endif()
|
||||||
|
|
@ -188,7 +188,7 @@ macro(make_tcc native_name cross_name cross_enabled definitions tcc_sources libt
|
||||||
add_executable(${cross_name}-tcc tcc.c)
|
add_executable(${cross_name}-tcc tcc.c)
|
||||||
set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}")
|
set_target_properties(${cross_name}-tcc PROPERTIES COMPILE_DEFINITIONS "ONE_SOURCE;${definitions}")
|
||||||
install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH})
|
install(TARGETS ${cross_name}-tcc RUNTIME DESTINATION ${EXE_PATH})
|
||||||
|
|
||||||
if("${libtcc_sources}" STRGREATER "")
|
if("${libtcc_sources}" STRGREATER "")
|
||||||
make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}")
|
make_libtcc1(${cross_name} "${cross_name}-tcc" "${libtcc_ar}" "${definitions}" "${libtcc_includes}" "${libtcc_sources}")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
82
c67-gen.c
82
c67-gen.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* TMS320C67xx code generator for TCC
|
* TMS320C67xx code generator for TCC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001, 2002 Fabrice Bellard
|
* Copyright (c) 2001, 2002 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -130,7 +130,7 @@ enum {
|
||||||
#include "tcc.h"
|
#include "tcc.h"
|
||||||
|
|
||||||
ST_DATA const int reg_classes[NB_REGS] = {
|
ST_DATA const int reg_classes[NB_REGS] = {
|
||||||
/* eax */ RC_INT | RC_FLOAT | RC_EAX,
|
/* eax */ RC_INT | RC_FLOAT | RC_EAX,
|
||||||
// only allow even regs for floats (allow for doubles)
|
// only allow even regs for floats (allow for doubles)
|
||||||
/* ecx */ RC_INT | RC_ECX,
|
/* ecx */ RC_INT | RC_ECX,
|
||||||
/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
|
/* edx */ RC_INT | RC_INT_BSIDE | RC_FLOAT | RC_EDX,
|
||||||
|
|
@ -161,7 +161,7 @@ ST_DATA const int reg_classes[NB_REGS] = {
|
||||||
// although tcc thinks it is passing parameters on the stack,
|
// although tcc thinks it is passing parameters on the stack,
|
||||||
// the C67 really passes up to the first 10 params in special
|
// the C67 really passes up to the first 10 params in special
|
||||||
// regs or regs pairs (for 64 bit params). So keep track of
|
// regs or regs pairs (for 64 bit params). So keep track of
|
||||||
// the stack offsets so we can translate to the appropriate
|
// the stack offsets so we can translate to the appropriate
|
||||||
// reg (pair)
|
// reg (pair)
|
||||||
|
|
||||||
#define NoCallArgsPassedOnStack 10
|
#define NoCallArgsPassedOnStack 10
|
||||||
|
|
@ -246,7 +246,7 @@ void gsym(int t)
|
||||||
gsym_addr(t, ind);
|
gsym_addr(t, ind);
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are regs that tcc doesn't really know about,
|
// these are regs that tcc doesn't really know about,
|
||||||
// but assign them unique values so the mapping routines
|
// but assign them unique values so the mapping routines
|
||||||
// can distinguish them
|
// can distinguish them
|
||||||
|
|
||||||
|
|
@ -298,7 +298,7 @@ int C67_map_regn(int r)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapping from tcc reg number to
|
// mapping from tcc reg number to
|
||||||
// C67 register to condition code field
|
// C67 register to condition code field
|
||||||
//
|
//
|
||||||
// valid condition code regs are:
|
// valid condition code regs are:
|
||||||
|
|
@ -343,15 +343,15 @@ int C67_map_regs(int r)
|
||||||
else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
|
else if (r >= TREG_C67_A4 && r <= TREG_C67_B13) // these form a pattern of alt pairs
|
||||||
return (r & 2) >> 1;
|
return (r & 2) >> 1;
|
||||||
else if (r == C67_A0)
|
else if (r == C67_A0)
|
||||||
return 0; // set to A side
|
return 0; // set to A side
|
||||||
else if (r == C67_B2)
|
else if (r == C67_B2)
|
||||||
return 1; // set to B side
|
return 1; // set to B side
|
||||||
else if (r == C67_B3)
|
else if (r == C67_B3)
|
||||||
return 1; // set to B side
|
return 1; // set to B side
|
||||||
else if (r == C67_SP)
|
else if (r == C67_SP)
|
||||||
return 0x1; // set to SP (B15) B side
|
return 0x1; // set to SP (B15) B side
|
||||||
else if (r == C67_FP)
|
else if (r == C67_FP)
|
||||||
return 0x0; // set to FP (A15) A side
|
return 0x0; // set to FP (A15) A side
|
||||||
else
|
else
|
||||||
ALWAYS_ASSERT(FALSE);
|
ALWAYS_ASSERT(FALSE);
|
||||||
|
|
||||||
|
|
@ -420,7 +420,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(5 << 9) | //mode 5 = pos offset, base reg + off reg
|
(5 << 9) | //mode 5 = pos offset, base reg + off reg
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(0 << 7) | //y D1/D2 A side
|
(0 << 7) | //y D1/D2 A side
|
||||||
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -442,7 +442,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(5 << 9) | //mode 5 = pos offset, base reg + off reg
|
(5 << 9) | //mode 5 = pos offset, base reg + off reg
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(0 << 7) | //y D1/D2 A side
|
(0 << 7) | //y D1/D2 A side
|
||||||
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -464,7 +464,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(5 << 9) | //mode 5 = pos offset, base reg + off reg
|
(5 << 9) | //mode 5 = pos offset, base reg + off reg
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(0 << 7) | //y D1/D2 A side
|
(0 << 7) | //y D1/D2 A side
|
||||||
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -475,7 +475,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
||||||
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -486,7 +486,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
||||||
(5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(5 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -497,7 +497,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
||||||
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(3 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -509,7 +509,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
(C67_map_regs(b) << 7) | //y D1/D2 base reg side
|
||||||
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(7 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(a) << 1) | //side of src
|
(C67_map_regs(a) << 1) | //side of src
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -641,7 +641,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(a) << 7) | //y D1/D2 src side
|
(C67_map_regs(a) << 7) | //y D1/D2 src side
|
||||||
(2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(2 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(b) << 1) | //side of dst
|
(C67_map_regs(b) << 1) | //side of dst
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -652,7 +652,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(a) << 7) | //y D1/D2 src side
|
(C67_map_regs(a) << 7) | //y D1/D2 src side
|
||||||
(0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(0 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(b) << 1) | //side of dst
|
(C67_map_regs(b) << 1) | //side of dst
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -674,7 +674,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(1 << 9) | //mode 1 = pos cst offset
|
(1 << 9) | //mode 1 = pos cst offset
|
||||||
(0 << 8) | //r (LDDW bit 0)
|
(0 << 8) | //r (LDDW bit 0)
|
||||||
(C67_map_regs(a) << 7) | //y D1/D2 src side
|
(C67_map_regs(a) << 7) | //y D1/D2 src side
|
||||||
(6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
(6 << 4) | //ldst 3=STB, 5=STH 5, 7=STW, 6=LDW 4=LDH 2=LDB 0=LDHU 1=LDBU
|
||||||
(1 << 2) | //opcode
|
(1 << 2) | //opcode
|
||||||
(C67_map_regs(b) << 1) | //side of dst
|
(C67_map_regs(b) << 1) | //side of dst
|
||||||
(0 << 0)); //parallel
|
(0 << 0)); //parallel
|
||||||
|
|
@ -877,7 +877,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
C67_g((0 << 29) | //creg
|
C67_g((0 << 29) | //creg
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2
|
(C67_map_regn(b) << 18) | //src2
|
||||||
(0 << 13) | //src1 NA
|
(0 << 13) | //src1 NA
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x4a << 5) | //opcode
|
(0x4a << 5) | //opcode
|
||||||
|
|
@ -890,7 +890,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
C67_g((0 << 29) | //creg
|
C67_g((0 << 29) | //creg
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2
|
(C67_map_regn(b) << 18) | //src2
|
||||||
(0 << 13) | //src1 NA
|
(0 << 13) | //src1 NA
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x49 << 5) | //opcode
|
(0x49 << 5) | //opcode
|
||||||
|
|
@ -903,7 +903,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
C67_g((0 << 29) | //creg
|
C67_g((0 << 29) | //creg
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2
|
(C67_map_regn(b) << 18) | //src2
|
||||||
(0 << 13) | //src1 NA
|
(0 << 13) | //src1 NA
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x39 << 5) | //opcode
|
(0x39 << 5) | //opcode
|
||||||
|
|
@ -958,7 +958,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x3 << 5) | //opcode
|
(0x3 << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -973,7 +973,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x7 << 5) | //opcode
|
(0x7 << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -988,7 +988,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x7f << 5) | //opcode
|
(0x7f << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1003,7 +1003,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x7b << 5) | //opcode
|
(0x7b << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1018,7 +1018,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x6f << 5) | //opcode
|
(0x6f << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1033,7 +1033,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x10 << 5) | //opcode
|
(0x10 << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1048,7 +1048,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x18 << 5) | //opcode
|
(0x18 << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1063,7 +1063,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x11 << 5) | //opcode
|
(0x11 << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1078,7 +1078,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x19 << 5) | //opcode
|
(0x19 << 5) | //opcode
|
||||||
(0x6 << 2) | //opcode fixed
|
(0x6 << 2) | //opcode fixed
|
||||||
|
|
@ -1093,7 +1093,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x1c << 7) | //opcode
|
(0x1c << 7) | //opcode
|
||||||
(0x0 << 2) | //opcode fixed
|
(0x0 << 2) | //opcode fixed
|
||||||
|
|
@ -1108,7 +1108,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
(C67_map_regn(b) << 18) | //src2 (possible x path)
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x0e << 7) | //opcode
|
(0x0e << 7) | //opcode
|
||||||
(0x0 << 2) | //opcode fixed
|
(0x0 << 2) | //opcode fixed
|
||||||
|
|
@ -1138,7 +1138,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2
|
(C67_map_regn(b) << 18) | //src2
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x37 << 6) | //opcode
|
(0x37 << 6) | //opcode
|
||||||
(0x8 << 2) | //opcode fixed
|
(0x8 << 2) | //opcode fixed
|
||||||
|
|
@ -1153,7 +1153,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2
|
(C67_map_regn(b) << 18) | //src2
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x27 << 6) | //opcode
|
(0x27 << 6) | //opcode
|
||||||
(0x8 << 2) | //opcode fixed
|
(0x8 << 2) | //opcode fixed
|
||||||
|
|
@ -1168,7 +1168,7 @@ void C67_asm(char *s, int a, int b, int c)
|
||||||
(0 << 28) | //inv
|
(0 << 28) | //inv
|
||||||
(C67_map_regn(c) << 23) | //dst
|
(C67_map_regn(c) << 23) | //dst
|
||||||
(C67_map_regn(b) << 18) | //src2
|
(C67_map_regn(b) << 18) | //src2
|
||||||
(C67_map_regn(a) << 13) | //src1
|
(C67_map_regn(a) << 13) | //src1
|
||||||
(xpath << 12) | //x cross path if opposite sides
|
(xpath << 12) | //x cross path if opposite sides
|
||||||
(0x33 << 6) | //opcode
|
(0x33 << 6) | //opcode
|
||||||
(0x8 << 2) | //opcode fixed
|
(0x8 << 2) | //opcode fixed
|
||||||
|
|
@ -1597,7 +1597,7 @@ void load(int r, SValue * sv)
|
||||||
size = 4;
|
size = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if fc is a positive reference on the stack,
|
// check if fc is a positive reference on the stack,
|
||||||
// if it is tcc is referencing what it thinks is a parameter
|
// if it is tcc is referencing what it thinks is a parameter
|
||||||
// on the stack, so check if it is really in a register.
|
// on the stack, so check if it is really in a register.
|
||||||
|
|
||||||
|
|
@ -1962,7 +1962,7 @@ void gfunc_call(int nb_args)
|
||||||
// ending with B12:B13.
|
// ending with B12:B13.
|
||||||
//
|
//
|
||||||
// When a call is made, if the caller has its parameters
|
// When a call is made, if the caller has its parameters
|
||||||
// in regs A4-B13 these must be saved before/as the call
|
// in regs A4-B13 these must be saved before/as the call
|
||||||
// parameters are loaded and restored upon return (or if/when needed).
|
// parameters are loaded and restored upon return (or if/when needed).
|
||||||
|
|
||||||
/* generate function prolog of type 't' */
|
/* generate function prolog of type 't' */
|
||||||
|
|
@ -2033,7 +2033,7 @@ void gfunc_prolog(CType * func_type)
|
||||||
|
|
||||||
TotalBytesPushedOnStack = -loc;
|
TotalBytesPushedOnStack = -loc;
|
||||||
|
|
||||||
func_sub_sp_offset = ind; // remember where we put the stack instruction
|
func_sub_sp_offset = ind; // remember where we put the stack instruction
|
||||||
C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
|
C67_ADDK(0, C67_SP); // ADDK.L2 loc,SP (just put zero temporarily)
|
||||||
|
|
||||||
C67_PUSH(C67_A0);
|
C67_PUSH(C67_A0);
|
||||||
|
|
@ -2049,11 +2049,11 @@ void gfunc_epilog(void)
|
||||||
C67_NOP(4); // NOP wait for load
|
C67_NOP(4); // NOP wait for load
|
||||||
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
|
C67_IREG_B_REG(0, C67_CREG_ZERO, C67_B3); // B.S2 B3
|
||||||
C67_POP(C67_FP);
|
C67_POP(C67_FP);
|
||||||
C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
|
C67_ADDK(local, C67_SP); // ADDK.L2 loc,SP
|
||||||
C67_Adjust_ADDK((int *) (cur_text_section->data +
|
C67_Adjust_ADDK((int *) (cur_text_section->data +
|
||||||
func_sub_sp_offset),
|
func_sub_sp_offset),
|
||||||
-local + TotalBytesPushedOnStack);
|
-local + TotalBytesPushedOnStack);
|
||||||
C67_NOP(3); // NOP
|
C67_NOP(3); // NOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
12
coff.h
12
coff.h
|
|
@ -31,9 +31,9 @@ struct filehdr {
|
||||||
#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
|
#define F_LITTLE 0x100 /* byte ordering of an AR32WR (vax) */
|
||||||
#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
|
#define F_BIG 0x200 /* byte ordering of an AR32W (3B, maxi) */
|
||||||
#define F_PATCH 0x400 /* contains "patch" list in optional header */
|
#define F_PATCH 0x400 /* contains "patch" list in optional header */
|
||||||
#define F_NODF 0x400
|
#define F_NODF 0x400
|
||||||
|
|
||||||
#define F_VERSION (F_GSP10 | F_GSP20)
|
#define F_VERSION (F_GSP10 | F_GSP20)
|
||||||
#define F_BYTE_ORDER (F_LITTLE | F_BIG)
|
#define F_BYTE_ORDER (F_LITTLE | F_BIG)
|
||||||
#define FILHDR struct filehdr
|
#define FILHDR struct filehdr
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ typedef struct aouthdr {
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
/* When a UNIX aout header is to be built in the optional header, */
|
/* When a UNIX aout header is to be built in the optional header, */
|
||||||
/* the following magic numbers can appear in that header: */
|
/* the following magic numbers can appear in that header: */
|
||||||
/* */
|
/* */
|
||||||
/* AOUT1MAGIC : default : readonly sharable text segment */
|
/* AOUT1MAGIC : default : readonly sharable text segment */
|
||||||
/* AOUT2MAGIC: : writable text segment */
|
/* AOUT2MAGIC: : writable text segment */
|
||||||
|
|
@ -164,7 +164,7 @@ struct scnhdr {
|
||||||
#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
|
#define STYP_NOLOAD 0x02 /* "noload" : allocated, relocated, not loaded */
|
||||||
#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
|
#define STYP_GROUP 0x04 /* "grouped" : formed of input sections */
|
||||||
#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */
|
#define STYP_PAD 0x08 /* "padding" : not allocated, not relocated, loaded */
|
||||||
#define STYP_COPY 0x10 /* "copy" : used for C init tables -
|
#define STYP_COPY 0x10 /* "copy" : used for C init tables -
|
||||||
not allocated, relocated,
|
not allocated, relocated,
|
||||||
loaded; reloc & lineno
|
loaded; reloc & lineno
|
||||||
entries processed normally */
|
entries processed normally */
|
||||||
|
|
@ -358,11 +358,11 @@ struct syment
|
||||||
#define N_BTSHFT_COFF 4
|
#define N_BTSHFT_COFF 4
|
||||||
#define N_TSHIFT_COFF 2
|
#define N_TSHIFT_COFF 2
|
||||||
|
|
||||||
#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF)
|
#define BTYPE_COFF(x) ((x) & N_BTMASK_COFF)
|
||||||
#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \
|
#define ISINT(x) (((x) >= T_CHAR && (x) <= T_LONG) || \
|
||||||
((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
|
((x) >= T_UCHAR && (x) <= T_ULONG) || (x) == T_ENUM)
|
||||||
#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT)
|
#define ISFLT_COFF(x) ((x) == T_DOUBLE || (x) == T_FLOAT)
|
||||||
#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF))
|
#define ISPTR_COFF(x) (((x) & N_TMASK_COFF) == (DT_PTR << N_BTSHFT_COFF))
|
||||||
#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
|
#define ISFCN_COFF(x) (((x) & N_TMASK_COFF) == (DT_FCN << N_BTSHFT_COFF))
|
||||||
#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
|
#define ISARY_COFF(x) (((x) & N_TMASK_COFF) == (DT_ARY << N_BTSHFT_COFF))
|
||||||
#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
|
#define ISTAG_COFF(x) ((x)==C_STRTAG || (x)==C_UNTAG || (x)==C_ENTAG)
|
||||||
|
|
|
||||||
2
configure
vendored
2
configure
vendored
|
|
@ -66,7 +66,7 @@ case $targetos in
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# find source path
|
# find source path
|
||||||
# XXX: we assume an absolute path is given when launching configure,
|
# XXX: we assume an absolute path is given when launching configure,
|
||||||
# except in './configure' case.
|
# except in './configure' case.
|
||||||
source_path=${0%configure}
|
source_path=${0%configure}
|
||||||
source_path=${source_path%/}
|
source_path=${source_path%/}
|
||||||
|
|
|
||||||
|
|
@ -712,7 +712,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
||||||
a32 = addr32 = 1;
|
a32 = addr32 = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (b & 0xff00)
|
if (b & 0xff00)
|
||||||
g(b >> 8);
|
g(b >> 8);
|
||||||
g(b);
|
g(b);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
10
i386-asm.h
10
i386-asm.h
|
|
@ -57,7 +57,7 @@ ALT(DEF_ASM_OP0L(stosb, 0xaa, 0, OPC_BWL))
|
||||||
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
|
ALT(DEF_ASM_OP0L(sstob, 0xaa, 0, OPC_BWL))
|
||||||
|
|
||||||
/* bits */
|
/* bits */
|
||||||
|
|
||||||
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
|
ALT(DEF_ASM_OP2(bsfw, 0x0fbc, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
|
||||||
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
|
ALT(DEF_ASM_OP2(bsrw, 0x0fbd, 0, OPC_MODRM | OPC_WL, OPT_REGW | OPT_EA, OPT_REGW))
|
||||||
|
|
||||||
|
|
@ -91,7 +91,7 @@ ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)
|
||||||
DEF_ASM_OP0(repz, 0xf3)
|
DEF_ASM_OP0(repz, 0xf3)
|
||||||
DEF_ASM_OP0(repne, 0xf2)
|
DEF_ASM_OP0(repne, 0xf2)
|
||||||
DEF_ASM_OP0(repnz, 0xf2)
|
DEF_ASM_OP0(repnz, 0xf2)
|
||||||
|
|
||||||
DEF_ASM_OP0(invd, 0x0f08)
|
DEF_ASM_OP0(invd, 0x0f08)
|
||||||
DEF_ASM_OP0(wbinvd, 0x0f09)
|
DEF_ASM_OP0(wbinvd, 0x0f09)
|
||||||
DEF_ASM_OP0(cpuid, 0x0fa2)
|
DEF_ASM_OP0(cpuid, 0x0fa2)
|
||||||
|
|
@ -236,7 +236,7 @@ ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP | OPC_TEST, OPT_ADDR))
|
||||||
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||||
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||||
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
|
||||||
|
|
||||||
/* float */
|
/* float */
|
||||||
/* specific fcomp handling */
|
/* specific fcomp handling */
|
||||||
ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
|
ALT(DEF_ASM_OP0L(fcomp, 0xd8d9, 0, 0))
|
||||||
|
|
@ -298,7 +298,7 @@ ALT(DEF_ASM_OP1(fldl, 0xdd, 0, OPC_MODRM, OPT_EA))
|
||||||
DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
|
DEF_ASM_OP1(fildll, 0xdf, 5, OPC_MODRM,OPT_EA)
|
||||||
DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
|
DEF_ASM_OP1(fldt, 0xdb, 5, OPC_MODRM, OPT_EA)
|
||||||
DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
|
DEF_ASM_OP1(fbld, 0xdf, 4, OPC_MODRM, OPT_EA)
|
||||||
|
|
||||||
/* fp store */
|
/* fp store */
|
||||||
DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
|
DEF_ASM_OP1(fst, 0xddd0, 0, OPC_REG, OPT_ST)
|
||||||
DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
|
DEF_ASM_OP1(fstl, 0xddd0, 0, OPC_REG, OPT_ST)
|
||||||
|
|
@ -380,7 +380,7 @@ ALT(DEF_ASM_OP2(cmpxchgb, 0x0fb0, 0, OPC_MODRM | OPC_BWL, OPT_REG, OPT_REG | OPT
|
||||||
|
|
||||||
/* pentium */
|
/* pentium */
|
||||||
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
|
DEF_ASM_OP1(cmpxchg8b, 0x0fc7, 1, OPC_MODRM, OPT_EA )
|
||||||
|
|
||||||
/* pentium pro */
|
/* pentium pro */
|
||||||
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
|
ALT(DEF_ASM_OP2(cmovo, 0x0f40, 0, OPC_MODRM | OPC_TEST, OPT_REG32 | OPT_EA, OPT_REG32))
|
||||||
#ifdef I386_ASM_16
|
#ifdef I386_ASM_16
|
||||||
|
|
|
||||||
24
i386-gen.c
24
i386-gen.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* X86 code generator for TCC
|
* X86 code generator for TCC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -32,7 +32,7 @@ typedef int RegArgs;
|
||||||
#define RC_INT 0x0001 /* generic integer register */
|
#define RC_INT 0x0001 /* generic integer register */
|
||||||
#define RC_FLOAT 0x0002 /* generic float register */
|
#define RC_FLOAT 0x0002 /* generic float register */
|
||||||
#define RC_EAX 0x0004
|
#define RC_EAX 0x0004
|
||||||
#define RC_ST0 0x0008
|
#define RC_ST0 0x0008
|
||||||
#define RC_ECX 0x0010
|
#define RC_ECX 0x0010
|
||||||
#define RC_EDX 0x0020
|
#define RC_EDX 0x0020
|
||||||
#define RC_IRET RC_EAX /* function return: integer register */
|
#define RC_IRET RC_EAX /* function return: integer register */
|
||||||
|
|
@ -357,11 +357,11 @@ static void gcall_or_jmp(int is_jmp)
|
||||||
/* constant case */
|
/* constant case */
|
||||||
if (vtop->r & VT_SYM) {
|
if (vtop->r & VT_SYM) {
|
||||||
/* relocation case */
|
/* relocation case */
|
||||||
greloc(cur_text_section, vtop->sym,
|
greloc(cur_text_section, vtop->sym,
|
||||||
ind + 1, R_386_PC32);
|
ind + 1, R_386_PC32);
|
||||||
} else {
|
} else {
|
||||||
/* put an empty PC32 relocation */
|
/* put an empty PC32 relocation */
|
||||||
put_elf_reloc(symtab_section, cur_text_section,
|
put_elf_reloc(symtab_section, cur_text_section,
|
||||||
ind + 1, R_386_PC32, 0);
|
ind + 1, R_386_PC32, 0);
|
||||||
}
|
}
|
||||||
oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
|
oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
|
||||||
|
|
@ -417,7 +417,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
||||||
{
|
{
|
||||||
int size, align, r, args_size, i, func_call;
|
int size, align, r, args_size, i, func_call;
|
||||||
Sym *func_sym;
|
Sym *func_sym;
|
||||||
|
|
||||||
args_size = 0;
|
args_size = 0;
|
||||||
for(i = 0;i < nb_args; i++) {
|
for(i = 0;i < nb_args; i++) {
|
||||||
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
|
|
@ -610,7 +610,7 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
/* generate bound local allocation */
|
/* generate bound local allocation */
|
||||||
saved_ind = ind;
|
saved_ind = ind;
|
||||||
ind = func_sub_sp_offset;
|
ind = func_sub_sp_offset;
|
||||||
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
sym_data = get_sym_ref(&char_pointer_type, lbounds_section,
|
||||||
func_bound_offset, lbounds_section->data_offset);
|
func_bound_offset, lbounds_section->data_offset);
|
||||||
greloc(cur_text_section, sym_data,
|
greloc(cur_text_section, sym_data,
|
||||||
ind + 1, R_386_32);
|
ind + 1, R_386_32);
|
||||||
|
|
@ -637,8 +637,8 @@ ST_FUNC void gfunc_epilog(void)
|
||||||
g(func_ret_sub >> 8);
|
g(func_ret_sub >> 8);
|
||||||
}
|
}
|
||||||
/* align local size to word & save local variables */
|
/* align local size to word & save local variables */
|
||||||
|
|
||||||
v = (-loc + 3) & -4;
|
v = (-loc + 3) & -4;
|
||||||
saved_ind = ind;
|
saved_ind = ind;
|
||||||
ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
|
|
@ -741,7 +741,7 @@ ST_FUNC void gen_opi(int op)
|
||||||
r = vtop[-1].r;
|
r = vtop[-1].r;
|
||||||
fr = vtop[0].r;
|
fr = vtop[0].r;
|
||||||
o((opc << 3) | 0x01);
|
o((opc << 3) | 0x01);
|
||||||
o(0xc0 + r + fr * 8);
|
o(0xc0 + r + fr * 8);
|
||||||
}
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
if (op >= TOK_ULT && op <= TOK_GT) {
|
if (op >= TOK_ULT && op <= TOK_GT) {
|
||||||
|
|
@ -911,7 +911,7 @@ ST_FUNC void gen_opf(int op)
|
||||||
load(TREG_ST0, vtop);
|
load(TREG_ST0, vtop);
|
||||||
swapped = !swapped;
|
swapped = !swapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(op) {
|
switch(op) {
|
||||||
default:
|
default:
|
||||||
case '+':
|
case '+':
|
||||||
|
|
@ -972,7 +972,7 @@ ST_FUNC void gen_cvt_itof(int t)
|
||||||
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
|
o(0x50 + (vtop->r & VT_VALMASK)); /* push r */
|
||||||
o(0x242cdf); /* fildll (%esp) */
|
o(0x242cdf); /* fildll (%esp) */
|
||||||
o(0x08c483); /* add $8, %esp */
|
o(0x08c483); /* add $8, %esp */
|
||||||
} else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
} else if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||||
(VT_INT | VT_UNSIGNED)) {
|
(VT_INT | VT_UNSIGNED)) {
|
||||||
/* unsigned int to float/double/long double */
|
/* unsigned int to float/double/long double */
|
||||||
o(0x6a); /* push $0 */
|
o(0x6a); /* push $0 */
|
||||||
|
|
@ -1060,7 +1060,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
|
||||||
vtop++;
|
vtop++;
|
||||||
vtop->r = TREG_EAX | VT_BOUNDED;
|
vtop->r = TREG_EAX | VT_BOUNDED;
|
||||||
/* address of bounding function call point */
|
/* address of bounding function call point */
|
||||||
vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
|
vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch pointer addition in vtop so that pointer dereferencing is
|
/* patch pointer addition in vtop so that pointer dereferencing is
|
||||||
|
|
|
||||||
14
il-gen.c
14
il-gen.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* CIL code generator for TCC
|
* CIL code generator for TCC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002 Fabrice Bellard
|
* Copyright (c) 2002 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -112,7 +112,7 @@ static void init_outfile(void)
|
||||||
{
|
{
|
||||||
if (!il_outfile) {
|
if (!il_outfile) {
|
||||||
il_outfile = stdout;
|
il_outfile = stdout;
|
||||||
fprintf(il_outfile,
|
fprintf(il_outfile,
|
||||||
".assembly extern mscorlib\n"
|
".assembly extern mscorlib\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
".ver 1:0:2411:0\n"
|
".ver 1:0:2411:0\n"
|
||||||
|
|
@ -149,7 +149,7 @@ static void out_opi(int op, int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: not complete */
|
/* XXX: not complete */
|
||||||
static void il_type_to_str(char *buf, int buf_size,
|
static void il_type_to_str(char *buf, int buf_size,
|
||||||
int t, const char *varstr)
|
int t, const char *varstr)
|
||||||
{
|
{
|
||||||
int bt;
|
int bt;
|
||||||
|
|
@ -301,12 +301,12 @@ void load(int r, SValue *sv)
|
||||||
out_op(IL_OP_LDIND_U2);
|
out_op(IL_OP_LDIND_U2);
|
||||||
else
|
else
|
||||||
out_op(IL_OP_LDIND_I4);
|
out_op(IL_OP_LDIND_I4);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (v == VT_CONST) {
|
if (v == VT_CONST) {
|
||||||
/* XXX: handle globals */
|
/* XXX: handle globals */
|
||||||
if (fc >= -1 && fc <= 8) {
|
if (fc >= -1 && fc <= 8) {
|
||||||
out_op(IL_OP_LDC_I4_M1 + fc + 1);
|
out_op(IL_OP_LDC_I4_M1 + fc + 1);
|
||||||
} else {
|
} else {
|
||||||
out_opi(IL_OP_LDC_I4, fc);
|
out_opi(IL_OP_LDC_I4, fc);
|
||||||
}
|
}
|
||||||
|
|
@ -430,10 +430,10 @@ void gfunc_prolog(int t)
|
||||||
/* XXX: cannot do better now */
|
/* XXX: cannot do better now */
|
||||||
fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
|
fprintf(il_outfile, " .maxstack %d\n", NB_REGS);
|
||||||
fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
|
fprintf(il_outfile, " .locals (int32, int32, int32, int32, int32, int32, int32, int32)\n");
|
||||||
|
|
||||||
if (!strcmp(funcname, "main"))
|
if (!strcmp(funcname, "main"))
|
||||||
fprintf(il_outfile, " .entrypoint\n");
|
fprintf(il_outfile, " .entrypoint\n");
|
||||||
|
|
||||||
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
sym = sym_find((unsigned)t >> VT_STRUCT_SHIFT);
|
||||||
func_call = sym->r;
|
func_call = sym->r;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* CIL opcode definition
|
* CIL opcode definition
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002 Fabrice Bellard
|
* Copyright (c) 2002 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
|
|
||||||
56
lib/bcheck.c
56
lib/bcheck.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Tiny C Memory and bounds checker
|
* Tiny C Memory and bounds checker
|
||||||
*
|
*
|
||||||
* Copyright (c) 2002 Fabrice Bellard
|
* Copyright (c) 2002 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -88,7 +88,7 @@ int __bound_delete_region(void *p);
|
||||||
|
|
||||||
#ifdef __attribute__
|
#ifdef __attribute__
|
||||||
/* an __attribute__ macro is defined in the system headers */
|
/* an __attribute__ macro is defined in the system headers */
|
||||||
#undef __attribute__
|
#undef __attribute__
|
||||||
#endif
|
#endif
|
||||||
#define FASTCALL __attribute__((regparm(3)))
|
#define FASTCALL __attribute__((regparm(3)))
|
||||||
|
|
||||||
|
|
@ -177,8 +177,8 @@ void * FASTCALL __bound_ptr_add(void *p, size_t offset)
|
||||||
dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset);
|
dprintf(stderr, "%s %s: %p %p\n", __FILE__, __FUNCTION__, p, offset);
|
||||||
|
|
||||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||||
e = (BoundEntry *)((char *)e +
|
e = (BoundEntry *)((char *)e +
|
||||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
||||||
addr -= e->start;
|
addr -= e->start;
|
||||||
if (addr > e->size) {
|
if (addr > e->size) {
|
||||||
|
|
@ -236,7 +236,7 @@ BOUND_PTR_INDIR(16)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called when entering a function to add all the local regions */
|
/* called when entering a function to add all the local regions */
|
||||||
void FASTCALL __bound_local_new(void *p1)
|
void FASTCALL __bound_local_new(void *p1)
|
||||||
{
|
{
|
||||||
size_t addr, size, fp, *p = p1;
|
size_t addr, size, fp, *p = p1;
|
||||||
|
|
||||||
|
|
@ -255,7 +255,7 @@ void FASTCALL __bound_local_new(void *p1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called when leaving a function to delete all the local regions */
|
/* called when leaving a function to delete all the local regions */
|
||||||
void FASTCALL __bound_local_delete(void *p1)
|
void FASTCALL __bound_local_delete(void *p1)
|
||||||
{
|
{
|
||||||
size_t addr, fp, *p = p1;
|
size_t addr, fp, *p = p1;
|
||||||
GET_CALLER_FP(fp);
|
GET_CALLER_FP(fp);
|
||||||
|
|
@ -331,14 +331,14 @@ static void mark_invalid(size_t addr, size_t size)
|
||||||
#if 0
|
#if 0
|
||||||
dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
|
dprintf(stderr, "mark_invalid: start = %x %x\n", t2_start, t2_end);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* first we handle full pages */
|
/* first we handle full pages */
|
||||||
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
|
t1_start = (t2_start + BOUND_T2_SIZE - 1) >> BOUND_T2_BITS;
|
||||||
t1_end = t2_end >> BOUND_T2_BITS;
|
t1_end = t2_end >> BOUND_T2_BITS;
|
||||||
|
|
||||||
i = t2_start & (BOUND_T2_SIZE - 1);
|
i = t2_start & (BOUND_T2_SIZE - 1);
|
||||||
j = t2_end & (BOUND_T2_SIZE - 1);
|
j = t2_end & (BOUND_T2_SIZE - 1);
|
||||||
|
|
||||||
if (t1_start == t1_end) {
|
if (t1_start == t1_end) {
|
||||||
page = get_page(t2_start >> BOUND_T2_BITS);
|
page = get_page(t2_start >> BOUND_T2_BITS);
|
||||||
for(; i < j; i++) {
|
for(; i < j; i++) {
|
||||||
|
|
@ -456,7 +456,7 @@ void __bound_main_arg(void **p)
|
||||||
void *start = p;
|
void *start = p;
|
||||||
while (*p++);
|
while (*p++);
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
|
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
|
||||||
__FILE__, __FUNCTION__, (void *) p - start);
|
__FILE__, __FUNCTION__, (void *) p - start);
|
||||||
|
|
||||||
__bound_new_region(start, (void *) p - start);
|
__bound_new_region(start, (void *) p - start);
|
||||||
|
|
@ -467,7 +467,7 @@ void __bound_exit(void)
|
||||||
restore_malloc_hooks();
|
restore_malloc_hooks();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void add_region(BoundEntry *e,
|
static inline void add_region(BoundEntry *e,
|
||||||
size_t start, size_t size)
|
size_t start, size_t size)
|
||||||
{
|
{
|
||||||
BoundEntry *e1;
|
BoundEntry *e1;
|
||||||
|
|
@ -496,7 +496,7 @@ void __bound_new_region(void *p, size_t size)
|
||||||
|
|
||||||
__bound_init();
|
__bound_init();
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s(%p, %p) start\n",
|
dprintf(stderr, "%s, %s(%p, %p) start\n",
|
||||||
__FILE__, __FUNCTION__, p, size);
|
__FILE__, __FUNCTION__, p, size);
|
||||||
|
|
||||||
start = (size_t)p;
|
start = (size_t)p;
|
||||||
|
|
@ -506,9 +506,9 @@ void __bound_new_region(void *p, size_t size)
|
||||||
|
|
||||||
/* start */
|
/* start */
|
||||||
page = get_page(t1_start);
|
page = get_page(t1_start);
|
||||||
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||||
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -557,7 +557,7 @@ void __bound_new_region(void *p, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete a region */
|
/* delete a region */
|
||||||
static inline void delete_region(BoundEntry *e,
|
static inline void delete_region(BoundEntry *e,
|
||||||
void *p, size_t empty_size)
|
void *p, size_t empty_size)
|
||||||
{
|
{
|
||||||
size_t addr;
|
size_t addr;
|
||||||
|
|
@ -612,9 +612,9 @@ int __bound_delete_region(void *p)
|
||||||
|
|
||||||
start = (size_t)p;
|
start = (size_t)p;
|
||||||
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
t1_start = start >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||||
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
t2_start = (start >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||||
|
|
||||||
/* find region size */
|
/* find region size */
|
||||||
page = __bound_t1[t1_start];
|
page = __bound_t1[t1_start];
|
||||||
e = (BoundEntry *)((char *)page + t2_start);
|
e = (BoundEntry *)((char *)page + t2_start);
|
||||||
|
|
@ -622,7 +622,7 @@ int __bound_delete_region(void *p)
|
||||||
if (addr > e->size)
|
if (addr > e->size)
|
||||||
e = __bound_find_region(e, p);
|
e = __bound_find_region(e, p);
|
||||||
/* test if invalid region */
|
/* test if invalid region */
|
||||||
if (e->size == EMPTY_SIZE || (size_t)p != e->start)
|
if (e->size == EMPTY_SIZE || (size_t)p != e->start)
|
||||||
return -1;
|
return -1;
|
||||||
/* compute the size we put in invalid regions */
|
/* compute the size we put in invalid regions */
|
||||||
if (e->is_invalid)
|
if (e->is_invalid)
|
||||||
|
|
@ -634,7 +634,7 @@ int __bound_delete_region(void *p)
|
||||||
|
|
||||||
/* now we can free each entry */
|
/* now we can free each entry */
|
||||||
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
t1_end = end >> (BOUND_T2_BITS + BOUND_T3_BITS);
|
||||||
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
t2_end = (end >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS);
|
||||||
|
|
||||||
delete_region(e, p, empty_size);
|
delete_region(e, p, empty_size);
|
||||||
|
|
@ -690,8 +690,8 @@ static size_t get_region_size(void *p)
|
||||||
BoundEntry *e;
|
BoundEntry *e;
|
||||||
|
|
||||||
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
e = __bound_t1[addr >> (BOUND_T2_BITS + BOUND_T3_BITS)];
|
||||||
e = (BoundEntry *)((char *)e +
|
e = (BoundEntry *)((char *)e +
|
||||||
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
((addr >> (BOUND_T3_BITS - BOUND_E_BITS)) &
|
||||||
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
((BOUND_T2_SIZE - 1) << BOUND_E_BITS)));
|
||||||
addr -= e->start;
|
addr -= e->start;
|
||||||
if (addr > e->size)
|
if (addr > e->size)
|
||||||
|
|
@ -756,16 +756,16 @@ static void libc_free(void *ptr)
|
||||||
void *__bound_malloc(size_t size, const void *caller)
|
void *__bound_malloc(size_t size, const void *caller)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
/* we allocate one more byte to ensure the regions will be
|
/* we allocate one more byte to ensure the regions will be
|
||||||
separated by at least one byte. With the glibc malloc, it may
|
separated by at least one byte. With the glibc malloc, it may
|
||||||
be in fact not necessary */
|
be in fact not necessary */
|
||||||
ptr = libc_malloc(size + 1);
|
ptr = libc_malloc(size + 1);
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
|
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
|
||||||
__FILE__, __FUNCTION__, ptr, size);
|
__FILE__, __FUNCTION__, ptr, size);
|
||||||
|
|
||||||
__bound_new_region(ptr, size);
|
__bound_new_region(ptr, size);
|
||||||
|
|
@ -792,13 +792,13 @@ void *__bound_memalign(size_t size, size_t align, const void *caller)
|
||||||
be in fact not necessary */
|
be in fact not necessary */
|
||||||
ptr = memalign(size + 1, align);
|
ptr = memalign(size + 1, align);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
install_malloc_hooks();
|
install_malloc_hooks();
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
|
dprintf(stderr, "%s, %s calling __bound_new_region(%p, %p)\n",
|
||||||
__FILE__, __FUNCTION__, ptr, size);
|
__FILE__, __FUNCTION__, ptr, size);
|
||||||
|
|
||||||
__bound_new_region(ptr, size);
|
__bound_new_region(ptr, size);
|
||||||
|
|
@ -862,8 +862,8 @@ static void bound_dump(void)
|
||||||
e = page + j;
|
e = page + j;
|
||||||
/* do not print invalid or empty entries */
|
/* do not print invalid or empty entries */
|
||||||
if (e->size != EMPTY_SIZE && e->start != 0) {
|
if (e->size != EMPTY_SIZE && e->start != 0) {
|
||||||
fprintf(stderr, "%08x:",
|
fprintf(stderr, "%08x:",
|
||||||
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
|
(i << (BOUND_T2_BITS + BOUND_T3_BITS)) +
|
||||||
(j << BOUND_T3_BITS));
|
(j << BOUND_T3_BITS));
|
||||||
do {
|
do {
|
||||||
fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
|
fprintf(stderr, " %08lx:%08lx", e->start, e->start + e->size);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* TCC runtime library.
|
/* TCC runtime library.
|
||||||
Parts of this code are (c) 2002 Fabrice Bellard
|
Parts of this code are (c) 2002 Fabrice Bellard
|
||||||
|
|
||||||
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
|
Copyright (C) 1987, 1988, 1992, 1994, 1995 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; see the file COPYING. If not, write to
|
along with this program; see the file COPYING. If not, write to
|
||||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA.
|
Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
@ -370,10 +370,10 @@ long long __divdi3(long long u, long long v)
|
||||||
int c = 0;
|
int c = 0;
|
||||||
DWunion uu, vv;
|
DWunion uu, vv;
|
||||||
DWtype w;
|
DWtype w;
|
||||||
|
|
||||||
uu.ll = u;
|
uu.ll = u;
|
||||||
vv.ll = v;
|
vv.ll = v;
|
||||||
|
|
||||||
if (uu.s.high < 0) {
|
if (uu.s.high < 0) {
|
||||||
c = ~c;
|
c = ~c;
|
||||||
uu.ll = __negdi2 (uu.ll);
|
uu.ll = __negdi2 (uu.ll);
|
||||||
|
|
@ -393,17 +393,17 @@ long long __moddi3(long long u, long long v)
|
||||||
int c = 0;
|
int c = 0;
|
||||||
DWunion uu, vv;
|
DWunion uu, vv;
|
||||||
DWtype w;
|
DWtype w;
|
||||||
|
|
||||||
uu.ll = u;
|
uu.ll = u;
|
||||||
vv.ll = v;
|
vv.ll = v;
|
||||||
|
|
||||||
if (uu.s.high < 0) {
|
if (uu.s.high < 0) {
|
||||||
c = ~c;
|
c = ~c;
|
||||||
uu.ll = __negdi2 (uu.ll);
|
uu.ll = __negdi2 (uu.ll);
|
||||||
}
|
}
|
||||||
if (vv.s.high < 0)
|
if (vv.s.high < 0)
|
||||||
vv.ll = __negdi2 (vv.ll);
|
vv.ll = __negdi2 (vv.ll);
|
||||||
|
|
||||||
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
|
__udivmoddi4 (uu.ll, vv.ll, (UDWtype *) &w);
|
||||||
if (c)
|
if (c)
|
||||||
w = __negdi2 (w);
|
w = __negdi2 (w);
|
||||||
|
|
@ -418,7 +418,7 @@ unsigned long long __udivdi3(unsigned long long u, unsigned long long v)
|
||||||
unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
|
unsigned long long __umoddi3(unsigned long long u, unsigned long long v)
|
||||||
{
|
{
|
||||||
UDWtype w;
|
UDWtype w;
|
||||||
|
|
||||||
__udivmoddi4 (u, v, &w);
|
__udivmoddi4 (u, v, &w);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
@ -499,7 +499,7 @@ long long __tcc_cvt_ftol(long double x)
|
||||||
/* XXX: fix tcc's code generator to do this instead */
|
/* XXX: fix tcc's code generator to do this instead */
|
||||||
float __floatundisf(unsigned long long a)
|
float __floatundisf(unsigned long long a)
|
||||||
{
|
{
|
||||||
DWunion uu;
|
DWunion uu;
|
||||||
XFtype r;
|
XFtype r;
|
||||||
|
|
||||||
uu.ll = a;
|
uu.ll = a;
|
||||||
|
|
@ -514,7 +514,7 @@ float __floatundisf(unsigned long long a)
|
||||||
|
|
||||||
double __floatundidf(unsigned long long a)
|
double __floatundidf(unsigned long long a)
|
||||||
{
|
{
|
||||||
DWunion uu;
|
DWunion uu;
|
||||||
XFtype r;
|
XFtype r;
|
||||||
|
|
||||||
uu.ll = a;
|
uu.ll = a;
|
||||||
|
|
@ -529,7 +529,7 @@ double __floatundidf(unsigned long long a)
|
||||||
|
|
||||||
long double __floatundixf(unsigned long long a)
|
long double __floatundixf(unsigned long long a)
|
||||||
{
|
{
|
||||||
DWunion uu;
|
DWunion uu;
|
||||||
XFtype r;
|
XFtype r;
|
||||||
|
|
||||||
uu.ll = a;
|
uu.ll = a;
|
||||||
|
|
@ -608,7 +608,7 @@ unsigned long long __fixunsxfdi (long double a1)
|
||||||
|
|
||||||
if (exp > 0)
|
if (exp > 0)
|
||||||
return (unsigned long long)-1;
|
return (unsigned long long)-1;
|
||||||
else if (exp >= -63)
|
else if (exp >= -63)
|
||||||
return l >> -exp;
|
return l >> -exp;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
2
libtcc.c
2
libtcc.c
|
|
@ -318,7 +318,7 @@ PUB_FUNC void tcc_free_debug(void *ptr)
|
||||||
|
|
||||||
mem_cur_size -= header->size;
|
mem_cur_size -= header->size;
|
||||||
header->size = (size_t)-1;
|
header->size = (size_t)-1;
|
||||||
|
|
||||||
if (header->next)
|
if (header->next)
|
||||||
header->next->prev = header->prev;
|
header->next->prev = header->prev;
|
||||||
|
|
||||||
|
|
|
||||||
46
tcc-doc.texi
46
tcc-doc.texi
|
|
@ -99,9 +99,9 @@ the @code{main()} of a.c.
|
||||||
|
|
||||||
@item @samp{tcc a.c -run b.c arg1}
|
@item @samp{tcc a.c -run b.c arg1}
|
||||||
Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
|
Compile @file{a.c} and @file{b.c}, link them together and execute them. arg1 is given
|
||||||
as first argument to the @code{main()} of the resulting program.
|
as first argument to the @code{main()} of the resulting program.
|
||||||
@ignore
|
@ignore
|
||||||
Because multiple C files are specified, @option{--} are necessary to clearly
|
Because multiple C files are specified, @option{--} are necessary to clearly
|
||||||
separate the program arguments from the TCC options.
|
separate the program arguments from the TCC options.
|
||||||
@end ignore
|
@end ignore
|
||||||
|
|
||||||
|
|
@ -136,14 +136,14 @@ need to add @code{#!/usr/local/bin/tcc -run} at the start of your C source:
|
||||||
#!/usr/local/bin/tcc -run
|
#!/usr/local/bin/tcc -run
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@{
|
@{
|
||||||
printf("Hello World\n");
|
printf("Hello World\n");
|
||||||
return 0;
|
return 0;
|
||||||
@}
|
@}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
TCC can read C source code from @emph{standard input} when @option{-} is used in
|
TCC can read C source code from @emph{standard input} when @option{-} is used in
|
||||||
place of @option{infile}. Example:
|
place of @option{infile}. Example:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
|
|
@ -271,7 +271,7 @@ Make string constants be of type @code{const char *} instead of @code{char
|
||||||
@item -Werror
|
@item -Werror
|
||||||
Abort compilation if warnings are issued.
|
Abort compilation if warnings are issued.
|
||||||
|
|
||||||
@item -Wall
|
@item -Wall
|
||||||
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
|
Activate all warnings, except @option{-Werror}, @option{-Wunusupported} and
|
||||||
@option{-Wwrite-strings}.
|
@option{-Wwrite-strings}.
|
||||||
|
|
||||||
|
|
@ -451,7 +451,7 @@ function name.
|
||||||
|
|
||||||
int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
|
int tab[10] = @{ 1, 2, [5] = 5, [9] = 9@};
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item Compound initializers are supported:
|
@item Compound initializers are supported:
|
||||||
@example
|
@example
|
||||||
int *p = (int [])@{ 1, 2, 3 @};
|
int *p = (int [])@{ 1, 2, 3 @};
|
||||||
|
|
@ -465,7 +465,7 @@ works for structures and strings.
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
is the same as writing
|
is the same as writing
|
||||||
@example
|
@example
|
||||||
double d = 4771840.0;
|
double d = 4771840.0;
|
||||||
@end example
|
@end example
|
||||||
|
|
@ -481,12 +481,12 @@ TCC implements some GNU C extensions:
|
||||||
|
|
||||||
@itemize
|
@itemize
|
||||||
|
|
||||||
@item array designators can be used without '=':
|
@item array designators can be used without '=':
|
||||||
@example
|
@example
|
||||||
int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
|
int a[10] = @{ [0] 1, [5] 2, 3, 4 @};
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item Structure field designators can be a label:
|
@item Structure field designators can be a label:
|
||||||
@example
|
@example
|
||||||
struct @{ int x, y; @} st = @{ x: 1, y: 1@};
|
struct @{ int x, y; @} st = @{ x: 1, y: 1@};
|
||||||
@end example
|
@end example
|
||||||
|
|
@ -555,7 +555,7 @@ Here are some examples:
|
||||||
align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
|
align variable @code{a} to 8 bytes and put it in section @code{.mysection}.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
|
int my_add(int a, int b) __attribute__ ((section(".mycodesection")))
|
||||||
@{
|
@{
|
||||||
return a + b;
|
return a + b;
|
||||||
@}
|
@}
|
||||||
|
|
@ -572,17 +572,17 @@ generate function @code{my_add} in section @code{.mycodesection}.
|
||||||
dprintf("one arg %d\n", 1);
|
dprintf("one arg %d\n", 1);
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item @code{__FUNCTION__} is interpreted as C99 @code{__func__}
|
@item @code{__FUNCTION__} is interpreted as C99 @code{__func__}
|
||||||
(so it has not exactly the same semantics as string literal GNUC
|
(so it has not exactly the same semantics as string literal GNUC
|
||||||
where it is a string literal).
|
where it is a string literal).
|
||||||
|
|
||||||
@item The @code{__alignof__} keyword can be used as @code{sizeof}
|
@item The @code{__alignof__} keyword can be used as @code{sizeof}
|
||||||
to get the alignment of a type or an expression.
|
to get the alignment of a type or an expression.
|
||||||
|
|
||||||
@item The @code{typeof(x)} returns the type of @code{x}.
|
@item The @code{typeof(x)} returns the type of @code{x}.
|
||||||
@code{x} is an expression or a type.
|
@code{x} is an expression or a type.
|
||||||
|
|
||||||
@item Computed gotos: @code{&&label} returns a pointer of type
|
@item Computed gotos: @code{&&label} returns a pointer of type
|
||||||
@code{void *} on the goto label @code{label}. @code{goto *expr} can be
|
@code{void *} on the goto label @code{label}. @code{goto *expr} can be
|
||||||
used to jump on the pointer resulting from @code{expr}.
|
used to jump on the pointer resulting from @code{expr}.
|
||||||
|
|
||||||
|
|
@ -616,7 +616,7 @@ TCC includes its own x86 inline assembler with a @code{gas}-like (GNU
|
||||||
assembler) syntax. No intermediate files are generated. GCC 3.x named
|
assembler) syntax. No intermediate files are generated. GCC 3.x named
|
||||||
operands are supported.
|
operands are supported.
|
||||||
|
|
||||||
@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()}
|
@item @code{__builtin_types_compatible_p()} and @code{__builtin_constant_p()}
|
||||||
are supported.
|
are supported.
|
||||||
|
|
||||||
@item @code{#pragma pack} is supported for win32 compatibility.
|
@item @code{#pragma pack} is supported for win32 compatibility.
|
||||||
|
|
@ -681,7 +681,7 @@ same as C.
|
||||||
@item +, -
|
@item +, -
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
@item A value is either an absolute number or a label plus an offset.
|
@item A value is either an absolute number or a label plus an offset.
|
||||||
All operators accept absolute values except '+' and '-'. '+' or '-' can be
|
All operators accept absolute values except '+' and '-'. '+' or '-' can be
|
||||||
used to add an offset to a label. '-' supports two labels only if they
|
used to add an offset to a label. '-' supports two labels only if they
|
||||||
are the same or if they are both defined and in the same section.
|
are the same or if they are both defined and in the same section.
|
||||||
|
|
@ -694,7 +694,7 @@ are the same or if they are both defined and in the same section.
|
||||||
|
|
||||||
@item All labels are considered as local, except undefined ones.
|
@item All labels are considered as local, except undefined ones.
|
||||||
|
|
||||||
@item Numeric labels can be used as local @code{gas}-like labels.
|
@item Numeric labels can be used as local @code{gas}-like labels.
|
||||||
They can be defined several times in the same source. Use 'b'
|
They can be defined several times in the same source. Use 'b'
|
||||||
(backward) or 'f' (forward) as suffix to reference them:
|
(backward) or 'f' (forward) as suffix to reference them:
|
||||||
|
|
||||||
|
|
@ -901,7 +901,7 @@ Here are some examples of caught errors:
|
||||||
@chapter The @code{libtcc} library
|
@chapter The @code{libtcc} library
|
||||||
|
|
||||||
The @code{libtcc} library enables you to use TCC as a backend for
|
The @code{libtcc} library enables you to use TCC as a backend for
|
||||||
dynamic code generation.
|
dynamic code generation.
|
||||||
|
|
||||||
Read the @file{libtcc.h} to have an overview of the API. Read
|
Read the @file{libtcc.h} to have an overview of the API. Read
|
||||||
@file{libtcc_test.c} to have a very simple example.
|
@file{libtcc_test.c} to have a very simple example.
|
||||||
|
|
@ -941,10 +941,10 @@ except:
|
||||||
|
|
||||||
@itemize
|
@itemize
|
||||||
|
|
||||||
@item For initialized arrays with unknown size, a first pass
|
@item For initialized arrays with unknown size, a first pass
|
||||||
is done to count the number of elements.
|
is done to count the number of elements.
|
||||||
|
|
||||||
@item For architectures where arguments are evaluated in
|
@item For architectures where arguments are evaluated in
|
||||||
reverse order, a first pass is done to reverse the argument order.
|
reverse order, a first pass is done to reverse the argument order.
|
||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
@ -1156,7 +1156,7 @@ stack.
|
||||||
@item VT_CMP
|
@item VT_CMP
|
||||||
indicates that the value is actually stored in the CPU flags (i.e. the
|
indicates that the value is actually stored in the CPU flags (i.e. the
|
||||||
value is the consequence of a test). The value is either 0 or 1. The
|
value is the consequence of a test). The value is either 0 or 1. The
|
||||||
actual CPU flags used is indicated in @code{SValue.c.i}.
|
actual CPU flags used is indicated in @code{SValue.c.i}.
|
||||||
|
|
||||||
If any code is generated which destroys the CPU flags, this value MUST be
|
If any code is generated which destroys the CPU flags, this value MUST be
|
||||||
put in a normal register.
|
put in a normal register.
|
||||||
|
|
@ -1176,7 +1176,7 @@ taken.
|
||||||
@item VT_LVAL
|
@item VT_LVAL
|
||||||
is a flag indicating that the value is actually an lvalue (left value of
|
is a flag indicating that the value is actually an lvalue (left value of
|
||||||
an assignment). It means that the value stored is actually a pointer to
|
an assignment). It means that the value stored is actually a pointer to
|
||||||
the wanted value.
|
the wanted value.
|
||||||
|
|
||||||
Understanding the use @code{VT_LVAL} is very important if you want to
|
Understanding the use @code{VT_LVAL} is very important if you want to
|
||||||
understand how TCC works.
|
understand how TCC works.
|
||||||
|
|
|
||||||
2
tcc.c
2
tcc.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* TCC - Tiny C Compiler
|
* TCC - Tiny C Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
|
||||||
8
tcc.h
8
tcc.h
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* TCC - Tiny C Compiler
|
* TCC - Tiny C Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -605,7 +605,7 @@ struct TCCState {
|
||||||
int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used.
|
int old_struct_init_code; /* use old algorithm to init array in struct when there is no '{' used.
|
||||||
Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
|
Liuux 2.4.26 can't find initrd when compiled with a new algorithm */
|
||||||
int dollars_in_identifiers; /* allows '$' char in indentifiers */
|
int dollars_in_identifiers; /* allows '$' char in indentifiers */
|
||||||
|
|
||||||
/* warning switches */
|
/* warning switches */
|
||||||
int warn_write_strings;
|
int warn_write_strings;
|
||||||
int warn_unsupported;
|
int warn_unsupported;
|
||||||
|
|
@ -631,7 +631,7 @@ struct TCCState {
|
||||||
|
|
||||||
char *init_symbol; /* symbols to call at load-time (not used currently) */
|
char *init_symbol; /* symbols to call at load-time (not used currently) */
|
||||||
char *fini_symbol; /* symbols to call at unload-time (not used currently) */
|
char *fini_symbol; /* symbols to call at unload-time (not used currently) */
|
||||||
|
|
||||||
#ifdef TCC_TARGET_I386
|
#ifdef TCC_TARGET_I386
|
||||||
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
|
int seg_size; /* 32. Can be 16 with i386 assembler (.code16) */
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -885,7 +885,7 @@ struct TCCState {
|
||||||
|
|
||||||
#define TOK_SHL 0x01 /* shift left */
|
#define TOK_SHL 0x01 /* shift left */
|
||||||
#define TOK_SAR 0x02 /* signed shift right */
|
#define TOK_SAR 0x02 /* signed shift right */
|
||||||
|
|
||||||
/* assignement operators : normal operator or 0x80 */
|
/* assignement operators : normal operator or 0x80 */
|
||||||
#define TOK_A_MOD 0xa5
|
#define TOK_A_MOD 0xa5
|
||||||
#define TOK_A_AND 0xa6
|
#define TOK_A_AND 0xa6
|
||||||
|
|
|
||||||
50
tccasm.c
50
tccasm.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* GAS like assembler for TCC
|
* GAS like assembler for TCC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -125,7 +125,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
||||||
{
|
{
|
||||||
int op;
|
int op;
|
||||||
|
|
@ -134,7 +134,7 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
||||||
asm_expr_unary(s1, pe);
|
asm_expr_unary(s1, pe);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
op = tok;
|
op = tok;
|
||||||
if (op != '*' && op != '/' && op != '%' &&
|
if (op != '*' && op != '/' && op != '%' &&
|
||||||
op != TOK_SHL && op != TOK_SAR)
|
op != TOK_SHL && op != TOK_SAR)
|
||||||
break;
|
break;
|
||||||
next();
|
next();
|
||||||
|
|
@ -145,14 +145,14 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
||||||
case '*':
|
case '*':
|
||||||
pe->v *= e2.v;
|
pe->v *= e2.v;
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
if (e2.v == 0) {
|
if (e2.v == 0) {
|
||||||
div_error:
|
div_error:
|
||||||
tcc_error("division by zero");
|
tcc_error("division by zero");
|
||||||
}
|
}
|
||||||
pe->v /= e2.v;
|
pe->v /= e2.v;
|
||||||
break;
|
break;
|
||||||
case '%':
|
case '%':
|
||||||
if (e2.v == 0)
|
if (e2.v == 0)
|
||||||
goto div_error;
|
goto div_error;
|
||||||
pe->v %= e2.v;
|
pe->v %= e2.v;
|
||||||
|
|
@ -186,7 +186,7 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe)
|
||||||
case '&':
|
case '&':
|
||||||
pe->v &= e2.v;
|
pe->v &= e2.v;
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
pe->v |= e2.v;
|
pe->v |= e2.v;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -224,7 +224,7 @@ static inline void asm_expr_sum(TCCState *s1, ExprValue *pe)
|
||||||
} else if (pe->sym && !e2.sym) {
|
} else if (pe->sym && !e2.sym) {
|
||||||
/* OK */
|
/* OK */
|
||||||
} else if (pe->sym && e2.sym) {
|
} else if (pe->sym && e2.sym) {
|
||||||
if (pe->sym == e2.sym) {
|
if (pe->sym == e2.sym) {
|
||||||
/* OK */
|
/* OK */
|
||||||
} else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
|
} else if (pe->sym->r == e2.sym->r && pe->sym->r != 0) {
|
||||||
/* we also accept defined symbols in the same section */
|
/* we also accept defined symbols in the same section */
|
||||||
|
|
@ -267,7 +267,7 @@ static void asm_new_label1(TCCState *s1, int label, int is_local,
|
||||||
if (sym->r) {
|
if (sym->r) {
|
||||||
/* the label is already defined */
|
/* the label is already defined */
|
||||||
if (!is_local) {
|
if (!is_local) {
|
||||||
tcc_error("assembler label '%s' already defined",
|
tcc_error("assembler label '%s' already defined",
|
||||||
get_tok_str(label, NULL));
|
get_tok_str(label, NULL));
|
||||||
} else {
|
} else {
|
||||||
/* redefinition of local labels is possible */
|
/* redefinition of local labels is possible */
|
||||||
|
|
@ -493,7 +493,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
case TOK_ASM_weak:
|
case TOK_ASM_weak:
|
||||||
case TOK_ASM_hidden:
|
case TOK_ASM_hidden:
|
||||||
tok1 = tok;
|
tok1 = tok;
|
||||||
do {
|
do {
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
@ -541,7 +541,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
case TOK_ASM_text:
|
case TOK_ASM_text:
|
||||||
case TOK_ASM_data:
|
case TOK_ASM_data:
|
||||||
case TOK_ASM_bss:
|
case TOK_ASM_bss:
|
||||||
{
|
{
|
||||||
char sname[64];
|
char sname[64];
|
||||||
tok1 = tok;
|
tok1 = tok;
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
@ -591,7 +591,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_ASM_size:
|
case TOK_ASM_size:
|
||||||
{
|
{
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
@ -612,7 +612,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_ASM_type:
|
case TOK_ASM_type:
|
||||||
{
|
{
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
const char *newtype;
|
const char *newtype;
|
||||||
|
|
||||||
|
|
@ -637,7 +637,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
|
sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC;
|
||||||
}
|
}
|
||||||
else if (s1->warn_unsupported)
|
else if (s1->warn_unsupported)
|
||||||
tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
|
tcc_warning("change type of '%s' from 0x%x to '%s' ignored",
|
||||||
get_tok_str(sym->v, NULL), sym->type.t, newtype);
|
get_tok_str(sym->v, NULL), sym->type.t, newtype);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
@ -669,7 +669,7 @@ static void asm_parse_directive(TCCState *s1)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOK_ASM_previous:
|
case TOK_ASM_previous:
|
||||||
{
|
{
|
||||||
Section *sec;
|
Section *sec;
|
||||||
next();
|
next();
|
||||||
if (!last_text_section)
|
if (!last_text_section)
|
||||||
|
|
@ -830,7 +830,7 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess)
|
||||||
|
|
||||||
cur_text_section->data_offset = ind;
|
cur_text_section->data_offset = ind;
|
||||||
|
|
||||||
free_defines(define_start);
|
free_defines(define_start);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -863,7 +863,7 @@ static void tcc_assemble_inline(TCCState *s1, char *str, int len)
|
||||||
/* find a constraint by its number or id (gcc 3 extended
|
/* find a constraint by its number or id (gcc 3 extended
|
||||||
syntax). return -1 if not found. Return in *pp in char after the
|
syntax). return -1 if not found. Return in *pp in char after the
|
||||||
constraint */
|
constraint */
|
||||||
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
|
ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
|
||||||
const char *name, const char **pp)
|
const char *name, const char **pp)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
|
@ -901,7 +901,7 @@ ST_FUNC int find_constraint(ASMOperand *operands, int nb_operands,
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void subst_asm_operands(ASMOperand *operands, int nb_operands,
|
static void subst_asm_operands(ASMOperand *operands, int nb_operands,
|
||||||
int nb_outputs,
|
int nb_outputs,
|
||||||
CString *out_str, CString *in_str)
|
CString *out_str, CString *in_str)
|
||||||
{
|
{
|
||||||
|
|
@ -1052,12 +1052,12 @@ ST_FUNC void asm_instr(void)
|
||||||
token after the assembler parsing */
|
token after the assembler parsing */
|
||||||
if (tok != ';')
|
if (tok != ';')
|
||||||
expect("';'");
|
expect("';'");
|
||||||
|
|
||||||
/* save all values in the memory */
|
/* save all values in the memory */
|
||||||
save_regs(0);
|
save_regs(0);
|
||||||
|
|
||||||
/* compute constraints */
|
/* compute constraints */
|
||||||
asm_compute_constraints(operands, nb_operands, nb_outputs,
|
asm_compute_constraints(operands, nb_operands, nb_outputs,
|
||||||
clobber_regs, &out_reg);
|
clobber_regs, &out_reg);
|
||||||
|
|
||||||
/* substitute the operands in the asm string. No substitution is
|
/* substitute the operands in the asm string. No substitution is
|
||||||
|
|
@ -1076,8 +1076,8 @@ ST_FUNC void asm_instr(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* generate loads */
|
/* generate loads */
|
||||||
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
||||||
clobber_regs, out_reg);
|
clobber_regs, out_reg);
|
||||||
|
|
||||||
/* assemble the string with tcc internal assembler */
|
/* assemble the string with tcc internal assembler */
|
||||||
tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
|
tcc_assemble_inline(tcc_state, astr1.data, astr1.size - 1);
|
||||||
|
|
@ -1086,9 +1086,9 @@ ST_FUNC void asm_instr(void)
|
||||||
next();
|
next();
|
||||||
|
|
||||||
/* store the output values if needed */
|
/* store the output values if needed */
|
||||||
asm_gen_code(operands, nb_operands, nb_outputs, 1,
|
asm_gen_code(operands, nb_operands, nb_outputs, 1,
|
||||||
clobber_regs, out_reg);
|
clobber_regs, out_reg);
|
||||||
|
|
||||||
/* free everything */
|
/* free everything */
|
||||||
for(i=0;i<nb_operands;i++) {
|
for(i=0;i<nb_operands;i++) {
|
||||||
ASMOperand *op;
|
ASMOperand *op;
|
||||||
|
|
@ -1110,7 +1110,7 @@ ST_FUNC void asm_global_instr(void)
|
||||||
token after the assembler parsing */
|
token after the assembler parsing */
|
||||||
if (tok != ';')
|
if (tok != ';')
|
||||||
expect("';'");
|
expect("';'");
|
||||||
|
|
||||||
#ifdef ASM_DEBUG
|
#ifdef ASM_DEBUG
|
||||||
printf("asm_global: \"%s\"\n", (char *)astr.data);
|
printf("asm_global: \"%s\"\n", (char *)astr.data);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1119,7 +1119,7 @@ ST_FUNC void asm_global_instr(void)
|
||||||
|
|
||||||
/* assemble the string with tcc internal assembler */
|
/* assemble the string with tcc internal assembler */
|
||||||
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
|
tcc_assemble_inline(tcc_state, astr.data, astr.size - 1);
|
||||||
|
|
||||||
cur_text_section->data_offset = ind;
|
cur_text_section->data_offset = ind;
|
||||||
|
|
||||||
/* restore the current C token */
|
/* restore the current C token */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* COFF file handling for TCC
|
* COFF file handling for TCC
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003, 2004 TK
|
* Copyright (c) 2003, 2004 TK
|
||||||
* Copyright (c) 2004 Fabrice Bellard
|
* Copyright (c) 2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
|
|
@ -606,7 +606,7 @@ ST_FUNC int tcc_output_coff(TCCState *s1, FILE *f)
|
||||||
// put a .ef
|
// put a .ef
|
||||||
|
|
||||||
strcpy(csym._n._n_name, ".ef");
|
strcpy(csym._n._n_name, ".ef");
|
||||||
csym.n_value = EndAddress[k]; // physical address
|
csym.n_value = EndAddress[k]; // physical address
|
||||||
csym.n_scnum = CoffTextSectionNo;
|
csym.n_scnum = CoffTextSectionNo;
|
||||||
csym.n_type = 0;
|
csym.n_type = 0;
|
||||||
csym.n_sclass = C_FCN;
|
csym.n_sclass = C_FCN;
|
||||||
|
|
|
||||||
2
tccelf.c
2
tccelf.c
|
|
@ -1179,7 +1179,7 @@ static unsigned long put_got_entry(TCCState *s1,
|
||||||
p[11] = 0xe9; /* jmp plt_start */
|
p[11] = 0xe9; /* jmp plt_start */
|
||||||
put32(p + 12, -(plt->data_offset));
|
put32(p + 12, -(plt->data_offset));
|
||||||
|
|
||||||
/* If this was an UNDEF symbol set the offset in the
|
/* If this was an UNDEF symbol set the offset in the
|
||||||
dynsymtab to the PLT slot, so that PC32 relocs to it
|
dynsymtab to the PLT slot, so that PC32 relocs to it
|
||||||
can be resolved. */
|
can be resolved. */
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
if (sym->st_shndx == SHN_UNDEF)
|
||||||
|
|
|
||||||
220
tccgen.c
220
tccgen.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* TCC - Tiny C Compiler
|
* TCC - Tiny C Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -299,7 +299,7 @@ static void weaken_symbol(Sym *sym)
|
||||||
if (sym->c > 0) {
|
if (sym->c > 0) {
|
||||||
int esym_type;
|
int esym_type;
|
||||||
ElfW(Sym) *esym;
|
ElfW(Sym) *esym;
|
||||||
|
|
||||||
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
||||||
esym_type = ELFW(ST_TYPE)(esym->st_info);
|
esym_type = ELFW(ST_TYPE)(esym->st_info);
|
||||||
esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
|
esym->st_info = ELFW(ST_INFO)(STB_WEAK, esym_type);
|
||||||
|
|
@ -321,7 +321,7 @@ static void apply_visibility(Sym *sym, CType *type)
|
||||||
|
|
||||||
if (sym->c > 0) {
|
if (sym->c > 0) {
|
||||||
ElfW(Sym) *esym;
|
ElfW(Sym) *esym;
|
||||||
|
|
||||||
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
|
||||||
vis >>= VT_VIS_SHIFT;
|
vis >>= VT_VIS_SHIFT;
|
||||||
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
|
esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
|
||||||
|
|
@ -425,7 +425,7 @@ ST_FUNC Sym *get_sym_ref(CType *type, Section *sec, unsigned long offset, unsign
|
||||||
/* push a reference to a section offset by adding a dummy symbol */
|
/* push a reference to a section offset by adding a dummy symbol */
|
||||||
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
|
static void vpush_ref(CType *type, Section *sec, unsigned long offset, unsigned long size)
|
||||||
{
|
{
|
||||||
vpushsym(type, get_sym_ref(type, sec, offset, size));
|
vpushsym(type, get_sym_ref(type, sec, offset, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* define a new external reference to a symbol 'v' of type 'u' */
|
/* define a new external reference to a symbol 'v' of type 'u' */
|
||||||
|
|
@ -461,7 +461,7 @@ static Sym *external_sym(int v, CType *type, int r, char *asm_label)
|
||||||
s->r = r | VT_CONST | VT_SYM;
|
s->r = r | VT_CONST | VT_SYM;
|
||||||
s->type.t |= VT_EXTERN;
|
s->type.t |= VT_EXTERN;
|
||||||
} else if (!is_compatible_types(&s->type, type)) {
|
} else if (!is_compatible_types(&s->type, type)) {
|
||||||
tcc_error("incompatible types for redefinition of '%s'",
|
tcc_error("incompatible types for redefinition of '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
/* Merge some storage attributes. */
|
/* Merge some storage attributes. */
|
||||||
|
|
@ -600,7 +600,7 @@ ST_FUNC int get_reg_ex(int rc, int rc2)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
SValue *p;
|
SValue *p;
|
||||||
|
|
||||||
for(r=0;r<NB_REGS;r++) {
|
for(r=0;r<NB_REGS;r++) {
|
||||||
if (reg_classes[r] & rc2) {
|
if (reg_classes[r] & rc2) {
|
||||||
int n;
|
int n;
|
||||||
|
|
@ -636,7 +636,7 @@ ST_FUNC int get_reg(int rc)
|
||||||
}
|
}
|
||||||
notfound: ;
|
notfound: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no register left : free the first one on the stack (VERY
|
/* no register left : free the first one on the stack (VERY
|
||||||
IMPORTANT to start from the bottom to ensure that we don't
|
IMPORTANT to start from the bottom to ensure that we don't
|
||||||
spill registers used in gen_opi()) */
|
spill registers used in gen_opi()) */
|
||||||
|
|
@ -761,7 +761,7 @@ ST_FUNC int gv(int rc)
|
||||||
gen_op(TOK_SAR);
|
gen_op(TOK_SAR);
|
||||||
r = gv(rc);
|
r = gv(rc);
|
||||||
} else {
|
} else {
|
||||||
if (is_float(vtop->type.t) &&
|
if (is_float(vtop->type.t) &&
|
||||||
(vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
(vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST) {
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
int *ptr;
|
int *ptr;
|
||||||
|
|
@ -769,7 +769,7 @@ ST_FUNC int gv(int rc)
|
||||||
#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
|
#if defined(TCC_TARGET_ARM) && !defined(TCC_ARM_VFP)
|
||||||
CValue check;
|
CValue check;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX: unify with initializers handling ? */
|
/* XXX: unify with initializers handling ? */
|
||||||
/* CPUs usually cannot use float constants, so we store them
|
/* CPUs usually cannot use float constants, so we store them
|
||||||
generically in data segment */
|
generically in data segment */
|
||||||
|
|
@ -803,7 +803,7 @@ ST_FUNC int gv(int rc)
|
||||||
vtop->c.ptr_offset = 0;
|
vtop->c.ptr_offset = 0;
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (vtop->r & VT_MUSTBOUND)
|
if (vtop->r & VT_MUSTBOUND)
|
||||||
gbound();
|
gbound();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -921,7 +921,7 @@ ST_FUNC int gv(int rc)
|
||||||
vtop->r = r;
|
vtop->r = r;
|
||||||
#ifdef TCC_TARGET_C67
|
#ifdef TCC_TARGET_C67
|
||||||
/* uses register pairs for doubles */
|
/* uses register pairs for doubles */
|
||||||
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||||
vtop->r2 = r+1;
|
vtop->r2 = r+1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -1036,7 +1036,7 @@ static void lbuild(int t)
|
||||||
vpop();
|
vpop();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* rotate n first stack elements to the bottom
|
/* rotate n first stack elements to the bottom
|
||||||
I1 ... In -> I2 ... In I1 [top is right]
|
I1 ... In -> I2 ... In I1 [top is right]
|
||||||
*/
|
*/
|
||||||
ST_FUNC void vrotb(int n)
|
ST_FUNC void vrotb(int n)
|
||||||
|
|
@ -1476,7 +1476,7 @@ static void gen_opic(int op)
|
||||||
vtop--;
|
vtop--;
|
||||||
} else {
|
} else {
|
||||||
/* if commutative ops, put c2 as constant */
|
/* if commutative ops, put c2 as constant */
|
||||||
if (c1 && (op == '+' || op == '&' || op == '^' ||
|
if (c1 && (op == '+' || op == '&' || op == '^' ||
|
||||||
op == '|' || op == '*')) {
|
op == '|' || op == '*')) {
|
||||||
vswap();
|
vswap();
|
||||||
c2 = c1; //c = c1, c1 = c2, c2 = c;
|
c2 = c1; //c = c1, c1 = c2, c2 = c;
|
||||||
|
|
@ -1582,13 +1582,13 @@ static void gen_opif(int op)
|
||||||
case '+': f1 += f2; break;
|
case '+': f1 += f2; break;
|
||||||
case '-': f1 -= f2; break;
|
case '-': f1 -= f2; break;
|
||||||
case '*': f1 *= f2; break;
|
case '*': f1 *= f2; break;
|
||||||
case '/':
|
case '/':
|
||||||
if (f2 == 0.0) {
|
if (f2 == 0.0) {
|
||||||
if (const_wanted)
|
if (const_wanted)
|
||||||
tcc_error("division by zero in constant");
|
tcc_error("division by zero in constant");
|
||||||
goto general_case;
|
goto general_case;
|
||||||
}
|
}
|
||||||
f1 /= f2;
|
f1 /= f2;
|
||||||
break;
|
break;
|
||||||
/* XXX: also handles tests ? */
|
/* XXX: also handles tests ? */
|
||||||
default:
|
default:
|
||||||
|
|
@ -1636,7 +1636,7 @@ static inline int is_null_pointer(SValue *p)
|
||||||
|
|
||||||
static inline int is_integer_btype(int bt)
|
static inline int is_integer_btype(int bt)
|
||||||
{
|
{
|
||||||
return (bt == VT_BYTE || bt == VT_SHORT ||
|
return (bt == VT_BYTE || bt == VT_SHORT ||
|
||||||
bt == VT_INT || bt == VT_LLONG);
|
bt == VT_INT || bt == VT_LLONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1645,7 +1645,7 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
|
||||||
{
|
{
|
||||||
CType *type1, *type2, tmp_type1, tmp_type2;
|
CType *type1, *type2, tmp_type1, tmp_type2;
|
||||||
int bt1, bt2;
|
int bt1, bt2;
|
||||||
|
|
||||||
/* null pointers are accepted for all comparisons as gcc */
|
/* null pointers are accepted for all comparisons as gcc */
|
||||||
if (is_null_pointer(p1) || is_null_pointer(p2))
|
if (is_null_pointer(p1) || is_null_pointer(p2))
|
||||||
return;
|
return;
|
||||||
|
|
@ -1663,16 +1663,16 @@ static void check_comparison_pointer_types(SValue *p1, SValue *p2, int op)
|
||||||
/* both must be pointers or implicit function pointers */
|
/* both must be pointers or implicit function pointers */
|
||||||
if (bt1 == VT_PTR) {
|
if (bt1 == VT_PTR) {
|
||||||
type1 = pointed_type(type1);
|
type1 = pointed_type(type1);
|
||||||
} else if (bt1 != VT_FUNC)
|
} else if (bt1 != VT_FUNC)
|
||||||
goto invalid_operands;
|
goto invalid_operands;
|
||||||
|
|
||||||
if (bt2 == VT_PTR) {
|
if (bt2 == VT_PTR) {
|
||||||
type2 = pointed_type(type2);
|
type2 = pointed_type(type2);
|
||||||
} else if (bt2 != VT_FUNC) {
|
} else if (bt2 != VT_FUNC) {
|
||||||
invalid_operands:
|
invalid_operands:
|
||||||
tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
|
tcc_error("invalid operands to binary %s", get_tok_str(op, NULL));
|
||||||
}
|
}
|
||||||
if ((type1->t & VT_BTYPE) == VT_VOID ||
|
if ((type1->t & VT_BTYPE) == VT_VOID ||
|
||||||
(type2->t & VT_BTYPE) == VT_VOID)
|
(type2->t & VT_BTYPE) == VT_VOID)
|
||||||
return;
|
return;
|
||||||
tmp_type1 = *type1;
|
tmp_type1 = *type1;
|
||||||
|
|
@ -1698,7 +1698,7 @@ ST_FUNC void gen_op(int op)
|
||||||
t2 = vtop[0].type.t;
|
t2 = vtop[0].type.t;
|
||||||
bt1 = t1 & VT_BTYPE;
|
bt1 = t1 & VT_BTYPE;
|
||||||
bt2 = t2 & VT_BTYPE;
|
bt2 = t2 & VT_BTYPE;
|
||||||
|
|
||||||
if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
if (bt1 == VT_PTR || bt2 == VT_PTR) {
|
||||||
/* at least one operand is a pointer */
|
/* at least one operand is a pointer */
|
||||||
/* relationnal op: must be both pointers */
|
/* relationnal op: must be both pointers */
|
||||||
|
|
@ -1729,7 +1729,7 @@ ST_FUNC void gen_op(int op)
|
||||||
#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
|
#if defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
|
||||||
vtop->type.t = VT_LLONG;
|
vtop->type.t = VT_LLONG;
|
||||||
#else
|
#else
|
||||||
vtop->type.t = VT_INT;
|
vtop->type.t = VT_INT;
|
||||||
#endif
|
#endif
|
||||||
vswap();
|
vswap();
|
||||||
gen_op(TOK_PDIV);
|
gen_op(TOK_PDIV);
|
||||||
|
|
@ -1770,7 +1770,7 @@ ST_FUNC void gen_op(int op)
|
||||||
fprintf(stderr, "v+i-j = %p\n", v+i-j);
|
fprintf(stderr, "v+i-j = %p\n", v+i-j);
|
||||||
fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
|
fprintf(stderr, "v+(i-j) = %p\n", v+(i-j));
|
||||||
}
|
}
|
||||||
When this code is on. then the output looks like
|
When this code is on. then the output looks like
|
||||||
v+i-j = 0xfffffffe
|
v+i-j = 0xfffffffe
|
||||||
v+(i-j) = 0xbff84000
|
v+(i-j) = 0xbff84000
|
||||||
*/
|
*/
|
||||||
|
|
@ -1880,7 +1880,7 @@ static void gen_cvt_itof1(int t)
|
||||||
#ifdef TCC_TARGET_ARM64
|
#ifdef TCC_TARGET_ARM64
|
||||||
gen_cvt_itof(t);
|
gen_cvt_itof(t);
|
||||||
#else
|
#else
|
||||||
if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
if ((vtop->type.t & (VT_BTYPE | VT_UNSIGNED)) ==
|
||||||
(VT_LLONG | VT_UNSIGNED)) {
|
(VT_LLONG | VT_UNSIGNED)) {
|
||||||
|
|
||||||
if (t == VT_FLOAT)
|
if (t == VT_FLOAT)
|
||||||
|
|
@ -2127,7 +2127,7 @@ static void gen_cast(CType *type)
|
||||||
/* scalar to bool */
|
/* scalar to bool */
|
||||||
vpushi(0);
|
vpushi(0);
|
||||||
gen_op(TOK_NE);
|
gen_op(TOK_NE);
|
||||||
} else if ((dbt & VT_BTYPE) == VT_BYTE ||
|
} else if ((dbt & VT_BTYPE) == VT_BYTE ||
|
||||||
(dbt & VT_BTYPE) == VT_SHORT) {
|
(dbt & VT_BTYPE) == VT_SHORT) {
|
||||||
if (sbt == VT_PTR) {
|
if (sbt == VT_PTR) {
|
||||||
vtop->type.t = VT_INT;
|
vtop->type.t = VT_INT;
|
||||||
|
|
@ -2140,7 +2140,7 @@ static void gen_cast(CType *type)
|
||||||
/* from long long: just take low order word */
|
/* from long long: just take low order word */
|
||||||
lexpand();
|
lexpand();
|
||||||
vpop();
|
vpop();
|
||||||
}
|
}
|
||||||
/* if lvalue and single word type, nothing to do because
|
/* if lvalue and single word type, nothing to do because
|
||||||
the lvalue already contains the real type size (see
|
the lvalue already contains the real type size (see
|
||||||
VT_LVAL_xxx constants) */
|
VT_LVAL_xxx constants) */
|
||||||
|
|
@ -2194,7 +2194,7 @@ ST_FUNC int type_size(CType *type, int *a)
|
||||||
#endif
|
#endif
|
||||||
#elif defined(TCC_TARGET_ARM)
|
#elif defined(TCC_TARGET_ARM)
|
||||||
#ifdef TCC_ARM_EABI
|
#ifdef TCC_ARM_EABI
|
||||||
*a = 8;
|
*a = 8;
|
||||||
#else
|
#else
|
||||||
*a = 4;
|
*a = 4;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -2289,7 +2289,7 @@ static int is_compatible_func(CType *type1, CType *type2)
|
||||||
/* return true if type1 and type2 are the same. If unqualified is
|
/* return true if type1 and type2 are the same. If unqualified is
|
||||||
true, qualifiers on the types are ignored.
|
true, qualifiers on the types are ignored.
|
||||||
|
|
||||||
- enums are not checked as gcc __builtin_types_compatible_p ()
|
- enums are not checked as gcc __builtin_types_compatible_p ()
|
||||||
*/
|
*/
|
||||||
static int compare_types(CType *type1, CType *type2, int unqualified)
|
static int compare_types(CType *type1, CType *type2, int unqualified)
|
||||||
{
|
{
|
||||||
|
|
@ -2326,7 +2326,7 @@ static int compare_types(CType *type1, CType *type2, int unqualified)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return true if type1 and type2 are exactly the same (including
|
/* return true if type1 and type2 are exactly the same (including
|
||||||
qualifiers).
|
qualifiers).
|
||||||
*/
|
*/
|
||||||
static int is_compatible_types(CType *type1, CType *type2)
|
static int is_compatible_types(CType *type1, CType *type2)
|
||||||
{
|
{
|
||||||
|
|
@ -2344,7 +2344,7 @@ static int is_compatible_parameter_types(CType *type1, CType *type2)
|
||||||
printed in the type */
|
printed in the type */
|
||||||
/* XXX: union */
|
/* XXX: union */
|
||||||
/* XXX: add array and function pointers */
|
/* XXX: add array and function pointers */
|
||||||
static void type_to_str(char *buf, int buf_size,
|
static void type_to_str(char *buf, int buf_size,
|
||||||
CType *type, const char *varstr)
|
CType *type, const char *varstr)
|
||||||
{
|
{
|
||||||
int bt, v, t;
|
int bt, v, t;
|
||||||
|
|
@ -2487,7 +2487,7 @@ static void gen_assign_cast(CType *dt)
|
||||||
if (sbt != VT_PTR)
|
if (sbt != VT_PTR)
|
||||||
goto error;
|
goto error;
|
||||||
type2 = pointed_type(st);
|
type2 = pointed_type(st);
|
||||||
if ((type1->t & VT_BTYPE) == VT_VOID ||
|
if ((type1->t & VT_BTYPE) == VT_VOID ||
|
||||||
(type2->t & VT_BTYPE) == VT_VOID) {
|
(type2->t & VT_BTYPE) == VT_VOID) {
|
||||||
/* void * can match anything */
|
/* void * can match anything */
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2716,7 +2716,7 @@ ST_FUNC void inc(int post, int c)
|
||||||
vrotb(3);
|
vrotb(3);
|
||||||
}
|
}
|
||||||
/* add constant */
|
/* add constant */
|
||||||
vpushi(c - TOK_MID);
|
vpushi(c - TOK_MID);
|
||||||
gen_op('+');
|
gen_op('+');
|
||||||
vstore(); /* store value */
|
vstore(); /* store value */
|
||||||
if (post)
|
if (post)
|
||||||
|
|
@ -2734,7 +2734,7 @@ ST_FUNC void inc(int post, int c)
|
||||||
static void parse_attribute(AttributeDef *ad)
|
static void parse_attribute(AttributeDef *ad)
|
||||||
{
|
{
|
||||||
int t, n;
|
int t, n;
|
||||||
|
|
||||||
while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
|
while (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) {
|
||||||
next();
|
next();
|
||||||
skip('(');
|
skip('(');
|
||||||
|
|
@ -2787,7 +2787,7 @@ static void parse_attribute(AttributeDef *ad)
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
next();
|
next();
|
||||||
n = expr_const();
|
n = expr_const();
|
||||||
if (n <= 0 || (n & (n - 1)) != 0)
|
if (n <= 0 || (n & (n - 1)) != 0)
|
||||||
tcc_error("alignment must be a positive power of two");
|
tcc_error("alignment must be a positive power of two");
|
||||||
skip(')');
|
skip(')');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2828,7 +2828,7 @@ static void parse_attribute(AttributeDef *ad)
|
||||||
case TOK_REGPARM2:
|
case TOK_REGPARM2:
|
||||||
skip('(');
|
skip('(');
|
||||||
n = expr_const();
|
n = expr_const();
|
||||||
if (n > 3)
|
if (n > 3)
|
||||||
n = 3;
|
n = 3;
|
||||||
else if (n < 0)
|
else if (n < 0)
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
@ -2840,7 +2840,7 @@ static void parse_attribute(AttributeDef *ad)
|
||||||
case TOK_FASTCALL2:
|
case TOK_FASTCALL2:
|
||||||
case TOK_FASTCALL3:
|
case TOK_FASTCALL3:
|
||||||
ad->a.func_call = FUNC_FASTCALLW;
|
ad->a.func_call = FUNC_FASTCALLW;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case TOK_MODE:
|
case TOK_MODE:
|
||||||
skip('(');
|
skip('(');
|
||||||
|
|
@ -2874,9 +2874,9 @@ static void parse_attribute(AttributeDef *ad)
|
||||||
if (tok == '(') {
|
if (tok == '(') {
|
||||||
int parenthesis = 0;
|
int parenthesis = 0;
|
||||||
do {
|
do {
|
||||||
if (tok == '(')
|
if (tok == '(')
|
||||||
parenthesis++;
|
parenthesis++;
|
||||||
else if (tok == ')')
|
else if (tok == ')')
|
||||||
parenthesis--;
|
parenthesis--;
|
||||||
next();
|
next();
|
||||||
} while (parenthesis && tok != -1);
|
} while (parenthesis && tok != -1);
|
||||||
|
|
@ -2928,7 +2928,7 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
do_decl:
|
do_decl:
|
||||||
type->t = u;
|
type->t = u;
|
||||||
type->ref = s;
|
type->ref = s;
|
||||||
|
|
||||||
if (tok == '{') {
|
if (tok == '{') {
|
||||||
next();
|
next();
|
||||||
if (s->c != -1)
|
if (s->c != -1)
|
||||||
|
|
@ -3001,7 +3001,7 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
}
|
}
|
||||||
if ((type1.t & VT_BTYPE) == VT_FUNC ||
|
if ((type1.t & VT_BTYPE) == VT_FUNC ||
|
||||||
(type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
|
(type1.t & (VT_TYPEDEF | VT_STATIC | VT_EXTERN | VT_INLINE)))
|
||||||
tcc_error("invalid type for '%s'",
|
tcc_error("invalid type for '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
if (tok == ':') {
|
if (tok == ':') {
|
||||||
|
|
@ -3009,10 +3009,10 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
bit_size = expr_const();
|
bit_size = expr_const();
|
||||||
/* XXX: handle v = 0 case for messages */
|
/* XXX: handle v = 0 case for messages */
|
||||||
if (bit_size < 0)
|
if (bit_size < 0)
|
||||||
tcc_error("negative width in bit-field '%s'",
|
tcc_error("negative width in bit-field '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
if (v && bit_size == 0)
|
if (v && bit_size == 0)
|
||||||
tcc_error("zero width for bit-field '%s'",
|
tcc_error("zero width for bit-field '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
size = type_size(&type1, &align);
|
size = type_size(&type1, &align);
|
||||||
|
|
@ -3028,8 +3028,8 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
lbit_pos = 0;
|
lbit_pos = 0;
|
||||||
if (bit_size >= 0) {
|
if (bit_size >= 0) {
|
||||||
bt = type1.t & VT_BTYPE;
|
bt = type1.t & VT_BTYPE;
|
||||||
if (bt != VT_INT &&
|
if (bt != VT_INT &&
|
||||||
bt != VT_BYTE &&
|
bt != VT_BYTE &&
|
||||||
bt != VT_SHORT &&
|
bt != VT_SHORT &&
|
||||||
bt != VT_BOOL &&
|
bt != VT_BOOL &&
|
||||||
bt != VT_ENUM &&
|
bt != VT_ENUM &&
|
||||||
|
|
@ -3056,7 +3056,7 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
bit_pos = 0;
|
bit_pos = 0;
|
||||||
lbit_pos = bit_pos;
|
lbit_pos = bit_pos;
|
||||||
/* XXX: handle LSB first */
|
/* XXX: handle LSB first */
|
||||||
type1.t |= VT_BITFIELD |
|
type1.t |= VT_BITFIELD |
|
||||||
(bit_pos << VT_STRUCT_SHIFT) |
|
(bit_pos << VT_STRUCT_SHIFT) |
|
||||||
(bit_size << (VT_STRUCT_SHIFT + 6));
|
(bit_size << (VT_STRUCT_SHIFT + 6));
|
||||||
bit_pos += bit_size;
|
bit_pos += bit_size;
|
||||||
|
|
@ -3083,10 +3083,10 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
maxalign = align;
|
maxalign = align;
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
printf("add field %s offset=%d",
|
printf("add field %s offset=%d",
|
||||||
get_tok_str(v, NULL), offset);
|
get_tok_str(v, NULL), offset);
|
||||||
if (type1.t & VT_BITFIELD) {
|
if (type1.t & VT_BITFIELD) {
|
||||||
printf(" pos=%d size=%d",
|
printf(" pos=%d size=%d",
|
||||||
(type1.t >> VT_STRUCT_SHIFT) & 0x3f,
|
(type1.t >> VT_STRUCT_SHIFT) & 0x3f,
|
||||||
(type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
|
(type1.t >> (VT_STRUCT_SHIFT + 6)) & 0x3f);
|
||||||
}
|
}
|
||||||
|
|
@ -3113,7 +3113,7 @@ static void struct_decl(CType *type, int u, int tdef)
|
||||||
}
|
}
|
||||||
skip('}');
|
skip('}');
|
||||||
/* store size and alignment */
|
/* store size and alignment */
|
||||||
s->c = (c + maxalign - 1) & -maxalign;
|
s->c = (c + maxalign - 1) & -maxalign;
|
||||||
s->r = maxalign;
|
s->r = maxalign;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3126,7 +3126,7 @@ ST_FUNC int is_btype_size(int bt)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 0 if no type declaration. otherwise, return the basic type
|
/* return 0 if no type declaration. otherwise, return the basic type
|
||||||
and skip it.
|
and skip it.
|
||||||
*/
|
*/
|
||||||
static int parse_btype(CType *type, AttributeDef *ad)
|
static int parse_btype(CType *type, AttributeDef *ad)
|
||||||
{
|
{
|
||||||
|
|
@ -3436,9 +3436,9 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||||
skip(')');
|
skip(')');
|
||||||
/* NOTE: const is ignored in returned type as it has a special
|
/* NOTE: const is ignored in returned type as it has a special
|
||||||
meaning in gcc / C++ */
|
meaning in gcc / C++ */
|
||||||
type->t &= ~VT_CONSTANT;
|
type->t &= ~VT_CONSTANT;
|
||||||
/* some ancient pre-K&R C allows a function to return an array
|
/* some ancient pre-K&R C allows a function to return an array
|
||||||
and the array brackets to be put after the arguments, such
|
and the array brackets to be put after the arguments, such
|
||||||
that "int c()[]" means something like "int[] c()" */
|
that "int c()[]" means something like "int[] c()" */
|
||||||
if (tok == '[') {
|
if (tok == '[') {
|
||||||
next();
|
next();
|
||||||
|
|
@ -3479,7 +3479,7 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||||
if (type->t == VT_FUNC)
|
if (type->t == VT_FUNC)
|
||||||
tcc_error("declaration of an array of functions");
|
tcc_error("declaration of an array of functions");
|
||||||
t1 |= type->t & VT_VLA;
|
t1 |= type->t & VT_VLA;
|
||||||
|
|
||||||
if (t1 & VT_VLA) {
|
if (t1 & VT_VLA) {
|
||||||
loc -= type_size(&int_type, &align);
|
loc -= type_size(&int_type, &align);
|
||||||
loc &= -align;
|
loc &= -align;
|
||||||
|
|
@ -3493,7 +3493,7 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||||
}
|
}
|
||||||
if (n != -1)
|
if (n != -1)
|
||||||
vpop();
|
vpop();
|
||||||
|
|
||||||
/* we push an anonymous symbol which will contain the array
|
/* we push an anonymous symbol which will contain the array
|
||||||
element type */
|
element type */
|
||||||
s = sym_push(SYM_FIELD, type, 0, n);
|
s = sym_push(SYM_FIELD, type, 0, n);
|
||||||
|
|
@ -3506,7 +3506,7 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||||
in 'type'. 'td' is a bitmask indicating which kind of type decl is
|
in 'type'. 'td' is a bitmask indicating which kind of type decl is
|
||||||
expected. 'type' should contain the basic type. 'ad' is the
|
expected. 'type' should contain the basic type. 'ad' is the
|
||||||
attribute definition of the basic type. It can be modified by
|
attribute definition of the basic type. It can be modified by
|
||||||
type_decl().
|
type_decl().
|
||||||
*/
|
*/
|
||||||
static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
|
static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
|
||||||
{
|
{
|
||||||
|
|
@ -3537,7 +3537,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
|
||||||
mk_pointer(type);
|
mk_pointer(type);
|
||||||
type->t |= qualifiers;
|
type->t |= qualifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: clarify attribute handling */
|
/* XXX: clarify attribute handling */
|
||||||
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
|
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
|
||||||
parse_attribute(ad);
|
parse_attribute(ad);
|
||||||
|
|
@ -3576,7 +3576,7 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td)
|
||||||
type->t |= storage;
|
type->t |= storage;
|
||||||
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
|
if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)
|
||||||
parse_attribute(ad);
|
parse_attribute(ad);
|
||||||
|
|
||||||
if (!type1.t)
|
if (!type1.t)
|
||||||
return;
|
return;
|
||||||
/* append type at the end of type1 */
|
/* append type at the end of type1 */
|
||||||
|
|
@ -3711,7 +3711,7 @@ ST_FUNC void unary(void)
|
||||||
next();
|
next();
|
||||||
goto tok_next;
|
goto tok_next;
|
||||||
case TOK_CINT:
|
case TOK_CINT:
|
||||||
case TOK_CCHAR:
|
case TOK_CCHAR:
|
||||||
case TOK_LCHAR:
|
case TOK_LCHAR:
|
||||||
vpushi(tokc.i);
|
vpushi(tokc.i);
|
||||||
next();
|
next();
|
||||||
|
|
@ -3814,7 +3814,7 @@ ST_FUNC void unary(void)
|
||||||
linux/include/net/tcp.h:945: error: statement expression in global scope */
|
linux/include/net/tcp.h:945: error: statement expression in global scope */
|
||||||
|
|
||||||
/* save all registers */
|
/* save all registers */
|
||||||
save_regs(0);
|
save_regs(0);
|
||||||
/* statement expression : we do not accept break/continue
|
/* statement expression : we do not accept break/continue
|
||||||
inside as GCC does */
|
inside as GCC does */
|
||||||
block(NULL, NULL, NULL, NULL, 0, 1);
|
block(NULL, NULL, NULL, NULL, 0, 1);
|
||||||
|
|
@ -4087,7 +4087,7 @@ ST_FUNC void unary(void)
|
||||||
vpushsym(&s->type, s);
|
vpushsym(&s->type, s);
|
||||||
next();
|
next();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// special qnan , snan and infinity values
|
// special qnan , snan and infinity values
|
||||||
case TOK___NAN__:
|
case TOK___NAN__:
|
||||||
vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
|
vpush64(VT_DOUBLE, 0x7ff8000000000000ULL);
|
||||||
|
|
@ -4123,7 +4123,7 @@ ST_FUNC void unary(void)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
tcc_warning("implicit declaration of function '%s'", name);
|
tcc_warning("implicit declaration of function '%s'", name);
|
||||||
s = external_global_sym(t, &func_old_type, 0);
|
s = external_global_sym(t, &func_old_type, 0);
|
||||||
}
|
}
|
||||||
if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
|
if ((s->type.t & (VT_STATIC | VT_INLINE | VT_BTYPE)) ==
|
||||||
(VT_STATIC | VT_INLINE | VT_FUNC)) {
|
(VT_STATIC | VT_INLINE | VT_FUNC)) {
|
||||||
|
|
@ -4146,7 +4146,7 @@ ST_FUNC void unary(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* post operations */
|
/* post operations */
|
||||||
while (1) {
|
while (1) {
|
||||||
if (tok == TOK_INC || tok == TOK_DEC) {
|
if (tok == TOK_INC || tok == TOK_DEC) {
|
||||||
|
|
@ -4154,8 +4154,8 @@ ST_FUNC void unary(void)
|
||||||
next();
|
next();
|
||||||
} else if (tok == '.' || tok == TOK_ARROW) {
|
} else if (tok == '.' || tok == TOK_ARROW) {
|
||||||
int qualifiers;
|
int qualifiers;
|
||||||
/* field */
|
/* field */
|
||||||
if (tok == TOK_ARROW)
|
if (tok == TOK_ARROW)
|
||||||
indir();
|
indir();
|
||||||
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
qualifiers = vtop->type.t & (VT_CONSTANT | VT_VOLATILE);
|
||||||
test_lvalue();
|
test_lvalue();
|
||||||
|
|
@ -4637,7 +4637,7 @@ static void expr_cond(void)
|
||||||
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
|
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED))
|
||||||
type.t |= VT_UNSIGNED;
|
type.t |= VT_UNSIGNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now we convert second operand */
|
/* now we convert second operand */
|
||||||
gen_cast(&type);
|
gen_cast(&type);
|
||||||
if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
|
if (VT_STRUCT == (vtop->type.t & VT_BTYPE))
|
||||||
|
|
@ -4653,9 +4653,9 @@ static void expr_cond(void)
|
||||||
} else if ((type.t & VT_BTYPE) == VT_LLONG) {
|
} else if ((type.t & VT_BTYPE) == VT_LLONG) {
|
||||||
/* for long longs, we use fixed registers to avoid having
|
/* for long longs, we use fixed registers to avoid having
|
||||||
to handle a complicated move */
|
to handle a complicated move */
|
||||||
rc = RC_IRET;
|
rc = RC_IRET;
|
||||||
}
|
}
|
||||||
|
|
||||||
r2 = gv(rc);
|
r2 = gv(rc);
|
||||||
/* this is horrible, but we must also convert first
|
/* this is horrible, but we must also convert first
|
||||||
operand */
|
operand */
|
||||||
|
|
@ -4677,7 +4677,7 @@ static void expr_cond(void)
|
||||||
static void expr_eq(void)
|
static void expr_eq(void)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
expr_cond();
|
expr_cond();
|
||||||
if (tok == '=' ||
|
if (tok == '=' ||
|
||||||
(tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
|
(tok >= TOK_A_MOD && tok <= TOK_A_DIV) ||
|
||||||
|
|
@ -4797,7 +4797,7 @@ static void label_or_decl(int l)
|
||||||
decl(l);
|
decl(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
int case_reg, int is_expr)
|
int case_reg, int is_expr)
|
||||||
{
|
{
|
||||||
int a, b, c, d;
|
int a, b, c, d;
|
||||||
|
|
@ -4858,7 +4858,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
frame_bottom->next = scope_stack_bottom;
|
frame_bottom->next = scope_stack_bottom;
|
||||||
scope_stack_bottom = frame_bottom;
|
scope_stack_bottom = frame_bottom;
|
||||||
llabel = local_label_stack;
|
llabel = local_label_stack;
|
||||||
|
|
||||||
/* handle local labels declarations */
|
/* handle local labels declarations */
|
||||||
if (tok == TOK_LABEL) {
|
if (tok == TOK_LABEL) {
|
||||||
next();
|
next();
|
||||||
|
|
@ -4906,14 +4906,14 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
/* pop locally defined symbols */
|
/* pop locally defined symbols */
|
||||||
scope_stack_bottom = scope_stack_bottom->next;
|
scope_stack_bottom = scope_stack_bottom->next;
|
||||||
sym_pop(&local_stack, s);
|
sym_pop(&local_stack, s);
|
||||||
|
|
||||||
/* Pop VLA frames and restore stack pointer if required */
|
/* Pop VLA frames and restore stack pointer if required */
|
||||||
if (vlas_in_scope > saved_vlas_in_scope) {
|
if (vlas_in_scope > saved_vlas_in_scope) {
|
||||||
vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
|
vla_sp_loc = saved_vlas_in_scope ? block_vla_sp_loc : vla_sp_root_loc;
|
||||||
vla_sp_restore();
|
vla_sp_restore();
|
||||||
}
|
}
|
||||||
vlas_in_scope = saved_vlas_in_scope;
|
vlas_in_scope = saved_vlas_in_scope;
|
||||||
|
|
||||||
next();
|
next();
|
||||||
} else if (tok == TOK_RETURN) {
|
} else if (tok == TOK_RETURN) {
|
||||||
next();
|
next();
|
||||||
|
|
@ -5080,7 +5080,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
gsym_addr(b, c);
|
gsym_addr(b, c);
|
||||||
scope_stack_bottom = scope_stack_bottom->next;
|
scope_stack_bottom = scope_stack_bottom->next;
|
||||||
sym_pop(&local_stack, s);
|
sym_pop(&local_stack, s);
|
||||||
} else
|
} else
|
||||||
if (tok == TOK_DO) {
|
if (tok == TOK_DO) {
|
||||||
next();
|
next();
|
||||||
a = 0;
|
a = 0;
|
||||||
|
|
@ -5154,7 +5154,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
skip(':');
|
skip(':');
|
||||||
is_expr = 0;
|
is_expr = 0;
|
||||||
goto block_after_label;
|
goto block_after_label;
|
||||||
} else
|
} else
|
||||||
if (tok == TOK_DEFAULT) {
|
if (tok == TOK_DEFAULT) {
|
||||||
next();
|
next();
|
||||||
skip(':');
|
skip(':');
|
||||||
|
|
@ -5185,7 +5185,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
s->r = LABEL_FORWARD;
|
s->r = LABEL_FORWARD;
|
||||||
}
|
}
|
||||||
vla_sp_restore_root();
|
vla_sp_restore_root();
|
||||||
if (s->r & LABEL_FORWARD)
|
if (s->r & LABEL_FORWARD)
|
||||||
s->jnext = gjmp(s->jnext);
|
s->jnext = gjmp(s->jnext);
|
||||||
else
|
else
|
||||||
gjmp_addr(s->jnext);
|
gjmp_addr(s->jnext);
|
||||||
|
|
@ -5240,8 +5240,8 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym,
|
||||||
address. cur_index/cur_field is the pointer to the current
|
address. cur_index/cur_field is the pointer to the current
|
||||||
value. 'size_only' is true if only size info is needed (only used
|
value. 'size_only' is true if only size info is needed (only used
|
||||||
in arrays) */
|
in arrays) */
|
||||||
static void decl_designator(CType *type, Section *sec, unsigned long c,
|
static void decl_designator(CType *type, Section *sec, unsigned long c,
|
||||||
int *cur_index, Sym **cur_field,
|
int *cur_index, Sym **cur_field,
|
||||||
int size_only)
|
int size_only)
|
||||||
{
|
{
|
||||||
Sym *s, *f;
|
Sym *s, *f;
|
||||||
|
|
@ -5265,7 +5265,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
|
||||||
if (tok == TOK_DOTS && gnu_ext) {
|
if (tok == TOK_DOTS && gnu_ext) {
|
||||||
next();
|
next();
|
||||||
index_last = expr_const();
|
index_last = expr_const();
|
||||||
if (index_last < 0 ||
|
if (index_last < 0 ||
|
||||||
(s->c >= 0 && index_last >= s->c) ||
|
(s->c >= 0 && index_last >= s->c) ||
|
||||||
index_last < index)
|
index_last < index)
|
||||||
expect("invalid index");
|
expect("invalid index");
|
||||||
|
|
@ -5361,7 +5361,7 @@ static void decl_designator(CType *type, Section *sec, unsigned long c,
|
||||||
#define EXPR_ANY 2
|
#define EXPR_ANY 2
|
||||||
|
|
||||||
/* store a value or an expression directly in global data or in local array */
|
/* store a value or an expression directly in global data or in local array */
|
||||||
static void init_putv(CType *type, Section *sec, unsigned long c,
|
static void init_putv(CType *type, Section *sec, unsigned long c,
|
||||||
int v, int expr_type)
|
int v, int expr_type)
|
||||||
{
|
{
|
||||||
int saved_global_expr, bt, bit_pos, bit_size;
|
int saved_global_expr, bt, bit_pos, bit_size;
|
||||||
|
|
@ -5387,7 +5387,7 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
|
||||||
expr_eq();
|
expr_eq();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dtype = *type;
|
dtype = *type;
|
||||||
dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
|
dtype.t &= ~VT_CONSTANT; /* need to do that to avoid false warning */
|
||||||
|
|
||||||
|
|
@ -5502,7 +5502,7 @@ static void init_putz(CType *t, Section *sec, unsigned long c, int size)
|
||||||
allocation. 'first' is true if array '{' must be read (multi
|
allocation. 'first' is true if array '{' must be read (multi
|
||||||
dimension implicit array init handling). 'size_only' is true if
|
dimension implicit array init handling). 'size_only' is true if
|
||||||
size only evaluation is wanted (only for arrays). */
|
size only evaluation is wanted (only for arrays). */
|
||||||
static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
int first, int size_only)
|
int first, int size_only)
|
||||||
{
|
{
|
||||||
int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
|
int index, array_length, n, no_oblock, nb, parlevel, parlevel1, i;
|
||||||
|
|
@ -5512,14 +5512,14 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
|
|
||||||
if (type->t & VT_VLA) {
|
if (type->t & VT_VLA) {
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
/* save current stack pointer */
|
/* save current stack pointer */
|
||||||
if (vlas_in_scope == 0) {
|
if (vlas_in_scope == 0) {
|
||||||
if (vla_sp_root_loc == -1)
|
if (vla_sp_root_loc == -1)
|
||||||
vla_sp_root_loc = (loc -= PTR_SIZE);
|
vla_sp_root_loc = (loc -= PTR_SIZE);
|
||||||
gen_vla_sp_save(vla_sp_root_loc);
|
gen_vla_sp_save(vla_sp_root_loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
vla_runtime_type_size(type, &a);
|
vla_runtime_type_size(type, &a);
|
||||||
gen_vla_alloc(type, a);
|
gen_vla_alloc(type, a);
|
||||||
gen_vla_sp_save(c);
|
gen_vla_sp_save(c);
|
||||||
|
|
@ -5533,7 +5533,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
size1 = type_size(t1, &align1);
|
size1 = type_size(t1, &align1);
|
||||||
|
|
||||||
no_oblock = 1;
|
no_oblock = 1;
|
||||||
if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
|
if ((first && tok != TOK_LSTR && tok != TOK_STR) ||
|
||||||
tok == '{') {
|
tok == '{') {
|
||||||
if (tok != '{')
|
if (tok != '{')
|
||||||
tcc_error("character array initializer must be a literal,"
|
tcc_error("character array initializer must be a literal,"
|
||||||
|
|
@ -5544,7 +5544,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
|
|
||||||
/* only parse strings here if correct type (otherwise: handle
|
/* only parse strings here if correct type (otherwise: handle
|
||||||
them as ((w)char *) expressions */
|
them as ((w)char *) expressions */
|
||||||
if ((tok == TOK_LSTR &&
|
if ((tok == TOK_LSTR &&
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
(t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
|
(t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
|
||||||
#else
|
#else
|
||||||
|
|
@ -5604,7 +5604,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
/* must put zero in holes (note that doing it that way
|
/* must put zero in holes (note that doing it that way
|
||||||
ensures that it even works with designators) */
|
ensures that it even works with designators) */
|
||||||
if (!size_only && array_length < index) {
|
if (!size_only && array_length < index) {
|
||||||
init_putz(t1, sec, c + array_length * size1,
|
init_putz(t1, sec, c + array_length * size1,
|
||||||
(index - array_length) * size1);
|
(index - array_length) * size1);
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
|
|
@ -5624,7 +5624,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
skip('}');
|
skip('}');
|
||||||
/* put zeros at the end */
|
/* put zeros at the end */
|
||||||
if (!size_only && n >= 0 && array_length < n) {
|
if (!size_only && n >= 0 && array_length < n) {
|
||||||
init_putz(t1, sec, c + array_length * size1,
|
init_putz(t1, sec, c + array_length * size1,
|
||||||
(n - array_length) * size1);
|
(n - array_length) * size1);
|
||||||
}
|
}
|
||||||
/* patch type size if needed */
|
/* patch type size if needed */
|
||||||
|
|
@ -5690,7 +5690,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
decl_designator(type, sec, c, NULL, &f, size_only);
|
decl_designator(type, sec, c, NULL, &f, size_only);
|
||||||
index = f->c;
|
index = f->c;
|
||||||
if (!size_only && array_length < index) {
|
if (!size_only && array_length < index) {
|
||||||
init_putz(type, sec, c + array_length,
|
init_putz(type, sec, c + array_length,
|
||||||
index - array_length);
|
index - array_length);
|
||||||
}
|
}
|
||||||
index = index + type_size(&f->type, &align1);
|
index = index + type_size(&f->type, &align1);
|
||||||
|
|
@ -5743,7 +5743,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
}
|
}
|
||||||
/* put zeros at the end */
|
/* put zeros at the end */
|
||||||
if (!size_only && array_length < n) {
|
if (!size_only && array_length < n) {
|
||||||
init_putz(type, sec, c + array_length,
|
init_putz(type, sec, c + array_length,
|
||||||
n - array_length);
|
n - array_length);
|
||||||
}
|
}
|
||||||
if (!no_oblock)
|
if (!no_oblock)
|
||||||
|
|
@ -5795,7 +5795,7 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||||
zero, then a reference to the new object is put in the value stack.
|
zero, then a reference to the new object is put in the value stack.
|
||||||
If 'has_init' is 2, a special parsing is done to handle string
|
If 'has_init' is 2, a special parsing is done to handle string
|
||||||
constants. */
|
constants. */
|
||||||
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
int has_init, int v, char *asm_label,
|
int has_init, int v, char *asm_label,
|
||||||
int scope)
|
int scope)
|
||||||
{
|
{
|
||||||
|
|
@ -5826,7 +5826,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
initializers handling */
|
initializers handling */
|
||||||
tok_str_new(&init_str);
|
tok_str_new(&init_str);
|
||||||
if (size < 0 || (flexible_array && has_init)) {
|
if (size < 0 || (flexible_array && has_init)) {
|
||||||
if (!has_init)
|
if (!has_init)
|
||||||
tcc_error("unknown type size");
|
tcc_error("unknown type size");
|
||||||
/* get all init string */
|
/* get all init string */
|
||||||
if (has_init == 2) {
|
if (has_init == 2) {
|
||||||
|
|
@ -5855,7 +5855,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
}
|
}
|
||||||
tok_str_add(&init_str, -1);
|
tok_str_add(&init_str, -1);
|
||||||
tok_str_add(&init_str, 0);
|
tok_str_add(&init_str, 0);
|
||||||
|
|
||||||
/* compute size */
|
/* compute size */
|
||||||
save_parse_state(&saved_parse_state);
|
save_parse_state(&saved_parse_state);
|
||||||
|
|
||||||
|
|
@ -5865,10 +5865,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
/* prepare second initializer parsing */
|
/* prepare second initializer parsing */
|
||||||
macro_ptr = init_str.str;
|
macro_ptr = init_str.str;
|
||||||
next();
|
next();
|
||||||
|
|
||||||
/* if still unknown size, error */
|
/* if still unknown size, error */
|
||||||
size = type_size(type, &align);
|
size = type_size(type, &align);
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
tcc_error("unknown type size");
|
tcc_error("unknown type size");
|
||||||
}
|
}
|
||||||
if (flexible_array)
|
if (flexible_array)
|
||||||
|
|
@ -5919,14 +5919,14 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
sym = sym_find(v);
|
sym = sym_find(v);
|
||||||
if (sym) {
|
if (sym) {
|
||||||
if (!is_compatible_types(&sym->type, type))
|
if (!is_compatible_types(&sym->type, type))
|
||||||
tcc_error("incompatible types for redefinition of '%s'",
|
tcc_error("incompatible types for redefinition of '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
if (sym->type.t & VT_EXTERN) {
|
if (sym->type.t & VT_EXTERN) {
|
||||||
/* if the variable is extern, it was not allocated */
|
/* if the variable is extern, it was not allocated */
|
||||||
sym->type.t &= ~VT_EXTERN;
|
sym->type.t &= ~VT_EXTERN;
|
||||||
/* set array size if it was omitted in extern
|
/* set array size if it was omitted in extern
|
||||||
declaration */
|
declaration */
|
||||||
if ((sym->type.t & VT_ARRAY) &&
|
if ((sym->type.t & VT_ARRAY) &&
|
||||||
sym->type.ref->c < 0 &&
|
sym->type.ref->c < 0 &&
|
||||||
type->ref->c >= 0)
|
type->ref->c >= 0)
|
||||||
sym->type.ref->c = type->ref->c;
|
sym->type.ref->c = type->ref->c;
|
||||||
|
|
@ -5966,7 +5966,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
#endif
|
#endif
|
||||||
sec->data_offset = data_offset;
|
sec->data_offset = data_offset;
|
||||||
/* allocate section space to put the data */
|
/* allocate section space to put the data */
|
||||||
if (sec->sh_type != SHT_NOBITS &&
|
if (sec->sh_type != SHT_NOBITS &&
|
||||||
data_offset > sec->data_allocated)
|
data_offset > sec->data_allocated)
|
||||||
section_realloc(sec, data_offset);
|
section_realloc(sec, data_offset);
|
||||||
/* align section if needed */
|
/* align section if needed */
|
||||||
|
|
@ -6036,12 +6036,12 @@ static void put_func_debug(Sym *sym)
|
||||||
|
|
||||||
/* stabs info */
|
/* stabs info */
|
||||||
/* XXX: we put here a dummy type */
|
/* XXX: we put here a dummy type */
|
||||||
snprintf(buf, sizeof(buf), "%s:%c1",
|
snprintf(buf, sizeof(buf), "%s:%c1",
|
||||||
funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
|
funcname, sym->type.t & VT_STATIC ? 'f' : 'F');
|
||||||
put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
|
put_stabs_r(buf, N_FUN, 0, file->line_num, 0,
|
||||||
cur_text_section, sym->c);
|
cur_text_section, sym->c);
|
||||||
/* //gr gdb wants a line at the function */
|
/* //gr gdb wants a line at the function */
|
||||||
put_stabn(N_SLINE, 0, file->line_num, 0);
|
put_stabn(N_SLINE, 0, file->line_num, 0);
|
||||||
last_ind = 0;
|
last_ind = 0;
|
||||||
last_line_num = 0;
|
last_line_num = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -6058,10 +6058,10 @@ static void func_decl_list(Sym *func_sym)
|
||||||
/* parse each declaration */
|
/* parse each declaration */
|
||||||
while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
|
while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF &&
|
||||||
tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
|
tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) {
|
||||||
if (!parse_btype(&btype, &ad))
|
if (!parse_btype(&btype, &ad))
|
||||||
expect("declaration list");
|
expect("declaration list");
|
||||||
if (((btype.t & VT_BTYPE) == VT_ENUM ||
|
if (((btype.t & VT_BTYPE) == VT_ENUM ||
|
||||||
(btype.t & VT_BTYPE) == VT_STRUCT) &&
|
(btype.t & VT_BTYPE) == VT_STRUCT) &&
|
||||||
tok == ';') {
|
tok == ';') {
|
||||||
/* we accept no variable after */
|
/* we accept no variable after */
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -6080,7 +6080,7 @@ static void func_decl_list(Sym *func_sym)
|
||||||
found:
|
found:
|
||||||
/* check that no storage specifier except 'register' was given */
|
/* check that no storage specifier except 'register' was given */
|
||||||
if (type.t & VT_STORAGE)
|
if (type.t & VT_STORAGE)
|
||||||
tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
|
tcc_error("storage class specified for '%s'", get_tok_str(v, NULL));
|
||||||
convert_parameter_type(&type);
|
convert_parameter_type(&type);
|
||||||
/* we can add the type (NOTE: it could be local to the function) */
|
/* we can add the type (NOTE: it could be local to the function) */
|
||||||
s->type = type;
|
s->type = type;
|
||||||
|
|
@ -6140,7 +6140,7 @@ static void gen_function(Sym *sym)
|
||||||
sym_pop(&local_stack, NULL);
|
sym_pop(&local_stack, NULL);
|
||||||
/* end of function */
|
/* end of function */
|
||||||
/* patch symbol size */
|
/* patch symbol size */
|
||||||
((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
|
((ElfW(Sym) *)symtab_section->data)[sym->c].st_size =
|
||||||
ind - func_ind;
|
ind - func_ind;
|
||||||
/* patch symbol weakness (this definition overrules any prototype) */
|
/* patch symbol weakness (this definition overrules any prototype) */
|
||||||
if (sym->type.t & VT_WEAK)
|
if (sym->type.t & VT_WEAK)
|
||||||
|
|
@ -6234,7 +6234,7 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
btype.t = VT_INT;
|
btype.t = VT_INT;
|
||||||
}
|
}
|
||||||
if (((btype.t & VT_BTYPE) == VT_ENUM ||
|
if (((btype.t & VT_BTYPE) == VT_ENUM ||
|
||||||
(btype.t & VT_BTYPE) == VT_STRUCT) &&
|
(btype.t & VT_BTYPE) == VT_STRUCT) &&
|
||||||
tok == ';') {
|
tok == ';') {
|
||||||
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
|
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
int v = btype.ref->v;
|
int v = btype.ref->v;
|
||||||
|
|
@ -6273,7 +6273,7 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
asm_label_instr(&astr);
|
asm_label_instr(&astr);
|
||||||
asm_label = tcc_strdup(astr.data);
|
asm_label = tcc_strdup(astr.data);
|
||||||
cstr_free(&astr);
|
cstr_free(&astr);
|
||||||
|
|
||||||
/* parse one last attribute list, after asm label */
|
/* parse one last attribute list, after asm label */
|
||||||
parse_attribute(&ad);
|
parse_attribute(&ad);
|
||||||
}
|
}
|
||||||
|
|
@ -6299,11 +6299,11 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
while ((sym = sym->next) != NULL)
|
while ((sym = sym->next) != NULL)
|
||||||
if (!(sym->v & ~SYM_FIELD))
|
if (!(sym->v & ~SYM_FIELD))
|
||||||
expect("identifier");
|
expect("identifier");
|
||||||
|
|
||||||
/* XXX: cannot do better now: convert extern line to static inline */
|
/* XXX: cannot do better now: convert extern line to static inline */
|
||||||
if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
|
if ((type.t & (VT_EXTERN | VT_INLINE)) == (VT_EXTERN | VT_INLINE))
|
||||||
type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
|
type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
|
||||||
|
|
||||||
sym = sym_find(v);
|
sym = sym_find(v);
|
||||||
if (sym) {
|
if (sym) {
|
||||||
Sym *ref;
|
Sym *ref;
|
||||||
|
|
@ -6334,7 +6334,7 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
|
|
||||||
if (!is_compatible_types(&sym->type, &type)) {
|
if (!is_compatible_types(&sym->type, &type)) {
|
||||||
func_error1:
|
func_error1:
|
||||||
tcc_error("incompatible types for redefinition of '%s'",
|
tcc_error("incompatible types for redefinition of '%s'",
|
||||||
get_tok_str(v, NULL));
|
get_tok_str(v, NULL));
|
||||||
}
|
}
|
||||||
type.ref->a.func_proto = 0;
|
type.ref->a.func_proto = 0;
|
||||||
|
|
@ -6349,18 +6349,18 @@ static int decl0(int l, int is_for_loop_init)
|
||||||
/* static inline functions are just recorded as a kind
|
/* static inline functions are just recorded as a kind
|
||||||
of macro. Their code will be emitted at the end of
|
of macro. Their code will be emitted at the end of
|
||||||
the compilation unit only if they are used */
|
the compilation unit only if they are used */
|
||||||
if ((type.t & (VT_INLINE | VT_STATIC)) ==
|
if ((type.t & (VT_INLINE | VT_STATIC)) ==
|
||||||
(VT_INLINE | VT_STATIC)) {
|
(VT_INLINE | VT_STATIC)) {
|
||||||
int block_level;
|
int block_level;
|
||||||
struct InlineFunc *fn;
|
struct InlineFunc *fn;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
|
||||||
filename = file ? file->filename : "";
|
filename = file ? file->filename : "";
|
||||||
fn = tcc_malloc(sizeof *fn + strlen(filename));
|
fn = tcc_malloc(sizeof *fn + strlen(filename));
|
||||||
strcpy(fn->filename, filename);
|
strcpy(fn->filename, filename);
|
||||||
fn->sym = sym;
|
fn->sym = sym;
|
||||||
tok_str_new(&fn->func_str);
|
tok_str_new(&fn->func_str);
|
||||||
|
|
||||||
block_level = 0;
|
block_level = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int t;
|
int t;
|
||||||
|
|
|
||||||
6
tcclib.h
6
tcclib.h
|
|
@ -1,8 +1,8 @@
|
||||||
/* Simple libc header for TCC
|
/* Simple libc header for TCC
|
||||||
*
|
*
|
||||||
* Add any function you want from the libc there. This file is here
|
* Add any function you want from the libc there. This file is here
|
||||||
* only for your convenience so that you do not need to put the whole
|
* only for your convenience so that you do not need to put the whole
|
||||||
* glibc include files on your floppy disk
|
* glibc include files on your floppy disk
|
||||||
*/
|
*/
|
||||||
#ifndef _TCCLIB_H
|
#ifndef _TCCLIB_H
|
||||||
#define _TCCLIB_H
|
#define _TCCLIB_H
|
||||||
|
|
|
||||||
2
tccpe.c
2
tccpe.c
|
|
@ -1266,7 +1266,7 @@ static int pe_check_symbols(struct pe_info *pe)
|
||||||
put_elf_reloc(symtab_section, text_section,
|
put_elf_reloc(symtab_section, text_section,
|
||||||
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
|
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
|
||||||
#else
|
#else
|
||||||
put_elf_reloc(symtab_section, text_section,
|
put_elf_reloc(symtab_section, text_section,
|
||||||
offset + 2, R_XXX_THUNKFIX, is->iat_index);
|
offset + 2, R_XXX_THUNKFIX, is->iat_index);
|
||||||
#endif
|
#endif
|
||||||
is->thk_offset = offset;
|
is->thk_offset = offset;
|
||||||
|
|
|
||||||
72
tccpp.c
72
tccpp.c
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* TCC - Tiny C Compiler
|
* TCC - Tiny C Compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2001-2004 Fabrice Bellard
|
* Copyright (c) 2001-2004 Fabrice Bellard
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
|
@ -50,7 +50,7 @@ static unsigned char isidnum_table[256 - CH_EOF];
|
||||||
|
|
||||||
static TokenString *macro_stack;
|
static TokenString *macro_stack;
|
||||||
|
|
||||||
static const char tcc_keywords[] =
|
static const char tcc_keywords[] =
|
||||||
#define DEF(id, str) str "\0"
|
#define DEF(id, str) str "\0"
|
||||||
#include "tcctok.h"
|
#include "tcctok.h"
|
||||||
#undef DEF
|
#undef DEF
|
||||||
|
|
@ -221,7 +221,7 @@ static TokenSym *tok_alloc_new(TokenSym **pts, const char *str, int len)
|
||||||
TokenSym *ts, **ptable;
|
TokenSym *ts, **ptable;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (tok_ident >= SYM_FIRST_ANOM)
|
if (tok_ident >= SYM_FIRST_ANOM)
|
||||||
tcc_error("memory full (symbols)");
|
tcc_error("memory full (symbols)");
|
||||||
|
|
||||||
/* expand token table if needed */
|
/* expand token table if needed */
|
||||||
|
|
@ -255,7 +255,7 @@ ST_FUNC TokenSym *tok_alloc(const char *str, int len)
|
||||||
TokenSym *ts, **pts;
|
TokenSym *ts, **pts;
|
||||||
int i;
|
int i;
|
||||||
unsigned int h;
|
unsigned int h;
|
||||||
|
|
||||||
h = TOK_HASH_INIT;
|
h = TOK_HASH_INIT;
|
||||||
for(i=0;i<len;i++)
|
for(i=0;i<len;i++)
|
||||||
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
|
h = TOK_HASH_FUNC(h, ((unsigned char *)str)[i]);
|
||||||
|
|
@ -511,7 +511,7 @@ static int handle_stray1(uint8_t *p)
|
||||||
ST_FUNC void minp(void)
|
ST_FUNC void minp(void)
|
||||||
{
|
{
|
||||||
inp();
|
inp();
|
||||||
if (ch == '\\')
|
if (ch == '\\')
|
||||||
handle_stray();
|
handle_stray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,7 +557,7 @@ static uint8_t *parse_line_comment(uint8_t *p)
|
||||||
ST_FUNC uint8_t *parse_comment(uint8_t *p)
|
ST_FUNC uint8_t *parse_comment(uint8_t *p)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
/* fast skip loop */
|
/* fast skip loop */
|
||||||
|
|
@ -635,13 +635,13 @@ static inline void skip_spaces(void)
|
||||||
cinp();
|
cinp();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int check_space(int t, int *spc)
|
static inline int check_space(int t, int *spc)
|
||||||
{
|
{
|
||||||
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
|
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
|
||||||
if (*spc)
|
if (*spc)
|
||||||
return 1;
|
return 1;
|
||||||
*spc = 1;
|
*spc = 1;
|
||||||
} else
|
} else
|
||||||
*spc = 0;
|
*spc = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -774,7 +774,7 @@ redo_start:
|
||||||
file->buf_ptr = p;
|
file->buf_ptr = p;
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
p = file->buf_ptr;
|
p = file->buf_ptr;
|
||||||
if (a == 0 &&
|
if (a == 0 &&
|
||||||
(tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
|
(tok == TOK_ELSE || tok == TOK_ELIF || tok == TOK_ENDIF))
|
||||||
goto the_end;
|
goto the_end;
|
||||||
if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
|
if (tok == TOK_IF || tok == TOK_IFDEF || tok == TOK_IFNDEF)
|
||||||
|
|
@ -930,7 +930,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
|
||||||
cstr->size = cv->cstr->size;
|
cstr->size = cv->cstr->size;
|
||||||
cstr->data_allocated = NULL;
|
cstr->data_allocated = NULL;
|
||||||
cstr->size_allocated = cstr->size;
|
cstr->size_allocated = cstr->size;
|
||||||
memcpy((char *)cstr + sizeof(CString),
|
memcpy((char *)cstr + sizeof(CString),
|
||||||
cv->cstr->data, cstr->size);
|
cv->cstr->data, cstr->size);
|
||||||
len += nb_words;
|
len += nb_words;
|
||||||
}
|
}
|
||||||
|
|
@ -1253,14 +1253,14 @@ static int expr_preprocess(void)
|
||||||
{
|
{
|
||||||
int c, t;
|
int c, t;
|
||||||
TokenString str;
|
TokenString str;
|
||||||
|
|
||||||
tok_str_new(&str);
|
tok_str_new(&str);
|
||||||
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
|
while (tok != TOK_LINEFEED && tok != TOK_EOF) {
|
||||||
next(); /* do macro subst */
|
next(); /* do macro subst */
|
||||||
if (tok == TOK_DEFINED) {
|
if (tok == TOK_DEFINED) {
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
t = tok;
|
t = tok;
|
||||||
if (t == '(')
|
if (t == '(')
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
c = define_find(tok) != 0;
|
c = define_find(tok) != 0;
|
||||||
if (t == '(')
|
if (t == '(')
|
||||||
|
|
@ -1914,7 +1914,7 @@ static void parse_escape_string(CString *outstr, const uint8_t *buf, int is_long
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
case '\"':
|
case '\"':
|
||||||
case '\\':
|
case '\\':
|
||||||
case '?':
|
case '?':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -2070,7 +2070,7 @@ static void parse_number(const char *p)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
if (b == 16)
|
if (b == 16)
|
||||||
shift = 4;
|
shift = 4;
|
||||||
else
|
else
|
||||||
shift = 1;
|
shift = 1;
|
||||||
bn_zero(bn);
|
bn_zero(bn);
|
||||||
q = token_buf;
|
q = token_buf;
|
||||||
|
|
@ -2126,7 +2126,7 @@ static void parse_number(const char *p)
|
||||||
ch = *p++;
|
ch = *p++;
|
||||||
}
|
}
|
||||||
exp_val = exp_val * s;
|
exp_val = exp_val * s;
|
||||||
|
|
||||||
/* now we can generate the number */
|
/* now we can generate the number */
|
||||||
/* XXX: should patch directly float number */
|
/* XXX: should patch directly float number */
|
||||||
d = (double)bn[1] * 4294967296.0 + (double)bn[0];
|
d = (double)bn[1] * 4294967296.0 + (double)bn[0];
|
||||||
|
|
@ -2363,7 +2363,7 @@ static inline void next_nomacro1(void)
|
||||||
} else {
|
} else {
|
||||||
tok_flags &= ~TOK_FLAG_EOF;
|
tok_flags &= ~TOK_FLAG_EOF;
|
||||||
/* pop include file */
|
/* pop include file */
|
||||||
|
|
||||||
/* test if previous '#endif' was after a #ifdef at
|
/* test if previous '#endif' was after a #ifdef at
|
||||||
start of file */
|
start of file */
|
||||||
if (tok_flags & TOK_FLAG_ENDIF) {
|
if (tok_flags & TOK_FLAG_ENDIF) {
|
||||||
|
|
@ -2400,7 +2400,7 @@ maybe_newline:
|
||||||
case '#':
|
case '#':
|
||||||
/* XXX: simplify */
|
/* XXX: simplify */
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if ((tok_flags & TOK_FLAG_BOL) &&
|
if ((tok_flags & TOK_FLAG_BOL) &&
|
||||||
(parse_flags & PARSE_FLAG_PREPROCESS)) {
|
(parse_flags & PARSE_FLAG_PREPROCESS)) {
|
||||||
file->buf_ptr = p;
|
file->buf_ptr = p;
|
||||||
preprocess(tok_flags & TOK_FLAG_BOF);
|
preprocess(tok_flags & TOK_FLAG_BOF);
|
||||||
|
|
@ -2420,7 +2420,7 @@ maybe_newline:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* dollar is allowed to start identifiers when not parsing asm */
|
/* dollar is allowed to start identifiers when not parsing asm */
|
||||||
case '$':
|
case '$':
|
||||||
if (!(isidnum_table[c - CH_EOF] & IS_ID)
|
if (!(isidnum_table[c - CH_EOF] & IS_ID)
|
||||||
|
|
@ -2433,14 +2433,14 @@ maybe_newline:
|
||||||
case 'm': case 'n': case 'o': case 'p':
|
case 'm': case 'n': case 'o': case 'p':
|
||||||
case 'q': case 'r': case 's': case 't':
|
case 'q': case 'r': case 's': case 't':
|
||||||
case 'u': case 'v': case 'w': case 'x':
|
case 'u': case 'v': case 'w': case 'x':
|
||||||
case 'y': case 'z':
|
case 'y': case 'z':
|
||||||
case 'A': case 'B': case 'C': case 'D':
|
case 'A': case 'B': case 'C': case 'D':
|
||||||
case 'E': case 'F': case 'G': case 'H':
|
case 'E': case 'F': case 'G': case 'H':
|
||||||
case 'I': case 'J': case 'K':
|
case 'I': case 'J': case 'K':
|
||||||
case 'M': case 'N': case 'O': case 'P':
|
case 'M': case 'N': case 'O': case 'P':
|
||||||
case 'Q': case 'R': case 'S': case 'T':
|
case 'Q': case 'R': case 'S': case 'T':
|
||||||
case 'U': case 'V': case 'W': case 'X':
|
case 'U': case 'V': case 'W': case 'X':
|
||||||
case 'Y': case 'Z':
|
case 'Y': case 'Z':
|
||||||
case '_':
|
case '_':
|
||||||
parse_ident_fast:
|
parse_ident_fast:
|
||||||
p1 = p;
|
p1 = p;
|
||||||
|
|
@ -2594,7 +2594,7 @@ maybe_newline:
|
||||||
tok = TOK_GT;
|
tok = TOK_GT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '&':
|
case '&':
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c == '&') {
|
if (c == '&') {
|
||||||
|
|
@ -2607,7 +2607,7 @@ maybe_newline:
|
||||||
tok = '&';
|
tok = '&';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '|':
|
case '|':
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c == '|') {
|
if (c == '|') {
|
||||||
|
|
@ -2633,7 +2633,7 @@ maybe_newline:
|
||||||
tok = '+';
|
tok = '+';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '-':
|
case '-':
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c == '-') {
|
if (c == '-') {
|
||||||
|
|
@ -2655,7 +2655,7 @@ maybe_newline:
|
||||||
PARSE2('*', '*', '=', TOK_A_MUL)
|
PARSE2('*', '*', '=', TOK_A_MUL)
|
||||||
PARSE2('%', '%', '=', TOK_A_MOD)
|
PARSE2('%', '%', '=', TOK_A_MOD)
|
||||||
PARSE2('^', '^', '=', TOK_A_XOR)
|
PARSE2('^', '^', '=', TOK_A_XOR)
|
||||||
|
|
||||||
/* comments or operator */
|
/* comments or operator */
|
||||||
case '/':
|
case '/':
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
|
|
@ -2675,7 +2675,7 @@ maybe_newline:
|
||||||
tok = '/';
|
tok = '/';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* simple tokens */
|
/* simple tokens */
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
|
|
@ -2730,7 +2730,7 @@ ST_FUNC void next_nomacro(void)
|
||||||
next_nomacro_spc();
|
next_nomacro_spc();
|
||||||
} while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
|
} while (tok < 256 && (isidnum_table[tok - CH_EOF] & IS_SPC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void macro_subst(
|
static void macro_subst(
|
||||||
TokenString *tok_str,
|
TokenString *tok_str,
|
||||||
|
|
@ -2924,7 +2924,7 @@ static int macro_subst_tok(
|
||||||
CValue cval;
|
CValue cval;
|
||||||
CString cstr;
|
CString cstr;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
||||||
/* if symbol is a macro, prepare substitution */
|
/* if symbol is a macro, prepare substitution */
|
||||||
/* special macros */
|
/* special macros */
|
||||||
if (tok == TOK___LINE__) {
|
if (tok == TOK___LINE__) {
|
||||||
|
|
@ -2942,10 +2942,10 @@ static int macro_subst_tok(
|
||||||
time(&ti);
|
time(&ti);
|
||||||
tm = localtime(&ti);
|
tm = localtime(&ti);
|
||||||
if (tok == TOK___DATE__) {
|
if (tok == TOK___DATE__) {
|
||||||
snprintf(buf, sizeof(buf), "%s %2d %d",
|
snprintf(buf, sizeof(buf), "%s %2d %d",
|
||||||
ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
|
ab_month_name[tm->tm_mon], tm->tm_mday, tm->tm_year + 1900);
|
||||||
} else {
|
} else {
|
||||||
snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
|
snprintf(buf, sizeof(buf), "%02d:%02d:%02d",
|
||||||
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
}
|
}
|
||||||
cstrval = buf;
|
cstrval = buf;
|
||||||
|
|
@ -3010,8 +3010,8 @@ static int macro_subst_tok(
|
||||||
tok_str_new(&str);
|
tok_str_new(&str);
|
||||||
parlevel = spc = 0;
|
parlevel = spc = 0;
|
||||||
/* NOTE: non zero sa->t indicates VA_ARGS */
|
/* NOTE: non zero sa->t indicates VA_ARGS */
|
||||||
while ((parlevel > 0 ||
|
while ((parlevel > 0 ||
|
||||||
(tok != ')' &&
|
(tok != ')' &&
|
||||||
(tok != ',' || sa->type.t)))) {
|
(tok != ',' || sa->type.t)))) {
|
||||||
if (tok == TOK_EOF || tok == 0)
|
if (tok == TOK_EOF || tok == 0)
|
||||||
break;
|
break;
|
||||||
|
|
@ -3143,7 +3143,7 @@ static inline int *macro_twosharps(const int *ptr0)
|
||||||
/* given 'a##b', remove nosubsts preceding 'b' */
|
/* given 'a##b', remove nosubsts preceding 'b' */
|
||||||
while ((t1 = *++ptr) == TOK_NOSUBST)
|
while ((t1 = *++ptr) == TOK_NOSUBST)
|
||||||
;
|
;
|
||||||
if (t1 && t1 != TOK_TWOSHARPS
|
if (t1 && t1 != TOK_TWOSHARPS
|
||||||
&& t1 != ':') /* 'a##:' don't build a new token */
|
&& t1 != ':') /* 'a##:' don't build a new token */
|
||||||
{
|
{
|
||||||
TOK_GET(&t1, &ptr, &cv1);
|
TOK_GET(&t1, &ptr, &cv1);
|
||||||
|
|
@ -3181,7 +3181,7 @@ static void macro_subst(
|
||||||
int t, spc, nosubst;
|
int t, spc, nosubst;
|
||||||
CValue cval;
|
CValue cval;
|
||||||
int *macro_str1 = NULL;
|
int *macro_str1 = NULL;
|
||||||
|
|
||||||
/* first scan for '##' operator handling */
|
/* first scan for '##' operator handling */
|
||||||
ptr = macro_str;
|
ptr = macro_str;
|
||||||
spc = nosubst = 0;
|
spc = nosubst = 0;
|
||||||
|
|
@ -3334,7 +3334,7 @@ ST_FUNC void preprocess_new(void)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
memset(hash_ident, 0, TOK_HASH_SIZE * sizeof(TokenSym *));
|
||||||
|
|
||||||
tok_ident = TOK_IDENT;
|
tok_ident = TOK_IDENT;
|
||||||
p = tcc_keywords;
|
p = tcc_keywords;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
|
|
|
||||||
2
tcctok.h
2
tcctok.h
|
|
@ -36,7 +36,7 @@
|
||||||
DEF(TOK_RESTRICT2, "__restrict")
|
DEF(TOK_RESTRICT2, "__restrict")
|
||||||
DEF(TOK_RESTRICT3, "__restrict__")
|
DEF(TOK_RESTRICT3, "__restrict__")
|
||||||
DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
|
DEF(TOK_EXTENSION, "__extension__") /* gcc keyword */
|
||||||
|
|
||||||
DEF(TOK_FLOAT, "float")
|
DEF(TOK_FLOAT, "float")
|
||||||
DEF(TOK_DOUBLE, "double")
|
DEF(TOK_DOUBLE, "double")
|
||||||
DEF(TOK_BOOL, "_Bool")
|
DEF(TOK_BOOL, "_Bool")
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ static int run_callback(const char *src, callback_type callback) {
|
||||||
TCCState *s;
|
TCCState *s;
|
||||||
int result;
|
int result;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
s = tcc_new();
|
s = tcc_new();
|
||||||
if (!s)
|
if (!s)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -54,14 +54,14 @@ static int run_callback(const char *src, callback_type callback) {
|
||||||
return -1;
|
return -1;
|
||||||
if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
|
if (tcc_relocate(s, TCC_RELOCATE_AUTO) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
ptr = tcc_get_symbol(s, "f");
|
ptr = tcc_get_symbol(s, "f");
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return -1;
|
return -1;
|
||||||
result = callback(ptr);
|
result = callback(ptr);
|
||||||
|
|
||||||
tcc_delete(s);
|
tcc_delete(s);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ RET_PRIMITIVE_TEST(longdouble, LONG_DOUBLE, LONG_DOUBLE_LITERAL(378943892.0))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ret_2float_test:
|
* ret_2float_test:
|
||||||
*
|
*
|
||||||
* On x86-64, a struct with 2 floats should be packed into a single
|
* On x86-64, a struct with 2 floats should be packed into a single
|
||||||
* SSE register (VT_DOUBLE is used for this purpose).
|
* SSE register (VT_DOUBLE is used for this purpose).
|
||||||
*/
|
*/
|
||||||
|
|
@ -117,7 +117,7 @@ static int ret_2float_test(void) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ret_2double_test:
|
* ret_2double_test:
|
||||||
*
|
*
|
||||||
* On x86-64, a struct with 2 doubles should be passed in two SSE
|
* On x86-64, a struct with 2 doubles should be passed in two SSE
|
||||||
* registers.
|
* registers.
|
||||||
*/
|
*/
|
||||||
|
|
@ -281,7 +281,7 @@ static int reg_pack_test(void) {
|
||||||
" reg_pack_test_type r = {a.x*5, a.y*3};\n"
|
" reg_pack_test_type r = {a.x*5, a.y*3};\n"
|
||||||
" return r;\n"
|
" return r;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
return run_callback(src, reg_pack_test_callback);
|
return run_callback(src, reg_pack_test_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -307,7 +307,7 @@ static int reg_pack_longlong_test(void) {
|
||||||
" reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
|
" reg_pack_longlong_test_type r = {a.x*5, a.y*3};\n"
|
||||||
" return r;\n"
|
" return r;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
return run_callback(src, reg_pack_longlong_test_callback);
|
return run_callback(src, reg_pack_longlong_test_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -365,13 +365,13 @@ static int sret_test(void) {
|
||||||
" sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
|
" sret_test_type r = {x.a*35, x.b*19, x.c*21};\n"
|
||||||
" return r;\n"
|
" return r;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
return run_callback(src, sret_test_callback);
|
return run_callback(src, sret_test_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* one_member_union_test:
|
* one_member_union_test:
|
||||||
*
|
*
|
||||||
* In the x86-64 ABI a union should always be passed on the stack. However
|
* In the x86-64 ABI a union should always be passed on the stack. However
|
||||||
* it appears that a single member union is treated by GCC as its member.
|
* it appears that a single member union is treated by GCC as its member.
|
||||||
*/
|
*/
|
||||||
|
|
@ -399,7 +399,7 @@ static int one_member_union_test(void) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* two_member_union_test:
|
* two_member_union_test:
|
||||||
*
|
*
|
||||||
* In the x86-64 ABI a union should always be passed on the stack.
|
* In the x86-64 ABI a union should always be passed on the stack.
|
||||||
*/
|
*/
|
||||||
typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
|
typedef union two_member_union_test_type_u {int x; long y;} two_member_union_test_type;
|
||||||
|
|
@ -430,7 +430,7 @@ static int two_member_union_test(void) {
|
||||||
|
|
||||||
typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
|
typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;
|
||||||
typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
|
typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type);
|
||||||
|
|
||||||
static int many_struct_test_callback(void *ptr) {
|
static int many_struct_test_callback(void *ptr) {
|
||||||
many_struct_test_function_type f = (many_struct_test_function_type)ptr;
|
many_struct_test_function_type f = (many_struct_test_function_type)ptr;
|
||||||
many_struct_test_type v = {1, 2, 3};
|
many_struct_test_type v = {1, 2, 3};
|
||||||
|
|
@ -457,7 +457,7 @@ static int many_struct_test(void) {
|
||||||
|
|
||||||
typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
|
typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;
|
||||||
typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
|
typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type);
|
||||||
|
|
||||||
static int many_struct_test_2_callback(void *ptr) {
|
static int many_struct_test_2_callback(void *ptr) {
|
||||||
many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
|
many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr;
|
||||||
many_struct_test_2_type v = {1,2};
|
many_struct_test_2_type v = {1,2};
|
||||||
|
|
@ -598,7 +598,7 @@ static int arg_align_test_callback(void *ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int arg_align_test(void) {
|
static int arg_align_test(void) {
|
||||||
const char *src =
|
const char *src =
|
||||||
"long double f(long double a, int b, long double c, int d, long double e) {\n"
|
"long double f(long double a, int b, long double c, int d, long double e) {\n"
|
||||||
" return a + c + e;\n"
|
" return a + c + e;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
@ -621,7 +621,7 @@ int main(int argc, char **argv) {
|
||||||
int i;
|
int i;
|
||||||
const char *testname = NULL;
|
const char *testname = NULL;
|
||||||
int retval = EXIT_SUCCESS;
|
int retval = EXIT_SUCCESS;
|
||||||
|
|
||||||
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
|
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
|
||||||
for (i = 1; i < argc; ++i) {
|
for (i = 1; i < argc; ++i) {
|
||||||
if (!memcmp(argv[i], "run_test=", 9))
|
if (!memcmp(argv[i], "run_test=", 9))
|
||||||
|
|
|
||||||
116
tests/tcctest.c
116
tests/tcctest.c
|
|
@ -320,7 +320,7 @@ void macro_test(void)
|
||||||
#line 200
|
#line 200
|
||||||
printf("__LINE__=%d __FILE__=%s\n",
|
printf("__LINE__=%d __FILE__=%s\n",
|
||||||
__LINE__, __FILE__);
|
__LINE__, __FILE__);
|
||||||
#line 203 "test"
|
#line 203 "test"
|
||||||
printf("__LINE__=%d __FILE__=%s\n",
|
printf("__LINE__=%d __FILE__=%s\n",
|
||||||
__LINE__, __FILE__);
|
__LINE__, __FILE__);
|
||||||
#line 227 "tcctest.c"
|
#line 227 "tcctest.c"
|
||||||
|
|
@ -348,7 +348,7 @@ void macro_test(void)
|
||||||
glue(a <, <= 2);
|
glue(a <, <= 2);
|
||||||
printf("a=%d\n", a);
|
printf("a=%d\n", a);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* macro function with argument outside the macro string */
|
/* macro function with argument outside the macro string */
|
||||||
#define MF_s MF_hello
|
#define MF_s MF_hello
|
||||||
#define MF_hello(msg) printf("%s\n",msg)
|
#define MF_hello(msg) printf("%s\n",msg)
|
||||||
|
|
@ -357,7 +357,7 @@ void macro_test(void)
|
||||||
|
|
||||||
MF_s("hi");
|
MF_s("hi");
|
||||||
MF_t("hi");
|
MF_t("hi");
|
||||||
|
|
||||||
/* test macro substituion inside args (should not eat stream) */
|
/* test macro substituion inside args (should not eat stream) */
|
||||||
printf("qq=%d\n", qq(qq)(2));
|
printf("qq=%d\n", qq(qq)(2));
|
||||||
|
|
||||||
|
|
@ -398,7 +398,7 @@ void recursive_macro_test(void)
|
||||||
printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
|
printf("%d\n", ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(123)));
|
||||||
|
|
||||||
#define WRAP(x) x
|
#define WRAP(x) x
|
||||||
|
|
||||||
#define print_num(x) print_num(__FILE__,__LINE__,x)
|
#define print_num(x) print_num(__FILE__,__LINE__,x)
|
||||||
print_num(123);
|
print_num(123);
|
||||||
WRAP(print_num(123));
|
WRAP(print_num(123));
|
||||||
|
|
@ -537,7 +537,7 @@ void goto_test()
|
||||||
/* This needs to parse as label, not as start of decl. */
|
/* This needs to parse as label, not as start of decl. */
|
||||||
typedef_and_label:
|
typedef_and_label:
|
||||||
s_loop:
|
s_loop:
|
||||||
if (i >= 10)
|
if (i >= 10)
|
||||||
goto s_end;
|
goto s_end;
|
||||||
printf("%d", i);
|
printf("%d", i);
|
||||||
i++;
|
i++;
|
||||||
|
|
@ -688,7 +688,7 @@ int main(int argc, char **argv)
|
||||||
callsave_test();
|
callsave_test();
|
||||||
builtin_frame_address_test();
|
builtin_frame_address_test();
|
||||||
intdiv_test();
|
intdiv_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tab[3];
|
int tab[3];
|
||||||
|
|
@ -797,10 +797,10 @@ void expr_test()
|
||||||
printf("%d\n", ~12);
|
printf("%d\n", ~12);
|
||||||
printf("%d\n", -12);
|
printf("%d\n", -12);
|
||||||
printf("%d\n", +12);
|
printf("%d\n", +12);
|
||||||
printf("%d %d %d %d\n",
|
printf("%d %d %d %d\n",
|
||||||
isid('a'),
|
isid('a'),
|
||||||
isid('g'),
|
isid('g'),
|
||||||
isid('T'),
|
isid('T'),
|
||||||
isid('('));
|
isid('('));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -984,7 +984,7 @@ void struct_test()
|
||||||
sizeof(struct aligntest3), __alignof__(struct aligntest3));
|
sizeof(struct aligntest3), __alignof__(struct aligntest3));
|
||||||
printf("aligntest4 sizeof=%d alignof=%d\n",
|
printf("aligntest4 sizeof=%d alignof=%d\n",
|
||||||
sizeof(struct aligntest4), __alignof__(struct aligntest4));
|
sizeof(struct aligntest4), __alignof__(struct aligntest4));
|
||||||
|
|
||||||
/* empty structures (GCC extension) */
|
/* empty structures (GCC extension) */
|
||||||
printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
|
printf("sizeof(struct empty) = %d\n", sizeof(struct empty));
|
||||||
printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
|
printf("alignof(struct empty) = %d\n", __alignof__(struct empty));
|
||||||
|
|
@ -999,17 +999,17 @@ void char_short_test()
|
||||||
|
|
||||||
var1 = 0x01020304;
|
var1 = 0x01020304;
|
||||||
var2 = 0xfffefdfc;
|
var2 = 0xfffefdfc;
|
||||||
printf("s8=%d %d\n",
|
printf("s8=%d %d\n",
|
||||||
*(char *)&var1, *(char *)&var2);
|
*(char *)&var1, *(char *)&var2);
|
||||||
printf("u8=%d %d\n",
|
printf("u8=%d %d\n",
|
||||||
*(unsigned char *)&var1, *(unsigned char *)&var2);
|
*(unsigned char *)&var1, *(unsigned char *)&var2);
|
||||||
printf("s16=%d %d\n",
|
printf("s16=%d %d\n",
|
||||||
*(short *)&var1, *(short *)&var2);
|
*(short *)&var1, *(short *)&var2);
|
||||||
printf("u16=%d %d\n",
|
printf("u16=%d %d\n",
|
||||||
*(unsigned short *)&var1, *(unsigned short *)&var2);
|
*(unsigned short *)&var1, *(unsigned short *)&var2);
|
||||||
printf("s32=%d %d\n",
|
printf("s32=%d %d\n",
|
||||||
*(int *)&var1, *(int *)&var2);
|
*(int *)&var1, *(int *)&var2);
|
||||||
printf("u32=%d %d\n",
|
printf("u32=%d %d\n",
|
||||||
*(unsigned int *)&var1, *(unsigned int *)&var2);
|
*(unsigned int *)&var1, *(unsigned int *)&var2);
|
||||||
*(char *)&var1 = 0x08;
|
*(char *)&var1 = 0x08;
|
||||||
printf("var1=%x\n", var1);
|
printf("var1=%x\n", var1);
|
||||||
|
|
@ -1099,7 +1099,7 @@ void bool_test()
|
||||||
static int v1 = 34 ? : -1; /* constant case */
|
static int v1 = 34 ? : -1; /* constant case */
|
||||||
static int v2 = 0 ? : -1; /* constant case */
|
static int v2 = 0 ? : -1; /* constant case */
|
||||||
int a = 30;
|
int a = 30;
|
||||||
|
|
||||||
printf("%d %d\n", v1, v2);
|
printf("%d %d\n", v1, v2);
|
||||||
printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
|
printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2);
|
||||||
}
|
}
|
||||||
|
|
@ -1116,8 +1116,8 @@ static int tab_reinit[];
|
||||||
static int tab_reinit[10];
|
static int tab_reinit[10];
|
||||||
|
|
||||||
//int cinit1; /* a global variable can be defined several times without error ! */
|
//int cinit1; /* a global variable can be defined several times without error ! */
|
||||||
int cinit1;
|
int cinit1;
|
||||||
int cinit1;
|
int cinit1;
|
||||||
int cinit1 = 0;
|
int cinit1 = 0;
|
||||||
int *cinit2 = (int []){3, 2, 1};
|
int *cinit2 = (int []){3, 2, 1};
|
||||||
|
|
||||||
|
|
@ -1157,7 +1157,7 @@ void compound_literal_test(void)
|
||||||
|
|
||||||
for(i=0;i<3;i++) {
|
for(i=0;i<3;i++) {
|
||||||
p = (int []){1, 2, 4 + i};
|
p = (int []){1, 2, 4 + i};
|
||||||
printf("%d %d %d\n",
|
printf("%d %d %d\n",
|
||||||
p[0],
|
p[0],
|
||||||
p[1],
|
p[1],
|
||||||
p[2]);
|
p[2]);
|
||||||
|
|
@ -1188,7 +1188,7 @@ kr_test()
|
||||||
void num(int n)
|
void num(int n)
|
||||||
{
|
{
|
||||||
char *tab, *p;
|
char *tab, *p;
|
||||||
tab = (char*)malloc(20);
|
tab = (char*)malloc(20);
|
||||||
p = tab;
|
p = tab;
|
||||||
while (1) {
|
while (1) {
|
||||||
*p = 48 + (n % 10);
|
*p = 48 + (n % 10);
|
||||||
|
|
@ -1231,7 +1231,7 @@ void struct_assign_test(void)
|
||||||
struct structa1 lsta1, lsta2;
|
struct structa1 lsta1, lsta2;
|
||||||
int i;
|
int i;
|
||||||
} s, *ps;
|
} s, *ps;
|
||||||
|
|
||||||
ps = &s;
|
ps = &s;
|
||||||
ps->i = 4;
|
ps->i = 4;
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -1247,7 +1247,7 @@ void struct_assign_test(void)
|
||||||
s.lsta2.f2 = 2;
|
s.lsta2.f2 = 2;
|
||||||
#endif
|
#endif
|
||||||
struct_assign_test1(ps->lsta2, 3, 4.5);
|
struct_assign_test1(ps->lsta2, 3, 4.5);
|
||||||
|
|
||||||
printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
|
printf("before call: %d %d\n", s.lsta2.f1, s.lsta2.f2);
|
||||||
ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
|
ps->lsta2 = struct_assign_test2(ps->lsta2, ps->i);
|
||||||
printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
|
printf("after call: %d %d\n", ps->lsta2.f1, ps->lsta2.f2);
|
||||||
|
|
@ -1300,9 +1300,9 @@ void cast_test()
|
||||||
printf("%d\n", a);
|
printf("%d\n", a);
|
||||||
a = (scast = 65536) + 1;
|
a = (scast = 65536) + 1;
|
||||||
printf("%d\n", a);
|
printf("%d\n", a);
|
||||||
|
|
||||||
printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
|
printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c));
|
||||||
|
|
||||||
/* test cast from unsigned to signed short to int */
|
/* test cast from unsigned to signed short to int */
|
||||||
b = 0xf000;
|
b = 0xf000;
|
||||||
d = (short)b;
|
d = (short)b;
|
||||||
|
|
@ -1310,7 +1310,7 @@ void cast_test()
|
||||||
b = 0xf0f0;
|
b = 0xf0f0;
|
||||||
d = (char)b;
|
d = (char)b;
|
||||||
printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
|
printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d);
|
||||||
|
|
||||||
/* test implicit int casting for array accesses */
|
/* test implicit int casting for array accesses */
|
||||||
c = 0;
|
c = 0;
|
||||||
tab[1] = 2;
|
tab[1] = 2;
|
||||||
|
|
@ -1352,7 +1352,7 @@ char sinit8[] = "hello" "trala";
|
||||||
|
|
||||||
struct structinit1 sinit9 = { 1, 2, 3 };
|
struct structinit1 sinit9 = { 1, 2, 3 };
|
||||||
struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
|
struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 };
|
||||||
struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
|
struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1,
|
||||||
#ifdef ALL_ISOC99
|
#ifdef ALL_ISOC99
|
||||||
.farray[0] = 10,
|
.farray[0] = 10,
|
||||||
.farray[1] = 11,
|
.farray[1] = 11,
|
||||||
|
|
@ -1437,36 +1437,36 @@ void init_test(void)
|
||||||
int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
|
int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, };
|
||||||
struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
|
struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 };
|
||||||
int linit17 = sizeof(linit17);
|
int linit17 = sizeof(linit17);
|
||||||
|
|
||||||
printf("init_test:\n");
|
printf("init_test:\n");
|
||||||
|
|
||||||
printf("sinit1=%d\n", sinit1);
|
printf("sinit1=%d\n", sinit1);
|
||||||
printf("sinit2=%d\n", sinit2);
|
printf("sinit2=%d\n", sinit2);
|
||||||
printf("sinit3=%d %d %d %d\n",
|
printf("sinit3=%d %d %d %d\n",
|
||||||
sizeof(sinit3),
|
sizeof(sinit3),
|
||||||
sinit3[0],
|
sinit3[0],
|
||||||
sinit3[1],
|
sinit3[1],
|
||||||
sinit3[2]
|
sinit3[2]
|
||||||
);
|
);
|
||||||
printf("sinit6=%d\n", sizeof(sinit6));
|
printf("sinit6=%d\n", sizeof(sinit6));
|
||||||
printf("sinit7=%d %d %d %d\n",
|
printf("sinit7=%d %d %d %d\n",
|
||||||
sizeof(sinit7),
|
sizeof(sinit7),
|
||||||
sinit7[0],
|
sinit7[0],
|
||||||
sinit7[1],
|
sinit7[1],
|
||||||
sinit7[2]
|
sinit7[2]
|
||||||
);
|
);
|
||||||
printf("sinit8=%s\n", sinit8);
|
printf("sinit8=%s\n", sinit8);
|
||||||
printf("sinit9=%d %d %d\n",
|
printf("sinit9=%d %d %d\n",
|
||||||
sinit9.f1,
|
sinit9.f1,
|
||||||
sinit9.f2,
|
sinit9.f2,
|
||||||
sinit9.f3
|
sinit9.f3
|
||||||
);
|
);
|
||||||
printf("sinit10=%d %d %d\n",
|
printf("sinit10=%d %d %d\n",
|
||||||
sinit10.f1,
|
sinit10.f1,
|
||||||
sinit10.f2,
|
sinit10.f2,
|
||||||
sinit10.f3
|
sinit10.f3
|
||||||
);
|
);
|
||||||
printf("sinit11=%d %d %d %d %d %d\n",
|
printf("sinit11=%d %d %d %d %d %d\n",
|
||||||
sinit11.f1,
|
sinit11.f1,
|
||||||
sinit11.f2,
|
sinit11.f2,
|
||||||
sinit11.f3,
|
sinit11.f3,
|
||||||
|
|
@ -1477,7 +1477,7 @@ void init_test(void)
|
||||||
|
|
||||||
for(i=0;i<3;i++)
|
for(i=0;i<3;i++)
|
||||||
for(j=0;j<2;j++)
|
for(j=0;j<2;j++)
|
||||||
printf("[%d][%d] = %d %d %d\n",
|
printf("[%d][%d] = %d %d %d\n",
|
||||||
i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
|
i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]);
|
||||||
printf("linit1=%d\n", linit1);
|
printf("linit1=%d\n", linit1);
|
||||||
printf("linit2=%d\n", linit2);
|
printf("linit2=%d\n", linit2);
|
||||||
|
|
@ -1486,7 +1486,7 @@ void init_test(void)
|
||||||
|
|
||||||
printf("sinit12=%s\n", sinit12);
|
printf("sinit12=%s\n", sinit12);
|
||||||
printf("sinit13=%d %s %s %s\n",
|
printf("sinit13=%d %s %s %s\n",
|
||||||
sizeof(sinit13),
|
sizeof(sinit13),
|
||||||
sinit13[0],
|
sinit13[0],
|
||||||
sinit13[1],
|
sinit13[1],
|
||||||
sinit13[2]);
|
sinit13[2]);
|
||||||
|
|
@ -1500,7 +1500,7 @@ void init_test(void)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
for(i=0;i<10;i++) printf(" %d", linit15[i]);
|
for(i=0;i<10;i++) printf(" %d", linit15[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("%d %d %d %d\n",
|
printf("%d %d %d %d\n",
|
||||||
linit16.a1,
|
linit16.a1,
|
||||||
linit16.a2,
|
linit16.a2,
|
||||||
linit16.a3,
|
linit16.a3,
|
||||||
|
|
@ -1599,13 +1599,13 @@ void bitfield_test(void)
|
||||||
printf("%d %d\n", sa, ca);
|
printf("%d %d\n", sa, ca);
|
||||||
|
|
||||||
st1.f1 = 7;
|
st1.f1 = 7;
|
||||||
if (st1.f1 == -1)
|
if (st1.f1 == -1)
|
||||||
printf("st1.f1 == -1\n");
|
printf("st1.f1 == -1\n");
|
||||||
else
|
else
|
||||||
printf("st1.f1 != -1\n");
|
printf("st1.f1 != -1\n");
|
||||||
if (st1.f2 == -1)
|
if (st1.f2 == -1)
|
||||||
printf("st1.f2 == -1\n");
|
printf("st1.f2 == -1\n");
|
||||||
else
|
else
|
||||||
printf("st1.f2 != -1\n");
|
printf("st1.f2 != -1\n");
|
||||||
|
|
||||||
/* bit sizes below must be bigger than 32 since GCC doesn't allow
|
/* bit sizes below must be bigger than 32 since GCC doesn't allow
|
||||||
|
|
@ -1835,7 +1835,7 @@ void lloptest(long long a, long long b)
|
||||||
a + b,
|
a + b,
|
||||||
a - b,
|
a - b,
|
||||||
a * b);
|
a * b);
|
||||||
|
|
||||||
if (b != 0) {
|
if (b != 0) {
|
||||||
printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
|
printf("arith1: " LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n",
|
||||||
a / b,
|
a / b,
|
||||||
|
|
@ -1856,7 +1856,7 @@ void lloptest(long long a, long long b)
|
||||||
a > b,
|
a > b,
|
||||||
a >= b,
|
a >= b,
|
||||||
a <= b);
|
a <= b);
|
||||||
|
|
||||||
printf("utest: %d %d %d %d %d %d\n",
|
printf("utest: %d %d %d %d %d %d\n",
|
||||||
ua == ub,
|
ua == ub,
|
||||||
ua != ub,
|
ua != ub,
|
||||||
|
|
@ -1932,7 +1932,7 @@ long long llfunc1(int a)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct S {
|
struct S {
|
||||||
int id;
|
int id;
|
||||||
char item;
|
char item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1953,8 +1953,8 @@ void longlong_test(void)
|
||||||
a = ia;
|
a = ia;
|
||||||
b = ua;
|
b = ua;
|
||||||
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
|
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT "\n", a, b);
|
||||||
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
|
printf(LONG_LONG_FORMAT " " LONG_LONG_FORMAT " " LONG_LONG_FORMAT " %Lx\n",
|
||||||
(long long)1,
|
(long long)1,
|
||||||
(long long)-2,
|
(long long)-2,
|
||||||
1LL,
|
1LL,
|
||||||
0x1234567812345679);
|
0x1234567812345679);
|
||||||
|
|
@ -2049,7 +2049,7 @@ void vprintf1(const char *fmt, ...)
|
||||||
|
|
||||||
va_start(aq, fmt);
|
va_start(aq, fmt);
|
||||||
va_copy(ap, aq);
|
va_copy(ap, aq);
|
||||||
|
|
||||||
p = fmt;
|
p = fmt;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = *p;
|
c = *p;
|
||||||
|
|
@ -2250,10 +2250,10 @@ void c99_vla_test(int size1, int size2)
|
||||||
int tab1[size][2], tab2[10][2];
|
int tab1[size][2], tab2[10][2];
|
||||||
void *tab1_ptr, *tab2_ptr, *bad_ptr;
|
void *tab1_ptr, *tab2_ptr, *bad_ptr;
|
||||||
|
|
||||||
/* "size" should have been 'captured' at tab1 declaration,
|
/* "size" should have been 'captured' at tab1 declaration,
|
||||||
so modifying it should have no effect on VLA behaviour. */
|
so modifying it should have no effect on VLA behaviour. */
|
||||||
size = size-1;
|
size = size-1;
|
||||||
|
|
||||||
printf("Test C99 VLA 1 (sizeof): ");
|
printf("Test C99 VLA 1 (sizeof): ");
|
||||||
printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
|
printf("%s\n", (sizeof tab1 == size1 * size2 * 2 * sizeof(int)) ? "PASSED" : "FAILED");
|
||||||
tab1_ptr = tab1;
|
tab1_ptr = tab1;
|
||||||
|
|
@ -2325,7 +2325,7 @@ void sizeof_test(void)
|
||||||
t <<= 16;
|
t <<= 16;
|
||||||
t <<= 16;
|
t <<= 16;
|
||||||
t++;
|
t++;
|
||||||
/* This checks that sizeof really can be used to manipulate
|
/* This checks that sizeof really can be used to manipulate
|
||||||
uintptr_t objects, without truncation. */
|
uintptr_t objects, without truncation. */
|
||||||
t2 = t & -sizeof(uintptr_t);
|
t2 = t & -sizeof(uintptr_t);
|
||||||
printf ("%lu %lu\n", t, t2);
|
printf ("%lu %lu\n", t, t2);
|
||||||
|
|
@ -2358,15 +2358,15 @@ void statement_expr_test(void)
|
||||||
|
|
||||||
a = 0;
|
a = 0;
|
||||||
for(i=0;i<10;i++) {
|
for(i=0;i<10;i++) {
|
||||||
a += 1 +
|
a += 1 +
|
||||||
( { int b, j;
|
( { int b, j;
|
||||||
b = 0;
|
b = 0;
|
||||||
for(j=0;j<5;j++)
|
for(j=0;j<5;j++)
|
||||||
b += j; b;
|
b += j; b;
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
printf("a=%d\n", a);
|
printf("a=%d\n", a);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void local_label_test(void)
|
void local_label_test(void)
|
||||||
|
|
@ -2589,7 +2589,7 @@ void builtin_test(void)
|
||||||
COMPAT_TYPE(char *, signed char *);
|
COMPAT_TYPE(char *, signed char *);
|
||||||
COMPAT_TYPE(char *, char *);
|
COMPAT_TYPE(char *, char *);
|
||||||
/* space is needed because tcc preprocessor introduces a space between each token */
|
/* space is needed because tcc preprocessor introduces a space between each token */
|
||||||
COMPAT_TYPE(char * *, void *);
|
COMPAT_TYPE(char * *, void *);
|
||||||
#endif
|
#endif
|
||||||
printf("res = %d\n", __builtin_constant_p(1));
|
printf("res = %d\n", __builtin_constant_p(1));
|
||||||
printf("res = %d\n", __builtin_constant_p(1 + 2));
|
printf("res = %d\n", __builtin_constant_p(1 + 2));
|
||||||
|
|
@ -2640,7 +2640,7 @@ void __attribute__((weak)) weak_test(void)
|
||||||
printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
|
printf("weak_fpa=%d\n",&weak_fpa ? weak_fpa() : 123);
|
||||||
printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
|
printf("weak_fpb=%d\n",&weak_fpb ? weak_fpb() : 123);
|
||||||
printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
|
printf("weak_fpc=%d\n",&weak_fpc ? weak_fpc() : 123);
|
||||||
|
|
||||||
printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
|
printf("weak_asm_f1=%d\n", weak_asm_f1 != NULL);
|
||||||
printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
|
printf("weak_asm_f2=%d\n", weak_asm_f2 != NULL);
|
||||||
printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
|
printf("weak_asm_f3=%d\n", weak_asm_f3 != NULL);
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@ while(<$inf>) {
|
||||||
$inf = gensym();
|
$inf = gensym();
|
||||||
|
|
||||||
# Try cwd and $ibase.
|
# Try cwd and $ibase.
|
||||||
open($inf, "<" . $1)
|
open($inf, "<" . $1)
|
||||||
or open($inf, "<" . $ibase . "/" . $1)
|
or open($inf, "<" . $ibase . "/" . $1)
|
||||||
or die "cannot open $1 or $ibase/$1: $!\n";
|
or die "cannot open $1 or $ibase/$1: $!\n";
|
||||||
next;
|
next;
|
||||||
|
|
|
||||||
60
x86_64-gen.c
60
x86_64-gen.c
|
|
@ -681,7 +681,7 @@ ST_FUNC void gen_bounded_ptr_add(void)
|
||||||
|
|
||||||
|
|
||||||
/* relocation offset of the bounding function call point */
|
/* relocation offset of the bounding function call point */
|
||||||
vtop->c.ull = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
|
vtop->c.ull = (cur_text_section->reloc->data_offset - sizeof(ElfW(Rela)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch pointer addition in vtop so that pointer dereferencing is
|
/* patch pointer addition in vtop so that pointer dereferencing is
|
||||||
|
|
@ -823,7 +823,7 @@ void gfunc_call(int nb_args)
|
||||||
struct_size = args_size;
|
struct_size = args_size;
|
||||||
for(i = 0; i < nb_args; i++) {
|
for(i = 0; i < nb_args; i++) {
|
||||||
SValue *sv;
|
SValue *sv;
|
||||||
|
|
||||||
--arg;
|
--arg;
|
||||||
sv = &vtop[-i];
|
sv = &vtop[-i];
|
||||||
bt = (sv->type.t & VT_BTYPE);
|
bt = (sv->type.t & VT_BTYPE);
|
||||||
|
|
@ -897,7 +897,7 @@ void gfunc_call(int nb_args)
|
||||||
vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
|
vtop->type.t = size > 4 ? VT_LLONG : size > 2 ? VT_INT
|
||||||
: size > 1 ? VT_SHORT : VT_BYTE;
|
: size > 1 ? VT_SHORT : VT_BYTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = gv(RC_INT);
|
r = gv(RC_INT);
|
||||||
if (arg >= REGN) {
|
if (arg >= REGN) {
|
||||||
gen_offs_sp(0x89, r, arg*8);
|
gen_offs_sp(0x89, r, arg*8);
|
||||||
|
|
@ -911,7 +911,7 @@ void gfunc_call(int nb_args)
|
||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
save_regs(0);
|
save_regs(0);
|
||||||
|
|
||||||
/* Copy R10 and R11 into RCX and RDX, respectively */
|
/* Copy R10 and R11 into RCX and RDX, respectively */
|
||||||
if (nb_args > 0) {
|
if (nb_args > 0) {
|
||||||
o(0xd1894c); /* mov %r10, %rcx */
|
o(0xd1894c); /* mov %r10, %rcx */
|
||||||
|
|
@ -919,7 +919,7 @@ void gfunc_call(int nb_args)
|
||||||
o(0xda894c); /* mov %r11, %rdx */
|
o(0xda894c); /* mov %r11, %rdx */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gcall_or_jmp(0);
|
gcall_or_jmp(0);
|
||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
|
|
@ -1072,10 +1072,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
|
||||||
{
|
{
|
||||||
X86_64_Mode mode;
|
X86_64_Mode mode;
|
||||||
Sym *f;
|
Sym *f;
|
||||||
|
|
||||||
switch (ty->t & VT_BTYPE) {
|
switch (ty->t & VT_BTYPE) {
|
||||||
case VT_VOID: return x86_64_mode_none;
|
case VT_VOID: return x86_64_mode_none;
|
||||||
|
|
||||||
case VT_INT:
|
case VT_INT:
|
||||||
case VT_BYTE:
|
case VT_BYTE:
|
||||||
case VT_SHORT:
|
case VT_SHORT:
|
||||||
|
|
@ -1084,12 +1084,12 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
|
||||||
case VT_PTR:
|
case VT_PTR:
|
||||||
case VT_FUNC:
|
case VT_FUNC:
|
||||||
case VT_ENUM: return x86_64_mode_integer;
|
case VT_ENUM: return x86_64_mode_integer;
|
||||||
|
|
||||||
case VT_FLOAT:
|
case VT_FLOAT:
|
||||||
case VT_DOUBLE: return x86_64_mode_sse;
|
case VT_DOUBLE: return x86_64_mode_sse;
|
||||||
|
|
||||||
case VT_LDOUBLE: return x86_64_mode_x87;
|
case VT_LDOUBLE: return x86_64_mode_x87;
|
||||||
|
|
||||||
case VT_STRUCT:
|
case VT_STRUCT:
|
||||||
f = ty->ref;
|
f = ty->ref;
|
||||||
|
|
||||||
|
|
@ -1098,10 +1098,10 @@ static X86_64_Mode classify_x86_64_inner(CType *ty, int offset, int start, int e
|
||||||
if (f->c + offset >= start && f->c + offset < end)
|
if (f->c + offset >= start && f->c + offset < end)
|
||||||
mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end));
|
mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type, f->c + offset, start, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1305,7 +1305,7 @@ void gfunc_call(int nb_args)
|
||||||
args_size = 0;
|
args_size = 0;
|
||||||
while (run_start != nb_args) {
|
while (run_start != nb_args) {
|
||||||
int run_gen_reg = gen_reg, run_sse_reg = sse_reg;
|
int run_gen_reg = gen_reg, run_sse_reg = sse_reg;
|
||||||
|
|
||||||
run_end = nb_args;
|
run_end = nb_args;
|
||||||
stack_adjust = 0;
|
stack_adjust = 0;
|
||||||
for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) {
|
for(i = run_start; (i < nb_args) && (run_end == nb_args); i++) {
|
||||||
|
|
@ -1319,10 +1319,10 @@ void gfunc_call(int nb_args)
|
||||||
stack_adjust += size;
|
stack_adjust += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_reg = run_gen_reg;
|
gen_reg = run_gen_reg;
|
||||||
sse_reg = run_sse_reg;
|
sse_reg = run_sse_reg;
|
||||||
|
|
||||||
/* adjust stack to align SSE boundary */
|
/* adjust stack to align SSE boundary */
|
||||||
if (stack_adjust &= 15) {
|
if (stack_adjust &= 15) {
|
||||||
/* fetch cpu flag before the following sub will change the value */
|
/* fetch cpu flag before the following sub will change the value */
|
||||||
|
|
@ -1334,7 +1334,7 @@ void gfunc_call(int nb_args)
|
||||||
oad(0xec81, stack_adjust); /* sub $xxx, %rsp */
|
oad(0xec81, stack_adjust); /* sub $xxx, %rsp */
|
||||||
args_size += stack_adjust;
|
args_size += stack_adjust;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = run_start; i < run_end;) {
|
for(i = run_start; i < run_end;) {
|
||||||
int arg_stored = regargs_nregs(®_args[i]) == 0;
|
int arg_stored = regargs_nregs(®_args[i]) == 0;
|
||||||
SValue tmp;
|
SValue tmp;
|
||||||
|
|
@ -1344,7 +1344,7 @@ void gfunc_call(int nb_args)
|
||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Swap argument to top, it will possibly be changed here,
|
/* Swap argument to top, it will possibly be changed here,
|
||||||
and might use more temps. At the end of the loop we keep
|
and might use more temps. At the end of the loop we keep
|
||||||
in on the stack and swap it back to its original position
|
in on the stack and swap it back to its original position
|
||||||
|
|
@ -1352,7 +1352,7 @@ void gfunc_call(int nb_args)
|
||||||
tmp = vtop[0];
|
tmp = vtop[0];
|
||||||
vtop[0] = vtop[-i];
|
vtop[0] = vtop[-i];
|
||||||
vtop[-i] = tmp;
|
vtop[-i] = tmp;
|
||||||
|
|
||||||
classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args);
|
classify_x86_64_arg(&vtop->type, NULL, &size, &align, &args);
|
||||||
|
|
||||||
switch (vtop->type.t & VT_BTYPE) {
|
switch (vtop->type.t & VT_BTYPE) {
|
||||||
|
|
@ -1369,11 +1369,11 @@ void gfunc_call(int nb_args)
|
||||||
vstore();
|
vstore();
|
||||||
args_size += size;
|
args_size += size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_LDOUBLE:
|
case VT_LDOUBLE:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VT_FLOAT:
|
case VT_FLOAT:
|
||||||
case VT_DOUBLE:
|
case VT_DOUBLE:
|
||||||
r = gv(RC_FLOAT);
|
r = gv(RC_FLOAT);
|
||||||
|
|
@ -1384,7 +1384,7 @@ void gfunc_call(int nb_args)
|
||||||
o(0x24);
|
o(0x24);
|
||||||
args_size += size;
|
args_size += size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* simple type */
|
/* simple type */
|
||||||
/* XXX: implicit cast ? */
|
/* XXX: implicit cast ? */
|
||||||
|
|
@ -1417,7 +1417,7 @@ void gfunc_call(int nb_args)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
vrotb(i+1);
|
vrotb(i+1);
|
||||||
|
|
||||||
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
if ((vtop->type.t & VT_BTYPE) == VT_LDOUBLE) {
|
||||||
gv(RC_ST0);
|
gv(RC_ST0);
|
||||||
oad(0xec8148, size); /* sub $xxx, %rsp */
|
oad(0xec8148, size); /* sub $xxx, %rsp */
|
||||||
|
|
@ -1440,7 +1440,7 @@ void gfunc_call(int nb_args)
|
||||||
vstore();
|
vstore();
|
||||||
args_size += size;
|
args_size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpop();
|
vpop();
|
||||||
memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args);
|
memmove(reg_args + i, reg_args + i + 1, (nb_args - i - 1) * sizeof *reg_args);
|
||||||
--nb_args;
|
--nb_args;
|
||||||
|
|
@ -1698,7 +1698,7 @@ void gfunc_prolog(CType *func_type)
|
||||||
addr += size;
|
addr += size;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case x86_64_mode_memory:
|
case x86_64_mode_memory:
|
||||||
case x86_64_mode_x87:
|
case x86_64_mode_x87:
|
||||||
addr = (addr + align - 1) & -align;
|
addr = (addr + align - 1) & -align;
|
||||||
|
|
@ -2104,7 +2104,7 @@ void gen_opf(int op)
|
||||||
vswap();
|
vswap();
|
||||||
}
|
}
|
||||||
assert(!(vtop[-1].r & VT_LVAL));
|
assert(!(vtop[-1].r & VT_LVAL));
|
||||||
|
|
||||||
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
|
||||||
o(0x66);
|
o(0x66);
|
||||||
if (op == TOK_EQ || op == TOK_NE)
|
if (op == TOK_EQ || op == TOK_NE)
|
||||||
|
|
@ -2141,7 +2141,7 @@ void gen_opf(int op)
|
||||||
ft = vtop->type.t;
|
ft = vtop->type.t;
|
||||||
fc = vtop->c.ul;
|
fc = vtop->c.ul;
|
||||||
assert((ft & VT_BTYPE) != VT_LDOUBLE);
|
assert((ft & VT_BTYPE) != VT_LDOUBLE);
|
||||||
|
|
||||||
r = vtop->r;
|
r = vtop->r;
|
||||||
/* if saved lvalue, then we must reload it */
|
/* if saved lvalue, then we must reload it */
|
||||||
if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
|
if ((vtop->r & VT_VALMASK) == VT_LLOCAL) {
|
||||||
|
|
@ -2153,14 +2153,14 @@ void gen_opf(int op)
|
||||||
load(r, &v1);
|
load(r, &v1);
|
||||||
fc = 0;
|
fc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!(vtop[-1].r & VT_LVAL));
|
assert(!(vtop[-1].r & VT_LVAL));
|
||||||
if (swapped) {
|
if (swapped) {
|
||||||
assert(vtop->r & VT_LVAL);
|
assert(vtop->r & VT_LVAL);
|
||||||
gv(RC_FLOAT);
|
gv(RC_FLOAT);
|
||||||
vswap();
|
vswap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
if ((ft & VT_BTYPE) == VT_DOUBLE) {
|
||||||
o(0xf2);
|
o(0xf2);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2168,7 +2168,7 @@ void gen_opf(int op)
|
||||||
}
|
}
|
||||||
o(0x0f);
|
o(0x0f);
|
||||||
o(0x58 + a);
|
o(0x58 + a);
|
||||||
|
|
||||||
if (vtop->r & VT_LVAL) {
|
if (vtop->r & VT_LVAL) {
|
||||||
gen_modrm(vtop[-1].r, r, vtop->sym, fc);
|
gen_modrm(vtop[-1].r, r, vtop->sym, fc);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2231,7 +2231,7 @@ void gen_cvt_ftof(int t)
|
||||||
ft = vtop->type.t;
|
ft = vtop->type.t;
|
||||||
bt = ft & VT_BTYPE;
|
bt = ft & VT_BTYPE;
|
||||||
tbt = t & VT_BTYPE;
|
tbt = t & VT_BTYPE;
|
||||||
|
|
||||||
if (bt == VT_FLOAT) {
|
if (bt == VT_FLOAT) {
|
||||||
gv(RC_FLOAT);
|
gv(RC_FLOAT);
|
||||||
if (tbt == VT_DOUBLE) {
|
if (tbt == VT_DOUBLE) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue