Files
Rocky5 921f9fe9f8 Clean Copy
If ever adding the XBMC4Xbox source to GitHub use "git add -f -A" or it wont add all the files.
2024-01-08 19:01:29 +00:00

211 lines
4.0 KiB
C++

/*
* Copyright (C) 2005-2013 Team XBMC
* http://xbmc.org
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This Program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with XBMC; see the file COPYING. If not, see
* <http://www.gnu.org/licenses/>.
*
*/
#include "system.h"
#include "memutil.h"
#ifdef _XBOX
#include "xbox/Undocumented.h"
#endif
void fast_memcpy(void* d, const void* s, unsigned n)
{
// around 50% faster than memcpy
// only worthwhile if the destination buffer is not likely to be read back immediately
// and the number of bytes copied is >16
// somewhat faster if the source and destination are a multiple of 16 bytes apart
__asm {
mov edx, n
mov esi, s
prefetchnta [esi]
prefetchnta [esi + 32]
mov edi, d
// pre align
mov eax, edi
mov ecx, 16
and eax, 15
sub ecx, eax
and ecx, 15
cmp edx, ecx
jb fmc_exit_main
sub edx, ecx
test ecx, ecx
fmc_start_pre:
jz fmc_exit_pre
mov al, [esi]
mov [edi], al
inc esi
inc edi
dec ecx
jmp fmc_start_pre
fmc_exit_pre:
mov eax, esi
and eax, 15
jnz fmc_notaligned
// main copy, aligned
mov ecx, edx
shr ecx, 4
fmc_start_main_a:
jz fmc_exit_main
prefetchnta [esi + 32]
movaps xmm0, [esi]
movntps [edi], xmm0
add esi, 16
add edi, 16
dec ecx
jmp fmc_start_main_a
fmc_notaligned:
// main copy, unaligned
mov ecx, edx
shr ecx, 4
fmc_start_main_u:
jz fmc_exit_main
prefetchnta [esi + 32]
movups xmm0, [esi]
movntps [edi], xmm0
add esi, 16
add edi, 16
dec ecx
jmp fmc_start_main_u
fmc_exit_main:
// post align
mov ecx, edx
and ecx, 15
fmc_start_post:
jz fmc_exit_post
mov al, [esi]
mov [edi], al
inc esi
inc edi
dec ecx
jmp fmc_start_post
fmc_exit_post:
}
}
void fast_memset(void* d, int c, unsigned n)
{
char __declspec(align(16)) buf[16];
__asm {
mov edx, n
mov edi, d
// pre align
mov eax, edi
mov ecx, 16
and eax, 15
sub ecx, eax
and ecx, 15
cmp edx, ecx
jb fms_exit_main
sub edx, ecx
mov eax, c
test ecx, ecx
fms_start_pre:
jz fms_exit_pre
mov [edi], al
inc edi
dec ecx
jmp fms_start_pre
fms_exit_pre:
test al, al
jz fms_initzero
// duplicate the value 16 times
lea esi, buf
mov [esi], al
mov [esi + 1], al
mov [esi + 2], al
mov [esi + 3], al
mov eax, [esi]
mov [esi + 4], eax
mov [esi + 8], eax
mov [esi + 12], eax
movaps xmm0, [esi]
jmp fms_init_loop
fms_initzero:
// optimzed set zero
xorps xmm0, xmm0
fms_init_loop:
mov ecx, edx
shr ecx, 4
fms_start_main:
jz fms_exit_main
movntps [edi], xmm0
add edi, 16
dec ecx
jmp fms_start_main
fms_exit_main:
// post align
mov ecx, edx
and ecx, 15
fms_start_post:
jz fms_exit_post
mov [edi], al
inc edi
dec ecx
jmp fms_start_post
fms_exit_post:
}
}
#ifdef _XBOX
void usleep(int t)
{
LARGE_INTEGER li;
li.QuadPart = (LONGLONG)t * -10;
// Where possible, Alertable should be set to FALSE and WaitMode should be set to KernelMode,
// in order to reduce driver complexity. The principal exception to this is when the wait is a long term wait.
KeDelayExecutionThread(KernelMode, false, &li);
}
#endif