Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
  28. *               DESCRIBE IT HERE!
  29. *
  30. ****************************************************************************/
  31.  
  32.  
  33. #include "variety.h"
  34. #include <ctype.h>
  35. #include <string.h>
  36.  
  37. #ifdef M_I86
  38.  
  39. /*
  40.   explanation of algorithm:
  41.  
  42.   (1) reverse as much of the string as possible as words
  43.  
  44.   (2) after main loop: reverse residual inner string (0-3 bytes)
  45.  
  46.   the string falls into one of these forms:
  47.  
  48.  { prefix_word }* { suffix_word }*
  49.  { prefix_word }* middle_byte { suffix_word }*
  50.  { prefix_word }* pre_middle_byte post_middle_byte { suffix_word }*
  51.  { prefix_word }* pre_middle_byte middle_byte post_middle_byte { suffix_word }*
  52.  
  53.  we only have to swap two bytes when:
  54.  
  55.  len & 2 != 0 is true (ie. the carry is set after second shr cx,1)
  56.  
  57. *****************************************************************************
  58.   WARNING: the code in the L1: ... reverse loop cannot modify the carry flag
  59. *****************************************************************************
  60. */
  61.  
  62. extern void fast_rev( char _WCFAR * );
  63.  
  64. #pragma aux     fast_rev = \
  65.         0x1e            /* push ds */\
  66.         0x8e 0xc1       /* mov es,cx */\
  67.         0x8e 0xd9       /* mov ds,cx */\
  68.         0x89 0xfe       /* mov si,di */\
  69.         0xb9 0xff 0xff  /* mov cx,ffff */\
  70.         0x30 0xc0       /* xor al,al */\
  71.         0xf2 0xae       /* repne scasb */\
  72.         0xf7 0xd1       /* not cx */\
  73.         0x49            /* dec cx */\
  74.         0xfd            /* std */\
  75.         0x83 0xef 0x03  /* sub di,3 */\
  76.         0xd1 0xe9       /* shr cx,1 */\
  77.         0xd1 0xe9       /* shr cx,1 */\
  78.         0xe3 0x0d       /* jcxz L2 */\
  79.         0x8b 0x05       /* L1:mov ax,[di] */\
  80.         0x86 0xe0       /* xchg ah,al */\
  81.         0x87 0x04       /* xchg ax,[si] */\
  82.         0x86 0xe0       /* xchg ah,al */\
  83.         0xab            /* stosw */\
  84.         0x46            /* inc si */\
  85.         0x46            /* inc si */\
  86.         0xe2 0xf3       /* loop L1 */\
  87.         0x73 0x07       /* L2:jnc L3 */\
  88.         0x47            /* inc di */\
  89.         0x8a 0x05       /* mov al,[di] */\
  90.         0x86 0x04       /* xchg al,[si] */\
  91.         0x88 0x05       /* mov [di],al */\
  92.         0xfc            /* L3:cld */\
  93.         0x1f            /* pop ds */\
  94.         parm caller     [cx di] \
  95.         modify          [si cx ax di es];
  96. #endif
  97.  
  98. _WCRTLINK char _WCFAR *_fstrrev( char _WCFAR *str )  /* reverse characters in string */
  99.     {
  100. #if  defined(M_I86)
  101.         fast_rev( str );
  102.         return( str );
  103. #else
  104.         char _WCFAR *p1;
  105.         char _WCFAR *p2;
  106.         char c1;
  107.         char c2;
  108.  
  109.         p1 = str;
  110.         p2 = p1 + _fstrlen( p1 ) - 1;
  111.         while( p1 < p2 ) {
  112.             c1 = *p1;
  113.             c2 = *p2;
  114.             *p1 = c2;
  115.             *p2 = c1;
  116.             ++p1;
  117.             --p2;
  118.         }
  119.         return( str );
  120. #endif
  121.     }
  122.