This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

nested functions on Arm


The nested function handling on Arm is completely broken in the
moment.  This prevents glibc from being used on Arm in the moment.

The problem is this piece from config/arm/arm.h:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Output assembler code for a block containing the constant parts
   of a trampoline, leaving space for the variable parts.

   On the ARM, (if r8 is the static chain regnum, and remembering that
   referencing pc adds an offset of 8) the trampoline looks like:
	   ldr 		r8, [pc, #0]
	   ldr		pc, [pc]
	   .word	static chain value
	   .word	function's address
   ??? FIXME: When the trampoline returns, r8 will be clobbered.  */
#define ARM_TRAMPOLINE_TEMPLATE(FILE)			\
{							\
  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",		\
	       STATIC_CHAIN_REGNUM, PC_REGNUM);		\
  asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n",		\
	       PC_REGNUM, PC_REGNUM);			\
  ASM_OUTPUT_INT (FILE, const0_rtx);			\
  ASM_OUTPUT_INT (FILE, const0_rtx);			\
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

r8 must be saved by the called function but the trampoline code
clobbers the register even before control reaches the actual function.

I append a program which current terminates with a SIGILL on Arm (I'm
using the mainline compiler from 20000909 but this shouldn't make a
difference).  It's not this specific code which I need to have
running, I just tried to construct a test case.  The test case should
probably be added to the test suite as well.

-- 
---------------.                          ,-.   1325 Chesapeake Terrace
Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
Red Hat          `--' drepper at redhat.com   `------------------------

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdlib.h>

extern int foo (int a, int b, int (*fp) (int, int));


int
main (void)
{
  int sum = 0;
  int i;

  int nested (int a, int b)
    {
      if (a > 2 * b)
	return a - b;
      else
	return b - a;
    }

  for (i = 0; i < 10; ++i)
    {
      int j;

      for (j = 0; j < 10; ++j)
	{
	  int k;

	  for (k = 0; k < 10; ++k)
	    sum += foo (i, j > k ? j - k : k - j, nested);
	}
    }

  if (sum != 2300)
    abort ();

  exit (0);
}


int
foo (int a, int b, int (*fp) (int, int))
{
  return fp (a, b);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]