1# - Set a number of variables to indicate things about the current CPU and OS
2#
3#  CPU_COUNT
4#  CPU_INTEL
5#  CPU_EXE_64BIT
6#  CPU_EXE_32BIT
7#  CPU_HAS_SSE
8#  CPU_HAS_SSE2
9#  CPU_HAS_SSE3
10#  CPU_HAS_SSSE3
11#  CPU_HAS_SSE4_1
12#  CPU_HAS_SSE4_2
13#
14# Requires these CMake modules:
15#  no additional modules required
16#
17# Original Author:
18# 2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
19# http://academic.cleardefinition.com
20# Iowa State University HCI Graduate Program/VRAC
21#
22# Copyright Iowa State University 2009-2010.
23# Distributed under the Boost Software License, Version 1.0.
24# (See accompanying file LICENSE_1_0.txt or copy at
25# http://www.boost.org/LICENSE_1_0.txt)
26#
27
28
29if(__get_cpu_details)
30	return()
31endif()
32set(__get_cpu_details YES)
33
34function(get_cpu_details)
35	option(CPUDETAILS_VERBOSE
36		"Should we display results of the CPU info check?"
37		NO)
38	mark_as_advanced(CPUDETAILS_VERBOSE)
39
40	### See http://www.kitware.com/blog/home/post/63
41	if(NOT DEFINED CPU_COUNT)
42		# Unknown:
43		set(CPU_COUNT 1)
44		# Linux:
45		set(cpuinfo_file "/proc/cpuinfo")
46		if(EXISTS "${cpuinfo_file}")
47			file(STRINGS "${cpuinfo_file}" procs REGEX "^processor.: [0-9]+$")
48			list(LENGTH procs CPU_COUNT)
49		endif()
50		# Mac:
51		if(APPLE)
52			find_program(cmd_sys_pro "system_profiler")
53			if(cmd_sys_pro)
54				execute_process(COMMAND ${cmd_sys_pro} OUTPUT_VARIABLE info)
55				string(REGEX REPLACE "^.*Total Number Of Cores: ([0-9]+).*$" "\\1"
56				CPU_COUNT "${info}")
57			endif()
58		endif()
59		# Windows:
60		if(WIN32)
61			set(CPU_COUNT "$ENV{NUMBER_OF_PROCESSORS}")
62		endif()
63	endif()
64
65	###
66	# CPU_INTEL
67
68	if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "i[3456]86")
69		set(CPU_INTEL YES)
70	elseif(APPLE)
71		# Mac Intel boxes return i386 in 10.5 - so assume this is a PPC
72		set(CPU_INTEL NO)
73	else()
74		# TODO: Assuming yes in case of doubt - probably not a great idea
75		set(CPU_INTEL YES)
76	endif()
77
78	set(CPU_INTEL
79		${CPU_INTEL}
80		CACHE
81		INTERNAL
82		"Intel x86 or x86_64 architecture machine?")
83
84	###
85	# CPU_EXE_64BIT/32BIT
86	if(CMAKE_SIZEOF_VOID_P EQUAL 8)
87		set(CPU_EXE_64BIT ON)
88		set(CPU_EXE_32BIT OFF)
89	else()
90		set(CPU_EXE_64BIT OFF)
91		set(CPU_EXE_32BIT ON)
92	endif()
93
94	###
95	# CPU_HAS_SSE/SSE2/SSE3/SSSE3/SSE4.1/SSE4.2
96	if(CPU_INTEL)
97		if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
98			# Use /proc/cpuinfo to find this out.
99			file(STRINGS "/proc/cpuinfo" _cpuinfo)
100			if(_cpuinfo MATCHES "(sse)|(xmm)")
101				set(CPU_HAS_SSE YES)
102			else()
103				set(CPU_HAS_SSE NO)
104			endif()
105
106			if(_cpuinfo MATCHES "(sse2)|(xmm2)")
107				set(CPU_HAS_SSE2 YES)
108			else()
109				set(CPU_HAS_SSE2 NO)
110			endif()
111
112			if(_cpuinfo MATCHES "(sse3)|(xmm3)")
113				set(CPU_HAS_SSE3 YES)
114			else()
115				set(CPU_HAS_SSE3 NO)
116			endif()
117
118			if(_cpuinfo MATCHES "ssse3")
119				set(CPU_HAS_SSSE3 YES)
120			else()
121				set(CPU_HAS_SSSE3 NO)
122			endif()
123
124			if(_cpuinfo MATCHES "(sse4_1)|(xmm4_1)")
125				set(CPU_HAS_SSE4_1 YES)
126			else()
127				set(CPU_HAS_SSE4_1 NO)
128			endif()
129
130			if(_cpuinfo MATCHES "(sse4_2)|(xmm4_2)")
131				set(CPU_HAS_SSE4_2 YES)
132			else()
133				set(CPU_HAS_SSE4_2 NO)
134			endif()
135
136		elseif(APPLE)
137			# Mac OS X Intel requires SSE3
138			set(CPU_HAS_SSE YES)
139			set(CPU_HAS_SSE2 YES)
140			set(CPU_HAS_SSE3 YES)
141			set(CPU_HAS_SSSE3 NO)
142			set(CPU_HAS_SSE4_1 NO)
143			set(CPU_HAS_SSE4_2 NO)
144		elseif(WIN32)
145			if(CPU_EXE_64BIT)
146				#TODO: Assume only common-denominator for 64-bit machines,
147				# since I don't know how to check.
148				set(CPU_HAS_SSE YES)
149				set(CPU_HAS_SSE2 YES)
150				set(CPU_HAS_SSE3 NO)
151				set(CPU_HAS_SSSE3 NO)
152				set(CPU_HAS_SSE4_1 NO)
153				set(CPU_HAS_SSE4_2 NO)
154			else()
155				#TODO:  Assume no SSE, since I don't know how to check.
156				set(CPU_HAS_SSE NO)
157				set(CPU_HAS_SSE2 NO)
158				set(CPU_HAS_SSE3 NO)
159				set(CPU_HAS_SSSE3 NO)
160				set(CPU_HAS_SSE4_1 NO)
161				set(CPU_HAS_SSE4_2 NO)
162			endif()
163		endif()
164	endif()
165
166	set(CPU_INTEL
167		${CPU_INTEL}
168		CACHE
169		INTERNAL
170		"Intel x86 or x86_64 architecture machine?")
171
172	foreach(_var
173		CPU_COUNT
174		CPU_EXE_64BIT
175		CPU_EXE_32BIT
176		CPU_HAS_SSE
177		CPU_HAS_SSE2
178		CPU_HAS_SSE3
179		CPU_HAS_SSSE3
180		CPU_HAS_SSE4_1
181		CPU_HAS_SSE4_2)
182		set(${_var} ${${_var}} CACHE INTERNAL "")
183	endforeach()
184
185	if(CPUDETAILS_VERBOSE)
186		foreach(_var
187			CPU_COUNT
188			CPU_INTEL
189			CPU_EXE_64BIT
190			CPU_EXE_32BIT
191			CPU_HAS_SSE
192			CPU_HAS_SSE2
193			CPU_HAS_SSE3
194			CPU_HAS_SSSE3
195			CPU_HAS_SSE4_1
196			CPU_HAS_SSE4_2)
197			get_property(_help CACHE ${_var} PROPERTY HELPSTRING)
198			message(STATUS "[get_cpu_details] ${_var} (${_help}): ${${_var}}")
199		endforeach()
200	endif()
201endfunction()
202