Inline Assembly With DJNZ
DavidZemon
Posts: 2,973
I'm getting a "truncated to fit" error when compiling the following code. Google says this happens when an address is too long to fit in a jmp operand - the djnz in my case. I'm not sure how to fix it. Surely there is a way. It's probably just because I haven't done asm in quite a while
__asm__ ("mov %[_waitCycles], %[_bitCycles]\n" "1:\twaitcnt %[_waitCycles], %[_bitCycles]\n\t" "djnz %[_bits], #1b" : [_waitCycles] "+r" (waitCycles), [_bits] "+r" (bits) : [_bitCycles] "r" (bitCycles));
Comments
This thread says to add .cog_ram to the top of the inline assembly. I'm trying that now...
I also tried surrounding with ".compress off" and ".compress default" which changes the error to "Relocation overflows" 4 times.
In any case, I managed to get my desired result in a slightly different way. Turns out, do-while gets compiled differently (correctly) compared to while. Here's the end result (with my functional code as well, instead of just the snippet)
This compiles to a perfect djnz loop with all variables loaded into cog ram before being referenced. The fcache attribute on the function was very important - without that, something wasn't getting loaded until the first call of the function. When that first call happened, the delay between initializing waitCycles and calling waitcnt was too long, and it would hang for 53 seconds. All remaining calls to the function worked great.
https://github.com/libpropeller/libpropeller/blob/master/libpropeller/i2c/i2c_base.h
That's actually how I got as far as I did lol. Your code definitely helped a lot. However, I still couldn't get it working even with that example to go off of. It might help if I knew what "=&r" does and how it compares to "+r". I tried Googling it when I first ran across your code but found nothing that was thorough enough for me to really understand it. Something about the & telling the assembler not to move registers around and reuse them or something? Idk... I know it decreased code size but a couple hundred bytes... but it also broke the code.
This method transmits at 4.414 MBaud