diff options
| author | Kirill Smelkov <kirr@navytux.spb.ru> | 2012-11-15 03:31:49 +0400 |
|---|---|---|
| committer | Kirill Smelkov <kirr@navytux.spb.ru> | 2012-11-16 10:22:14 +0400 |
| commit | b2a02961b4407ca76db5a66ca5ae855cbfba4e8e (patch) | |
| tree | 3c0d00665fab9e4b352fcf5b1ad32063d955afb7 /tests | |
| parent | e79c3533ecefd004daad8a27333582b2dad7f0b0 (diff) | |
| download | tinycc-b2a02961b4407ca76db5a66ca5ae855cbfba4e8e.tar.gz tinycc-b2a02961b4407ca76db5a66ca5ae855cbfba4e8e.tar.bz2 | |
Add support for __builtin_frame_address(level)
Continuing d6072d37 (Add __builtin_frame_address(0)) implement
__builtin_frame_address for levels greater than zero, in order for
tinycc to be able to compile its own lib/bcheck.c after
cffb7af9 (lib/bcheck: Prevent __bound_local_new / __bound_local_delete
from being miscompiled).
I'm new to the internals, and used the most simple way to do it.
Generated code is not very good for levels >= 2, compare
gcc tcc
level=0 mov %ebp,%eax lea 0x0(%ebp),%eax
level=1 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
level=2 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
mov (%eax),%eax mov %eax,-0x10(%ebp)
mov -0x10(%ebp),%eax
mov (%eax),%eax
level=3 mov 0x0(%ebp),%eax mov 0x0(%ebp),%eax
mov (%eax),%eax mov (%eax),%ecx
mov (%eax),%eax mov (%ecx),%eax
But this is still an improvement and for bcheck we need level=1 for
which the code is good.
For the tests I had to force gcc use -O0 to not inline the functions.
And -fno-omit-frame-pointer just in case.
If someone knows how to improve the generated code - help is
appreciated.
Thanks,
Kirill
Cc: Michael Matz <matz@suse.de>
Cc: Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/Makefile | 2 | ||||
| -rw-r--r-- | tests/tcctest.c | 27 |
2 files changed, 28 insertions, 1 deletions
diff --git a/tests/Makefile b/tests/Makefile index 2e7dd23..af1fdb8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -73,7 +73,7 @@ libtcc_test$(EXESUF): libtcc_test.c ../$(LIBTCC) # copy only tcclib.h so GCC's stddef and stdarg will be used test.ref: tcctest.c cp ../include/tcclib.h . - $(CC) -o tcctest.gcc $< -I. $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 $(LDFLAGS) + $(CC) -o tcctest.gcc $< -I. $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 -O0 -fno-omit-frame-pointer $(LDFLAGS) ./tcctest.gcc > $@ # auto test diff --git a/tests/tcctest.c b/tests/tcctest.c index 82762ea..4f9f2a3 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -89,6 +89,7 @@ void global_data_test(void); void cmp_comparison_test(void); void math_cmp_test(void); void callsave_test(void); +void builtin_frame_address_test(void); int fib(int n); void num(int n); @@ -598,6 +599,7 @@ int main(int argc, char **argv) cmp_comparison_test(); math_cmp_test(); callsave_test(); + builtin_frame_address_test(); return 0; } @@ -2680,3 +2682,28 @@ void callsave_test(void) printf ("%d\n", i); #endif } + + +void bfa3(ptrdiff_t str_offset) +{ + printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset); +} +void bfa2(ptrdiff_t str_offset) +{ + printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset); + bfa3(str_offset); +} +void bfa1(ptrdiff_t str_offset) +{ + printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset); + bfa2(str_offset); +} + +void builtin_frame_address_test(void) +{ + char str[] = "__builtin_frame_address"; + char *fp0 = __builtin_frame_address(0); + + printf("str: %s\n", str); + bfa1(str-fp0); +} |
