1 /* Check that long calls to different sections are not optimized to "bl". */ 2 /* { dg-do compile { target { arm32 && fpic } } } */ 3 /* { dg-options "-O2 -fpic -mlong-calls" } */ 4 5 #define section(S) __attribute__((section(S))) 6 #define weak __attribute__((weak)) 7 #define noinline __attribute__((noinline)) 8 #define long_call __attribute__((long_call)) 9 #define short_call __attribute__((short_call)) 10 11 #define REMOTE_CALL(ID, TARGET_ATTRS, CALL_ATTRS) \ 12 const char *TARGET_ATTRS ID (void); \ 13 const char *CALL_ATTRS call_##ID (void) { return ID () + 1; } 14 15 #define EXTERN_CALL(ID, TARGET_ATTRS, CALL_ATTRS) \ 16 const char *TARGET_ATTRS noinline ID (void) { return #ID; } \ 17 const char *CALL_ATTRS call_##ID (void) { return ID () + 1; } \ 18 const char *CALL_ATTRS sibcall_##ID (void) { return ID (); } 19 20 #define STATIC_CALL(ID, TARGET_ATTRS, CALL_ATTRS) \ 21 static const char *TARGET_ATTRS noinline ID (void) { return #ID; } \ 22 const char *CALL_ATTRS call_##ID (void) { return ID () + 1; } \ 23 const char *CALL_ATTRS sibcall_##ID (void) { return ID (); } 24 25 #define DO_TESTS_SECTION(ID, TEST, TARGET_ATTRS) \ 26 TEST (ID##1, TARGET_ATTRS, ) \ 27 TEST (ID##2, TARGET_ATTRS section (".test.a"), section (".test.b")) \ 28 TEST (ID##3, TARGET_ATTRS section (".test.c"), section (".test.c")) 29 30 #define DO_TESTS_CALL_ATTR(ID, TEST, TARGET_ATTRS) \ 31 DO_TESTS_SECTION (ID##n, TEST, TARGET_ATTRS) \ 32 DO_TESTS_SECTION (ID##l, TEST, TARGET_ATTRS long_call) \ 33 DO_TESTS_SECTION (ID##s, TEST, TARGET_ATTRS short_call) 34 35 DO_TESTS_CALL_ATTR (remote_, REMOTE_CALL,) 36 DO_TESTS_CALL_ATTR (strong_, EXTERN_CALL,) 37 DO_TESTS_CALL_ATTR (weak_, EXTERN_CALL, weak) 38 DO_TESTS_CALL_ATTR (static_, STATIC_CALL,) 39 40 41 /* Calls to remote_*, strong_* and weak_* should honor the call type 42 attribute, with "long" being the default. 43 44 In the regular expressions below: 45 46 * The PLT marker is optional, even though we are using -fpic, 47 because it is not used (or required) on some targets. 48 49 * We allow both "b" and "bl" in some cases to allow for the 50 possibility of sibling calls. As of this writing, GCC does not 51 use sibling calls in Thumb-2 mode. */ 52 53 /* { dg-final { scan-assembler-not "\tbl\tremote_n1(\\(PLT\\))?\n" } } */ 54 /* { dg-final { scan-assembler-not "\tbl\tremote_n2(\\(PLT\\))?\n" } } */ 55 /* { dg-final { scan-assembler-not "\tbl\tremote_n3(\\(PLT\\))?\n" } } */ 56 57 /* { dg-final { scan-assembler-not "\tbl\tremote_l1(\\(PLT\\))?\n" } } */ 58 /* { dg-final { scan-assembler-not "\tbl\tremote_l2(\\(PLT\\))?\n" } } */ 59 /* { dg-final { scan-assembler-not "\tbl\tremote_l3(\\(PLT\\))?\n" } } */ 60 61 /* { dg-final { scan-assembler "\tbl\tremote_s1(\\(PLT\\))?\n" } } */ 62 /* { dg-final { scan-assembler "\tbl\tremote_s2(\\(PLT\\))?\n" } } */ 63 /* { dg-final { scan-assembler "\tbl\tremote_s3(\\(PLT\\))?\n" } } */ 64 65 66 /* { dg-final { scan-assembler-not "\tbl?\tstrong_n1(\\(PLT\\))?\n" } } */ 67 /* { dg-final { scan-assembler-not "\tbl?\tstrong_n2(\\(PLT\\))?\n" } } */ 68 /* { dg-final { scan-assembler-not "\tbl?\tstrong_n3(\\(PLT\\))?\n" } } */ 69 70 /* { dg-final { scan-assembler-not "\tbl?\tstrong_l1(\\(PLT\\))?\n" } } */ 71 /* { dg-final { scan-assembler-not "\tbl?\tstrong_l2(\\(PLT\\))?\n" } } */ 72 /* { dg-final { scan-assembler-not "\tbl?\tstrong_l3(\\(PLT\\))?\n" } } */ 73 74 /* { dg-final { scan-assembler "\tbl\tstrong_s1(\\(PLT\\))?\n" } } */ 75 /* { dg-final { scan-assembler "\tbl?\tstrong_s1(\\(PLT\\))?\n" } } */ 76 /* { dg-final { scan-assembler "\tbl\tstrong_s2(\\(PLT\\))?\n" } } */ 77 /* { dg-final { scan-assembler "\tbl?\tstrong_s2(\\(PLT\\))?\n" } } */ 78 /* { dg-final { scan-assembler "\tbl\tstrong_s3(\\(PLT\\))?\n" } } */ 79 /* { dg-final { scan-assembler "\tbl?\tstrong_s3(\\(PLT\\))?\n" } } */ 80 81 82 /* { dg-final { scan-assembler-not "\tbl?\tweak_n1(\\(PLT\\))?\n" } } */ 83 /* { dg-final { scan-assembler-not "\tbl?\tweak_n2(\\(PLT\\))?\n" } } */ 84 /* { dg-final { scan-assembler-not "\tbl?\tweak_n3(\\(PLT\\))?\n" } } */ 85 86 /* { dg-final { scan-assembler-not "\tbl?\tweak_l1(\\(PLT\\))?\n" } } */ 87 /* { dg-final { scan-assembler-not "\tbl?\tweak_l2(\\(PLT\\))?\n" } } */ 88 /* { dg-final { scan-assembler-not "\tbl?\tweak_l3(\\(PLT\\))?\n" } } */ 89 90 /* { dg-final { scan-assembler "\tbl\tweak_s1(\\(PLT\\))?\n" } } */ 91 /* { dg-final { scan-assembler "\tbl?\tweak_s1(\\(PLT\\))?\n" } } */ 92 /* { dg-final { scan-assembler "\tbl\tweak_s2(\\(PLT\\))?\n" } } */ 93 /* { dg-final { scan-assembler "\tbl?\tweak_s2(\\(PLT\\))?\n" } } */ 94 /* { dg-final { scan-assembler "\tbl\tweak_s3(\\(PLT\\))?\n" } } */ 95 /* { dg-final { scan-assembler "\tbl?\tweak_s3(\\(PLT\\))?\n" } } */ 96 97 98 /* Calls to static_*2 calls should honor the call type attribute, 99 with "long" being the default. Calls to other static_* functions 100 should be short. */ 101 102 /* { dg-final { scan-assembler "\tbl\tstatic_n1((\\(PLT\\))?)\n" } } */ 103 /* { dg-final { scan-assembler "\tbl?\tstatic_n1((\\(PLT\\))?)\n" } } */ 104 /* { dg-final { scan-assembler-not "\tbl?\tstatic_n2((\\(PLT\\))?)\n" } } */ 105 /* { dg-final { scan-assembler "\tbl\tstatic_n3((\\(PLT\\))?)\n" } } */ 106 /* { dg-final { scan-assembler "\tbl?\tstatic_n3((\\(PLT\\))?)\n" } } */ 107 108 /* { dg-final { scan-assembler "\tbl\tstatic_l1((\\(PLT\\))?)\n" } } */ 109 /* { dg-final { scan-assembler "\tbl?\tstatic_l1((\\(PLT\\))?)\n" } } */ 110 /* { dg-final { scan-assembler-not "\tbl?\tstatic_l2((\\(PLT\\))?)\n" } } */ 111 /* { dg-final { scan-assembler "\tbl\tstatic_l3((\\(PLT\\))?)\n" } } */ 112 /* { dg-final { scan-assembler "\tbl?\tstatic_l3((\\(PLT\\))?)\n" } } */ 113 114 /* { dg-final { scan-assembler "\tbl\tstatic_s1((\\(PLT\\))?)\n" } } */ 115 /* { dg-final { scan-assembler "\tbl?\tstatic_s1((\\(PLT\\))?)\n" } } */ 116 /* { dg-final { scan-assembler "\tbl\tstatic_s2((\\(PLT\\))?)\n" } } */ 117 /* { dg-final { scan-assembler "\tbl?\tstatic_s2((\\(PLT\\))?)\n" } } */ 118 /* { dg-final { scan-assembler "\tbl\tstatic_s3((\\(PLT\\))?)\n" } } */ 119 /* { dg-final { scan-assembler "\tbl?\tstatic_s3((\\(PLT\\))?)\n" } } */ 120