Files
@ r28520:f9aebe299cae
Branch filter:
Location: cpp/openttd-patchpack/source/src/cpu.cpp - annotation
r28520:f9aebe299cae
5.1 KiB
text/x-c
Codechange: MacOS already has MIN/MAX macros defined
This is caused because we use PreCompile Headers, and one of them
includes a system headers which defines MIN/MAX.
This is caused because we use PreCompile Headers, and one of them
includes a system headers which defines MIN/MAX.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21140:a1f68ae49850 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21122:bb3972c9fc84 r21110:6caf8b808fd2 r21383:942c32fb8b0e r21383:942c32fb8b0e r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r24679:ada7b2cc1164 r21110:6caf8b808fd2 r24679:ada7b2cc1164 r27737:728d55b97775 r21110:6caf8b808fd2 r24679:ada7b2cc1164 r24679:ada7b2cc1164 r24679:ada7b2cc1164 r24679:ada7b2cc1164 r24679:ada7b2cc1164 r21110:6caf8b808fd2 r24679:ada7b2cc1164 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r23482:de566f8c088d r27737:728d55b97775 r21110:6caf8b808fd2 r27737:728d55b97775 r21110:6caf8b808fd2 r27737:728d55b97775 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r27737:728d55b97775 r21110:6caf8b808fd2 r27737:728d55b97775 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r27737:728d55b97775 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r25990:2674824c1e00 r25990:2674824c1e00 r27737:728d55b97775 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r24504:754994973c7b r24504:754994973c7b r27737:728d55b97775 r24504:754994973c7b r24504:754994973c7b r24504:754994973c7b r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r27737:728d55b97775 r21110:6caf8b808fd2 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r23993:98bfabb75614 r21112:6db11ecb3ca0 r21115:d5bd4869a943 r21114:37902b8d2f2b r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21135:63fcf9e9277a r21140:a1f68ae49850 r21140:a1f68ae49850 r21140:a1f68ae49850 r21140:a1f68ae49850 r21140:a1f68ae49850 r21140:a1f68ae49850 r21112:6db11ecb3ca0 r21134:e1cbf2e07eaf r21134:e1cbf2e07eaf r21134:e1cbf2e07eaf r21123:eb4aaaa1deb9 r21140:a1f68ae49850 r21140:a1f68ae49850 r21140:a1f68ae49850 r21135:63fcf9e9277a r21112:6db11ecb3ca0 r21135:63fcf9e9277a r21135:63fcf9e9277a r21135:63fcf9e9277a r21135:63fcf9e9277a r21135:63fcf9e9277a r21135:63fcf9e9277a r21135:63fcf9e9277a r21112:6db11ecb3ca0 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r21112:6db11ecb3ca0 r27942:f7389062d120 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21112:6db11ecb3ca0 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 r21122:bb3972c9fc84 | /*
* This file is part of OpenTTD.
* OpenTTD 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, version 2.
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file cpu.cpp OS/CPU/compiler dependent CPU specific calls. */
#include "stdafx.h"
#include "core/bitmath_func.hpp"
#include "safeguards.h"
#undef RDTSC_AVAILABLE
/* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc
* from external win64.asm because VS2005 does not support inline assembly */
#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE)
#include <intrin.h>
#include <windows.h>
uint64_t ottd_rdtsc()
{
#if defined(_M_ARM)
return __rdpmccntr64();
#elif defined(_M_ARM64)
return _ReadStatusReg(ARM64_PMCCNTR_EL0);
#else
return __rdtsc();
#endif
}
#define RDTSC_AVAILABLE
#endif
/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */
#if (defined(__i386__) || defined(__x86_64__)) && !defined(RDTSC_AVAILABLE)
uint64_t ottd_rdtsc()
{
uint32_t high, low;
__asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
return ((uint64_t)high << 32) | low;
}
# define RDTSC_AVAILABLE
#endif
/* rdtsc for PPC which has this not */
#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE)
uint64_t ottd_rdtsc()
{
uint32_t high = 0, high2 = 0, low;
/* PPC does not have rdtsc, so we cheat by reading the two 32-bit time-counters
* it has, 'Move From Time Base (Upper)'. Since these are two reads, in the
* very unlikely event that the lower part overflows to the upper part while we
* read it; we double-check and reread the registers */
asm volatile (
"mftbu %0\n"
"mftb %1\n"
"mftbu %2\n"
"cmpw %3,%4\n"
"bne- $-16\n"
: "=r" (high), "=r" (low), "=r" (high2)
: "0" (high), "2" (high2)
);
return ((uint64_t)high << 32) | low;
}
# define RDTSC_AVAILABLE
#endif
/* rdtsc for MCST Elbrus 2000 */
#if defined(__e2k__) && !defined(RDTSC_AVAILABLE)
uint64_t ottd_rdtsc()
{
uint64_t dst;
# pragma asm_inline
asm("rrd %%clkr, %0" : "=r" (dst));
return dst;
}
# define RDTSC_AVAILABLE
#endif
#if defined(__EMSCRIPTEN__) && !defined(RDTSC_AVAILABLE)
/* On emscripten doing TIC/TOC would be ill-advised */
uint64_t ottd_rdtsc() {return 0;}
# define RDTSC_AVAILABLE
#endif
/* In all other cases we have no support for rdtsc. No major issue,
* you just won't be able to profile your code with TIC()/TOC() */
#if !defined(RDTSC_AVAILABLE)
#warning "(non-fatal) No support for rdtsc(), you won't be able to profile with TIC/TOC"
uint64_t ottd_rdtsc() {return 0;}
#endif
/**
* Definitions for CPU detection:
*
* MSVC offers cpu information while gcc only implements in gcc 4.8
* __builtin_cpu_supports and friends
* http://msdn.microsoft.com/library/vstudio/hskdteyh%28v=vs.100%29.aspx
* http://gcc.gnu.org/onlinedocs/gcc/X86-Built-in-Functions.html
*
* Other platforms/architectures don't have CPUID, so zero the info and then
* most (if not all) of the features are set as if they do not exist.
*/
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
void ottd_cpuid(int info[4], int type)
{
__cpuid(info, type);
}
#elif defined(__x86_64__) || defined(__i386)
void ottd_cpuid(int info[4], int type)
{
#if defined(__i386) && defined(__PIC__)
/* The easy variant would be just cpuid, however... ebx is being used by the GOT (Global Offset Table)
* in case of PIC;
* clobbering ebx is no alternative: some compiler versions don't like this
* and will issue an error message like
* "can't find a register in class 'BREG' while reloading 'asm'"
*/
__asm__ __volatile__ (
"xchgl %%ebx, %1 \n\t"
"cpuid \n\t"
"xchgl %%ebx, %1 \n\t"
: "=a" (info[0]), "=r" (info[1]), "=c" (info[2]), "=d" (info[3])
/* It is safe to write "=r" for (info[1]) as in case that PIC is enabled for i386,
* the compiler will not choose EBX as target register (but something else).
*/
: "a" (type)
);
#else
__asm__ __volatile__ (
"cpuid \n\t"
: "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3])
: "a" (type)
);
#endif /* i386 PIC */
}
#elif defined(__e2k__) /* MCST Elbrus 2000*/
void ottd_cpuid(int info[4], int type)
{
info[0] = info[1] = info[2] = info[3] = 0;
if (type == 0) {
info[0] = 1;
} else if (type == 1) {
#if defined(__SSE4_1__)
info[2] |= (1<<19); /* HasCPUIDFlag(1, 2, 19) */
#endif
#if defined(__SSSE3__)
info[2] |= (1<<9); /* HasCPUIDFlag(1, 2, 9) */
#endif
#if defined(__SSE2__)
info[3] |= (1<<26); /* HasCPUIDFlag(1, 3, 26) */
#endif
}
}
#else
void ottd_cpuid(int info[4], int)
{
info[0] = info[1] = info[2] = info[3] = 0;
}
#endif
bool HasCPUIDFlag(uint type, uint index, uint bit)
{
int cpu_info[4] = {-1};
ottd_cpuid(cpu_info, 0);
uint max_info_type = cpu_info[0];
if (max_info_type < type) return false;
ottd_cpuid(cpu_info, type);
return HasBit(cpu_info[index], bit);
}
|