This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more information.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: powerpc-eabi subroutine calls


> >> GCC generates a "bl" (Opcode 0x48000000) for procedure
> >> calls. Unfortunately this PPC instruction allows only 24bit (signed)
> >> relative offset, i.e. the branch destination must be within +-8MByte
> >> distance from the caller.
> >>
> >
> >This is not true... gcc is generating absolutely correct code in this
> >case!
> >
> >The "bl" instruction uses the link register (LR) as a target address,
> >and with link register the core can achieve every position within
> >4Gbytes of the PowerPC 32-bit implementation) address space...
> >
> >Please, take a look into "PowerPC Microprocessor Family: The
> >Programming Environments for 32-Bit Microprocessor". It's free on the
> >Motorola web site.
>
> I'm sorry to disagree, but from the documentaion, the 'bl' instruction
> will branch to a address specified as PC-relative using 24 bits of
> address, and updates the LR with the return address.  The 'blrl'
> branches to the contents of the LR.  THe issue is that the two memory
> segments are farther apart than the 16MB that the 24 offset bits in
> the 'bl' instruction can encode, which is why you get the linker error:
>
> >       relocation truncated to fit: R_PPC_REL24 foo
>

For sure! Terrible sorry! Gunter and Peter are absolutely correct! Let me
see if I can help in another way...

I'll take a look one more time at gcc command line options to see if
something can force gcc to use 'blrl' instead of 'bl', but in this mean
time, maybe you can think in using a macro to do the "dirty" work of calling
a function from one flash region to another. In one of my MPC8XX projects in
the past, I use the following macros do get the read the machine state
register (MSR) and to write into it. Maybe you can build a similar macro (a
little bit more complex...) to call your "far" subroutines using the 'blrl'
instruction, test is only one time, and use it for the "rest of your project
life"...


#define GetMsr()                      \
({ unsigned int __value;              \
   asm ("mfmsr %0": "=r" (__value) ); \
   __value; })

#define SetMsr(new_msr)                 \
({ unsigned int __msr = (new_msr);      \
   asm ("mtmsr %0": : "r" (__msr) );    \
   asm ("isync"); })


The following code is tested and works very fine in calling a function using
the "blrl" instruction:

lis  2,YourFuncName@h
ori  2,2,YourFuncName@l
mtlr 2
blrl



Another suggestion, if the processor is completely under your control and we
cannot find any other resonable solution using compiler options, is to use
the system call exception ("sc" instruction) to call your subroutines, as
the operating systems do to perform OS function calls.


Joćo Cadamuro Junior
LIT / CPDTT / CEFET-PR



------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com


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