Ulrich Weigand schrieb:
Georg-Johann Lay wrote:
Ulrich Weigand wrote:
I'd be happy to bring this up to date if you're willing to work with
me to get this tested on a target that needs this support ...
Just attached a patch to bugzilla because an AVR user wanted to play
with the AS support and asked me to supply my changes. It's still in
a mess but you could get a more reasonable base than on a target where
all named addresses vanish at expand.
The patch is fresh and attached to the enhancement PR49868, just BE stuff.
There is also some sample code.
OK, I'll have a look.
Looking at your definition of the routines avr_addr_space_subset_p and
avr_addr_space_convert, they appear to imply that any generic address
can be used without conversion as a __pgm address and vice versa.
There is a conversion HI (pmode) <-> PHI (__pgm)
These two modes resp. insns have the same arithmetic but differ in the
instructions they emit and in reloading.
That is: avr_addr_space_subset_p says that __pgm is both a superset
and a subset of the generic address space, so they must be co-extensive.
avr_addr_space_convert then says that the addresses can be converted
between the two without changing their value.
Is this really true? If so, why have a distinct __pgm address space
in the first place?
Bye,
Ulrich
AVR hardware has basically three address spaces:
Memoy Physical Mode Instruction Holds
----------------------------------------------------------------------
RAM 0, 1, 2, ... HI=Pmode LD*, ST* .data, .rodata, .bss
Flash 0, 1, 2, ... PHI LPM .text, .progmem.data
EEPROM 0, 1, 2, ... -- via SFR .eeprom
Devices have just some KB of RAM and constants are put into
.progmem.data via attribute progmem and read via inline asm.
AVR has three address registers X, Y and Z that can access memory.
SP is fixed and can just do push/pop on RAM.
Adressing capabilities follow. Only accessing byte is supported by HW:
RAM:
Constant address
*X, *--X, *X++
*Y, *--Y, *Y++, *(Y+offset) is Frame pointer
*Z, *--Z, *Z++, *(Z+offset)
Offset in [0, 63]
Flash:
*Z, *Z++
Of course, RAM and Flash are no subsets of each other when regarded as
physical memory, but they are subsets when regarded as numbers. This
lead to my mistake to define RAM and Flash being no subsets of each other:
http://gcc.gnu.org/ml/gcc/2010-11/msg00170.html
In a typical AVR program the user knows at compile time how to access a
variable and use an appropriate pointer like int* or const __pgm int*.
In a current program he uses inline asm for the second case.
However, there are situations like the following where you like to take
the decision at runtime:
char cast_3 (char in_pgm, void * p)
{
return in_pgm ? (*((char __pgm *) p)) : (*((char *) p));
}
The numeric value of p will stay exactly the same; just the mode and
thus the access instruction changes like
if (in_pgm)
r = LPM Z (PHI:Z)
else
r = LD Z (HI:Z or LD X+ or whatever)
Linearizing the address space at compiler level is not wanted because
that lead to bulky, slow code and reduced the effective address space
available for Flash which might be up to 64kWords.
An address in X, Y, Z is 16 bits wide, these regs occupy 2 hard regs.
Johann