diff options
| author | Michael Matz <matz@suse.de> | 2016-10-08 22:50:16 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:49:55 +0100 |
| commit | a2a596e76724a7915361b4d0f1b5553929d26a31 (patch) | |
| tree | 2cc4185467b9003c95ce8e079dd11f9723e8c1d6 /tests | |
| parent | ddd461dcc866d17f1c89137dc275ce1da95e7be2 (diff) | |
| download | tinycc-a2a596e76724a7915361b4d0f1b5553929d26a31.tar.gz tinycc-a2a596e76724a7915361b4d0f1b5553929d26a31.tar.bz2 | |
x86-64-asm: Accept high register in clobbers
The callee saved registers (among them r12-r15) really need
saving/restoring if mentioned in asm clobbers, even if TCC
itself doesn't use them. E.g. the linux kernel relies on that
in its switch_to() implementation.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/tcctest.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/tests/tcctest.c b/tests/tcctest.c index d4a6a5a..5124a4f 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -2925,6 +2925,29 @@ void fancy_copy2 (unsigned *in, unsigned *out) asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); } +#ifdef __x86_64__ +void clobber_r12(void) +{ + asm volatile("mov $1, %%r12" ::: "r12"); +} +#endif + +void test_high_clobbers(void) +{ +#ifdef __x86_64__ + register long val asm("r12"); + long val2; + /* This tests if asm clobbers correctly save/restore callee saved + registers if they are clobbered and if it's the high 8 x86-64 + registers. This is fragile for GCC as the constraints do not + correctly capture the data flow, but good enough for us. */ + asm volatile("mov $0x4542, %%r12" : "=r" (val):: "memory"); + clobber_r12(); + asm volatile("mov %%r12, %0" : "=r" (val2) : "r" (val): "memory"); + printf("asmhc: 0x%x\n", val2); +#endif +} + void asm_test(void) { char buf[128]; @@ -3004,6 +3027,7 @@ void asm_test(void) printf ("fancycpy2(%d)=%d\n", val, val2); asm volatile ("mov $0x4243, %%esi" : "=r" (regvar)); printf ("regvar=%x\n", regvar); + test_high_clobbers(); return; label1: goto label2; |
