[BUG mm] "fixed" i386 memcpy inlining buggy

Richard B. Johnson linux-os@analogic.com
Wed Apr 6 13:20:00 GMT 2005


Attached is inline ix86 memcpy() plus test code that tests its
corner-cases. The in-line code makes no jumps, but uses longword
copies, word copies and any spare byte copy. It works at all
offsets, doesn't require alignment but would work fastest if
both source and destination were longword aligned.

On Wed, 6 Apr 2005, Dave Korn wrote:

> ----Original Message----
>> From: Dave Korn
>> Sent: 06 April 2005 12:13
>
>> ----Original Message----
>>> From: Dave Korn
>>> Sent: 06 April 2005 12:06
>>
>>
>>   Me and my big mouth.
>>
>>   OK, that one does work.
>>
>>   Sorry for the outburst.
>>
>
>
> .... well, actually, maybe it doesn't after all.
>
>
>  What's that uninitialised variable ecx doing there eh?
>
>
>    cheers,
>      DaveK
> -- 
> Can't think of a witty .sigline today....
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.11 on an i686 machine (5537.79 BogoMips).
  Notice : All mail here is now cached for review by Dictator Bush.
                  98.36% of all statistics are fiction.
-------------- next part --------------

#include <stdio.h>
#include <string.h>


//
//  Inline ix86 memcpy() that contains no jumps. Not copied from
//  anybody.	Contributed by rjohnson@analogic.com
//

static __inline__ void *memcpy(void *dst, void *src, size_t len) {
        void *ret = dst;
        __asm__ __volatile__(	\
	"cld\n"			\
	"shr $1, %%ecx\n"	\
	"pushf\n"		\
	"shr $1, %%ecx\n"	\
	"pushf\n"		\
	"rep\n"			\
	"movsl\n"		\
	"popf\n"		\
	"adcl %%ecx, %%ecx\n"	\
	"rep\n"			\
	"movsw\n"		\
	"popf\n"		\
	"adcl %%ecx, %%ecx\n"	\
	"rep\n"			\
	"movsb\n"		\
	: "=D" (dst), "=S" (src), "=c"(len)
	: "0"  (dst), "1"  (src), "2" (len)
	: "memory" );
    return ret;
}


const char tester[]=	"0123456789"
			"0123456789"
			"0123456789"
			"0123456789"
			"0123456789"
			"0123456789"
			"0123456789"
			"0123456789";
char allocated[0x1000];

int main()
{
    size_t i;
    char buf[0x1000];

    memset(buf, 0x00, sizeof(buf));
    for(i=0; i< sizeof(buf); i++)
        puts(memcpy(buf, (char *)tester, i));
    memset(buf, 0x00, sizeof(buf));
    for(i=0; i< sizeof(buf)-1; i++)
        puts(memcpy(&buf[1], (char *)tester, i));
    memset(buf, 0x00, sizeof(buf));
    for(i=0; i< sizeof(buf)-2; i++)
        puts(memcpy(&buf[2], (char *)tester, i));
    memset(buf, 0x00, sizeof(buf));
    for(i=0; i< sizeof(buf)-3; i++)
        puts(memcpy(&buf[3], (char *)tester, i));
    return 0;
}


More information about the Gcc mailing list