Commit Graph

752 Commits

Author SHA1 Message Date
grischka
610fd47510 win32: structure return GCC compatible (ret 4 with cdecl) 2009-06-17 02:11:13 +02:00
grischka
ec54c34b9e error messages: print "error: ..." 2009-06-17 02:10:56 +02:00
grischka
e4ae77c7bb tcc_preprocess: add gcc-style include-depth flags
# 1 "main.c"
    # 1 "include/stdio.h" 1
    # 123 "include/stdio.h" 3
    # 10 "main.c" 2

flags: 1: level++; 3: same-level  2: level--
2009-06-17 02:10:42 +02:00
grischka
956b4beec1 incompatible function ptr assignment: just warn
void fn_1(int i) {}
    void (*fn_2)(char*) = fn_1;
2009-06-17 02:10:24 +02:00
grischka
6a004ed19f allow redefinition of func_old_type functions
void *memcpy(void*, const void*, unsigned);

This gave an error if memcpy() has been used before
implicitely,  e.g. for structure passing etc.
2009-06-17 02:09:52 +02:00
Soloist Deng
c3701df16c trying to fix the bug of unclean FPU st(0)
Date: Mon, 8 Jun 2009 19:06:56 +0800
From: Soloist Deng <soloist.deng-gmail-com>
Subject: [Tinycc-devel] trying to fix the bug of unclean FPU st(0)

Hi all:

   I  am using  tcc-0.9.25, and the FPU bug brought a big trouble to
me. I read the source and tried to fix it.
Below is my solution.

 There are two places where program(`o(0xd9dd)') will generates `fstp
%st(1)': vpop() in tccgen.c:689 and save_reg() in tccgen.c:210.
We should first change both of them to `o(0xd8dd) // fstp %st(0)'.
But these changes are not enough.  Let's check the following code.

void foo()
{
 double var = 2.7;
 var++;
}

Using  the changed tcc will generate following machine code:

.text:08000000                 public foo
.text:08000000 foo             proc near
.text:08000000
.text:08000000 var_18          = qword ptr -18h
.text:08000000 var_10          = qword ptr -10h
.text:08000000 var_8           = qword ptr -8
.text:08000000
.text:08000000                 push    ebp
.text:08000001                 mov     ebp, esp
.text:08000003                 sub     esp, 18h
.text:08000009                 nop
.text:0800000A                 fld     L_0
.text:08000010                 fst     [ebp+var_8]
.text:08000013                 fstp    st(0)
.text:08000015                 fld     [ebp+var_8]
.text:08000018                 fst     [ebp+var_10]
.text:0800001B                 fstp    st(0)
.text:0800001D                 fst     [ebp+var_18]
.text:08000020                 fstp    st(0)
.text:08000022                 fld     L_1
.text:08000028                 fadd    [ebp+var_10]
.text:0800002B                 fst     [ebp+var_8]
.text:0800002E                 fstp    st(0)
.text:08000030                 leave
.text:08000031                 retn
.text:08000031 foo             endp
.text:08000031
.text:08000031 _text           ends
--------------------------------------------------
.data:08000040 ; Segment type: Pure data
.data:08000040 ; Segment permissions: Read/Write
.data:08000040 ; Segment alignment '32byte' can not be represented in assembly
.data:08000040 _data           segment page public 'DATA' use32
.data:08000040                 assume cs:_data
.data:08000040                 ;org 8000040h
.data:08000040 L_0             dq 400599999999999Ah
.data:08000048 L_1             dq 3FF0000000000000h
.data:08000048 _data           ends

Please notice the code snippet from 0800000A  to 08000020
// double var = 2.7; load constant to st(0)
.text:0800000A                 fld     L_0
// double var = 2.7; store st(0) to `var'
.text:08000010                 fst     [ebp+var_8]
// double var = 2.7; poping st(0)  will empty the floating registers stack
.text:08000013                 fstp    st(0)

  After that ,tcc will call `void inc(int post, int c)" in
tccgen.c:2150, and produce 08000015 to 0800001B through the calling
chain (inc ->gv_dup)
// load from `var' to st(0)
.text:08000015                 fld     [ebp+var_8]
// store st(0) to a temporary location
.text:08000018                 fst     [ebp+var_10]
// poping st(0)  will empty the floating registers stack
.text:0800001B                 fstp    st(0)

  And the calling chain
(gen_op('+')->gen_opif('+')->gen_opf('+')->gv(rc=2)->get_reg(rc=2)->save_reg(r=3))
will produce 0800001D to 08000020 .
// store st(0) to a temporary location, but floating stack is empty!
.text:0800001D                 fst     [ebp+var_18]
// poping st(0)  will empty the floating registers stack
.text:08000020                 fstp    st(0)

   The `0800001D   fst     [ebp+var_18]' will store st(0) to a memory
location, but st(0) is empty. That will cause  FPU invalid operation
exception(#IE).
Why does tcc do that? Please read `gv_dup' called by `inc' carefully.
Notice these lines:

(1):        r = gv(rc);
(2):        r1 = get_reg(rc);
(3):        sv.r = r;
            sv.c.ul = 0;
(4)         load(r1, &sv); /* move r to r1 */
(5)         vdup();
            /* duplicates value */
(6)         vtop->r = r1;

 (1)  let the vtop occupy TREG_ST0, and `r' will be TREG_ST0.  (2)
try to get a free floating register,but tcc assume
there is only one, so it wil force vtop goto memory and assign `r1'
with TREG_ST0. When executing (3), it will do nothing
because `r' equals `r1'. (5) duplicates vtop.  Then (6) let the new
vtop occupy TREG_ST0, but this will cause problem
because the old vtop has been moved to memory, so the new duplicated
vtop does not reside in TREG_ST0 but also
in memory after that. TREG_ST0 is not occupied but freely availabe
now.   `gen_op('+')'  need at least one oprand in register,
so it will incorrectly think TREG_ST0 is occupied by vtop and produce
instructions(0800001D and 08000020) to store it to
a temporary memory location.

  According program above, if `r' == `r1' it is impossible for the old
vtop to still occupy the `r' register .  And `load' will do nothing
too at this condition.
So the `gv_dup' can not promise the semantics that old vtop in one
register and the new duplicated vtop in another register at the same
time.

  I changed (6) to
if (r != r1)
{
 vtop->r = r1;
}

  Then the new generated machine code will be :

.text:08000000                 push    ebp
.text:08000001                 mov     ebp, esp
.text:08000003                 sub     esp, 10h
.text:08000009                 nop
.text:0800000A                 fld     L_0
.text:08000010                 fst     [ebp+var_8]
.text:08000013                 fstp    st(0)
.text:08000015                 fld     [ebp+var_8]
.text:08000018                 fst     [ebp+var_10]
.text:0800001B                 fstp    st(0)
.text:0800001D                 fld     L_1
.text:08000023                 fadd    [ebp+var_10]
.text:08000026                 fst     [ebp+var_8]
.text:08000029                 fstp    st(0)
.text:0800002B                 leave
.text:0800002C                 retn

 It works well, and will clean the floating registers stack when return.
 Finally, I want to know there is any potential problem of this fixing ?

soloist
2009-06-17 02:09:26 +02:00
grischka
a342bbadc8 use static declaration from prototype
static int func();
    ...
    int func() { }

As result, func needs to be static.
2009-06-17 02:09:20 +02:00
grischka
69fdb57edd unions: initzialize only one field
struct {
      union {
        int a,b;
      };
      int c;
    } sss = { 1,2 };

This had previously assigned 1,2 to a,b and 0 to c which is wrong.
2009-06-17 02:09:07 +02:00
grischka
bba515afe5 tccelf: accept BSS symbol with same name from other module
... such as 'int baz;' in two files at the same time
2009-06-17 02:08:54 +02:00
Sam Watkins
e7297581fc pass constness from structs to members 2009-06-16 04:26:44 +08:00
Shinichiro Hamaji
dca2b15df4 x86-64: Align return value of alloca by 16. 2009-06-11 08:33:41 +09:00
Shinichiro Hamaji
8ea8305199 x86-64: Add alloca. 2009-06-09 03:23:08 +09:00
grischka
110a4edc15 drop alloca #define
(Because GNU's alloca.h unconditionally #undef's alloca)

Also, remove gcc specific sections in headers. and
instead change tests such that gcc does not use them.
2009-05-16 22:30:13 +02:00
grischka
68310299b6 ulibc: #define TCC_UCLIBC and load elf_interp 2009-05-16 22:29:40 +02:00
grischka
bf8d8f5f3e update Changelog, bump version: 0.9.25 2009-05-11 19:01:26 +02:00
grischka
aed6a7cb60 fix "cached include" optimization
comparing the filenames as in the #include statement can be
ambiguous if including files are in different directories.

Now caches and checks the really opened filename instead.
2009-05-11 18:55:16 +02:00
Daniel Glöckner
530b77e365 ARM: fix big immediate offset construction
The loop constructs to iterate over the non-overlapping, even
positions of two or three bytes in a word were broken.

This patch fixes the loops. It has been verified to generate the
72 combinations for two and the 80 combinations for three bytes.
2009-05-11 18:54:14 +02:00
grischka
ca4b4a52ad fix build with msvc 2009-05-11 18:53:52 +02:00
grischka
03c787d6ce fix unused/uninitalized warnings 2009-05-11 18:46:39 +02:00
grischka
40f5ce002e fix warnings with tcc_add/get_symbol 2009-05-11 18:46:25 +02:00
grischka
67aebdd5b7 enable making tcc using libtcc 2009-05-11 18:46:02 +02:00
grischka
0a35f9d66e move static prototypes to libtcc.c 2009-05-11 18:45:56 +02:00
grischka
f9181416f6 move some global variables into TCCState 2009-05-11 18:45:44 +02:00
grischka
5c6509578e make tcc from tcc.c and libtcc from libtcc.c 2009-05-05 20:41:17 +02:00
grischka
b8f6e1ae30 move minor things from libtcc.c to other files 2009-05-05 20:30:39 +02:00
grischka
92204e8818 move global variables to libtcc.c 2009-05-05 20:30:13 +02:00
grischka
9dc9cbf319 move libtcc interface and helper functions to libtcc.c 2009-05-05 20:18:53 +02:00
grischka
0d1ed74102 move parser/generator to tccgen.c 2009-05-05 20:18:10 +02:00
grischka
805990b94e move preprocessor to tccpp.c 2009-05-05 20:17:49 +02:00
grischka
ae37bd5abc move declarations to tcc.h 2009-05-05 20:17:26 +02:00
grischka
a93bcdffae new files: tcc.h libtcc.c tccpp.c tccgen.c 2009-05-05 20:17:11 +02:00
grischka
15626621fb cleanup makefiles 2009-04-19 21:24:32 +02:00
grischka
e9e89ad699 enable backtrace only when it's supported 2009-04-18 18:39:27 +02:00
Shinichiro Hamaji
859da934e0 Return value of exit should be void. 2009-04-18 23:55:51 +09:00
Shinichiro Hamaji
48ae0c0468 Fixes for tests/Makefile.
- On x86-64, we need $(TARGET) in RUN_TCC.
- s/RuN_TCC/RUN_TCC/
2009-04-18 23:53:25 +09:00
grischka
5829791ffa fix makefiles etc for subdirs 2009-04-18 15:08:03 +02:00
grischka
ea5e81bd6a new subdirs: include, lib, tests 2009-04-18 15:08:03 +02:00
grischka
e8a52a8249 win32: readme.txt->tcc-win32.txt, update tcc-doc 2009-04-18 15:08:03 +02:00
grischka
eca1fbaf92 mute strange difference in tcctest 2009-04-18 15:08:03 +02:00
grischka
b56f956247 libtcc: add support to be build as DLL 2009-04-18 15:08:03 +02:00
grischka
d165e87340 libtcc: new api tcc_set_lib_path 2009-04-18 15:08:03 +02:00
grischka
73ba078d2f tcc_relocate: return error and remove unused code 2009-04-18 15:08:03 +02:00
Shinichiro Hamaji
d36fea34e3 Call relocate_sym() before we return the offset, so user doesn't need to check the return value twice. 2009-04-18 15:08:03 +02:00
grischka
dd5630ff95 tcc -E: fix pasting empty tokens
/* test case */
#define t(x,y,z) x ## y ## z
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
        t(10,,), t(,11,), t(,,12), t(,,) };

tcc -E: xpected result:
int j[] = { 123, 45, 67, 89,
 10, 11, 12, };
2009-04-18 15:08:02 +02:00
grischka
0f0ed4a8bf tcc -E: preserve spaces, alternative solution
/* test case */
#define STR(x) #x
#define MKSTR(x) STR(x)
MKSTR(-A-)
MKSTR(+ B +)

tcc -E: expected result:
"-A-"
"+ B +"
2009-04-18 15:08:02 +02:00
grischka
90697c4c56 CONFIG_TCC_STATIC: add dummy for dlclose 2009-04-18 15:08:02 +02:00
grischka
d62301b050 avoid warning uninitialized 2009-04-18 15:08:02 +02:00
Shinichiro Hamaji
9a7173bf69 x86-64: Fix tcc -run. We need extra memory for PLT and GOT.
Size of the extra buffer is too large for now.
2009-04-18 15:08:02 +02:00
grischka
e6ba81b012 get rid of 8 bytes memory leak 2009-04-18 15:08:02 +02:00
grischka
b1697be691 change tcc_add/get_symbol to use void* 2009-04-18 15:08:02 +02:00