-
Notifications
You must be signed in to change notification settings - Fork 274
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
Pi Zero W compiler error: "asm operand has impossible constraints" #171
Comments
I bumbled around a bit and eventually got something which at least builds: I replaced one of the input I cannot emphasise enough that I have no idea what I am doing, but with those changes it compiled "successfully". From what I gather, The really weird part (for me) is that I can't just change any input to So it compiles with that, but when I run it, it promptly segfaults just after the "All initialized, now running main loop..." log line. Which implies it's crashing the first time it encounters my mangled assembly. Guess I got something wrong then. Here's the patch so far (minus some windows/unix line ending changes which hopefully won't break things): diff --git a/diff.cpp b/diff.cpp
index 8966a15..fd0cc43 100644
--- a/diff.cpp
+++ b/diff.cpp
@@ -30,7 +30,7 @@ static int coarse_linear_diff(uint16_t *framebuffer, uint16_t *prevFramebuffer,
asm volatile(
"mov r0, %[framebufferEnd]\n" // r0 <- pointer to end of current framebuffer
"mov r1, %[framebuffer]\n" // r1 <- current framebuffer
- "mov r2, %[prevFramebuffer]\n" // r2 <- framebuffer of previous frame
+ "str r2, %[prevFramebuffer]\n" // r2 <- framebuffer of previous frame
"start_%=:\n"
"pld [r1, #128]\n" // preload data caches for both current and previous framebuffers 128 bytes ahead of time
@@ -64,7 +64,7 @@ static int coarse_linear_diff(uint16_t *framebuffer, uint16_t *prevFramebuffer,
"done_%=:\n"
"mov %[endPtr], r1\n" // output endPtr back to C code
: [endPtr]"=r"(endPtr)
- : [framebuffer]"r"(framebuffer), [prevFramebuffer]"r"(prevFramebuffer), [framebufferEnd]"r"(framebufferEnd)
+ : [framebuffer]"r"(framebuffer), [prevFramebuffer]"g"(prevFramebuffer), [framebufferEnd]"r"(framebufferEnd)
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc"
);
return endPtr - framebuffer;
@@ -77,7 +77,7 @@ static int coarse_backwards_linear_diff(uint16_t *framebuffer, uint16_t *prevFra
uint16_t *endPtr;
asm volatile(
"mov r0, %[framebufferBegin]\n" // r0 <- pointer to beginning of current framebuffer
- "mov r1, %[framebuffer]\n" // r1 <- current framebuffer (starting from end of framebuffer)
+ "str r1, %[framebuffer]\n" // r1 <- current framebuffer (starting from end of framebuffer)
"mov r2, %[prevFramebuffer]\n" // r2 <- framebuffer of previous frame (starting from end of framebuffer)
"start_%=:\n"
@@ -112,7 +112,7 @@ static int coarse_backwards_linear_diff(uint16_t *framebuffer, uint16_t *prevFra
"done_%=:\n"
"mov %[endPtr], r1\n" // output endPtr back to C code
: [endPtr]"=r"(endPtr)
- : [framebuffer]"r"(framebufferEnd), [prevFramebuffer]"r"(prevFramebuffer+(framebufferEnd-framebuffer)), [framebufferBegin]"r"(framebuffer)
+ : [framebuffer]"g"(framebufferEnd), [prevFramebuffer]"r"(prevFramebuffer+(framebufferEnd-framebuffer)), [framebufferBegin]"r"(framebuffer)
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc"
);
return endPtr - framebuffer; I'd love it if somebody who actually understands this stuff could weigh-in and explain how to fix this correctly. |
Switching from DietPi to Pi OS Lite resolves this, but I don't know what the differences are. Happy to run experiments if anybody wants to investigate further. I'll probably try PiCore later so I'll see if that has the same problem. |
hmmhmm, very odd indeed. This kind of thing seems to be about the compiler version, rather than he hardware or OS itself (though OS distros certainly dictate which compiler is available by default). Might try running Using |
Hmm, I should have checked the compiler version before I clobbered it with Pi OS Lite. I'll find another SD card and check soon. In theory it uses the same apt repositories (debian + raspbian) so should get the same versions, but maybe something funny is going on. For what it's worth, the working compiler is As I say, I have basically zero experience with assembly so I have no idea what I'm doing there. What I know is that changing "r" to "g" caused it to enter |
My expectation with the code in that function was that it would get inlined and avoid any memory load/stores in the first place. I.e. the |
When trying to build on a Pi Zero W (using DietPi as the base OS) I get the following:
I am entirely unfamiliar with ASM programming, but THE INTERNET suggests this is due to the target architecture not having enough scratch registers (in this case, presumably 3 are needed. Maybe 4 if it has to include the return too).
By following that answer's advice (changing the
r
flags tog
for the 3 input params) I am able to continue to the next error (i.e. the next assembly block in the same file). And fixing that gets me to:Which is presumably because "g" doesn't actually mean "magically make this thing work please".
I see from the readme and config options that this library has been built for the Pi Zero before, so hopefully this is something easy to fix.
My full installation looked like this:
The text was updated successfully, but these errors were encountered: