From: hlu@poly2.eecs.wsu.edu (H.J. Lu)
Newsgroups: comp.os.linux
Subject: Re: gcc 2.2.2d: htonl, etc. problem with -O and netinet/in.h
Date: 31 Aug 92 23:25:58 GMT
Article-I.D.: serval.1992Aug31.232558.6471
Organization: Washington State University

In article <1992Aug31.151452.26313@ERA.COM>, ejb@ERA.COM (Jay Berkenbilt) writes:
|> 
|> Hello.  With gcc 2.2.2d, htonl, htons, ntohl, or ntohs,
|> everything works fine except when you #include <netinet/in.h>
|> and compile with -O.  In this case, bytes/words are not swapped.
|> This can be demonstrated with the following program:
|> 
|> #include <netinet/in.h>
|> int main(void)
|> {
|>     printf("%08x, %08x, %04x, %04x\n",
|> 	   htonl(0x01020304), ntohl(0x01020304),
|> 	   htons(0x0102), ntohs(0x0102));
|>     return 0;
|> }
|> 
|> The output of this program should be
|> 
|> 04030201, 04030201, 0201, 0201
|> 
|> If you compile this with gcc -O, you will get
|> 
|> 01020304, 01020304, 0102, 0102
|> 
|> Although it seems that this should be an error with the inline
|> assembly routines defined in netinet/in.h, I'm not sure whether
|> that is really the problem or not.  Either not including
|> <netinet/in.h> or not using -O produces correct results.
|

My fault. Here is the fix.

H.J.
------
*** ../disk2/usr/include/netinet/in.h	Fri Jul 17 10:21:10 1992
--- include/netinet//in.h	Mon Aug 31 14:31:52 1992
***************
*** 171,207 ****
  static __inline__ unsigned long int
  __ntohl(unsigned long int x)
  {
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap lower bytes */
  		"rorl $16,%%eax\n\t"    /* swap words */
  		"xchgb %%al,%%ah\n\t"   /* swap higher bytes */
! 		: : "a" (x));
!   return x;
  }
  
  static __inline__ unsigned short int
  __ntohs(unsigned short int x)
  {
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap bytes */
! 		: : "a" (x));
!   return x;
  }
  
  static __inline__ unsigned long int
  __htonl(unsigned long int x)
  {
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap lower bytes */
  		"rorl $16,%%eax\n\t"    /* swap words */
  		"xchgb %%al,%%ah\n\t"   /* swap higher bytes */
! 		: : "a" (x));
!   return x;
  }
  
  static __inline__ unsigned short int
  __htons(unsigned short int x)
  {
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap bytes */
! 		: : "a" (x));
!   return x;
  }
  
  #ifdef  __OPTIMIZE__
--- 171,211 ----
  static __inline__ unsigned long int
  __ntohl(unsigned long int x)
  {
+   register unsigned long int tmp __asm__ ("ax") = x;
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap lower bytes */
  		"rorl $16,%%eax\n\t"    /* swap words */
  		"xchgb %%al,%%ah\n\t"   /* swap higher bytes */
! 		: "=a" (tmp) : "a" (tmp) );
!   return tmp;
  }
  
  static __inline__ unsigned short int
  __ntohs(unsigned short int x)
  {
+   register unsigned short int tmp __asm__ ("ax") = x;
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap bytes */
! 		: "=a" (tmp) : "a" (tmp));
!   return tmp;
  }
  
  static __inline__ unsigned long int
  __htonl(unsigned long int x)
  {
+   register unsigned long int tmp __asm__ ("ax") = x;
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap lower bytes */
  		"rorl $16,%%eax\n\t"    /* swap words */
  		"xchgb %%al,%%ah\n\t"   /* swap higher bytes */
! 		: "=a" (tmp) : "a" (tmp));
!   return tmp;
  }
  
  static __inline__ unsigned short int
  __htons(unsigned short int x)
  {
+   register unsigned short int tmp __asm__ ("ax") = x;
    __asm__ __volatile__ ("xchgb %%al,%%ah\n\t"   /* swap bytes */
! 		: "=a" (tmp) : "a" (tmp));
!   return tmp;
  }
  
  #ifdef  __OPTIMIZE__
Newsgroups: comp.os.linux