aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/os/mac/hardware.rb
blob: a6b5ccf2ca4f4cd8d145bfbffc37338d140b76d6 (plain)
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
require 'mach'

module MacCPUs
  OPTIMIZATION_FLAGS = {
    :penryn => '-march=core2 -msse4.1',
    :core2 => '-march=core2',
    :core => '-march=prescott',
    :g3 => '-mcpu=750',
    :g4 => '-mcpu=7400',
    :g4e => '-mcpu=7450',
    :g5 => '-mcpu=970'
  }.freeze
  def optimization_flags; OPTIMIZATION_FLAGS; end

  # These methods use info spewed out by sysctl.
  # Look in <mach/machine.h> for decoding info.
  def type
    @type ||= `/usr/sbin/sysctl -n hw.cputype`.to_i
    case @type
    when 7
      :intel
    when 18
      :ppc
    else
      :dunno
    end
  end

  def family
    if intel?
      case @intel_family ||= `/usr/sbin/sysctl -n hw.cpufamily`.to_i
      when 0x73d67300 # Yonah: Core Solo/Duo
        :core
      when 0x426f69ef # Merom: Core 2 Duo
        :core2
      when 0x78ea4fbc # Penryn
        :penryn
      when 0x6b5a4cd2 # Nehalem
        :nehalem
      when 0x573B5EEC # Arrandale
        :arrandale
      when 0x5490B78C # Sandy Bridge
        :sandybridge
      when 0x1F65E835 # Ivy Bridge
        :ivybridge
      when 0x10B282DC # Haswell
        :haswell
      else
        :dunno
      end
    elsif ppc?
      case @ppc_family ||= `/usr/sbin/sysctl -n hw.cpusubtype`.to_i
      when 9
        :g3  # PowerPC 750
      when 10
        :g4  # PowerPC 7400
      when 11
        :g4e # PowerPC 7450
      when 100
        # This is the only 64-bit PPC CPU type, so it's useful
        # to distinguish in `brew config` output and in bottle tags
        MacOS.prefer_64_bit? ? :g5_64 : :g5  # PowerPC 970
      else
        :dunno
      end
    end
  end

  def extmodel
    @extmodel ||= `/usr/sbin/sysctl -n machdep.cpu.extmodel`.to_i
  end

  def cores
    @cores ||= `/usr/sbin/sysctl -n hw.ncpu`.to_i
  end

  def bits
    @bits ||= sysctl_bool("hw.cpu64bit_capable") ? 64 : 32
  end

  def arch_32_bit
    intel? ? :i386 : :ppc
  end

  def arch_64_bit
    intel? ? :x86_64 : :ppc64
  end

  # Returns an array that's been extended with ArchitectureListExtension,
  # which provides helpers like #as_arch_flags and #as_cmake_arch_flags.
  def universal_archs
    # Building 64-bit is a no-go on Tiger, and pretty hit or miss on Leopard.
    # Don't even try unless Tigerbrew's experimental 64-bit Leopard support is enabled.
    if MacOS.version <= :leopard and !MacOS.prefer_64_bit?
      [arch_32_bit].extend ArchitectureListExtension
    else
      [arch_32_bit, arch_64_bit].extend ArchitectureListExtension
    end
  end

  def features
    @features ||= `/usr/sbin/sysctl -n machdep.cpu.features`.split(" ").map do |s|
      s.downcase.intern
    end
  end

  def aes?
    sysctl_bool('hw.optional.aes')
  end

  def altivec?
    sysctl_bool('hw.optional.altivec')
  end

  def avx?
    sysctl_bool('hw.optional.avx1_0')
  end

  def avx2?
    sysctl_bool('hw.optional.avx2_0')
  end

  def sse3?
    sysctl_bool('hw.optional.sse3')
  end

  def ssse3?
    sysctl_bool('hw.optional.supplementalsse3')
  end

  def sse4?
    sysctl_bool('hw.optional.sse4_1')
  end

  def sse4_2?
    sysctl_bool('hw.optional.sse4_2')
  end

  protected

  def sysctl_bool(property)
    (@properties ||= {}).fetch(property) do
      result = nil
      IO.popen("/usr/sbin/sysctl -n '#{property}' 2>/dev/null") do |f|
        result = f.gets.to_i # should be 0 or 1
      end
      # sysctl call succeded and printed 1
      @properties[property] = $?.success? && result == 1
    end
  end
end