Discussion:
[uClinux-dev] Fatal Error: tried to convert PC relative
Chris Alfred
2002-06-07 00:37:57 UTC
Permalink
I am trying to compile microperl.
(microperl is now available in Perl-5.8.0-RC1 via
Makefile.micro)

I can compile all but one file. The result is as
below:

[chris at redhat perl-5.8.0-RC1]$ m68k-elf-gcc -m5307 -DCONFIG_COLDFIRE -c -o
utoke.o
-Os -g -fomit-frame-pointer -Dlinux -D__linux__ -Dunix -D__uClinux__
-DEMBED
-I/home/chris/CD1/uClinux-dist/lib/uClibc/include
-I/home/chris/CD1/uClinux-dist/lib/libm
-I/home/chris/CD1/uClinux-dist
-fno-builtin -msep-data
-I/home/chris/CD1/uClinux-dist/linux-2.4.x/include
-DPERL_CORE -DPERL_MICRO toke.c
/tmp/cc0KNTmO.s: Assembler messages:
/tmp/cc0KNTmO.s:40788: Fatal error: Tried to convert PC relative branch to
absolute jump

Anyone got any ideas?

When I get this going, I will post a patch for microperl to
work under uClinux. Then I will have a bash at the real perl
(unless someone beats me to it!).

Chris
This message resent by the uclinux-dev at uclinux.org list server http://www.uClinux.org/
pauli
2002-06-07 01:10:58 UTC
Permalink
Hi,
Post by Chris Alfred
/tmp/cc0KNTmO.s:40788: Fatal error: Tried to convert PC relative branch to
absolute jump
Anyone got any ideas?
Yep, the function concerned is too large. We've got a limited range in our relative branches (sixteen bit offset) on the 5307 and there is a branch in that code that exceeds this.


Pauli


This message resent by the uclinux-dev at uclinux.org list server http://www.uClinux.org/
Chris Alfred
2002-06-07 02:47:24 UTC
Permalink
Post by Chris Alfred
Post by Chris Alfred
/tmp/cc0KNTmO.s:40788: Fatal error: Tried to convert PC
relative branch to
Post by Chris Alfred
absolute jump
Anyone got any ideas?
Yep, the function concerned is too large. We've got a
limited range in our relative branches (sixteen bit offset)
on the 5307 and there is a branch in that code that exceeds this.
Pauli
Is this because the m68k-elf- compiler cannot not convert out of
range branches (16 bit offset limited) to 'PC indirect with scaled index
with 8 bit displacement' i.e. jmp (d8,PC,Xi*SF)?

This is an interesting limitation. Lexical languages like yacc generate
BIG switch statements which can make their automated output hard
to port to the ColdFire or anything without large offset branch
instructions.

Chris
This message resent by the uclinux-dev at uclinux.org list server http://www.uClinux.org/
pauli
2002-06-07 03:13:05 UTC
Permalink
Hi all,
Post by Chris Alfred
Is this because the m68k-elf- compiler cannot not convert out of
range branches (16 bit offset limited) to 'PC indirect with scaled index
with 8 bit displacement' i.e. jmp (d8,PC,Xi*SF)?
It isn't the compiler that is the problem. The compiler has generated
assembly code and the assembler is the thing that has discovered that the
branch goes too far. Too late to switch to a different addressing mode since
the register usage isn't known.

It could also be a conditional branch which further complicates things.
Post by Chris Alfred
This is an interesting limitation. Lexical languages like yacc generate
BIG switch statements which can make their automated output hard
to port to the ColdFire or anything without large offset branch
instructions.
I think switch statements are done differently. If I remember the code
generation properly, the switch produces a table of addresses and this is used
for the branch.


Two solutions, either reduce the size of the code block being jumped over (via
introduced procedures, possibly nested to avoid parameter redeclaration) or
use the address of a label extension in gcc.


Regards,

Pauli


This message resent by the uclinux-dev at uclinux.org list server http://www.uClinux.org/
Chris Alfred
2002-06-07 06:23:19 UTC
Permalink
Post by pauli
Post by Chris Alfred
Is this because the m68k-elf- compiler cannot not convert out of
range branches (16 bit offset limited) to 'PC indirect with
scaled index with 8 bit displacement' i.e. jmp (d8,PC,Xi*SF)?
It isn't the compiler that is the problem. The compiler has
generated
assembly code and the assembler is the thing that has
discovered that the
branch goes too far. Too late to switch to a different
addressing mode since
the register usage isn't known.
It could also be a conditional branch which further
complicates things.
[Oops I meant to say the assembler].

True, but it does limit what applications we can run on the
68000 based processors.

In fact, the same assembler works for the 68040 which can handle
long branches. The limited branch is a peculiarity of the 68000 which
should be accounted for in the assembler.

I guess it all depends on the architecture of gcc and as.
Post by pauli
Two solutions, either reduce the size of the code block being
jumped over (via
introduced procedures, possibly nested to avoid parameter
redeclaration) or
use the address of a label extension in gcc.
Unfortunately these are dead end solutions as the next version
of perl would have to be hand patched again.

It appears that the code is auto-generated by yacc or bison
creating a massive 3000 line function - this is out of the
user's control.

Chris
This message resent by the uclinux-dev at uclinux.org list server http://www.uClinux.org/
Loading...