Compiler Error: "error: unable to find a register to sp

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

Umm...

I think I've uncovered an odd compiler error.

"error: unable to find a register to spill in class `BASE_POINTER_REGS'"

I have some sample code that exposes the error see below Was wondering how I should report this.

Matt

/*
  Sample code that exposes some sort of compiler error.

  Error Message is:
  tests.c:65: error: unable to find a register to spill in class `BASE_POINTER_REGS'

  If EXPOSE_ERROR is defined as 1 then the error appears.  If defined 
  as 0 then the  error disappears.

  Complied with the following command line with avr-gcc 3.4.5
  
  avr-gcc -c -mmcu=atmega16 -Os tests.c

*/
#include 
#include 

#define EXPOSE_ERROR  1

// Sensor Data typedef and array
typedef struct 
{
	uint8_t sensor_type;		// sensor type 
	uint8_t (*Read)(uint8_t sensor_num);	// sensor function

	uint8_t tst1;		        // rate alarm flag
	uint8_t tst2;		        // rate alarm flag
	uint8_t tst3;		        // rate alarm flag
	uint8_t tst4;		        // rate alarm flag
	uint8_t tst5;		        // rate alarm flag
	uint8_t tst6;		        // rate alarm flag
#if EXPOSE_ERROR
	uint8_t tst7;		        // rate alarm flag
#endif
} SENSOR_DATA_T;

#define MAX_SENSOR_CHAN  5
#define SENSOR_NULL 0xff

extern SENSOR_DATA_T sensor_data[];

SENSOR_DATA_T sensor_data[MAX_SENSOR_CHAN];

uint8_t (*Read)(uint8_t sensor_num);
uint8_t ReadSensors(void)
{
	uint8_t sensor_num;
	uint8_t alarm = 0;
	
	// read sensors
	for(sensor_num=0; sensor_num
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

I did copy&paste your code an got the same error with AVR-GCC 3.4.5 (AtmanAVR)

It does not depend on the Taret-CPU, but on the optimization level. With -O0 and -O1 it does compile, but not with any higer optimization level.

Nevertheless, maybe there is a problem in you code?

extern SENSOR_DATA_T sensor_data[]; // ???

This is not the reason for your error, but why do you use this extern declaration, while you define it also local..?

Regards Peter

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

I tested you code sample, that you present above.
gcc-4.0.3 binutils-2.16.1 avr-libc-1.4.3 + all possible patches. Build under AVRS 4.12 :

Quote:

Build started 16.4.2006 at 13:10:32
avr-gcc.exe -mmcu=atmega16 -Wall -gdwarf-2 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT MovW.o -MF dep/MovW.o.d -c ../MovW.c
avr-gcc.exe -mmcu=atmega16 -lm -Wl,-Map=MovW.map MovW.o -o MovW.elf
avr-objcopy -O ihex -R .eeprom MovW.elf MovW.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O ihex MovW.elf MovW.eep
avr-objdump -h -S MovW.elf > MovW.lss
Build succeeded with 0 Warnings...

In all case (EXPOSE_ERROR 1 & EXPOSE_ERROR 0 and different optimization level) compiller do not throw error message, program passage ander debugger don't arosed error suspicion.
:(
For experiment, you can change version(any builds) of toots-chain componets(gcc,binutils,libc). It's possible you can differt compile result.

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

peter.sager wrote:
Hi

I did copy&paste your code an got the same error with AVR-GCC 3.4.5 (AtmanAVR)

It does not depend on the Taret-CPU, but on the optimization level. With -O0 and -O1 it does compile, but not with any higer optimization level.

Regards Peter

Yeah I noticed that too. It seesm that at higher optimiztion levels and certain array element sizes the bug is exposed.

peter.sager wrote:
Hi
Nevertheless, maybe there is a problem in you code?

extern SENSOR_DATA_T sensor_data[]; // ???

This is not the reason for your error, but why do you use this extern declaration, while you define it also local..?

Regards Peter

I don't think so. The extern is extranious. You can ditch it, or the local definition of sensor_data and the code still gives an error.

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

I have no idea whether GCC 3.x errors will still be fixed.
I suggest filing an official bug report anyway.

I can confirm that it doesn't happen for GCC 4.x.

Workaround: explicitly use a struct pointer. Probably more
efficient anyway.

#include 
#include 

#define EXPOSE_ERROR  1

// Sensor Data typedef and array
typedef struct
{
   uint8_t sensor_type;      // sensor type
   uint8_t (*Read)(uint8_t sensor_num);   // sensor function

   uint8_t tst1;              // rate alarm flag
   uint8_t tst2;              // rate alarm flag
   uint8_t tst3;              // rate alarm flag
   uint8_t tst4;              // rate alarm flag
   uint8_t tst5;              // rate alarm flag
   uint8_t tst6;              // rate alarm flag
#if EXPOSE_ERROR
   uint8_t tst7;              // rate alarm flag
#endif
} SENSOR_DATA_T;

#define MAX_SENSOR_CHAN  5
#define SENSOR_NULL 0xff

extern SENSOR_DATA_T sensor_data[];

SENSOR_DATA_T sensor_data[MAX_SENSOR_CHAN];
uint8_t (*Read)(uint8_t sensor_num);

uint8_t ReadSensors(void)
{
   uint8_t sensor_num;
   uint8_t alarm = 0;
   SENSOR_DATA_T *tp;

   // read sensors
   for(sensor_num=0, tp = sensor_data; sensor_numsensor_type == SENSOR_NULL)
         continue;

      Read = tp->Read;
      // Call sensor function pointer, if not zero
      if(!Read)
         continue;

      alarm = Read(sensor_num);
   }
   return(alarm);
}

int main(void)
{
   ReadSensors();
   return(0);
}

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.