aboutsummaryrefslogtreecommitdiff
path: root/tccgen.c
Commit message (Collapse)AuthorAgeFilesLines
* Misc. fixesgrischka2016-10-051-1/+2
| | | | | | | | | | | | | | | | | | | | Makefile : - do not 'uninstall' peoples /usr/local/doc entirely libtcc.c : - MEM_DEBUG : IDE-friendly output "file:line: ..." - always ELF for objects tccgen.c : - fix memory leak in new switch code - move static 'in_sizeof' out of function profiling : - define 'static' to empty resolve_sym() : - replace by dlsym() win32/64: fix R_XXX_RELATIVE fixme - was fixed for i386 already in 8e4d64be2fc1d707c7800c5096f6e0ea22cbd - do not -Lsystemdir if compiling to .o
* tccgen: arm/i386: save_reg_upstackgrischka2016-10-041-18/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | tccgen.c:gv() when loading long long from lvalue, before was saving all registers which caused problems in the arm function call register parameter preparation, as with void foo(long long y, int x); int main(void) { unsigned int *xx[1], x; unsigned long long *yy[1], y; foo(**yy, **xx); return 0; } Now only the modified register is saved if necessary, as in this case where it is used to store the result of the post-inc: long long *p, v, **pp; v = 1; p = &v; p[0]++; printf("another long long spill test : %lld\n", *p); i386-gen.c : - found a similar problem with TOK_UMULL caused by the vstack juggle in tccgen:gen_opl() (bug seen only when using EBX as 4th register)
* Alternative fix for "Incorrect function call code on ARMv6"grischka2016-10-031-0/+5
| | | | | | | | | | | "make test" crashes without that "save_regs()". This partially reverts commit 49d3118621a68f6583228f123efd16f0f803d908. Found another solution: In a 2nd pass Just look if any of the argument registers has been saved again, and restore if so.
* switch: binary searchPavlas, Zdenek2016-10-031-23/+51
|
* switch: fix label sortingPavlas, Zdenek2016-10-031-2/+6
|
* tccgen: fix long long -> char/short castgrischka2016-10-021-1/+4
| | | | | | | | | | | | | | | | | | | | | | | This was causing assembler bugs in a tcc compiled by itself at i386-asm.c:352 when ExprValue.v was changed to uint64_t: if (op->e.v == (int8_t)op->e.v) op->type |= OP_IM8S; A general test case: #include <stdio.h> int main(int argc, char **argv) { long long ll = 4000; int i = (char)ll; printf("%d\n", i); return 0; } Output was "4000", now "-96". Also: add "asmtest2" as asmtest with tcc compiled by itself
* 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
|