gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Compiling problem with inline assembly and smull

#165688 - Kaiser - Sat Jan 03, 2009 9:45 pm

For some reason, GCC seems to throw a fit whenever I am using the SMULL instruction in my inline'ed assembly code:

Code:

typedef int fixed_t;

fixed_t FixedMul(fixed_t a, fixed_t b)
{
   __asm ("smull   r2, r3, %0, %1\n"
         "mov   %1, r2, lsr #16\n"
         "mov   r2, r3, lsl #16\n"
         "orr   %0, %1, r2"
         : "=r" (a) : "r" (a), "r" (b) : "r2", "r3");

   return(a);
}


When compiling, GCC would then spew out this message:

Error: selected processor does not support `smull r4,r5,r0,r0'
Error: selected processor does not support `smull r4,r5,r1,r1'

Anyone could point out any work-arounds for this? I appreciate the help, thanks.

#165690 - Cearn - Sat Jan 03, 2009 11:12 pm

If you're using the standard makefiles, the source files are likely to be compiled as Thumb code, and thumb code doesn't have long-multiply instructions. If you want to compile as ARM, give the file an .arm.c or .arm.cpp extension. That said, if you do C in ARM mode, you can also simply use ((s64)a*b)>>16. This will even work in Thumb mode, but in that case a very slow library routine will be called for the multiplication.

I'll also mention that inline assembly can be pretty fickle at times. In this case, for example, the syntax isn't quite correct and generates code for a 'smull r2, r3, r0, r0', which is probably not what you are after. If you need stand-alone functions with assembly code, you might as well create a proper assembly file for it, where you won't trip over things like this. Example:

Code:
@ Put this is a file with a .s extension

    .text               @ In text section
    .arm                @ as ARM code
    .align              @ align to 4-bytes
    .global FixedMul    @ declaration for externa visibility
FixedMul:
    smull   r2, r3, r0, r1
    mov     r0, r3, lsr #16
    orr     r0, r2, lsl #16
    bx      lr

#165691 - Kaiser - Sun Jan 04, 2009 1:09 am

I was creating functions in seperate .s (assembly) files before, but I ran into a situation where some GPRs in my functions were getting clobbered and resulted in corrupted data (and crashes).

I was assuming with inline assembly, I could have more control on what registers I want to set and to avoid clobbering?

#165694 - Dwedit - Sun Jan 04, 2009 2:26 am

Register corruption? Are you sure you're following the standard convention where r0-r3 and r12 are destroyable, and everything else needs to be preserved when you return?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#165696 - Kaiser - Sun Jan 04, 2009 4:27 am

Dwedit wrote:
Register corruption? Are you sure you're following the standard convention where r0-r3 and r12 are destroyable, and everything else needs to be preserved when you return?


I think I may have missed out on 'preserving'. Can you provide an example of what you mean?

#165697 - wintermute - Sun Jan 04, 2009 5:27 am

http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042c/IHI0042C_aapcs.pdf
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog