⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmemory.cpp

📁 成熟的RPG引擎,Flysky发布. 斜视角引擎.
💻 CPP
字号:
#include <windows.h>
#include "CMemory.h"
#include "CMMX.h"

//MMX 内存拷贝

//注意:count 为 64 的倍数
void Qmemcpy_mmx_64(void *dst, void *src, int count)
{
	_asm
	{
			mov edi,dst;
			mov esi,src;
			mov ecx, count;			//要拷贝多少个块
			lea	esi, [esi+ecx];
			lea	edi, [edi+ecx];
			neg ecx; //eax=-eax;
			loopwrite:
			movq mm0,[esi+ecx]; //放入mm0
			movq mm1,[esi+ecx+8]; //放入mm0
			movq mm2,[esi+ecx+16]; //放入mm0
			movq mm3,[esi+ecx+24]; //放入mm0
			movq mm4,[esi+ecx+32]; //放入mm0
			movq mm5,[esi+ecx+40]; //放入mm0
			movq mm6,[esi+ecx+48]; //放入mm0
			movq mm7,[esi+ecx+56]; //放入mm0
			movq [edi+ecx],mm0;
			movq [edi+ecx+8],mm1; //放入mm0
			movq [edi+ecx+16],mm2; //放入mm0
			movq [edi+ecx+24],mm3; //放入mm0
			movq [edi+ecx+32],mm4;
			movq [edi+ecx+40],mm5; //放入mm0
			movq [edi+ecx+48],mm6; //放入mm0
			movq [edi+ecx+56],mm7; //放入mm0
			add ecx, 64; //一次16个字节,当然加16
			jnz loopwrite; //如果不等于0就循环
			emms; //清空
	}
}

//注意:count 为 32 的倍数
void Qmemcpy_mmx_32(void *dst, void *src, int count)
{
	_asm
	{
			mov edi,dst;
			mov esi,src;
			mov ecx, count;			//要拷贝多少个块
			lea	esi, [esi+ecx];
			lea	edi, [edi+ecx];
			neg ecx; //eax=-eax;
			loopwrite:
			movq mm0,[esi+ecx]; //放入mm0
			movq mm1,[esi+ecx+8]; //放入mm0
			movq mm2,[esi+ecx+16]; //放入mm0
			movq mm3,[esi+ecx+24]; //放入mm0
			movq [edi+ecx],mm0;
			movq [edi+ecx+8],mm1; //放入mm0
			movq [edi+ecx+16],mm2; //放入mm0
			movq [edi+ecx+24],mm3; //放入mm0
			add ecx, 32; //一次16个字节,当然加16
			jnz loopwrite; //如果不等于0就循环
			emms; //清空
	}
}

//注意:count 为 16 的倍数
void Qmemcpy_mmx_16(void *dst, void *src, int count)
{
	_asm
	{
			mov edi,dst;
			mov esi,src;
			mov ecx, count;			//要拷贝多少个块
			lea	esi, [esi+ecx];
			lea	edi, [edi+ecx];
			neg ecx; //eax=-eax;
			loopwrite:
			movd mm0,dword ptr [esi+ecx]; //放入mm0
			movd mm1,dword ptr [esi+ecx+4]; //放入mm0
			movd mm2,dword ptr [esi+ecx+8]; //放入mm0
			movd mm3,dword ptr [esi+ecx+12]; //放入mm0
			movd dword ptr[edi+ecx],mm0;
			movd dword ptr [edi+ecx+4],mm1; //放入mm0
			movd dword ptr [edi+ecx+8],mm2; //放入mm0
			movd dword ptr [edi+ecx+12],mm3; //放入mm0
			add ecx, 16; //一次16个字节,当然加16
			jnz loopwrite; //如果不等于0就循环
			emms; //清空
	}
}

//注意:count 为 8 的倍数
void Qmemcpy_mmx_8(void *dst, void *src, int count)
{
	int n=count;
	_asm
	{
			mov edi,dst;
			mov esi,src;
			mov ecx, n;			//要拷贝多少个块
			lea	esi, [esi+ecx];
			lea	edi, [edi+ecx];
			neg ecx; //eax=-eax;
			loopwrite:
			movd mm0,dword ptr [esi+ecx]; //放入mm0
			movd mm1,dword ptr [esi+ecx+4]; //放入mm0
			movd dword ptr[edi+ecx],mm0;
			movd dword ptr [edi+ecx+4],mm1; //放入mm0
			add ecx, 8; //一次四个字节,当然加4
			jnz loopwrite; //如果不等于0就循环
			emms; //清空
	}
}


//MMX内存重置
void Qmemset_mmx_32(void *dst, int c, int count)
{
	//QMemset MMX版本
	//注意 count 应被 32 整除
	__asm 
	{
		movq mm0, c //因为Int是32位的,直接用movd读入
		//以下将 mm0重置成64位
		punpcklbw mm0, mm0  //将 8 Byte 转 4 WORD //|cccccccc00000000|
		punpcklwd mm0, mm0  //将 4 Word 转 2 DWORD//|c0c0c0c0c0c0c0c0|
		punpckldq mm0, mm0 //将 2DWORD 转 1 QWORD //|cccccccccccccccc|0000000000000000|
		mov edi, dst
		mov ecx, count
		lea	edi, [edi + ecx]
		neg ecx //ecx=-ecx;
		movq mm1, mm0 //将mm1 置0
		movq mm2, mm0 //将mm2 置0
		movq mm3, mm0 //将mm3 置0
		movq mm4, mm0 //将mm4 置0
loopwrite:
		movq qword ptr[edi+ecx], mm0
		movq qword ptr[edi+ecx+8 ], mm1
		movq qword ptr[edi+ecx+16], mm2
		movq qword ptr[edi+ecx+24], mm3
		add ecx, 32;
		jnz loopwrite;
		emms;
	}
}

void Qmemset_mmx_16(void *dst, int c, int count)
{
	//QMemset MMX版本
	//注意 count 应被 32 整除
	__asm 
	{
		movq mm0, c //因为Int是32位的,直接用movd读入
		//以下将 mm0重置成64位
		punpcklbw mm0, mm0  //将 8 Byte 转 4 WORD //|cccccccc00000000|
		punpcklwd mm0, mm0  //将 4 Word 转 2 DWORD//|c0c0c0c0c0c0c0c0|
		punpckldq mm0, mm0 //将 2DWORD 转 1 QWORD //|cccccccccccccccc|0000000000000000|
		mov edi, dst
		mov ecx, count
		lea	edi, [edi + ecx]
		neg ecx //ecx=-ecx;
		movq mm1, mm0 //将mm1 置0
		movq mm2, mm0 //将mm2 置0
loopwrite:
		movq qword ptr[edi+ecx], mm0
		movq qword ptr[edi+ecx+8 ], mm1
		add ecx, 16;
		jnz loopwrite;
		emms;
	}
}

//=================================
//------------接口部分-------------
//=================================

//===================================================
//函数:void Qmemcpy(void *dest, void *src, int count)
//功能:将Src的Count个字节拷贝到Dest
//===================================================
void Qmemcpy(void *dest, void *src, int count)
{
	bool IsMMX=CheckMMX();
	if (IsMMX==true&&(count%2==0)&&count>=8)
	{
		if (count%64==0)Qmemcpy_mmx_64(dest,src,count);
		else if (count%32==0)Qmemcpy_mmx_32(dest,src,count);
		else if (count%16==0) Qmemcpy_mmx_16(dest,src,count);
	    else if(count%8==0)Qmemcpy_mmx_8(dest,src,count);
		else goto _cmemcpy;
	}
	else
	{
_cmemcpy:
		int i;
		BYTE *d=(BYTE *)dest;
		const BYTE *s=(const BYTE *)src;
		for (i=0;i<count;i++,++d,++s)
		*d=*s;
	}
}



void Qmemset(void *dst, int c, int count)
{
	if (c==0) //特殊的时候
	{
		ZeroMemory(dst,count); //用Windows提供的宏
	}
	else
	{
		bool IsMMX=CheckMMX(); //查找 MMX
		if (IsMMX==true&&(count%2==0)&&count>=16) 
		{
			if (count%32==0) Qmemset_mmx_32(dst,c,count);
			else if (count%16==0) Qmemset_mmx_16(dst,c,count);
			else goto _cmemset;
		}
		else _cmemset:FillMemory(dst,count,c); //用Windows宏
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -