aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
Commit message (Collapse)AuthorAgeFilesLines
* Fix binding of assignment expressions.Ben Bacarisse2010-10-251-29/+29
|
* Move asm label functions from tccasm.c to tccgen.cThomas Preud'homme2010-09-141-1/+28
| | | | | | | | | | * Move functions parse_asm_str and asm_label_instr from tccasm.c to tccgen.c * Remove CONFIG_TCC_ASM_LABEL macro as asm label are available on all archs. See: http://lists.nongnu.org/archive/html/tinycc-devel/2010-09/msg00026.html for the rationale.
* Add support of asm label for functions.Thomas Preud'homme2010-09-101-1/+24
| | | | | | Add support for asm labels for functions, that is the ability to rename a function at assembly level with __asm__ ("newname") appended in function declaration.
* Fix casts from 32bit integer types to 64bit integer types.Shinichiro Hamaji2010-08-311-5/+7
| | | | | | | This bug was reported in http://lists.gnu.org/archive/html/tinycc-devel/2010-08/msg00050.html In this case, we should not emit any code when we cast from VT_FUNC to VT_PTR.
* Revert "implemented C99 for loop with variable declaration"grischka2010-08-211-37/+4
| | | | | | | | | | | | | | | This reverts commit 433ecdfc9d1402ecf03e710de481e2063ad6de90. The patch breaks e.g. with for ((i = 10); --i;); In particular to check for a type decl. this is not sufficient: if (tok < TOK_UIDENT) { A future approach to c99 loop variables might instead use: if (parse_btype(...)) { plus refactor function decl() accordingly.
* tccgen: Revert yuanbin's recent patchesgrischka2010-06-211-19/+17
| | | | | This reverts commits 670993..d35138 Maybe these commits fixed something but also seemed to cause problems.
* implemented C99 for loop with variable declarationClaudio Bley2010-06-211-4/+37
|
* Revert "Complain for static fct declared w/o file scope"grischka2010-06-151-3/+0
| | | | | | | | | | This reverts commit e9406c09a3212ab3f120412a6bbdacb0cdd25deb. We don't want errors for static local function pointers, such as: { static void (*fn)(); ... }
* Fix last commits: remove CRLF, chmod 644 tccgen.cgrischka2010-06-151-24/+24
|
* tccgen: skip ')' in front of ',' for initializeryuanbin2010-06-131-5/+14
|
* tccgen: skip fields from same unionyuanbin2010-06-131-2/+8
|
* tccgen.c: skip fields from same unionyuanbin2010-06-131-26/+5
|
* tccgen: initial the last member of unionyuanbin2010-06-111-1/+1
|
* tccgen: initial last member of unionyuanbin2010-06-111-20/+28
|
* append ULL to big constantsDaniel Glöckner2010-05-131-3/+3
|
* Add nan, snan and inf float constantsThomas Preud'homme2010-05-061-0/+25
|
* Delete unused vtop_saved variable in unary_typeThomas Preud'homme2010-04-201-2/+0
|
* Complain for static fct declared w/o file scopeThomas Preud'homme2010-04-151-0/+3
| | | | | Error out on static function without file scope and give an explaination to the user
* Correctly support all unary expression with sizeofThomas Preud'homme2010-04-151-6/+19
| | | | | | | 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
* Error out on bad char array initializationRomain Francoise2010-04-151-0/+3
| | | | | | | 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.
* tccgen: Fix broken use of ATTR_MODEDetlef Riekenberg2010-04-061-2/+2
| | | | | | | Sorry for that. -- By by ... Detlef
* tccgen: Detect (but ignore) function redirectionDetlef Riekenberg2010-04-061-1/+30
| | | | | | | | tcc is now able to parse <stdio.h> from gcc, when __GNUC__ is also defined -- By by ... Detlef
* Catch array[index] with unknown sizeof(*array)Daniel Glöckner2010-03-151-2/+5
| | | | We could support this for index == 0, but GCC doesn't bother, so why should we?
* weak function symbolsManuel Simoni2010-02-271-0/+4
|
* Add support for the __mode__ attributeDetlef Riekenberg2010-01-261-0/+23
| | | | | -- By by ... Detlef
* tccpe: improve dllimport/export and use for tcc_add_symbolgrischka2010-01-141-16/+10
|
* build from multiple objects: fix other targetsgrischka2009-12-201-3/+3
|
* use vpushv in some placesgrischka2009-12-201-1/+1
|
* allow tcc be build from separate objectsgrischka2009-12-201-52/+290
| | | | If you want that, run: make NOTALLINONE=1
* win32: enable bounds checker & exception handlergrischka2009-12-191-1/+12
| | | | exception handler borrowed from k1w1. Thanks.
* fix uninitialized warnings with 'type.ref'grischka2009-12-191-0/+3
|
* tccpe: improve dllimportgrischka2009-12-191-2/+6
|
* x86-64: in gv(): ignore second registergrischka2009-12-191-5/+8
|
* x86-64: Fix Wrong comparisonbetweenpointerandlongcsteChristian Jullien2009-12-191-0/+4
| | | | | | | | | | main (int argc, char *argv[]) { char *p = (char *)0x12345678ABCD000F; int res; res = (p != (char *)0x12345678ABCD000F); return res; }
* tccgen: propagate alignment from typedefgrischka2009-12-061-12/+19
| | | | | Store (part of) the AttributeDef structure in the (int)sym-r field of the typedef symbol (kludgy).
* avoid needless register save when storing structuresbobbl2009-12-011-7/+7
| | | | | | | 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.
* fix sizeof(array + integer)Daniel Glöckner2009-11-131-0/+1
| | | | | Previously sizeof would return the size of the array although the expression is always a plain pointer of 4 (or 8) bytes.
* win32: handle __declspec(dllimport)grischka2009-11-131-2/+10
|
* x86-64: Fix stab debug information.Shinichiro Hamaji2009-08-241-2/+2
| | | | | We need 32bit relocations for code and 64bit for debug info. Introduce a new macro R_DATA_PTR to distinguish the two usages.
* tccgen: free inline functions correctlygrischka2009-08-241-1/+5
|
* win32: treat long double as doublegrischka2009-07-181-0/+6
|
* win64: fix pointer <-> unsigned long typecast issuesgrischka2009-07-181-4/+4
|
* pe32+ target: add in various #define'sgrischka2009-07-181-1/+1
|
* cleanup: stop abuse of sym->r for inline functionsgrischka2009-07-181-25/+20
|
* incompatible function ptr assignment: just warngrischka2009-06-171-3/+2
| | | | | void fn_1(int i) {} void (*fn_2)(char*) = fn_1;
* allow redefinition of func_old_type functionsgrischka2009-06-171-4/+7
| | | | | | | void *memcpy(void*, const void*, unsigned); This gave an error if memcpy() has been used before implicitely, e.g. for structure passing etc.
* trying to fix the bug of unclean FPU st(0)Soloist Deng2009-06-171-3/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* use static declaration from prototypegrischka2009-06-171-3/+8
| | | | | | | | static int func(); ... int func() { } As result, func needs to be static.
* unions: initzialize only one fieldgrischka2009-06-171-0/+18
| | | | | | | | | | | 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.
* pass constness from structs to membersSam Watkins2009-06-161-0/+3
|