Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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:  Implementation of memmove().
  28. *
  29. ****************************************************************************/
  30.  
  31.  
  32. #include "variety.h"
  33. #include <stddef.h>
  34. #include <string.h>
  35.  
  36. #if defined(__386__)
  37. extern  void    movefwd( char _WCFAR *dst, const char _WCNEAR *src, unsigned len);
  38. #pragma aux     movefwd =  \
  39.         0x06            /* push es   */\
  40.         0x8e 0xc2       /* mov es,dx */\
  41.         0x51            /* push ecx  */\
  42.         0xc1 0xe9 0x02  /* shr ecx,2 */\
  43.         0xf3 0xa5       /* rep movsd */\
  44.         0x59            /* pop ecx   */\
  45.         0x83 0xe1 0x03  /* and ecx,3 */\
  46.         0xf3 0xa4       /* rep movsb */\
  47.         0x07            /* pop es    */\
  48.         parm [dx edi] [esi] [ecx] \
  49.         modify exact [edi esi ecx];
  50. extern  void    movebwd( char _WCFAR *dst, const char _WCNEAR *src, unsigned len);
  51. #pragma aux     movebwd =  \
  52.         0x06            /* push es */\
  53.         0x8e 0xc2       /* mov es,dx */\
  54.         0xfd            /* std */\
  55.         0x4e            /* dec esi */\
  56.         0x4f            /* dec edi */\
  57.         0xd1 0xe9       /* shr ecx,1 */\
  58.         0x66 0xf3 0xa5  /* rep movsw */\
  59.         0x11 0xc9       /* adc ecx,ecx */\
  60.         0x46            /* inc esi */\
  61.         0x47            /* inc edi */\
  62.         0x66 0xf3 0xa4  /* rep movsb */\
  63.         0x07            /* pop es */\
  64.         0xfc            /* cld */\
  65.         parm [dx edi] [esi] [ecx] \
  66.         modify exact [edi esi ecx];
  67. #define HAVE_MOVEFWBW
  68.  
  69. #elif defined(M_I86) && defined(__SMALL_DATA__)
  70. extern  void    movebwd( char _WCFAR *dst, const char _WCNEAR *src, unsigned len);
  71. #pragma aux     movebwd =  \
  72.         0xfd            /* std */\
  73.         0x4e            /* dec si */\
  74.         0x4f            /* dec di */\
  75.         0xd1 0xe9       /* shr cx,1 */\
  76.         0xf3 0xa5       /* rep movsw */\
  77.         0x11 0xc9       /* adc cx,cx */\
  78.         0x46            /* inc si */\
  79.         0x47            /* inc di */\
  80.         0xf3 0xa4       /* rep movsb */\
  81.         0xfc            /* cld */\
  82.         parm [es di] [si] [cx] \
  83.         modify exact [di si cx];
  84.  
  85. extern  void    movefwd( char _WCFAR *dst, const char _WCNEAR *src, unsigned len);
  86. #pragma aux     movefwd =  \
  87.         0xd1 0xe9       /* shr cx,1 */\
  88.         0xf3 0xa5       /* rep movsw */\
  89.         0x11 0xc9       /* adc cx,cx */\
  90.         0xf3 0xa4       /* rep movsb */\
  91.         parm [es di] [si] [cx] \
  92.         modify exact [di si cx];
  93. #define HAVE_MOVEFWBW
  94.  
  95. #elif defined(M_I86) && defined(__BIG_DATA__)
  96. extern  void    movebwd( char _WCFAR *dst, const char _WCFAR *src, unsigned len);
  97. #pragma aux     movebwd =  \
  98.         0x1e            /* push ds */ \
  99.         0x8e 0xda       /* mov ds,dx */ \
  100.         0xfd            /* std */\
  101.         0x4e            /* dec si */\
  102.         0x4f            /* dec di */\
  103.         0xd1 0xe9       /* shr cx,1 */\
  104.         0xf3 0xa5       /* rep movsw */\
  105.         0x11 0xc9       /* adc cx,cx */\
  106.         0x46            /* inc si */\
  107.         0x47            /* inc di */\
  108.         0xf3 0xa4       /* rep movsb */\
  109.         0xfc            /* cld */\
  110.         0x1f            /* pop ds */ \
  111.         parm [es di] [dx si] [cx] \
  112.         modify exact [di si cx];
  113.  
  114. extern  void    movefwd( char _WCFAR *dst, const char _WCFAR *src, unsigned len);
  115. #pragma aux     movefwd =  \
  116.         0x1e            /* push ds */ \
  117.         0x8e 0xda       /* mov ds,dx */ \
  118.         0xd1 0xe9       /* shr cx,1 */\
  119.         0xf3 0xa5       /* rep movsw */\
  120.         0x11 0xc9       /* adc cx,cx */\
  121.         0xf3 0xa4       /* rep movsb */\
  122.         0x1f            /* pop ds */ \
  123.         parm [es di] [dx si] [cx] \
  124.         modify exact [di si cx];
  125. #define HAVE_MOVEFWBW
  126.  
  127. #else
  128. // no pragma for non-x86
  129. #endif
  130.  
  131.  
  132. _WCRTLINK void *memmove( void *toStart, const void *fromStart, size_t len )
  133. {
  134.     const char      *from = fromStart;
  135.     char            *to = toStart;
  136.  
  137.     if( from == to ) {
  138.         return( to );
  139.     }
  140.     if( from < to  &&  from + len > to ) {  /* if buffers are overlapped*/
  141. #if defined( __HUGE__ ) || !defined( HAVE_MOVEFWBW )
  142.         to += len;
  143.         from += len;
  144.         while( len != 0 ) {
  145.             *--to = *--from;
  146.             len--;
  147.         }
  148. #else
  149.         movebwd(( to + len ) - 1, ( from + len ) - 1, len );
  150. #endif
  151.     } else {
  152. #if !defined( HAVE_MOVEFWBW )
  153.         while( len != 0 ) {
  154.             *to++ = *from++;
  155.             len--;
  156.         }
  157. #else
  158.         movefwd( to, from, len );
  159. #endif
  160.     }
  161.  
  162. #if defined(__HUGE__) || !defined( HAVE_MOVEFWBW )
  163.     return( toStart );
  164. #else
  165.     return( to );
  166. #endif
  167. }
  168.