e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
1b10db2002-10-08Martin Nilsson 
aad99b2001-03-28Fredrik Hübinette (Hubbe) #include "global.h" #include "pike_cpulib.h" #include "svalue.h"
d6ea432010-10-17Martin Stjernholm #ifdef HAVE_X86_ASM #if !defined (CL_X86_ASM_STYLE) && !defined (GCC_X86_ASM_STYLE) #error Dont know how to inline assembler with this compiler #endif PMOD_EXPORT void x86_get_cpuid(int oper, INT32 *cpuid_ptr) /* eax -> cpuid_ptr[0] * ebx -> cpuid_ptr[1]
fb09e92015-09-28Martin Nilsson  * edx -> cpuid_ptr[2] * ecx -> cpuid_ptr[3] */
d6ea432010-10-17Martin Stjernholm { #ifdef CL_X86_ASM_STYLE
e95ae22016-07-11Martin Nilsson  __asm { mov eax, oper; mov edi, cpuid_ptr; cpuid; mov [edi], eax; mov [edi+4], ebx; mov [edi+8], edx; mov [edi+12], ecx; };
d6ea432010-10-17Martin Stjernholm #else /* GCC_X86_ASM_STYLE */
13bbbc2012-04-27Bill Welliver 
945e9f2012-04-29Henrik Grubbström (Grubba) #if SIZEOF_CHAR_P == 4
e95ae22016-07-11Martin Nilsson  __asm__ __volatile__("pushl %%ebx \n\t" /* save %ebx */
13bbbc2012-04-27Bill Welliver  "cpuid \n\t" "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */ "popl %%ebx \n\t" /* restore the old %ebx */
13670c2015-05-25Martin Nilsson  : "=a"(cpuid_ptr[0]), "=r"(cpuid_ptr[1]),
fb09e92015-09-28Martin Nilsson  "=d"(cpuid_ptr[2]), "=c"(cpuid_ptr[3])
13bbbc2012-04-27Bill Welliver  : "0"(oper) : "cc");
945e9f2012-04-29Henrik Grubbström (Grubba) #else
e95ae22016-07-11Martin Nilsson  __asm__ __volatile__("push %%rbx \n\t" /* save %rbx */
945e9f2012-04-29Henrik Grubbström (Grubba)  "cpuid \n\t" "movl %%ebx, %1 \n\t" /* save what cpuid just put in %ebx */ "pop %%rbx \n\t" /* restore the old %rbx */ : "=a"(cpuid_ptr[0]), "=r"(cpuid_ptr[1]),
fb09e92015-09-28Martin Nilsson  "=d"(cpuid_ptr[2]), "=c"(cpuid_ptr[3])
945e9f2012-04-29Henrik Grubbström (Grubba)  : "0"(oper) : "cc");
e95ae22016-07-11Martin Nilsson #endif /* SIZEOF_CHAR_P == 4 */ #endif /* CL_X86_ASM_STYLE */
d6ea432010-10-17Martin Stjernholm } #endif /* HAVE_IA32_ASM */
99218e2017-11-06Martin Nilsson  /* Same thing as (int)floor(log((double)x) / log(2.0)), except a bit quicker. Number of log2 per second: log(x)/log(2.0) 50,000,000 log2(x) 75,000,000 Table lookup 3,000,000,000 Intrinsic 30,000,000,000,000,000 */ PMOD_EXPORT int my_log2(UINT64 x) { if( x == 0 ) return 0; if(x & ~((UINT64)0xffffffffUL)) { return 32 + log2_u32((unsigned INT32)(x>>32)); } return log2_u32((unsigned INT32)x); }