aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
Commit message (Collapse)AuthorAgeFilesLines
...
* Incorrect function call code on ARMv6Balazs Kezes2016-10-011-5/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On 2016-08-11 09:24 +0100, Balazs Kezes wrote: > I think it's just that that copy_params() never restores the spilled > registers. Maybe it needs some extra code at the end to see if any > parameters have been spilled to stack and then restore them? I've spent some time on this and I've found an alternative solution. Although I'm not entirely sure about it but I've attached a patch nevertheless. And while poking at that I've found another problem affecting the unsigned long long division on arm and I've attached a patch for that too. More details in the patches themselves. Please review and consider them for merging! Thank you! -- Balazs [PATCH 1/2] Fix slow unsigned long long division on ARM The macro AEABI_UXDIVMOD expands to this bit: #define AEABI_UXDIVMOD(name,type, rettype, typemacro) \ ... while (num >= den) { \ ... while ((q << 1) * den <= num && q * den <= typemacro ## _MAX / 2) \ q <<= 1; \ ... With the current ULONG_MAX version the inner loop goes only until 4 billion so the outer loop will progress very slowly if num is large. With ULLONG_MAX the inner loop works as expected. The current version is probably a result of a typo. The following bash snippet demonstrates the bug: $ uname -a Linux eper 4.4.16-2-ARCH #1 Wed Aug 10 20:03:13 MDT 2016 armv6l GNU/Linux $ cat div.c int printf(const char *, ...); int main(void) { unsigned long long num, denom; num = 12345678901234567ULL; denom = 7; printf("%lld\n", num / denom); return 0; } $ time tcc -run div.c 1763668414462081 real 0m16.291s user 0m15.860s sys 0m0.020s [PATCH 2/2] Fix long long dereference during argument passing on ARMv6 For some reason the code spills the register to the stack. copy_params in arm-gen.c doesn't expect this so bad code is generated. It's not entirely clear why the saving part is necessary. It was added in commit 59c35638 with the comment "fixed long long code gen bug" with no further clarification. Given that tcctest.c passes without this, maybe it's no longer needed? Let's remove it. Also add a new testcase just for this. After I've managed to make the tests compile on a raspberry pi, I get the following diff without this patch: --- test.ref 2016-08-22 22:12:43.380000000 +0100 +++ test.out3 2016-08-22 22:12:49.990000000 +0100 @@ -499,7 +499,7 @@ 2 1 0 1 0 4886718345 -shift: 9 9 9312 +shift: 291 291 291 shiftc: 36 36 2328 shiftc: 0 0 9998683865088 manyarg_test: More discussion on this thread: https://lists.nongnu.org/archive/html/tinycc-devel/2016-08/msg00004.html
* Revert part of "fix installation amd bcheck for Windows"grischka2016-10-011-13/+0
| | | | | | | tccelf.c : force linking bcheck by adding elf symbol __bound_init bcheck.c : use (size_t)1 for x86_64 Fixes 7e7e6148fdb4adbda936f80b5d4ac3d738908d95
* tccpp: cleanupgrischka2016-10-011-13/+13
| | | | | | | | | | | | | | | | - "utf8 in identifiers" from 936819a1b90f2618bb3f86730189cf2895948ba0 - CValue: remove member str.data_allocated - make tiny allocator private to tccpp - allocate macro_stack objects on heap because otherwise it could crash after error/setjmp in preprocess_delete():end_macro() - mov "TinyAlloc" defs to tccpp.c - define_push: take int* str again
* gtst_addr(): short conditional jumps (i386, x86_64)Pavlas, Zdenek2016-09-301-2/+2
|
* switch: collect case ranges first, then generate codePavlas, Zdenek2016-09-301-49/+65
| | | | | Collect cases first, then emit lookup code. Elliminates jumps to implement pass-through and jumps to link cases.
* tccgen: return: avoid jmp to retsym if possiblePavlas, Zdenek2016-08-111-1/+5
| | | | | When 'return' is the last statement of the top-level block (very common and often recommended case) jump is not needed.
* win64: fix va_arggrischka2016-07-101-0/+1
| | | | | | | | | | | fixes 5c35ba66c5ade4713bbd9c005e66889f6d7db293 Implementation was consistent within tcc but incompatible with the ABI (for example library functions vprintf etc) Also: - tccpp.c/get_tok_str() : avoid "unknown format "%llu" warning - x86_64_gen.c/gen_vla_alloc() : fix vstack leak
* tccgen: gen_assign_cast(): cannot cast struct to scalargrischka2016-05-251-0/+3
| | | | | | | | | | | | | | | The case below previously was causing an assertion failure in the target specific generator. It probably is not incorrect not to allow this even if gcc does. struct S { long b; }; void f(struct S *x) { struct S y[1] = { *x }; }
* Error out on operations on structsMichael Matz2016-05-121-3/+3
| | | | | | | The check for structs was too late and on amd64 and aarch64 could lead to accepting and then asserting with code like: struct S {...} s; char *c = (char*)0x10 - s;
* tccgen: scopes levels for local symbols (update 2)grischka2016-05-061-11/+14
| | | | | | | allow typedef int xxx; typedef int xxx; in the same scope as long as it is the same type
* tccgen: scopes levels for local symbols (update 1)grischka2016-05-051-5/+6
| | | | | | | Catch top level redeclarations too. Also fix mistakes in tcctest.c and the tcc sources (win32) showing up now.
* tccgen: scope levels for local symbolsgrischka2016-05-051-23/+26
| | | | | | | | | | | | | | | | | | ... for fast redeclaration checks Also, check function parameters too: void foo(int a) { int a; ... } Also, try to fix struct/union/enum's on different scopes: { struct xxx { int x; }; { struct xxx { int y; }; ... }} and some (probably not all) combination with incomplete declarations "struct xxx;" Replaces 2bfedb18675228c3837c23fa523231f55e102c12 and 07d896c8e5d1b46bf4aebd403c78e5f7ffebe02a Fixes cf95ac399cbce1ea8a519f91dd36a5cfd4ea7943
* sym_push2 optimized for the local_stack case.seyko2016-05-041-3/+3
| | | | | | | | | | | | | | | | | A constant expression removed from the loop. If subroutine have 50000+ local variables, then currently compilation of such code takes obly 15 sec. Was 2 min. gcc-4.1.2 compiles such code in 7 sec. pcc -- 3.44 min. A test generator: #include <stdio.h> int main() { puts("#include <stdio.h>"); puts("int main()"); puts("{"); for (int i = 0; i < 50000; ++i) printf("int X%d = 1;\n", i); for (int i = 0; i < 50000; ++i) puts("scanf(\"%d\", &X0);"); puts("}"); return 0; }
* -fno-type-redefinition-checkseyko2016-05-041-5/+7
| | | | | | | | | | | | | don't catch redefinition for local vars. With this option on tcc accepts the following code: int main() { int a = 0; long a = 0; } But if you shure there is no problem with your local variables, then a compilation speed can be improved if you have a lots of the local variables (50000+)
* Improve hash performanceVlad Vissoultchev2016-04-171-1/+1
| | | | | | | | | | | | - better `TOK_HASH_FUNC` - increases `hash_ident` initial size to 16k (from 8k) - `cstr_cat` uses single `realloc` + `memcpy` - `cstr_cat` can append terminating zero - `tok_str_realloc` initial size to 16 (from 8) - `parse_define` uses static `tokstr_buf` - `next` uses static `tokstr_buf` - fixes two latent bugs (wrong deallocations in libtcc.c:482 and tccpp.c:2987)
* __builtin_expect no-opseyko2016-04-161-0/+37
| | | | | Taken from David Mertens tcc branch on github https://github.com/run4flat/tinycc.git
* tccgen.c: Allow type attributes to prefix enum/struct/union nameVlad Vissoultchev2016-04-061-10/+14
| | | | | | From gcc docs: "You may also specify attributes between the enum, struct or union tag and the name of the type rather than after the closing brace." Adds `82_attribs_position.c` in `tests/tests2`
* nocode_wanted with while/for inside ({})seyko2016-04-051-3/+6
| | | | a test included.
* Fix type parsingMichael Matz2016-03-241-6/+9
| | | | | | the check on incomplete struct/union/enum types was too early, disallowing mixed specifiers and qualifiers. Simply rely on the size (->c) field for that. See testcases.
* Keep lvalue category on structs when evaluating ternary operatorVlad Vissoultchev2016-03-131-4/+17
|
* tccgen.c: Fix flex array members some moreMichael Matz2016-03-111-2/+6
| | | | Last fix didn't work for function f1int in the added testcase.
* tccgen.c: off by one in flexible array membersHenry Kroll III2016-03-101-1/+1
| | | | tccgen.c: fix fexible array member breaking struct alignment
* tccgen.c: In parse_btype, handle type qualifiers applied to arrays.Edmund Grimley Evans2016-01-111-14/+25
| | | | Also add some test cases in tests/tests2/39_typedef.c.
* Change the way struct CStrings are handled.Edmund Grimley Evans2015-11-261-14/+12
| | | | | | | | | A CString used to be copied into a token string, which is an int array. On a 64-bit architecture the pointers were misaligned, so ASan gave lots of warnings. On a 64-bit architecture that required memory accesses to be correctly aligned it would not work at all. The CString is now included in CValue instead.
* tccgen.c: Give error if statement expression found when const wanted.Edmund Grimley Evans2015-11-261-6/+2
| | | | | | | | | | | | | | | | Some test cases: #define SE ({ switch (0) { } 0; }) // Should give error: int x = SE; void f(void) { static int x = SE; } void f(void) { enum e { a = SE }; } void f(void) { switch (0) { case SE: break; } } // Correct: int f(void) { return SE; } int f(void) { return sizeof(SE); }
* tccgen.c: Try to make sizeof(!x) work.Edmund Grimley Evans2015-11-221-3/+1
| | | | tests/tests2/27_sizeof.*: Add test.
* tccgen.c: Bug fix for 992cbda and 3ff77a1: set nocode_wanted.Edmund Grimley Evans2015-11-211-8/+26
| | | | tests/tests2/78_vla_label.*: Add test.
* Improve constant propagation with "&&" and "||".Edmund Grimley Evans2015-11-201-50/+53
|
* tccgen: asm_label cleanupgrischka2015-11-201-39/+30
| | | | | | | - avoid memory allocation by using its (int) token number - avoid additional function parameter by using Attribute Also: fix some strange looking error messages
* tccgen.c: Recognise constant expressions with conditional operator.Edmund Grimley Evans2015-11-201-7/+7
| | | | tests/tests2/78_vla_label.c: Check that int a[1 ? 1 : 1] is not a VLA.
* tccgen.c: In parse_btype, handle typedef types with added type qualifiers.Edmund Grimley Evans2015-11-191-1/+11
| | | | | | | | | | | | | | | | | | In a case like typedef int T[1]; const T x; we must make a copy of the typedef type so that we can add the type qualifiers to it. The following code used to give error: incompatible types for redefinition of 'f' typedef int T[1]; void f(const int [1]); void f(const T);
* tccgen.c: Improvements to type_to_str (only used for error messages).Edmund Grimley Evans2015-11-191-0/+9
| | | | | 1. Handle array types. 2. Print the type qualifiers of pointers.
* tccgen.c: Avoid undefined behaviour in constant propagation.Edmund Grimley Evans2015-11-171-31/+38
|
* Merge the integer members of union CValue into "uint64_t i".Edmund Grimley Evans2015-11-171-65/+61
|
* tccgen.c: Use memmove for struct assignment: dest and src may be equal.Edmund Grimley Evans2015-11-041-1/+2
|
* tccgen.c: Fix memory leak involving asm_label.Edmund Grimley Evans2015-11-041-5/+9
|
* tccgen.c: Remove undefined shift of negative signed value.Edmund Grimley Evans2015-10-151-3/+4
|
* a number as a field name (part 2)seyko2015-09-251-0/+2
| | | | | | | | | | | | | | | | don't crash a test program: ================ typedef struct X { int len; } X; #define init(s,len) s.len = len; int main(void) { X myX; init(myX,10); return 0; } ================ After a patch: error: field name expected
* a number as a field nameseyko2015-09-251-2/+4
| | | | | | | | | | | | | | | | a test program: ======== typedef struct X { int len; } X; int main(void) { X myX; myX.10 = 10; return 0; } ======== Error message before a patch: error: ';' expected (got "(null)") After a patch: error: field name expected
* Revert "fix-mixed-struct (patch by Pip Cet)"gus knight2015-07-291-81/+5
| | | | This reverts commit 4e04f67c94c97b4f28a4d73759a0ad38fb3a10f7. Requested by grischka.
* Revert all of my changes to directories & codingstyle.gus knight2015-07-291-0/+6463
|
* Reorganize the source tree.gus knight2015-07-271-6463/+0
| | | | | | | | | | * Documentation is now in "docs". * Source code is now in "src". * Misc. fixes here and there so that everything still works. I think I got everything in this commit, but I only tested this on Linux (Make) and Windows (CMake), so I might've messed something up on other platforms...
* Clean up lots of rogue tabs.gus knight2015-07-271-169/+169
| | | | | | Still some more tabs to be taken care of. arm-gen.c and tcccoff.c have so many style issues that I'm just going to throw clang-format at them.
* Trim trailing spaces everywhere.gus knight2015-07-271-110/+110
|
* fix-mixed-struct (patch by Pip Cet)seyko2015-05-141-5/+81
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Jsut for testing. It works for me (don't break anything) Small fixes for x86_64-gen.c in "tccpp: fix issues, add tests" are dropped in flavor of this patch. Pip Cet: Okay, here's a first patch that fixes the problem (but I've found another bug, yet unfixed, in the process), though it's not particularly pretty code (I tried hard to keep the changes to the minimum necessary). If we decide to actually get rid of VT_QLONG and VT_QFLOAT (please, can we?), there are some further simplifications in tccgen.c that might offset some of the cost of this patch. The idea is that an integer is no longer enough to describe how an argument is stored in registers. There are a number of possibilities (none, integer register, two integer registers, float register, two float registers, integer register plus float register, float register plus integer register), and instead of enumerating them I've introduced a RegArgs type that stores the offsets for each of our registers (for the other architectures, it's simply an int specifying the number of registers). If someone strongly prefers an enum, we could do that instead, but I believe this is a place where keeping things general is worth it, because this way it should be doable to add SSE or AVX support. There is one line in the patch that looks suspicious: } else { addr = (addr + align - 1) & -align; param_addr = addr; addr += size; - sse_param_index += reg_count; } break; However, this actually fixes one half of a bug we have when calling a function with eight double arguments "interrupted" by a two-double structure after the seventh double argument: f(double,double,double,double,double,double,double,struct { double x,y; },double); In this case, the last argument should be passed in %xmm7. This patch fixes the problem in gfunc_prolog, but not the corresponding problem in gfunc_call, which I'll try tackling next.
* tccpp: fix issues, add testsgrischka2015-05-091-25/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * fix some macro expansion issues * add some pp tests in tests/pp * improved tcc -E output for better diff'ability * remove -dD feature (quirky code, exotic feature, didn't work well) Based partially on ideas / researches from PipCet Some issues remain with VA_ARGS macros (if used in a rather tricky way). Also, to keep it simple, the pp doesn't automtically add any extra spaces to separate tokens which otherwise would form wrong tokens if re-read from tcc -E output (such as '+' '=') GCC does that, other compilers don't. * cleanups - #line 01 "file" / # 01 "file" processing - #pragma comment(lib,"foo") - tcc -E: forward some pragmas to output (pack, comment(lib)) - fix macro parameter list parsing mess from a3fc54345949535524d01319e1ca6378b7c2c201 a715d7143d9d17da17e67fec6af1c01409a71a31 (some coffee might help, next time ;) - introduce TOK_PPSTR - to have character constants as written in the file (similar to TOK_PPNUM) - allow '\' appear in macros - new functions begin/end_macro to: - fix switching macro levels during expansion - allow unget_tok to unget more than one tok - slight speedup by using bitflags in isidnum_table Also: - x86_64.c : fix decl after statements - i386-gen,c : fix a vstack leak with VLA on windows - configure/Makefile : build on windows (MSYS) was broken - tcc_warning: fflush stderr to keep output order (win32)
* a lot simpler VLA codeseyko2015-05-041-80/+33
| | | | | | | | Author: Philip <pipcet@gmail.com> Our VLA code can be made a lot simpler (simple enough for even me to understand it) by giving up on the optimization idea, which is very tempting. There's a patch to do that attached, feel free to test and commit it if you like. (It passes all the tests, at least
* fix vstack leakPhilip2015-04-291-1/+2
| | | | | | | | I think this code only affects the ARM EABI target, and only when returning small structures that might be unaligned. However, it was both leaking vstack entries and failing to achieve what I think is its purpose, to ensure the sret argument would be aligned properly. Both issues fixed.
* VLA fix: save stack pointer right after modificationPhilip2015-04-281-6/+9
| | | | | | | | | | | | | | | | This patch disables the optimization of saving stack pointers lazily, which didn't fully take into account that control flow might not reach the stack-saving instructions. I've decided to leave in the extra calls to vla_sp_save() in case anyone wants to restore this optimization. Tests added and enabled. There are two remaining bugs: VLA variables can be modified, and jumping into the scope of a declared VLA will cause a segfault rather than a compiler error. Both of these do not affect correct C code, but should be fixed at some point. Once VLA variables have been made properly immutable, we can share them with the saved stack pointer and save stack and instructions.
* fix VLA/continue issuePhilip2015-04-271-0/+23
| | | | | | | | | | | | | | | | | | as reported in http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00131.html. Note that this is one of two separate VLA bugs: A. labels aren't reached by program execution, so the stack pointer is never saved B. continue doesn't restore the stack pointer as goto does This fixes only B. I'm not sure whether the same issue applies to break as well as continue. Add a test case, but disable tests #78 and #79 for now as they're not fully fixed until the issue described in http://lists.nongnu.org/archive/html/tinycc-devel/2015-04/msg00110.html is resolved.