This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: How to inline a huge m68k code?
ami_stuff wrote:
>> Like this:
>>
>> inline int xxMULH(int a, int b)
>> {
>> uint32_t au = a;
>> uint32_t bu = b;
>>
>> uint32_t resh, resl;
>>
>> umul_ppmm(resh, resl, au, bu);
>>
>> if (a < 0)
>> resh -= bu;
>> if (b < 0)
>> resh -= au;
>>
>> return (int)resh;
>> }
>>
>
> printf("result 060: %d\n",MULH_060(55555555,55555555));
> printf("result inl: %d\n",MULH_INLINE(55555555,55555555));
>
> From asm function (external linkable object) which source code I posted I get:
>
> 718613
>
> from your inline code:
>
> 71861
This is incredibly tough for me because I haven't got a 68k.
> inline int MULH_INLINE(int a, int b)
> {
>
> uint32_t au = a;
> uint32_t bu = b;
>
> uint32_t resh, resl;
>
> #define umul_ppmm(resh, resl, a, b)
> __asm__ ("| Inlined umul_ppmm \n\t"
> " move%.l %2, %/d0 \n"
> " move%.l %3, %/d1 \n"
> " move%.l %/d0, %/d2 \n"
> " swap %/d0 \n"
> " move%.l %/d1, %/d3 \n"
> " swap %/d1 \n"
> " move%.w %/d2, %/d4 \n"
> " mulu %/d3, %/d4 \n"
> " mulu %/d1, %/d2 \n"
> " mulu %/d0, %/d3 \n"
> " mulu %/d0, %/d1 \n"
> " move%.l %/d4, %/d0 \n"
> " eor%.w %/d0, %/d0 \n"
> " swap %/d0 \n"
> " add%.l %/d0, %/d2 \n"
> " add%.l %/d3, %/d2 \n"
> " jcc 1f \n"
> " add%.l %#65536,%/d1 \n"
> "1: swap %/d2 \n"
> " moveq %#0, %/d0 \n"
> " move%.w %/d2, %/d0 \n"
> " move%.w %/d4, %/d2 \n"
> " move%.l %/d2, %1 \n"
> " add%.l %/d1, %/d0 \n"
> " move%.l %/d0, %0"
> : "=g" ((resh)),
> "=g" ((resl))
> : "g" ((a)),
> "g" ((b))
> : "d0", "d1", "d2", "d3", "d4")
>
> umul_ppmm(resh, resl, au, bu);
>
> if (a < 0)
> resh -= bu;
> if (b < 0)
> resh -= au;
>
> return (int)resh;
> }
This is wrong. It should be:
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("| Inlined umul_ppmm\n" \
" move%.l %2,%/d0\n" \
" move%.l %3,%/d1\n" \
" move%.l %/d0,%/d2\n" \
" swap %/d0\n" \
" move%.l %/d1,%/d3\n" \
" swap %/d1\n" \
" move%.w %/d2,%/d4\n" \
" mulu %/d3,%/d4\n" \
" mulu %/d1,%/d2\n" \
" mulu %/d0,%/d3\n" \
" mulu %/d0,%/d1\n" \
" move%.l %/d4,%/d0\n" \
" eor%.w %/d0,%/d0\n" \
" swap %/d0\n" \
" add%.l %/d0,%/d2\n" \
" add%.l %/d3,%/d2\n" \
" jcc 1f\n" \
" add%.l %#65536,%/d1\n" \
"1: swap %/d2\n" \
" moveq %#0,%/d0\n" \
" move%.w %/d2,%/d0\n" \
" move%.w %/d4,%/d2\n" \
" move%.l %/d2,%1\n" \
" add%.l %/d1,%/d0\n" \
" move%.l %/d0,%0" \
: "=g" ((uint32_t) (xh)), \
"=g" ((uint32_t) (xl)) \
: "g" ((uint32_t) (a)), \
"g" ((uint32_t) (b)) \
: "d0", "d1", "d2", "d3", "d4")
inline int xxMULH(int a, int b)
{
uint32_t au = a;
uint32_t bu = b;
uint32_t resh, resl;
umul_ppmm(resh, resl, au, bu);
if (a < 0)
resh -= bu;
if (b < 0)
resh -= au;
return (int)resh;
}
Andrew.