/* * Copyright 2002-2019 Intel Corporation. * * This software is provided to you as Sample Source Code as defined in the accompanying * End User License Agreement for the Intel(R) Software Development Products ("Agreement") * section 1.L. * * This software and the related documents are provided as is, with no express or implied * warranties, other than those that are expressly stated in the License. */ #include #include #include /* Simple string test */ /* Windows 32 bit implementation */ # if (defined(_WIN32)) # if (!defined (_M_X64)) # define WIN_CODE(...) __VA_ARGS__ # define WIN32_CODE(...) __VA_ARGS__ # define WIN64_CODE(...) # define LINUX_CODE(...) # define LINUX32_CODE(...) # define LINUX64_CODE(...) # else /* Windows 64 bit implementation */ # define WIN_CODE(...) __VA_ARGS__ # define WIN32_CODE(...) # define WIN64_CODE(...) __VA_ARGS__ # define LINUX_CODE(...) # define LINUX32_CODE(...) # define LINUX64_CODE(...) # endif # else /* Not windows, presumably a GNU compiler and (likely) Linux */ # if (!defined (_M_X64)) # define WIN_CODE(...) # define WIN32_CODE(...) # define WIN64_CODE(...) # define LINUX_CODE(...) __VA_ARGS__ # define LINUX32_CODE(...) __VA_ARGS__ # define LINUX64_CODE(...) # else /* Linux 64 bit implementations */ # define WIN_CODE(...) # define WIN32_CODE(...) # define WIN64_CODE(...) # define LINUX_CODE(...) __VA_ARGS__ # define LINUX32_CODE(...) # define LINUX64_CODE(...) __VA_ARGS__ # endif # endif static void movsb (char * dest, const char * src, int len, int decrement) { if (decrement) { WIN_CODE ( __asm std ) LINUX_CODE (__asm__ volatile ("std");) } WIN32_CODE ( __asm mov esi, src __asm mov edi, dest __asm mov ecx, len __asm rep movsb ) WIN64_CODE ( __asm mov rsi, src __asm mov rdi, dest __asm mov rcx, len __asm rep movsb ) LINUX_CODE( __asm__ volatile ("rep movsb" :: "S"(src),"D"(dest),"c"(len) : "memory"); ) if (decrement) { WIN_CODE ( __asm cld ) LINUX_CODE (__asm__ volatile ("cld");) } } static void movsd (void * dest, const void * src, int len, int decrement) { if (decrement) { WIN_CODE ( __asm std ) LINUX_CODE (__asm__ volatile ("std");) } WIN32_CODE ( __asm mov esi, src __asm mov edi, dest __asm mov ecx, len __asm rep movsd ) WIN64_CODE ( __asm mov rsi, src __asm mov rdi, dest __asm mov rcx, len __asm rep movsd ) LINUX_CODE( __asm__ volatile ("rep movsd" :: "S"(src),"D"(dest),"c"(len) : "memory"); ) if (decrement) { WIN_CODE ( __asm cld ) LINUX_CODE (__asm__ volatile ("cld");) } } /* Use repne scasb to calculate length of a string. */ static int length(const char * src, int maxlen) { const char * s = src; WIN32_CODE ( __asm mov edi, src __asm mov al, 0 __asm mov ecx, maxlen __asm repne scasb __asm mov src, edi ) WIN64_CODE ( __asm mov rdi, src __asm mov al, 0 __asm mov rcx, maxlen __asm repne scasb __asm mov src, rdi ) LINUX_CODE( __asm__ volatile ("xor %%al,%%al; repne scasb" : "=D"(src) :"0"(src),"c"(maxlen): "%eax"); ) return src-s; } static int cmps (const char * s1, const char * s2, int maxlen, int decrement) { int res = 1; if (decrement) { WIN_CODE ( __asm std ) LINUX_CODE (__asm__ volatile ("std");) } LINUX_CODE( __asm__ volatile ("repz cmpsb\n" "cmovz %2,%0\n" "jge 1f\n" "neg %0\n" "1:" : "=r"(res) :"0"(res),"r"(0), "S"(s1),"D"(s2),"c"(maxlen) ); ) if (decrement) { WIN_CODE ( __asm cld ) LINUX_CODE (__asm__ volatile ("cld");) } return res; } /* Use rep stosb to fill a chunk of store. */ static void fill(char * target, char value, int count) { WIN32_CODE ( __asm mov edi, target __asm mov al, value __asm mov ecx, count __asm rep stosb ) WIN64_CODE ( __asm mov rdi, target __asm mov al, value __asm mov rcx, count __asm rep stosb ) LINUX_CODE( __asm__ volatile ("mov %1,%%al; rep stosb" : "=D"(target) :"m"(value),"c"(count),"0"(target): "%eax", "memory"); ) } int copyAndTest (int * dest, int * src, int len,int df) { int i; int failed = 0; memset(dest, 0xff, (len+2)*sizeof(int)); for (i=0;i