src/video/SDL_memops.h
author Ryan C. Gordon <icculus@icculus.org>
Fri, 06 Jan 2006 13:20:10 +0000
changeset 1234 73676c1f56ee
parent 769 b8d311d90021
child 1312 c9b51268668f
permissions -rw-r--r--
For sanity's sake, removed the '&' when passing copy_row array to asm.
slouken@0
     1
/*
slouken@0
     2
    SDL - Simple DirectMedia Layer
slouken@769
     3
    Copyright (C) 1997-2004 Sam Lantinga
slouken@0
     4
slouken@0
     5
    This library is free software; you can redistribute it and/or
slouken@0
     6
    modify it under the terms of the GNU Library General Public
slouken@0
     7
    License as published by the Free Software Foundation; either
slouken@0
     8
    version 2 of the License, or (at your option) any later version.
slouken@0
     9
slouken@0
    10
    This library is distributed in the hope that it will be useful,
slouken@0
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@0
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@0
    13
    Library General Public License for more details.
slouken@0
    14
slouken@0
    15
    You should have received a copy of the GNU Library General Public
slouken@0
    16
    License along with this library; if not, write to the Free
slouken@0
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@0
    18
slouken@0
    19
    Sam Lantinga
slouken@252
    20
    slouken@libsdl.org
slouken@0
    21
*/
slouken@0
    22
slouken@0
    23
#ifdef SAVE_RCSID
slouken@0
    24
static char rcsid =
slouken@0
    25
 "@(#) $Id$";
slouken@0
    26
#endif
slouken@0
    27
slouken@0
    28
#ifndef _SDL_memops_h
slouken@0
    29
#define _SDL_memops_h
slouken@0
    30
slouken@0
    31
/* System dependent optimized memory manipulation routines:
slouken@0
    32
*/
slouken@0
    33
#include <string.h>
slouken@0
    34
slouken@0
    35
#if defined(__GNUC__) && defined(i386)
slouken@0
    36
/* Thanks to Brennan "Bas" Underwood, for the inspiration. :)
slouken@0
    37
 */
slouken@0
    38
#define SDL_memcpy(dst, src, len)					  \
slouken@0
    39
do {									  \
slouken@0
    40
	int u0, u1, u2;						  \
slouken@0
    41
	__asm__ __volatile__ (						  \
slouken@0
    42
		"cld\n\t"						  \
slouken@0
    43
		"rep ; movsl\n\t"					  \
slouken@0
    44
		"testb $2,%b4\n\t"					  \
slouken@0
    45
		"je 1f\n\t"						  \
slouken@0
    46
		"movsw\n"						  \
slouken@0
    47
		"1:\ttestb $1,%b4\n\t"					  \
slouken@0
    48
		"je 2f\n\t"						  \
slouken@0
    49
		"movsb\n"						  \
slouken@0
    50
		"2:"							  \
slouken@0
    51
		: "=&c" (u0), "=&D" (u1), "=&S" (u2)			  \
slouken@0
    52
		: "0" ((unsigned)(len)/4), "q" (len), "1" (dst),"2" (src) \
slouken@0
    53
		: "memory" );						  \
slouken@0
    54
} while(0)
slouken@0
    55
slouken@1
    56
#define SDL_memcpy4(dst, src, len)				\
slouken@1
    57
do {								\
slouken@1
    58
	int ecx, edi, esi;					\
slouken@1
    59
	__asm__ __volatile__ (					\
slouken@1
    60
		"cld\n\t"					\
slouken@1
    61
		"rep ; movsl"					\
slouken@1
    62
		: "=&c" (ecx), "=&D" (edi), "=&S" (esi)		\
slouken@1
    63
		: "0" ((unsigned)(len)), "1" (dst), "2" (src)	\
slouken@1
    64
		: "memory" );					\
slouken@1
    65
} while(0)
slouken@1
    66
slouken@0
    67
#define SDL_revcpy(dst, src, len)			\
slouken@0
    68
do {							\
slouken@0
    69
	int u0, u1, u2;					\
slouken@0
    70
	char *dstp = (char *)(dst);			\
slouken@0
    71
	char *srcp = (char *)(src);			\
slouken@0
    72
	int n = (len);					\
slouken@0
    73
	if ( n >= 4 ) {					\
slouken@0
    74
	__asm__ __volatile__ (				\
slouken@0
    75
		"std\n\t"				\
slouken@0
    76
		"rep ; movsl\n\t"			\
slouken@0
    77
		: "=&c" (u0), "=&D" (u1), "=&S" (u2)	\
slouken@0
    78
		: "0" (n >> 2),				\
slouken@0
    79
		  "1" (dstp+(n-4)), "2" (srcp+(n-4))	\
slouken@0
    80
		: "memory" );				\
slouken@0
    81
	}						\
slouken@0
    82
	switch (n & 3) {				\
slouken@0
    83
		case 3: dstp[2] = srcp[2];		\
slouken@0
    84
		case 2: dstp[1] = srcp[1];		\
slouken@0
    85
		case 1: dstp[0] = srcp[0];		\
slouken@0
    86
			break;				\
slouken@0
    87
		default:				\
slouken@0
    88
			break;				\
slouken@0
    89
	}						\
slouken@0
    90
} while(0)
slouken@0
    91
slouken@0
    92
#define SDL_memmove(dst, src, len)			\
slouken@0
    93
do {							\
slouken@0
    94
	if ( (dst) < (src) ) {				\
slouken@0
    95
		SDL_memcpy((dst), (src), (len));	\
slouken@0
    96
	} else {					\
slouken@0
    97
		SDL_revcpy((dst), (src), (len));	\
slouken@0
    98
	}						\
slouken@0
    99
} while(0)
slouken@0
   100
slouken@0
   101
#define SDL_memset4(dst, val, len)				\
slouken@0
   102
do {								\
slouken@0
   103
	int u0, u1, u2;					\
slouken@0
   104
	__asm__ __volatile__ (					\
slouken@0
   105
		"cld\n\t"					\
slouken@0
   106
		"rep ; stosl\n\t"				\
slouken@0
   107
		: "=&D" (u0), "=&a" (u1), "=&c" (u2)		\
slouken@0
   108
		: "0" (dst), "1" (val), "2" ((Uint32)(len))	\
slouken@0
   109
		: "memory" );					\
slouken@0
   110
} while(0)
slouken@0
   111
slouken@0
   112
#endif /* GNU C and x86 */
slouken@0
   113
slouken@0
   114
/* If there are no optimized versions, define the normal versions */
slouken@0
   115
#ifndef SDL_memcpy
slouken@0
   116
#define SDL_memcpy(dst, src, len)	memcpy(dst, src, len)
slouken@0
   117
#endif
slouken@1
   118
slouken@1
   119
#ifndef SDL_memcpy4
slouken@1
   120
#define SDL_memcpy4(dst, src, len)	memcpy(dst, src, (len) << 2)
slouken@1
   121
#endif
slouken@1
   122
slouken@0
   123
#ifndef SDL_revcpy
slouken@0
   124
#define SDL_revcpy(dst, src, len)	memmove(dst, src, len)
slouken@0
   125
#endif
slouken@1
   126
slouken@0
   127
#ifndef SDL_memset4
slouken@0
   128
#define SDL_memset4(dst, val, len)		\
slouken@0
   129
do {						\
slouken@0
   130
	unsigned _count = (len);		\
slouken@0
   131
	unsigned _n = (_count + 3) / 4;		\
slouken@0
   132
	Uint32 *_p = (Uint32 *)(dst);		\
slouken@0
   133
	Uint32 _val = (val);			\
slouken@0
   134
        switch (_count % 4) {			\
slouken@0
   135
        case 0: do {    *_p++ = _val;		\
slouken@0
   136
        case 3:         *_p++ = _val;		\
slouken@0
   137
        case 2:         *_p++ = _val;		\
slouken@0
   138
        case 1:         *_p++ = _val;		\
slouken@0
   139
		} while ( --_n );		\
slouken@0
   140
	}					\
slouken@0
   141
} while(0)
slouken@0
   142
#endif
slouken@0
   143
slouken@0
   144
#endif /* _SDL_memops_h */