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
36653665 break;
36663666 case TOK_builtin_frame_address:
36673667 {
3668+ int level;
36683669 CType type;
36693670 next();
36703671 skip('(');
3671− if (tok != TOK_CINT) {
3672− tcc_error("__builtin_frame_address only takes integers");
3673− }
3674− if (tokc.i != 0) {
3675− tcc_error("TCC only supports __builtin_frame_address(0)");
3672+ if (tok != TOK_CINT || tokc.i < 0) {
3673+ tcc_error("__builtin_frame_address only takes positive integers");
36763674 }
3675+ level = tokc.i;
36773676 next();
36783677 skip(')');
36793678 type.t = VT_VOID;
36803679 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+ }
36823685 }
36833686 break;
36843687 #ifdef TCC_TARGET_X86_64
tests/Makefile+1−1
@@ -73,7 +73,7 @@ libtcc_test$(EXESUF): libtcc_test.c ../$(LIBTCC) · 72 unmodified lines
7373 # copy only tcclib.h so GCC's stddef and stdarg will be used
7474 test.ref: tcctest.c
7575 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)
7777 ./tcctest.gcc > $@
7878
7979 # auto test
tests/tcctest.c+27−0
@@ -89,6 +89,7 @@ void global_data_test(void); · 88 unmodified lines
8989 void cmp_comparison_test(void);
9090 void math_cmp_test(void);
9191 void callsave_test(void);
92+void builtin_frame_address_test(void);
9293
9394 int fib(int n);
9495 void num(int n);
@@ -598,6 +599,7 @@ int main(int argc, char **argv) · 503 unmodified lines
598599 cmp_comparison_test();
599600 math_cmp_test();
600601 callsave_test();
602+ builtin_frame_address_test();
601603 return 0;
602604 }
603605
@@ -2680,3 +2682,28 @@ void callsave_test(void) · 2076 unmodified lines
26802682 printf ("%d\n", i);
26812683 #endif
26822684 }
2685+
2686+
2687+void bfa3(ptrdiff_t str_offset)
2688+{
2689+ printf("bfa3: %s\n", (char *)__builtin_frame_address(3) + str_offset);
2690+}
2691+void bfa2(ptrdiff_t str_offset)
2692+{
2693+ printf("bfa2: %s\n", (char *)__builtin_frame_address(2) + str_offset);
2694+ bfa3(str_offset);
2695+}
2696+void bfa1(ptrdiff_t str_offset)
2697+{
2698+ printf("bfa1: %s\n", (char *)__builtin_frame_address(1) + str_offset);
2699+ bfa2(str_offset);
2700+}
2701+
2702+void 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