Closed rjobling closed 4 years ago
Yeah, I also had that problem when trying to implement a fast memcpy routine that used all registers. My workaround was just to store all used registers to the stack at the beginning of the asm and restoring them afterwards. Then you don't need to tell the compiler about those registers. The included version of gcc uses a5 as a frame pointer. Also check this example: https://github.com/BartmanAbyss/vscode-amiga-debug/blob/7fdd369501706c07adc599b9a9ab6a6d347119a9/template/main.c#L162-L176
Thanks for the quick reply.
I did try pushing all the data registers and popping after but it was still locking up. I don't have any interrupt handler running so not sure what is going on.
In the example code you posted what does the "rf" constraint mean, when I looked it up it seemed to suggest "register" and "float", which seems an odd choice.
I was able to fix my bug by moving one of the parameters from an input to an input/output. It doesn't seem like that should be necessary since I don't modify its value. But for whatever reason gcc was reusing that register inside the asm code. Maybe it's a bug in gcc or more likely it's something subtle with the operands/clobbers I specified that I don't fully understand.
Actually I eventually figured out that if I correctly use an early-clobber the problem is fixed without any hackery. My code now happily used d0-d7/a0-a6.
Nice! How exactly did you do that? Would be good to know.
In the example code you posted what does the "rf" constraint mean, when I looked it up it seemed to suggest "register" and "float", which seems an odd choice.
I'm not sure, I copied that from the amiga includes. I think it's "register force" to force it to use a specific register (in that case a0, etc.)
I've added a code snippet so you can see what I've got, should be here: https://github.com/rjobling/snippets/blob/e5f43b25e31273fbf69ac551194670e937dcaeb9/earlyclobbers.cpp
The code is a vector rotation function where I've tried to keep as much as possible in registers. As you can hopefully see, I'm listing 8 data registers and 7 address registers. But the compiler will allocate those as it sees fit, it only has 6 address registers to play with as a7 and a5 are reserved for the stack and frame (I think).
Since the compiler has to reuse at least one address register I had to mark the scratch address registers as early clobbers, otherwise it was overwriting the "rot" register before I was finished using it.
I'm still learning this stuff, but it does seem that if you get it right then letting the compiler allocate registers frees you from some of that hassle.
Great. Thanks.
I'm adding inline asm so I can write some fast code without giving up on the convenience of C/C++. However if I use too many registers, such as 8 data register then I run into problems. I haven't taken the time to examine what exactly is going on but was wondering if you know where I can find more information about how the compiler uses the registers. Seems likely there is a stack frame pointer in a6 but from the problems I'm getting it seems like one of the data registers is also in use. I'll look more closely if you've no idea what I'm doing wrong.