-
Notifications
You must be signed in to change notification settings - Fork 164
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
riscv-rt
: partial compatibility with RV32E
#243
base: master
Are you sure you want to change the base?
Conversation
riscv-rt
: partial compatibility with RV32E
riscv-rt/src/lib.rs
Outdated
/// `x1`: return address, stores the address to return to after a function call or interrupt. | ||
pub ra: usize, | ||
/// `x5`: temporary register `t0`, used for intermediate values. | ||
pub t0: usize, | ||
/// `x6`: temporary register `t1`, used for intermediate values. | ||
pub t1: usize, | ||
/// `x7`: temporary register `t2`, used for intermediate values. | ||
pub t2: usize, | ||
/// `x28`: temporary register `t3`, used for intermediate values. | ||
pub t3: usize, | ||
/// `x29`: temporary register `t4`, used for intermediate values. | ||
pub t4: usize, | ||
/// `x30`: temporary register `t5`, used for intermediate values. | ||
pub t5: usize, | ||
/// `x31`: temporary register `t6`, used for intermediate values. | ||
pub t6: usize, | ||
/// `x10`: argument register `a0`. Used to pass the first argument to a function. | ||
pub a0: usize, | ||
/// `x11`: argument register `a1`. Used to pass the second argument to a function. | ||
pub a1: usize, | ||
/// `x12`: argument register `a2`. Used to pass the third argument to a function. | ||
pub a2: usize, | ||
/// `x13`: argument register `a3`. Used to pass the fourth argument to a function. | ||
pub a3: usize, | ||
/// `x14`: argument register `a4`. Used to pass the fifth argument to a function. | ||
pub a4: usize, | ||
/// `x15`: argument register `a5`. Used to pass the sixth argument to a function. | ||
pub a5: usize, | ||
/// `x16`: argument register `a6`. Used to pass the seventh argument to a function. | ||
pub a6: usize, | ||
/// `x17`: argument register `a7`. Used to pass the eighth argument to a function. | ||
pub a7: usize, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be a good idea to order these fields by there x*
name (similar to the spec)?
Also, maybe we use coniditional compilation to not include the x16
-x31
registers for RV32E builds?
Mostly thinking about downstream users that may use a pointer to the TrapFrame
, which they may or may not try to map to memory layout.
It may not be necessary, but could be a helpful reminder that those registers don't exist on RV32E platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd try to avoid changing the order of the attributes in case users use C or assembly code that relies on the current order.
I'm working on feature-gating registers for RVE32. It's a bit tricky, as we need to add "trash" padding to ensure that the stack is 16-byte aligned. I'll open a PR shortly with all this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd try to avoid changing the order of the attributes in case users use C or assembly code that relies on the current order.
I guess that's also part of what I'm asking, "should we intentionally break downstream users compiling RV32E?" Especially regarding not providing them in-memory registers that don't exist on the platform.
For non-RV32E users, I agree with you, we should avoid breaking them without a good reason.
I'm working on feature-gating registers for RVE32. It's a bit tricky, as we need to add "trash" padding to ensure that the stack is 16-byte aligned. I'll open a PR shortly with all this.
Sounds good, I'll keep an eye out for it.
Maybe for the missing registers on RV32E targets:
pub struct TrapFrame {
#[cfg(not(rv32e))]
pub a6: usize,
#[cfg(rv32e)]
_a6: usize,
...
}
b05269a
to
289206a
Compare
I've been working on a complete My main challenge now is configuring |
If this specifically about I would be happy to help out, if you have some work-in-progress code you would like extra eyes on. |
2e75fe7
to
9c3d91d
Compare
9c3d91d
to
1e71338
Compare
This is the best way I could think of. I tried forwarding environment variables from build scripts to no avail, as procedural macros are compiled separately from regular crates. The macro code can be squeezed a bit, but more or less this is it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the best way I could think of. I tried forwarding environment variables from build scripts to no avail, as procedural macros are compiled separately from regular crates. The macro code can be squeezed a bit, but more or less this is it.
Yeah, I tried using conditional compilation with target_feature = "i"
+ target_feature = "e"
, but it doesn't look like base ISA are available.
If target_feature = "i"
and target_feature = "e"
were available, we could use conditional compilation to define a core_interrupt_inner
the four variants we care about, i.e. riscv32e
, riscv32i
, riscv64e
, riscv64i
. Then we could have the single core_interrupt
macro function wrapping the unsafe inner functions.
I can look at the rustc/cargo
source, and see what it takes to add base ISA as conditional compilation attribute. It may make more sense for the base ISA stuff to go under the instruction_set attribute (currently only has ARM in the docs).
The changes here LGTM.
Edit: something like this is what I was thinking: rv32e-compat-asm...rmsyn:riscv:rv32e-compat-asm
I tried something like that, but I found out that the procedural macros are compiled for the host, not the target. Thus, the |
What about replacing them with the Something like: rmsyn/riscv@rust-embedded:riscv:rv32e-compat-asm...rv32e-compat-asm |
Avoids using
x16
+ registers in assembly code. This is necessary to provide compatibility with RV32E.Note that there is still work to do. Namely, the trap frame must adapt to the target base instruction set.
Solves #189
Related: #239