-
Notifications
You must be signed in to change notification settings - Fork 14
AVR is Harvard architecture #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Is there any existing LLVM target that uses Harvard architecture that we could pillage for ideas? I was hoping MSP430 might be, but no luck there. |
Maybe NVPTX? It has multiple address spaces. |
I believe the way this is implemented in other targets is via numbered address spaces. Address space We have an AVR-specific method for this already - I haven't looked at your patch in-depth yet but these are my thoughts
That's easy enough - we can teach Rust to emit global variables with address space
Maybe an attribute? I'm not entirely certain.
LLVM does have target-specific attributes, and they are also quite easy to add.
I believe that all loads/stores should use data memory (
Can you point me to where in GCC it does that? Looks like we're definitely going to need to implement that. |
By the way, it looks like we currently already lower progmem variables to the correct |
Wait, now I'm confused (hardly a first, I know). Why was I bumping into this in #47 then? |
I think that that is caused by the fact that the switch resides in program memory but it is not marked as such (via an address space attribute). In this case, Rust is probably emitting a switch lookup table and neglecting to put an address space attribute on it. |
I'm going to continue this conversation on #47 |
I haven't dived into GCC's source yet, but here's an example showing this copying in action. C source file:
Object file: note that string literal is in
Linked exe: note
|
Is this issue why I can't use byte strings? Code such as
... which produces assembly like ...
works, but code such as
which produces assembly like
and the .data section:
sends null bytes only. Interestingly, with --release it works either way -- it again stores the data inside the code with optimization, so I assume that's why it works. |
I believe you are right; that is the problem. You need to have |
Is this still an issue? if so i can add some details of how its implemented on C++... |
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 separatelpm
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 anld
and when to compile it into anlpm
. My experimental hack currently selectslpm
forisConstant
GlobalVariable
s andld
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 ofmain
) to RAM, and then use those addresses withld
.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 selectionThe text was updated successfully, but these errors were encountered: