aboutsummaryrefslogtreecommitdiffstats
path: root/Library/Homebrew/os/mac/hardware.rb
blob: c5e803261469afc9bd49853a807f96a37ba39763 (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
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'
  }
  def optimization_flags; OPTIMIZATION_FLAGS.dup; 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 type == :intel
      @intel_family ||= `/usr/sbin/sysctl -n hw.cpufamily`.to_i
      case @intel_family
      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
      else
        :dunno
      end
    elsif type == :ppc
      @ppc_family ||= `/usr/sbin/sysctl -n hw.cpusubtype`.to_i
      case @ppc_family
      when 9
        :g3  # PowerPC 750
      when 10
        :g4  # PowerPC 7400
      when 11
        :g4e # PowerPC 7450
      when 100
        :g5  # PowerPC 970
      else
        :dunno
      end
    end
  end

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

  def bits
    return @bits if defined? @bits

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

  def altivec?
    type == :ppc && family != :g3
  end

  def avx?
    pre_sandy = [:core, :core2, :penryn, :nehalem, :arrandale].include? family
    type == :intel && !pre_sandy
  end

  def sse3?
    type == :intel
  end

  def sse4?
    type == :intel && (family != :core && family != :core2)
  end

  protected

  def sysctl_bool(property)
    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
    $?.success? && result == 1 # sysctl call succeded and printed 1
  end
end