Re: How to inline a huge m68k code?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux