[Uclinux-h8-devel] bitop.h の最適化

Back to archive index

Kazu Hirata kazu****@cs*****
2003年 9月 9日 (火) 04:58:05 JST


佐藤様、

bitop.h の中にある set_bit, clear_bit, change_bit を最適化してみました。

	mov.l #1,er0
	bset r0l, @ er2

が

	bset #1, @ er2

になります。__builtin_constant_p を使った表現がやたらと大きくなってしまっ
ているので、生成マクロで繰返しをなくしています。

よろしくご検討下さい。

Kazu Hirata

Index: bitops.h
===================================================================
RCS file: /cvsroot/uclinux-h8/uClinux-2.4.x/include/asm-h8300/bitops.h,v
retrieving revision 1.13
diff -c -r1.13 bitops.h
*** bitops.h	22 Aug 2003 09:06:24 -0000	1.13
--- bitops.h	8 Sep 2003 19:50:01 -0000
***************
*** 35,52 ****
  	return result;
  }
  
! static __inline__ void set_bit(int nr, volatile void * addr)
! {
! 	volatile unsigned char *b_addr;
! 	b_addr = &(((volatile unsigned char *) addr)
! 	          [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);
! 	__asm__("mov.l %1,er0\n\t"
! 		"bset r0l,%0"
! 		:"+m"(*b_addr)
! 		:"g"(nr & 7),"m"(*b_addr)
! 		:"er0");
  }
  
  #define __set_bit(nr, addr) set_bit((nr), (addr))
  
  /*
--- 35,89 ----
  	return result;
  }
  
! #define H8300_GEN_BITOP(FNNAME,OP)					   \
! static __inline__ void FNNAME(int nr, volatile void * addr)		   \
! {									   \
! 	volatile unsigned char *b_addr;					   \
! 	b_addr = &(((volatile unsigned char *) addr)			   \
! 	          [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);		   \
! 	nr &= 7;							   \
! 	if (__builtin_constant_p (nr))					   \
! 	{								   \
! 		switch(nr)						   \
! 		{							   \
! 		case 0:							   \
! 			__asm__(OP " #0,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 1:							   \
! 			__asm__(OP " #1,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 2:							   \
! 			__asm__(OP " #2,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 3:							   \
! 			__asm__(OP " #3,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 4:							   \
! 			__asm__(OP " #4,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 5:							   \
! 			__asm__(OP " #5,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 6:							   \
! 			__asm__(OP " #6,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		case 7:							   \
! 			__asm__(OP " #7,%0" :"+m"(*b_addr) :"m"(*b_addr)); \
! 			break;						   \
! 		}							   \
! 	}								   \
! 	else								   \
! 	{								   \
! 		__asm__("mov.l %1,er0\n\t"				   \
! 			OP " r0l,%0"					   \
! 			:"+m"(*b_addr)					   \
! 			:"g"(nr),"m"(*b_addr)				   \
! 			:"er0");					   \
! 	}								   \
  }
  
+ H8300_GEN_BITOP(set_bit, "bset");
+ 
  #define __set_bit(nr, addr) set_bit((nr), (addr))
  
  /*
***************
*** 55,85 ****
  #define smp_mb__before_clear_bit()	barrier()
  #define smp_mb__after_clear_bit()	barrier()
  
! static __inline__ void clear_bit(int nr, volatile void * addr)
! {
! 	volatile unsigned char *b_addr;
! 	b_addr = &(((volatile unsigned char *) addr)
! 	          [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);
! 	__asm__("mov.l %1,er0\n\t"
! 		"bclr r0l,%0"
! 		:"+m"(*b_addr)
! 		:"g"(nr & 7),"m"(*b_addr)
! 		:"er0");
! }
  
  #define __clear_bit(nr, addr) clear_bit((nr),(addr))
  
! static __inline__ void change_bit(int nr, volatile void * addr)
! {
! 	volatile unsigned char *b_addr;
! 	b_addr = &(((volatile unsigned char *) addr)
! 	          [((nr >> 3) & ~3) + 3 - ((nr >> 3) & 3)]);
! 	__asm__("mov.l %1,er0\n\t"
! 		"bnot r0l,%0"
! 		:"+m"(*b_addr)
! 		:"g"(nr & 7),"m"(*b_addr)
! 		:"er0");
! }
  
  #define __change_bit(nr, addr) change_bit((nr), (addr))
  
--- 92,102 ----
  #define smp_mb__before_clear_bit()	barrier()
  #define smp_mb__after_clear_bit()	barrier()
  
! H8300_GEN_BITOP(clear_bit, "bclr");
  
  #define __clear_bit(nr, addr) clear_bit((nr),(addr))
  
! H8300_GEN_BITOP(change_bit, "bnot");
  
  #define __change_bit(nr, addr) change_bit((nr), (addr))
  



Uclinux-h8-devel メーリングリストの案内
Back to archive index