Files
@ r27407:1787a47352b7
Branch filter:
Location: cpp/openttd-patchpack/source/src/cpu.cpp - annotation
r27407:1787a47352b7
5.4 KiB
text/x-c
Codechange: prevent using (f)printf/(f)puts over fmt::print
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 174 175 176 177 178 179 180 | 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 r21110:6caf8b808fd2 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 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r23482:de566f8c088d 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 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 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r25990:2674824c1e00 r24504:754994973c7b r24504:754994973c7b r24504:754994973c7b r24504:754994973c7b r24504:754994973c7b r24504:754994973c7b r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 r21110:6caf8b808fd2 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 r21112:6db11ecb3ca0 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 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 OS/2. Hopefully this works, who knows */
#if defined (__WATCOMC__) && !defined(RDTSC_AVAILABLE)
unsigned __int64 ottd_rdtsc();
# pragma aux ottd_rdtsc = 0x0F 0x31 value [edx eax] parm nomemory modify exact [edx eax] nomemory;
# define RDTSC_AVAILABLE
#endif
/* rdtsc for all other *nix-en (hopefully). Use GCC syntax */
#if (defined(__i386__) || defined(__x86_64__)) && !defined(RDTSC_AVAILABLE)
uint64 ottd_rdtsc()
{
uint32 high, low;
__asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high));
return ((uint64)high << 32) | low;
}
# define RDTSC_AVAILABLE
#endif
/* rdtsc for PPC which has this not */
#if (defined(__POWERPC__) || defined(__powerpc__)) && !defined(RDTSC_AVAILABLE)
uint64 ottd_rdtsc()
{
uint32 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)high << 32) | low;
}
# define RDTSC_AVAILABLE
#endif
/* rdtsc for MCST Elbrus 2000 */
#if defined(__e2k__) && !defined(RDTSC_AVAILABLE)
uint64 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 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 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 type)
{
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);
}
|