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 "widechar.h"
  35. #include <ctype.h>
  36. #include <string.h>
  37.  
  38. #if defined(__WIDECHAR__)
  39. extern size_t wcslen( const CHAR_TYPE * );
  40. #endif
  41.  
  42. #if defined(M_I86) && !defined(__WIDECHAR__)
  43.  
  44. /*
  45.   explanation of algorithm:
  46.  
  47.   (1) reverse as much of the string as possible as words
  48.  
  49.   (2) after main loop: reverse residual inner string (0-3 bytes)
  50.  
  51.   the string falls into one of these forms:
  52.  
  53.  { prefix_word }* { suffix_word }*
  54.  { prefix_word }* middle_byte { suffix_word }*
  55.  { prefix_word }* pre_middle_byte post_middle_byte { suffix_word }*
  56.  { prefix_word }* pre_middle_byte middle_byte post_middle_byte { suffix_word }*
  57.  
  58.  we only have to swap two bytes when:
  59.  
  60.  len & 2 != 0 is true (ie. the carry is set after second shr cx,1)
  61.  
  62. *****************************************************************************
  63.   WARNING: the code in the L1: ... reverse loop cannot modify the carry flag
  64. *****************************************************************************
  65. */
  66.  
  67. extern void fast_rev( char *, char _WCFAR * );
  68.  
  69. #if defined(__SMALL_DATA__)
  70. #pragma aux     fast_rev = \
  71.         0xb9 0xff 0xff  /* mov cx,ffff */\
  72.         0x30 0xc0       /* xor al,al */\
  73.         0xf2 0xae       /* repne scasb */\
  74.         0xf7 0xd1       /* not cx */\
  75.         0x49            /* dec cx */\
  76.         0xfd            /* std */\
  77.         0x83 0xef 0x03  /* sub di,3 */\
  78.         0xd1 0xe9       /* shr cx,1 */\
  79.         0xd1 0xe9       /* shr cx,1 */\
  80.         0xe3 0x0d       /* jcxz L2 */\
  81.         0x8b 0x05       /* L1:mov ax,[di] */\
  82.         0x86 0xe0       /* xchg ah,al */\
  83.         0x87 0x04       /* xchg ax,[si] */\
  84.         0x86 0xe0       /* xchg ah,al */\
  85.         0xab            /* stosw */\
  86.         0x46            /* inc si */\
  87.         0x46            /* inc si */\
  88.         0xe2 0xf3       /* loop L1 */\
  89.         0x73 0x07       /* L2:jnc L3 */\
  90.         0x47            /* inc di */\
  91.         0x8a 0x05       /* mov al,[di] */\
  92.         0x86 0x04       /* xchg al,[si] */\
  93.         0x88 0x05       /* mov [di],al */\
  94.         0xfc            /* L3:cld */\
  95.         parm caller     [si] [es di] \
  96.         value           [ax] \
  97.         modify          [si cx ax di];
  98. #else
  99. #pragma aux     fast_rev = \
  100.         0x1e            /* push ds */ \
  101.         0x8e 0xda       /* mov ds,dx */ \
  102.         0xb9 0xff 0xff  /* mov cx,ffff */\
  103.         0x30 0xc0       /* xor al,al */\
  104.         0xf2 0xae       /* repne scasb */\
  105.         0xf7 0xd1       /* not cx */\
  106.         0x49            /* dec cx */\
  107.         0xfd            /* std */\
  108.         0x83 0xef 0x03  /* sub di,3 */\
  109.         0xd1 0xe9       /* shr cx,1 */\
  110.         0xd1 0xe9       /* shr cx,1 */\
  111.         0xe3 0x0d       /* jcxz L2 */\
  112.         0x8b 0x05       /* L1:mov ax,[di] */\
  113.         0x86 0xe0       /* xchg ah,al */\
  114.         0x87 0x04       /* xchg ax,[si] */\
  115.         0x86 0xe0       /* xchg ah,al */\
  116.         0xab            /* stosw */\
  117.         0x46            /* inc si */\
  118.         0x46            /* inc si */\
  119.         0xe2 0xf3       /* loop L1 */\
  120.         0x73 0x07       /* L2:jnc L3 */\
  121.         0x47            /* inc di */\
  122.         0x8a 0x05       /* mov al,[di] */\
  123.         0x86 0x04       /* xchg al,[si] */\
  124.         0x88 0x05       /* mov [di],al */\
  125.         0xfc            /* L3:cld */\
  126.         0x1f            /* pop ds */ \
  127.         parm caller     [dx si] [es di] \
  128.         value           [ax] \
  129.         modify          [si cx ax di];
  130. #endif
  131.  
  132. #endif
  133.  
  134.  
  135. _WCRTLINK CHAR_TYPE *__F_NAME(strrev,_wcsrev) ( CHAR_TYPE *str ) {  /* reverse characters in string */
  136.     #if  defined(M_I86) && !defined(__WIDECHAR__)
  137.         fast_rev( str, (char _WCFAR *) str );
  138.         return( str );
  139.     #else
  140.         CHAR_TYPE       *p1;
  141.         CHAR_TYPE       *p2;
  142.         CHAR_TYPE       c1;
  143.         CHAR_TYPE       c2;
  144.  
  145.         p1 = str;
  146.         p2 = p1 + __F_NAME(strlen,wcslen)( p1 ) - 1;
  147.         while( p1 < p2 ) {
  148.             c1 = *p1;
  149.             c2 = *p2;
  150.             *p1 = c2;
  151.             *p2 = c1;
  152.             ++p1;
  153.             --p2;
  154.         }
  155.         return( str );
  156.     #endif
  157. }
  158.