This is the mail archive of the gcc@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]
Other format: [Raw text]

initializing wider-than-pointers


For some chips, like xstormy16 and m16c, function pointers are wider
than other pointers.  These types of chips can use thunks to get
around this for gcc, but there are still a few cases when you want to
know the real (>16 bit) address of the function (reset vectors, for
example).

If you use code like this:

	long x = (long) &main;

(long long suffices for 32 bit machines, or -m32 on x86_64)

You stumble across two problems.  First, the tree for this has not
one but two conversions, so this code in varasm.c:

    case CONVERT_EXPR:
    case NOP_EXPR:
      {
	tree src;
	tree src_type;
	tree dest_type;

	src = TREE_OPERAND (value, 0);
	src_type = TREE_TYPE (src);
	dest_type = TREE_TYPE (value);

needs to look something like this:

	src = TREE_OPERAND (value, 0);

	while (TREE_CODE (src) == CONVERT_EXPR
	       || TREE_CODE (src) == NOP_EXPR)
	  src = TREE_OPERAND (src, 0);

Once past that, there's a second bit of code in varasm.c
(output_constant):

  thissize = int_size_in_bytes (TREE_TYPE (exp));

Which means the example code gets assembled like this (for example):

	.short main
	.zero 2

What we need, however, is this:

	.long main

First, this allows the linker to put in the real address of main
rather than the 16 bit thunk, and second, the code in
output_constant() always puts the zeros after the short, even on big
endian machines (visual inspection, not tested).

Ideas?


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