Description
One problem I've run into (see #47) is that Rust sometimes generates static lookup tables from code, then the generated AVR assembly tries accessing that data using ld
. Of course, that doesn't work because AVR uses the Harvard architecture: the program image and RAM are in two completely separate namespaces. There's a separate lpm
instruction for loading data from program memory. A similar issue applies to static strings as well.
First off, we need to know when to compile an LLVM IR load
instruction into an ld
and when to compile it into an lpm
. My experimental hack currently selects lpm
for isConstant
GlobalVariable
s and ld
for everything else.
However, this is problematic because Rust code is free to take pointers to static strings in the form of
str
. To support that, we need to do what GCC does, which is to copy over these strings at startup (in a stub pasted to the start of main
) to RAM, and then use those addresses with ld
.
Putting it all together, my proposal for handling all this would be:
-
Static data emitted by the Rust compiler should never take up RAM. They should always reside in PROGMEM, linked into
.text
and accessed vialpm
. -
Static data originating from the user (e.g. static strings) should be copied to RAM at startup and that copy should be used (via
ld
) whenever a pointer is to be taken. -
Open question: Come up with a nice Rust API for the user to explicitly access PROGMEM when that is what they want (similar to AVR-GCC)
This should be implementable by:
-
On the Rust side, mark lookup tables etc. emitted by Rust with some special attribute (I hope LLVM has support for target-specific attributes) so that the LLVM AVR backend has a way of recognizing them
-
In the LLVM AVR backend, collect all static globals that are not marked with the above special attribute, and generate a stub that copies them into RAM at startup.
-
In the LLVM AVR backend,
LowerGlobalAddress
checks for that attribute and generates an appropriate wrapper ISD that is then used to dispatch tolpm
orld
during instruction selection