Commit Graph

392 Commits (f87afa72e06842da1f1bb902e4a192195646134b)

Author SHA1 Message Date
yuanbin d6ce75b4d6 tccgen.c: skip fields from same union 2010-06-13 01:12:36 +08:00
yuanbin dd72577759 tccgen: initial the last member of union 2010-06-11 21:18:05 +08:00
yuanbin 6709933d78 tccgen: initial last member of union 2010-06-11 20:48:33 +08:00
Daniel Glöckner a64727ba7d append ULL to big constants 2010-05-13 22:18:33 +02:00
Thomas Preud'homme 8eb86ab78d Add nan, snan and inf float constants 2010-05-06 02:20:35 +02:00
Thomas Preud'homme 4d5fcfb971 Delete unused vtop_saved variable in unary_type 2010-04-20 16:12:41 +02:00
Thomas Preud'homme e9406c09a3 Complain for static fct declared w/o file scope
Error out on static function without file scope and give an explaination
to the user
2010-04-15 19:33:47 +02:00
Thomas Preud'homme 8de9b7a631 Correctly support all unary expression with sizeof
Unary expression can start with a parenthesis. Thus, the current test
to detect which sizeof form is being parsed is inaccurate. This patch
makes tcc able to handle things like sizeof (x)[1] where x is declared
as char x[5]; wich is a valid unary expression
2010-04-15 19:05:53 +02:00
Romain Francoise 6655e06ec8 Error out on bad char array initialization
Error out with an explicit message when trying to initialize a
character array with something that's not a literal (optionally
enclosed in braces) as per C99 6.7.8:14; thanks to Antti-Juhani
Kaijanaho <ajk@debian.org> who did all the work.
2010-04-15 19:04:25 +02:00
Detlef Riekenberg a3b932b3f9 tccgen: Fix broken use of ATTR_MODE
Sorry for that.

--
By by ... Detlef
2010-04-06 22:53:16 +02:00
Detlef Riekenberg 264a103610 tccgen: Detect (but ignore) function redirection
tcc is now able to parse <stdio.h> from gcc, when
__GNUC__ is also defined

--
By by ... Detlef
2010-04-06 00:33:15 +02:00
Daniel Glöckner 4d05a6319d Catch array[index] with unknown sizeof(*array)
We could support this for index == 0, but GCC doesn't bother, so why should we?
2010-03-15 22:51:19 +01:00
Manuel Simoni 95b9a477b6 weak function symbols 2010-02-27 17:37:59 +01:00
Detlef Riekenberg a975008ae7 Add support for the __mode__ attribute
--
By by ... Detlef
2010-01-26 22:56:22 +01:00
grischka 2341ee5142 tccpe: improve dllimport/export and use for tcc_add_symbol 2010-01-14 20:59:42 +01:00
grischka 0de95730ad build from multiple objects: fix other targets 2009-12-20 20:33:41 +01:00
grischka 4a01eb09d8 use vpushv in some places 2009-12-20 01:54:38 +01:00
grischka 88a3ccab9f allow tcc be build from separate objects
If you want that, run: make NOTALLINONE=1
2009-12-20 01:53:49 +01:00
grischka 7fa712e00c win32: enable bounds checker & exception handler
exception handler borrowed from k1w1. Thanks.
2009-12-19 22:22:43 +01:00
grischka 41e112360f fix uninitialized warnings with 'type.ref' 2009-12-19 22:16:22 +01:00
grischka 94bf4d2c22 tccpe: improve dllimport 2009-12-19 22:16:21 +01:00
grischka ab4a4ab25e x86-64: in gv(): ignore second register 2009-12-19 22:16:17 +01:00
Christian Jullien 614790dc14 x86-64: Fix Wrong comparisonbetweenpointerandlongcste
main (int argc, char *argv[])
{
    char *p = (char *)0x12345678ABCD000F;
    int res;
    res = (p != (char *)0x12345678ABCD000F);
    return res;
}
2009-12-19 22:16:16 +01:00
grischka 56d6abdb3d tccgen: propagate alignment from typedef
Store (part of) the AttributeDef structure in the (int)sym-r
field of the typedef symbol (kludgy).
2009-12-06 17:37:33 +01:00
bobbl c0620c8a00 avoid needless register save when storing structures
When storing structs with a memcpy call in vstore(),
so far a needless entry remaining on the vstack
sometimes resulted in an useless store generated by
save_regs() in gfunc_call() for the memcpy routine.
2009-12-01 17:59:30 +01:00
Daniel Glöckner bc48cc1edb fix sizeof(array + integer)
Previously sizeof would return the size of the array although the
expression is always a plain pointer of 4 (or 8) bytes.
2009-11-13 18:05:15 +01:00
grischka 5b113f3ee3 win32: handle __declspec(dllimport) 2009-11-13 18:04:56 +01:00
Shinichiro Hamaji 5dadff3de5 x86-64: Fix stab debug information.
We need 32bit relocations for code and 64bit for debug info.
Introduce a new macro R_DATA_PTR to distinguish the two usages.
2009-08-24 13:30:03 +02:00
grischka 0d34c2136e tccgen: free inline functions correctly 2009-08-24 13:30:00 +02:00
grischka 9fda4f4248 win32: treat long double as double 2009-07-18 22:07:17 +02:00
grischka 035918ef2f win64: fix pointer <-> unsigned long typecast issues 2009-07-18 22:05:58 +02:00
grischka 3ea4acb9b9 pe32+ target: add in various #define's 2009-07-18 22:05:27 +02:00
grischka d0b432ab38 cleanup: stop abuse of sym->r for inline functions 2009-07-18 21:55:06 +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
Sam Watkins e7297581fc pass constness from structs to members 2009-06-16 04:26:44 +08:00
grischka f9181416f6 move some global variables into TCCState 2009-05-11 18:45:44 +02:00
grischka 0d1ed74102 move parser/generator to tccgen.c 2009-05-05 20:18:10 +02:00
grischka a93bcdffae new files: tcc.h libtcc.c tccpp.c tccgen.c 2009-05-05 20:17:11 +02:00