Using -mcall-prologues generates several problems on AT2561

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using -mcall-prologues generates several problems on ATMEGA2561

One gets hundreds errors like
G:\ATMEGA/usart.h(831,1): internal error: out of range error

Yet the project is buildign itself OK.
The binary itself hangs easily when calling those functions.

apparently for all functions above 128KB limit.
same story in STUDIO4.

This option is an important size saver, therefore it is likely to be used when there are no alternatives, that is, exactly for 256KB devices...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My guess is that the compiler is hard-wired to try to RJMP to the prologue and epilogue code in FLASH, which will fail when the function is placed to far away for such an instruction. This sounds like you might need to do some hairy linker section relocations to get it to work until the compiler is patched.

That said, a 256KB device should have plenty of other places you can optimize to get the size down. What compiler and linker options are you using now?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Compilation:
-funsigned-char -funsigned-bitfields -DATMEGA2561 -DF_CPU=14745600 -I"G:\ATMEGA" -Os -fdata-sections -fno-exceptions -fno-jump-tables -fno-threadsafe-statics -ffunction-sections -fshort-enums -g3 -Wall -pedantic -c -Wextra -v -save-temps -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -mmcu=atmega2561

Linking:
-Wl,-s -Wl,-static -Wl,-Map="$(OutputFileName).map" -Wl,-u,vfprintf -Wl,--start-group -Wl,-lprintf_flt -Wl,-lscanf_flt -Wl,-lm -Wl,-lc -Wl,--end-group -Wl,--gc-sections -mrelax -Wl,-u,vfscanf -mmcu=atmega2561

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kbosak wrote:
Compilation:
-funsigned-char -funsigned-bitfields -DATMEGA2561 -DF_CPU=14745600 -I"G:\ATMEGA" -Os -fdata-sections -fno-exceptions -fno-jump-tables -fno-threadsafe-statics -ffunction-sections -fshort-enums -g3 -Wall -pedantic -c -Wextra -v -save-temps -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)" -mmcu=atmega2561
Haven't you just said that it's -mcall-prologues which causes you problems? I can't find it within the options you've posted.

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is exactly what I say: when I add -mcall-prologues, I have said error.
I fully understand and agree with abcminiuser's diagnosis. The question is what else could I do on compiler level for potential code size savings. My estimates from atmega128 say I could save some 5...8KB here. This is very important and costly to achieve with other means for me - the code is heterogenous, complex and every byte has been considered for removal during invremental builds since years. The more I am pressed, ther more I am likely to change processor; what I don't want to do yet because I am supporting several legacy products as well.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kbosak wrote:
I fully understand and agree with abcminiuser's diagnosis [RJMP to reach the prologue/epilogue code].
That would be easy to confirm: have a look at the asm listing. But I doubt it is the case. Besides, that would hit before the 64kW limit: RJMP reaches to +-4kW IIRC.

I would say it is some of the linker errors. My first guess would be http://sourceware.org/bugzilla/s... triggered by the ldi r30,lo8(gs(1f)) / ldi r31,hi8(gs(1f)) sequence to save the "return address" before jumping to __prologue_saves__+N , but you posted -mrelax in your linker options, while this error occurs specifically when non-relax . Without you posting more information (a minimal compilable program exhibiting the problem and the exact command-line options used to invoke the compiler/linker) it's hard to tell more.

JW

PS. An example demonstrating PR14058 triggered by -mcall-prologues:

#include 

volatile uint32_t v;

void foo(void) {
  volatile uint32_t a, b, c, d;
  v = a = v = b = v = c = v = d = v;
  __asm(
".skip 131072,0 \n\t"
  );
}

void bar(void) {
  volatile uint32_t a, b, c, d;
  v = a = v = b = v = c = v = d = v;
}


int main(void) {
  foo();
  bar();
}
c:\tmp>"c:\Program Files\Atmel\AVRTools\WinAVR20100110\bin\avr-gcc" -fno-inline -mcall-prologues   aa.c -Os -DF_CPU=14745600UL -mmcu=atmega2561 -Wa,-adhlns=aa.lst -Wl,-Map=aa.map,--cref -o aa.elf
C:\Users\OM7ZZ\AppData\Local\Temp/ccPzuVun.o: In function `bar':
aa.c:(.text+0x200d8): warning: internal error: out of range error
aa.c:(.text+0x200da): warning: internal error: out of range error