-
Notifications
You must be signed in to change notification settings - Fork 263
ASM wrappers produce code that violates borrow rules #309
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
This is a quick-and-dirty fix for immunant#309 without the ambition to get merged into c2rust in this way; at least it would need * exploring of other options * checking of the string-based "*mut _" and "&mut *" parts that may be better expressed using the mk() interfaces
I've put together a demo workaround at chrysn-pull-requests@a5d7880 -- not even PR'ing it because it's clearly not merge-ready by far. For one, it's going for Rust code in strings wherever the AST builder lets it. Is that OK? Should this rather be done by using the builder to exhaustion? (And is this done for tangible benefits, or more a matter of style?) Then, there's the question of whether it's really necessary to go with raw pointers. In a slightly rewritten example C file (see below under the expander), where the variables accessed in the assembly reside in independent locals, it is sufficient to move the resulting Rust code around a bit -- once the Finally, the question remains whether by also changing the c2rust_asm_casts interface, anything can be simplified -- and whether it's worth it. test2.c#include <stdint.h>
uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
{
union llreg_u{
uint32_t w32[2];
uint64_t w64;
} llr;
llr.w64 = acc;
uint32_t l0 = llr.w32[0];
uint32_t l1 = llr.w32[1];
asm volatile ("smlaldx %0, %1, %2, %3" : "=r" (l1), "=r" (l0): "r" (op1), "r" (op2) , "0" (l1), "1" (l0) );
llr.w32[0] = l0;
llr.w32[1] = l1;
return llr.w64;
} |
|
This is a quick-and-dirty fix for immunant#309 without the ambition to get merged into c2rust in this way; at least it would need * exploring of other options * checking of the string-based "*mut _" and "&mut *" parts that may be better expressed using the mk() interfaces
This is a quick-and-dirty fix for immunant#309 without the ambition to get merged into c2rust in this way; at least it would need * exploring of other options * checking of the string-based "*mut _" and "&mut *" parts that may be better expressed using the mk() interfaces
Other than exploring c2rust-asm-casts further, does the proposed approach sound viable? If so, I can clean it up into a PR -- it's been working (albeit without hard testing) well for a while, and it doesn't seem like there are other solutions coming up. (Going from the recently deprecated llvm_asm to asm might make this obsolete, but from afar that looks like a lot of work). |
Contributes-To: https://gitlab.com/etonomy/riot-sys/-/issues/4 Workaround-For: immunant/c2rust#309
With the following ARM assembly function in
test.c
(found in the ARM CMSIS standard library as used in RIOT-OS; disclaimer: I have no clue what this actually does, it looks like an inline wrapper around some CPU instruction), the resulting Rust code is not buildable:After manually fixing #306 by s/asm/llvm_asm/ on c2rust-lib.rs and test.rs, the error can be shown with:
I've deliberately not passed the
--target thumbv7em-none-eabihf
in to cargo as that'd necessitate several other workarounds to get things running, among them #297 and #307 as well as adding panic stuff.To explore possibilities, I've altered the fresh variables to be
*mut T
rather than&mut T
, and only reborrow for any use in the cast_in / cast_out functions. That eventually (ie. with all the no_std workarounds and LTO) the same four instructions as plain compiling clang (cf. godbolt output).Might it be suitable to generally go for raw pointers rather than references when building code for ASM in the first place? While C2Rust might manage to recognize some patterns where references can work, I figure (from my very limited knowledge of assembly) it's hard to tell in general when borrow semantics can be applied and when not.
The text was updated successfully, but these errors were encountered: