nested functions on Arm

Ulrich Drepper drepper@redhat.com
Wed Sep 13 00:00:00 GMT 2000


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);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


More information about the Gcc-bugs mailing list