From: H.J. Lu (hlu@poly2.eecs.wsu.edu)
Date: 08/31/92


From: hlu@poly2.eecs.wsu.edu (H.J. Lu)
Subject: Re: gcc 2.2.2d: htonl, etc. problem with -O and netinet/in.h
Date: 31 Aug 1992 23:25:58 GMT

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__