📄 memcpy.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * @(#)memcpy.c (libg) * * * Speeding up * Execute an access in CW unit wherever possible. * Execute a copy in multiple CW unit. */#include <basic.h>#include <string.h>#define NXT_ALIGN_PNT 8 /* next align pointer set *//* * Copy unit CW */typedef UW CW;#define BitWid ( sizeof(CW) * 8U ) /* Bit width of CW */#define ALIGN(p) ( (UINT)(p) & (sizeof(CW) - 1) )#define ALIGN_L(p) (CW*)((UINT)(p) & ~(UW)(sizeof(CW) - 1))#if BIGENDIAN#define SEC(w, n) ( (_w = w), (w <<= n), _w >> (BitWid - n) )#define BYTE(w) ( (_w = w), (w <<= 8U), (UB)(_w >> (BitWid - 8U)) )#else#define SEC(w, n) ( (_w = w), (w >>= n), _w << (BitWid - n) )#define BYTE(w) ( (_w = w), (w >>= 8U), (UB)_w )#endifEXPORT void* memcpy( void *dest, const void *src, size_t len ){ register CW _w, w1, w2, w3, w4; const CW *sw = src; CW *dw = dest; const CW *se; size_t align; if ( len < (sizeof(CW) * 4) ) { /* Execute a simple byte-copy when the bit width of CW is small-scaled */ while ( len-- > 0U ) { *(UB*)dw = *(const UB*)sw; dw = (CW*)((UB*)dw + 1); sw = (CW*)((UB*)sw + 1); } return dest; } /* Advance "src" up to the CW alignment */ while ( ALIGN((const UB*)sw) != 0U ) { *(UB*)dw = *(const UB*)sw; dw = (CW*)((UB*)dw + 1); sw = (CW*)((UB*)sw + 1); } w1 = *(sw++); /* Advance "dst" up to the CW alignment */ align = 0; while ( ALIGN((UB*)dw) != 0U ) { *(UB*)dw = BYTE(w1); dw = (CW*)((UB*)dw + 1); align += NXT_ALIGN_PNT; } /* Copy in 3 CW units * When the CW count(copy unit) is increased, the processing speed may grow late all the * more on the models with small register count. Adjust the range of CW count so that * the register count can fully hold it. */ se = (VP)(ALIGN_L((UB*)src + len) - 2); if ( align == 0 ) { while ( sw < se ) { w2 = sw[0]; w3 = sw[1]; w4 = sw[2]; sw += 3; dw[0] = w1; dw[1] = w2; dw[2] = w3; dw += 3; w1 = w4; } } else { while ( sw < se ) { w2 = sw[0]; w3 = sw[1]; w4 = sw[2]; sw += 3; dw[0] = (w1 | SEC(w2, align)); dw[1] = (w2 | SEC(w3, align)); dw[2] = (w3 | SEC(w4, align)); dw += 3; w1 = w4; } } /* Copy in 1 CW unit */ se = (VP)ALIGN_L((UB*)src + len); if ( align == 0 ) { while ( sw < se ) { w2 = *(sw++); *(dw++) = w1; w1 = w2; } *(dw++) = w1; align = BitWid; } else { while ( sw < se ) { w2 = *(sw++); *(dw++) = (w1 | SEC(w2, align)); w1 = w2; } } /* The copy of remaining half amount */ for ( ; align < BitWid; align += 8U ) { *(UB*)dw = BYTE(w1); dw = (CW*)((UB*)dw + 1); } se = (VP)((UB*)src + len); while ( (const UB*)sw < (const UB*)se ) { *(UB*)dw = *(const UB*)sw; dw = (CW*)((UB*)dw + 1); sw = (CW*)((UB*)sw + 1); } return dest;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -