summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2014-01-02 08:55:32 +0000
committerrubidium <rubidium@openttd.org>2014-01-02 08:55:32 +0000
commite76d294c1084bdb5c57465f0382b2171e3c3ba4f (patch)
treef8c0ed37fa9dc2b0aaff55f53d54efa8b2e28a90 /src
parent52c942b17723999bff3416ff67f33b84b06e0986 (diff)
downloadopenttd-e76d294c1084bdb5c57465f0382b2171e3c3ba4f.tar.xz
(svn r26197) -Add: wrappers around cpuid
Diffstat (limited to 'src')
-rw-r--r--src/cpu.cpp32
-rw-r--r--src/cpu.h7
2 files changed, 39 insertions, 0 deletions
diff --git a/src/cpu.cpp b/src/cpu.cpp
index a5715b829..ce923cfe9 100644
--- a/src/cpu.cpp
+++ b/src/cpu.cpp
@@ -74,3 +74,35 @@ uint64 ottd_rdtsc()
# endif
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)
+void ottd_cpuid(int info[4], int type)
+ __cpuiid(info, type);
+}
+#elif defined(__x86_64__) || defined(__i386)
+void ottd_cpuid(int info[4], int type)
+{
+ __asm__ __volatile__ (
+ "cpuid"
+ : "=a" (info[0]), "=b" (info[1]), "=c" (info[2]), "=d" (info[3])
+ : "a" (type)
+ );
+}
+#else
+void ottd_cpuid(int info[4], int type)
+{
+ info[0] = info[1] = info[2] = info[3] = 0;
+}
+#endif
diff --git a/src/cpu.h b/src/cpu.h
index 528c87076..8ea95f5bb 100644
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -18,4 +18,11 @@
*/
uint64 ottd_rdtsc();
+/**
+ * Get the CPUID information from the CPU.
+ * @param info The retrieved info. All zeros on architectures without CPUID.
+ * @param type The information this instruction should retrieve.
+ */
+void ottd_cpuid(int info[4], int type);
+
#endif /* CPU_H */