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]

Re: Branch instructions that depend on target distance


On Mon, 24 Feb 2020 12:05:28 +0100
Petr Tesarik <ptesarik@suse.cz> wrote:

> Hi all,
> 
> I'm looking into reviving the efforts to port gcc to VideoCore IV [1].
> One issue I've run into is the need to find out target branch distance
> at compile time. I looked around, and it's not the first one
> architecture with such requirement, but AFAICS it has never been solved
> properly.
> 
> For example, AVR tracks instruction length. Later, ret_cond_branch()
> selects between a branch instruction and an inverted branch followed by
> an unconditional jump based on these calculated lengths.
> 
> This works great ... until there's some inline asm() statement, for
> which gcc cannot keep track of the length attribute, so it is probably
> taken as zero. Linker then fails with a cryptic message:
> 
> > relocation truncated to fit: R_AVR_7_PCREL against `no symbol'  

The MSP430 backend just always generates maximum range branch instructions,
except for some special cases. We then rely on the linker to relax branch
instructions to shorter range "jump" instructions when the destination is
within range.

So the compiler output will always work, but not be the smallest possible code
size.

For that relocation truncated to fit error message you want to check that the
linker has the ability to relax whatever branch instruction it is failing on to
a longer range branch.

Jozef
> 
> I can provide a minimal test case and report a bug if you want...
> 
> Developers work around the issue by rewriting their code when they are
> bitten by this, but it is less than optimal, because you cannot really
> get rid of all inline assembly, and it's in general unpredictable where
> these inline asm() blocks will be placed by the compiler.
> 
> OTOH, the avr backend is pretty outdated, so there may be a better
> alternative that I'm just not seeing. Any hints?
> 
> Background: There is a port of the VC4 port of the LK embedded kernel
> [2]. I have tried to build that kernel with optimization turned on, but
> I'm getting:
> 
> compiling kernel/thread.c
> /tmp/ccJFdnfX.s: Assembler messages:
> /tmp/ccJFdnfX.s:1451: Error: operand out of range (64 not between -64 and 63)
> 
> That's because there is an inline "di" (disable interrupts) instruction
> inside a conditional statement in thread_yield(), which causes this
> off-by-one miscalculation.
> 
> Petr T
> 
> [1] https://github.com/itszor/gcc-vc4
> [2] https://github.com/librerpi/lk


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