(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
arm/
long-calls-4.c
       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" } } */