/* Test if functions marked __attribute__((used)), but with address never
|
/* Test if functions marked __attribute__((used)), but with address never
|
taken in C code, don't use alternate calling convention for local
|
taken in C code, don't use alternate calling convention for local
|
functions on IA-32. */
|
functions on IA-32. */
|
/* { dg-do run } */
|
/* { dg-do run } */
|
/* The asm in this test uses an absolute address. */
|
/* The asm in this test uses an absolute address. */
|
/* { dg-require-effective-target nonpic } */
|
/* { dg-require-effective-target nonpic } */
|
/* { dg-options "-O2" } */
|
/* { dg-options "-O2" } */
|
|
|
extern void abort (void);
|
extern void abort (void);
|
|
|
static int foo (int, int, int, int) __asm ("foo");
|
static int foo (int, int, int, int) __asm ("foo");
|
static __attribute__((noinline, used)) int
|
static __attribute__((noinline, used)) int
|
foo (int i, int j, int k, int l)
|
foo (int i, int j, int k, int l)
|
{
|
{
|
return i + j + k + l;
|
return i + j + k + l;
|
}
|
}
|
|
|
void
|
void
|
bar (void)
|
bar (void)
|
{
|
{
|
if (foo (1, 2, 3, 4) != 10)
|
if (foo (1, 2, 3, 4) != 10)
|
abort ();
|
abort ();
|
}
|
}
|
|
|
int (*fn) (int, int, int, int);
|
int (*fn) (int, int, int, int);
|
|
|
void
|
void
|
baz (void)
|
baz (void)
|
{
|
{
|
/* Darwin loads 64-bit regions above the 4GB boundary so
|
/* Darwin loads 64-bit regions above the 4GB boundary so
|
we need to use this instead. */
|
we need to use this instead. */
|
#if defined (__LP64__) && defined (__MACH__)
|
#if defined (__LP64__) && defined (__MACH__)
|
__asm ("leaq foo(%%rip), %0" : "=r" (fn));
|
__asm ("leaq foo(%%rip), %0" : "=r" (fn));
|
#else
|
#else
|
__asm ("movl $foo, %k0" : "=r" (fn));
|
__asm ("movl $foo, %k0" : "=r" (fn));
|
#endif
|
#endif
|
if (fn (2, 3, 4, 5) != 14)
|
if (fn (2, 3, 4, 5) != 14)
|
abort ();
|
abort ();
|
}
|
}
|
|
|
int
|
int
|
main (void)
|
main (void)
|
{
|
{
|
bar ();
|
bar ();
|
baz ();
|
baz ();
|
return 0;
|
return 0;
|
}
|
}
|
|
|