Add support for __builtin_frame_address(level)
Continuingd6072d37(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 aftercffb7af9(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>
This commit is contained in:
@ -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)
|
||||
generates a segfault. */
|
||||
i = d[0] > get100 ();
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user