Closed rjobling closed 4 years ago
I think these warnings are just from the IntelliSense. Microsoft's IntelliSense only officially supports Intel x86/x64 and ARM.
You should probably just wrap your inline assembly in #ifndef __INTELLISENSE__
#endif
.
Okay, well I'm still getting issues with the specified register being ignored, this leads to movem doing the wrong thing. Do you have any idea what might cause that? I'll see if I can come up with an example, but I suspect it only happens when the code starts to get a little bigger than the small examples in the sample.
Are you using too many registers? Had some issues with that, then I just stored/restored all registers in inline assembly... Can you post the problematic code?
If you copy this block of code right at the start of main in the sample and look at the output assembly then you should see what I mean.
short vecbuf[300];
short resultbuf[200];
int numVecs = 100;
short* vecs = vecbuf;
short* results = resultbuf;
for (int i = 0; i < numVecs; i++)
{
vecs[i * 3 + 0] = i;
vecs[i * 3 + 1] = i * 2;
vecs[i * 3 + 2] = i * 3;
}
int tx = 10;
int ty = 11;
int tz = 12;
register short vx asm("d1"); // Need to specify these so the movem is ordered correctly.
register short vy asm("d2");
register short vz asm("d3");
asm volatile(
" subq.w #1,%[num] \n"
"loop%=: \n"
" movem.w (%[vecs])+,%[vx]/%[vy]/%[vz] \n"
" add.l %[tx],%[vx] \n"
" add.l %[ty],%[vy] \n"
" add.l %[tz],%[vz] \n"
" asr.l #8,%[vz] \n"
" divs %[vz],%[vx] \n"
" divs %[vz],%[vy] \n"
" move.w %[vx],(%[results])+ \n"
" move.w %[vy],(%[results])+ \n"
" dbra %[num],loop%= \n"
:
[results] "+a" (results), // "result" pointer gets incremented.
[num] "+d" (numVecs), // "num" count gets decremented.
[vecs] "+a" (vecs), // "vecs" pointers gets incremented.
[vx] "=&d" (vx), // "vx, vy, vz" holds current vector.
[vy] "=&d" (vy),
[vz] "=&d" (vz)
:
[tx] "d" (tx), // "tx, ty, tz" holds the translation.
[ty] "d" (ty),
[tz] "d" (tz)
:
"cc",
"memory"
);
One work around is to specify tx/ty/tz as input/outputs. That seems to trick the compiler into doing what is expected, but I have little confidence that such a hack will hold up over time.
Hmm.. given that's a rather large loop, maybe the safer route would be to move that as a function call to a .s file?
I've been persisting with the inline stuff just because I quite like having all the code in the c file and being able to name registers. I know I can work around the problem in several ways, but it seems a shame.
I admire your perserverance ;) I'm no inline assembly expert...
It feels like there's a bug with how gcc understands the registers. Is there some part within your control that specs out the registers for gcc?
Not really, the sum of all my GCC patches is about 20 lines
That's all alien to me. I seem to be able to work around it consistently by promoting inputs so they are input/outputs. This avoids the need to specify some things as early clobbers, which is a confusing at the best of times. Maybe gcc just gets confused when mixing early clobbers with specified registers. The whole early clobber thing seems sketchy. But I don't know where do go to check if something could be done about it.
See, I don't even know about early clobbers ^_^
When compiling inline asm I seem to always get a bunch of "unknown register name" warnings.
The sample project does this for the unpacking and player inline asm.
It hasn't been a problem until recently. I now have a few different blocks of inline asm that need to specify the registers to use for some variables because they'll be used with a "movem". I do that the usual way: "register int var asm("d0");" for example. However the compiler is not always enforcing the register specification, I suspect the optimizer is doing something because it works okay with compiling with -Og.
It seems plausible that the problem stems from those compiler warnings. Do you know why those warnings are happening and if they can be fixed correctly?