History

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

Kirill Smelkov committed 14 years ago

Commit b2a02961 parent e79c3533 files · +37 −7Browse files

Unified · Split

3 files
  1. tccgen.c +9 −6
  2. tests/Makefile +1 −1
  3. tests/tcctest.c +27 −0
tccgen.c+9−6
@@ -3665,20 +3665,23 @@ ST_FUNC void unary(void) · 3664 unmodified lines
3665 break;3665 break;
3666 case TOK_builtin_frame_address:3666 case TOK_builtin_frame_address:
3667 {3667 {
3668 int level;
3668 CType type;3669 CType type;
3669 next();3670 next();
3670 skip('(');3671 skip('(');
3671 if (tok != TOK_CINT) {3672 if (tok != TOK_CINT || tokc.i < 0) {
3672 tcc_error("__builtin_frame_address only takes integers");3673 tcc_error("__builtin_frame_address only takes positive integers");
3673 }
3674 if (tokc.i != 0) {
3675 tcc_error("TCC only supports __builtin_frame_address(0)");
3676 }3674 }
3675 level = tokc.i;
3677 next();3676 next();
3678 skip(')');3677 skip(')');
3679 type.t = VT_VOID;3678 type.t = VT_VOID;
3680 mk_pointer(&type);3679 mk_pointer(&type);
3681 vset(&type, VT_LOCAL, 0);3680 vset(&type, VT_LOCAL, 0); /* local frame */
3681 while (level--) {
3682 mk_pointer(&vtop->type);
3683 indir(); /* -> parent frame */
3684 }
3682 }3685 }
3683 break;3686 break;
3684#ifdef TCC_TARGET_X86_643687#ifdef TCC_TARGET_X86_64
tests/Makefile+1−1
@@ -73,7 +73,7 @@ libtcc_test$(EXESUF): libtcc_test.c ../$(LIBTCC) · 72 unmodified lines
73# copy only tcclib.h so GCC's stddef and stdarg will be used73# copy only tcclib.h so GCC's stddef and stdarg will be used
74test.ref: tcctest.c74test.ref: tcctest.c
75 cp ../include/tcclib.h .75 cp ../include/tcclib.h .
76 $(CC) -o tcctest.gcc $< -I. $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 $(LDFLAGS)76 $(CC) -o tcctest.gcc $< -I. $(CPPFLAGS) -w $(CFLAGS) $(NATIVE_DEFINES) -std=gnu99 -O0 -fno-omit-frame-pointer $(LDFLAGS)
77 ./tcctest.gcc > $@77 ./tcctest.gcc > $@
78 78
79# auto test79# auto test
tests/tcctest.c+27−0
@@ -89,6 +89,7 @@ void global_data_test(void); · 88 unmodified lines
89void cmp_comparison_test(void);89void cmp_comparison_test(void);
90void math_cmp_test(void);90void math_cmp_test(void);
91void callsave_test(void);91void callsave_test(void);
92void builtin_frame_address_test(void);
92 93
93int fib(int n);94int fib(int n);
94void num(int n);95void num(int n);
@@ -598,6 +599,7 @@ int main(int argc, char **argv) · 503 unmodified lines
598 cmp_comparison_test();599 cmp_comparison_test();
599 math_cmp_test();600 math_cmp_test();
600 callsave_test();601 callsave_test();
602 builtin_frame_address_test();
601 return 0; 603 return 0;
602}604}
603 605
@@ -2680,3 +2682,28 @@ void callsave_test(void) · 2076 unmodified lines
2680 printf ("%d\n", i);2682 printf ("%d\n", i);
2681#endif2683#endif
2682}2684}
2685
2686
2687void bfa3(ptrdiff_t str_offset)
2688{
2689 printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
2690}
2691void bfa2(ptrdiff_t str_offset)
2692{
2693 printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
2694 bfa3(str_offset);
2695}
2696void bfa1(ptrdiff_t str_offset)
2697{
2698 printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
2699 bfa2(str_offset);
2700}
2701
2702void builtin_frame_address_test(void)
2703{
2704 char str[] = "__builtin_frame_address";
2705 char *fp0 = __builtin_frame_address(0);
2706
2707 printf("str: %s\n", str);
2708 bfa1(str-fp0);
2709}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t