aboutsummaryrefslogtreecommitdiff
path: root/x86_64-gen.c
Commit message (Collapse)AuthorAgeFilesLines
...
* fix a subtle x86-64 calling bugPhilip2015-04-231-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I ran into an issue playing with tinycc, and tracked it down to a rather weird assumption in the function calling code. This breaks only when varargs and float/double arguments are combined, I think, and only when calling GCC-generated (or non-TinyCC, at least) code. The problem is we sometimes generate code like this: 804a468: 4c 89 d9 mov %r11,%rcx 804a46b: b8 01 00 00 00 mov $0x1,%eax 804a470: 48 8b 45 c0 mov -0x40(%rbp),%rax 804a474: 4c 8b 18 mov (%rax),%r11 804a477: 41 ff d3 callq *%r11 for a function call. Note how $eax is first set to the correct value, then clobbered when we try to load the function pointer into R11. With the patch, the code generated is: 804a468: 4c 89 d9 mov %r11,%rcx 804a46b: b8 01 00 00 00 mov $0x1,%eax 804a470: 4c 8b 5d c0 mov -0x40(%rbp),%r11 804a474: 4d 8b 1b mov (%r11),%r11 804a477: 41 ff d3 callq *%r11 which is correct. This becomes an issue when get_reg(RC_INT) is modified not always to return %rax after a save_regs(0), because then another register (%ecx, say) is clobbered, and the function passed an invalid argument. A rather convoluted test case that generates the above code is included. Please note that the test will not cause a failure because TinyCC code ignores the %rax argument, but it will cause incorrect behavior when combined with GCC code, which might wrongly fail to save XMM registers and cause data corruption.
* Bugfix: 32-bit vs 64-bit bug in x86_64-gen.c:gcall_or_jmpPhilip2015-04-231-1/+2
| | | | | | | | | | | | | Verify an immediate value fits into 32 bits before jumping to it/calling it with a 32-bit immediate operand. Without this fix, code along the lines of ((int (*)(const char *, ...))140244834372944LL)("hi\n"); will fail mysteriously, even if that decimal constant is the correct address for printf. See https://github.com/pipcet/tinycc/tree/bugfix-1
* a bounds checking code for the ARCH=x86_64seyko2015-04-101-0/+126
|
* Fix stack overwrite on structure returnMichael Matz2015-03-091-2/+4
| | | | | | | | | The common code to move a returned structure packed into registers into memory on the caller side didn't take the register size into account when allocating local storage, so sometimes that lead to stack overwrites (e.g. in 73_arm64.c), on x86_64. This fixes it by generally making gfunc_sret also return the register size.
* A partial reverse for commit eda2c756edc4dca004ba217d5bf361235dd9de1fseyko2015-03-031-1/+1
| | | | | | | | | | | | | | | Author: Thomas Preud'homme <robotux@celest.fr> Date: Tue Dec 31 23:51:20 2013 +0800 Move logic for if (int value) to tccgen.c Move the logic to do a test of an integer value (ex if (0)) out of arch-specific code to tccgen.c to avoid code duplication. This also fixes test of long long value which was only testing the bottom half of such values on 32 bits architectures. I don't understand why if () in gtst(i) was removed. This patch allows to compile a linux kernel v.2.4.26 W/o this patch a tcc simply crashes.
* win64: try to fix linkagegrischka2014-06-241-3/+7
| | | | | | | | | - revert to R_X86_64_PC32 for near calls on PE - revert to s1->section_align set to zero by default Untested. Compared to release_0_9_26 the pe-image looks back to normal. There are some differences in dissassembly (r10/r11 usage) but maybe that's ok.
* x86-64: Use correct ELF valuesMichael Matz2014-04-031-2/+2
| | | | | The x86-64 uses different segment alignment (2MB) and a different start address.
* x86-64: Add basic shared lib supportMichael Matz2014-03-311-1/+1
| | | | Initial support for shared libraries on x86-64.
* Fix various errors uncovered by static analysisThomas Preud'homme2014-03-081-1/+1
| | | | Reported-by: Carlos Montiers <cmontiers@gmail.com>
* Ignore VT_DEFSIGN in load on x86-64 archThomas Preud'homme2014-02-071-1/+1
| | | | | This fixes commit b0b5165d1668373c5d7b7933da599426f33e723b for x86-64 targets.
* be stricter with aliasinggrischka2014-01-071-5/+10
| | | | | | | | | | | | | | Refactoring (no logical changes): - use memcpy in tccgen.c:ieee_finite(double d) - use union to store attribute flags in Sym Makefile: "CFLAGS+=-fno-strict-aliasing" basically not necessary anymore but I left it for now because gcc sometimes behaves unexpectedly without. Also: - configure: back to mode 100755 - tcc.h: remove unused variables tdata/tbss_section - x86_64-gen.c: adjust gfunc_sret for prototype
* Fix struct ret in variadic fct with ARM hardfloatThomas Preud'homme2014-01-061-1/+2
| | | | | | | | | | | | | The procedure calling standard for ARM architecture mandate the use of the base standard for variadic function. Therefore, hgen float aggregate must be returned via stack when greater than 4 bytes and via core registers else in case of variadic function. This patch improve gfunc_sret() to take into account whether the function is variadic or not and make use of gfunc_sret() return value to determine whether to pass a structure via stack in gfunc_prolog(). It also take advantage of knowing if a function is variadic or not move float result value from VFP register to core register in gfunc_epilog().
* Move logic for if (int value) to tccgen.cThomas Preud'homme2014-01-041-18/+1
| | | | | | | Move the logic to do a test of an integer value (ex if (0)) out of arch-specific code to tccgen.c to avoid code duplication. This also fixes test of long long value which was only testing the bottom half of such values on 32 bits architectures.
* Report error on NaN comparisonThomas Preud'homme2014-01-031-3/+9
| | | | | | | | Use comisd / fcompp for float comparison (except TOK_EQ and TOK_NE) instead of ucomisd / fucompp to detect NaN comparison. Thanks Vincent Lefèvre for the bug report and for also giving the solution.
* Always set *palign in classify_x86_64_argThomas Preud'homme2014-01-031-0/+1
| | | | | | | Set *palign for VT_BITFIELD and VT_ARRAY types in classify_x86_64_arg as else you happen to have in *palign what was already there. This can cause gfunc_call on !PE systems to consider an array as 16 bytes align and trigger the assert if the previous argument was 16 bytes aligned.
* Add support for struct > 4B returned via registersThomas Preud'homme2013-11-221-8/+10
| | | | | | | | On ARM with hardfloat calling convention, structure containing 4 fields or less of the same float type are returned via float registers. This means that a structure can be returned in up to 4 double registers in a structure is composed of 4 doubles. This commit adds support for return of structures in several registers.
* Fix commit 0f5942c6b382105075dabb6f975a313efc63a5f9Thomas Preud'homme2013-10-011-7/+3
|
* Avoid warnings with gcc 4.8 + default CFLAGSThomas Preud'homme2013-09-241-10/+16
|
* Add support for load/store of _Bool valueThomas Preud'homme2013-06-141-1/+1
| | | | | Add support for loading _Bool value in i386, x86_64 and arm as well as support for storing _Bool value on arm.
* avoid "decl after statement" pleasegrischka2013-04-301-6/+9
| | | | for compiling tcc with msc
* Improved variable length array support.James Lyon2013-04-271-4/+43
| | | | | | | | | | | | | | | VLA storage is now freed when it goes out of scope. This makes it possible to use a VLA inside a loop without consuming an unlimited amount of memory. Combining VLAs with alloca() should work as in GCC - when a VLA is freed, memory allocated by alloca() after the VLA was created is also freed. There are some exceptions to this rule when using goto: if a VLA is in scope at the goto, jumping to a label will reset the stack pointer to where it was immediately after the last VLA was created prior to the label, or to what it was before the first VLA was created if the label is outside the scope of any VLA. This means that in some cases combining alloca() and VLAs will free alloca() memory where GCC would not.
* Fixed x86-64 long double passing.James Lyon2013-04-261-120/+182
| | | | | | long double arguments require 16-byte alignment on the stack, which requires adjustment when the the stack offset is not an evven number of 8-byte words.
* Sorted out CMake on x86-64 and fixed silly XMM# bug introduced when working ↵James Lyon2013-04-251-4/+11
| | | | | | | | | on Win64 stdargs. I removed the XMM6/7 registers from the register list because they are not used on Win64 however they are necessary for parameter passing on x86-64. I have now restored them but not marked them with RC_FLOAT so they will not be used except for parameter passing.
* 64-bit tests now pass (well, nearly).James Lyon2013-04-241-106/+143
| | | | | tcctest1-3 fail, but this appears to be due to bugs in GCC rather than TCC (from manual inspection of the output).
* Improved x86-64 XMM register argument passing.James Lyon2013-04-191-75/+118
| | | | | | | Also made XMM0-7 available for use as temporary registers, since they are not used by the ABI. I'd like to do the same with RSI and RDI but that's trickier since they can be used by gv() as temporary registers and there isn't a way to disable that.
* Fixed problems with XMM1 use on Linux/x86-64.James Lyon2013-04-191-104/+115
| | | | | | All tests pass. I think I've caught all the cases assuming only XMM0 is used. I expect that Win64 is horribly broken by this point though, because I haven't altered it to cope with XMM1.
* Most x86-64 tests now work; only on error in test1-3.James Lyon2013-04-191-43/+80
| | | | | | I've had to introduce the XMM1 register to get the calling convention to work properly, unfortunately this has broken a fair bit of code which assumes that only XMM0 is used.
* Got test1-3 working on x86-64.James Lyon2013-04-191-72/+79
| | | | | | There are probably still issues on x86-64 I've missed. I've added a few new tests to abitest, which fail (2x long long and 2x double in a struct should be passed in registers).
* x86-64 ABI fixes.James Lyon2013-04-191-62/+243
| | | | | | | | | abitest now passes; however test1-3 fail in init_test. All other tests pass. I need to re-test Win32 and Linux-x86. I've added a dummy implementation of gfunc_sret to c67-gen.c so it should now compile, and I think it should behave as before I created gfunc_sret.
* tcc.h: declare CValue.tab[LDOUBLE_SIZE/4]grischka2013-02-081-4/+1
| | | | | | | | Should fix some warnings wrt. access out of array bounds. tccelf.c: fix "static function unused" warning x86_64-gen.c: fix "ctype.ref uninitialzed" warning and cleanup tcc-win32.txt: remove obsolete limitation notes.
* x86-64: Fix call saved register restoreMichael Matz2012-06-101-2/+2
| | | | | | Loads of VT_LLOCAL values (which effectively represent saved addresses of lvalues) were done in VT_INT type, loosing the upper 32 bits. Needs to be done in VT_PTR type.
* x86_64: Fix compares with NaNs.Michael Matz2012-05-131-2/+31
| | | | | | Comparisons with unordered doubles was broken, NaNs always compare unequal (and unordered) to everything, including to itself.
* x86_64: Fix segfault for global dataMichael Matz2012-04-181-1/+1
| | | | | | | | | | | When offsetted addresses of global non-static data are computed multiple times in the same statement the x86_64 backend uses gen_gotpcrel with offset, which implements an add insn on the register given. load() uses the R member of the to-be-loaded value, which doesn't yet have a reg assigned in all cases. So use the register we're supposed to load the value into as that register.
* x86_64: Fix indirection in struct paramatersMichael Matz2012-04-181-16/+23
| | | | | | | | | | | | | The first loop setting up struct arguments must not remove elements from the vstack (via vtop--), as gen_reg needs them to potentially evict some argument still held in registers to stack. Swapping the arg in question to top (and back to its place) also simplifies the vstore call itself, as not funny save/restore or some "non-existing" stack elements need to be done. Generally for a stack a vop-- operation conceptually clobbers that element, so further references to it aren't allowed anymore.
* x86_64: fix loading of LLOCAL floatsgrischka2012-03-051-4/+8
| | | | | | | | See also commit 9527c4949fd94adb2567229413c70c19b663a118 On x86_64 we need to extend the reg_classes array because load() is called for (at least) R11 too, which was not part of reg_classes previously.
* win64: va_arg with structuresgrischka2011-07-141-34/+38
|
* tccrun: win64: add unwind function table for dynamic codegrischka2011-07-141-3/+4
| | | | | This works only when tcc.exe is compiled using MSC. MinGW does something in the startup code that defeats it.
* Make alignments for struct arguments 8 bytesShinichiro Hamaji2010-12-281-4/+4
| | | | | The ABI (http://www.x86-64.org/documentation/abi.pdf) says "The size of each argument gets rounded up to eightbytes"
* Probably wrong stack alignment for struct on Win64Shinichiro Hamaji2010-08-271-1/+1
|
* Fix alignment around struct for SSE.Shinichiro Hamaji2010-08-271-6/+18
| | | | | | | - Fix a wrong calculation for size of struct - Handle cases where struct size isn't multple of 8 - Recover vstack after memcpy for pushing struct - Add a float parameter for struct_assign_test1 to check SSE alignment
* tccpe: improve dllimport/export and use for tcc_add_symbolgrischka2010-01-141-4/+4
|
* build from multiple objects: fix other targetsgrischka2009-12-201-1/+1
|
* x86-64: fix gtst, back to only 5 regs for nowgrischka2009-12-201-17/+9
|
* x86-64: use r8/r9 as generic integer registersgrischka2009-12-201-151/+98
|
* x86-64: use r8,r9 as load/store registersgrischka2009-12-201-43/+74
|
* use vpushv in some placesgrischka2009-12-201-1/+1
|
* win64: add tiny unwind data for setjmp/longjmpgrischka2009-12-201-104/+232
| | | | | | | | | This enables native unwind semantics with longjmp on win64 by putting an entry into the .pdata section for each compiled fuction. Also, the function now use a fixed stack and store arguments into X(%rsp) rather than using push.
* allow tcc be build from separate objectsgrischka2009-12-201-14/+24
| | | | If you want that, run: make NOTALLINONE=1
* tccpe: improve dllimportgrischka2009-12-191-0/+10
|
* integrate x86_64-asm.c into i386-asm.cgrischka2009-12-191-2/+13
| | | | | Also, disable 16bit support for now as it causes bugs in 32bit mode. #define I386_ASM_16 if you want it.