1# This file is part of PeachPy package and is licensed under the Simplified BSD license.
2#    See license.rst for the full text of the license.
3
4from peachpy.x86_64 import isa
5
6
7class Microarchitecture:
8    def __init__(self, name, extensions, alu_width, fpu_width, load_with, store_width):
9        self.name = name
10        self.extensions = isa.Extensions(*[prerequisite for extension in extensions
11                                           for prerequisite in extension.prerequisites])
12        self.alu_width = alu_width
13        self.fpu_width = fpu_width
14        self.load_width = load_with
15        self.store_width = store_width
16
17    def is_supported(self, extension):
18        return extension in self.extensions
19
20    @property
21    def id(self):
22        return self.name.replace(" ", "")
23
24    @property
25    def has_sse3(self):
26        return isa.sse3 in self.extensions
27
28    @property
29    def has_ssse3(self):
30        return isa.ssse3 in self.extensions
31
32    @property
33    def has_sse4_1(self):
34        return isa.sse4_1 in self.extensions
35
36    @property
37    def has_sse4_2(self):
38        return isa.sse4_2 in self.extensions
39
40    @property
41    def has_avx(self):
42        return isa.avx in self.extensions
43
44    @property
45    def has_avx2(self):
46        return isa.avx2 in self.extensions
47
48    @property
49    def has_fma3(self):
50        return isa.fma3 in self.extensions
51
52    @property
53    def has_fma4(self):
54        return isa.fma4 in self.extensions
55
56    @property
57    def has_fma(self):
58        return self.has_fma3 or self.has_fma4
59
60    @property
61    def has_avx512f(self):
62        return isa.avx512f in self.extensions
63
64    def __add__(self, extension):
65        return Microarchitecture(self.name, self.extensions + extension,
66                                 self.alu_width, self.fpu_width, self.load_width, self.store_width)
67
68    def __sub__(self, extension):
69        return Microarchitecture(self.name, self.extensions - extension,
70                                 self.alu_width, self.fpu_width, self.load_width, self.store_width)
71
72    def __hash__(self):
73        return hash(self.name)
74
75    def __eq__(self, other):
76        return isinstance(other, Microarchitecture) and self.name == other.name
77
78    def __ne__(self, other):
79        return not isinstance(other, Microarchitecture) or self.name != other.name
80
81    def __str__(self):
82        return self.name
83
84    def __repr__(self):
85        return str(self)
86
87default = Microarchitecture('Default', isa.default,
88                            alu_width=128, fpu_width=128, load_with=128, store_width=128)
89prescott = Microarchitecture('Prescott', (isa.cmov, isa.sse3, isa.clflush),
90                             alu_width=64, fpu_width=64, load_with=64, store_width=64)
91conroe = Microarchitecture('Conroe', (isa.cmov, isa.mmx_plus, isa.ssse3, isa.clflush),
92                           alu_width=128, fpu_width=128, load_with=128, store_width=128)
93penryn = Microarchitecture('Penryn', (isa.cmov, isa.mmx_plus, isa.sse4_1, isa.clflush),
94                           alu_width=128, fpu_width=128, load_with=128, store_width=128)
95nehalem = Microarchitecture('Nehalem', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.clflush),
96                            alu_width=128, fpu_width=128, load_with=128, store_width=128)
97sandy_bridge = Microarchitecture('Sandy Bridge', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.avx),
98                                 alu_width=128, fpu_width=256, load_with=256, store_width=128)
99ivy_bridge = Microarchitecture('Ivy Bridge', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.avx, isa.f16c),
100                               alu_width=128, fpu_width=256, load_with=256, store_width=128)
101haswell = Microarchitecture('Haswell', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.avx, isa.f16c, isa.fma3,
102                                        isa.avx2, isa.lzcnt, isa.prefetchw, isa.movbe, isa.bmi2),
103                            alu_width=256, fpu_width=256, load_with=256, store_width=256)
104broadwell = Microarchitecture('Broadwell', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.f16c, isa.fma3, isa.avx2,
105                                            isa.lzcnt, isa.prefetchw, isa.movbe, isa.bmi2, isa.adx),
106                              alu_width=256, fpu_width=256, load_with=256, store_width=256)
107skylake = Microarchitecture('Skylake', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.f16c, isa.fma3, isa.avx2,
108                                        isa.lzcnt, isa.prefetchw, isa.clflushopt, isa.movbe, isa.bmi2, isa.adx),
109                            alu_width=256, fpu_width=256, load_with=256, store_width=256)
110skylake_xeon = Microarchitecture('Skylake Xeon', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.f16c, isa.fma3,
111                                                  isa.lzcnt, isa.prefetchw, isa.clflushopt, isa.movbe, isa.bmi2, isa.adx,
112                                                  isa.avx512bw, isa.avx512dq, isa.avx512vl, isa.avx512cd),
113                                 alu_width=512, fpu_width=512, load_with=512, store_width=512)
114cannonlake = Microarchitecture('Cannonlake', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.f16c, isa.fma3,
115                                              isa.lzcnt, isa.prefetchw, isa.clflushopt, isa.movbe, isa.bmi2, isa.adx,
116                                              isa.avx512bw, isa.avx512dq, isa.avx512vl, isa.avx512cd,
117                                              isa.avx512ifma, isa.avx512vbmi),
118                               # TODO: update EU width when CNL is out
119                               alu_width=512, fpu_width=512, load_with=512, store_width=512)
120knights_landing = Microarchitecture('Knights Landing',
121                                    (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.popcnt, isa.f16c, isa.fma3,
122                                     isa.lzcnt, isa.prefetchw, isa.movbe, isa.bmi2, isa.adx,
123                                     isa.avx512cd, isa.avx512cd, isa.avx512er),
124                                    alu_width=512, fpu_width=512, load_with=512, store_width=512)
125k8 = Microarchitecture('K8', (isa.cmov, isa.mmx_plus, isa.three_d_now_plus, isa.sse2,
126                              isa.prefetch, isa.prefetchw, isa.clflush),
127                       alu_width=64, fpu_width=64, load_with=64, store_width=64)
128k10 = Microarchitecture('K10', (isa.cmov, isa.mmx_plus, isa.three_d_now_plus, isa.sse4a,
129                                isa.prefetch, isa.prefetchw, isa.clflush, isa.popcnt, isa.lzcnt),
130                        alu_width=128, fpu_width=128, load_with=128, store_width=64)
131bulldozer = Microarchitecture('Bulldozer', (isa.cmov, isa.mmx_plus, isa.sse4a, isa.avx, isa.xop, isa.fma4,
132                                            isa.prefetch, isa.prefetchw, isa.clflush,
133                                            isa.aes, isa.pclmulqdq, isa.lzcnt, isa.popcnt),
134                              alu_width=128, fpu_width=128, load_with=128, store_width=128)
135piledriver = Microarchitecture('Piledriver', (isa.cmov, isa.mmx_plus, isa.sse4a, isa.sse4_2,
136                                              isa.avx, isa.xop, isa.fma4, isa.fma3, isa.f16c, isa.aes, isa.pclmulqdq,
137                                              isa.prefetch, isa.prefetchw, isa.clflush,
138                                              isa.lzcnt, isa.popcnt, isa.bmi, isa.tbm),
139                               alu_width=128, fpu_width=128, load_with=128, store_width=128)
140steamroller = Microarchitecture('Steamroller', (isa.cmov, isa.mmx_plus, isa.sse4a, isa.sse4_2,
141                                                isa.avx, isa.xop, isa.fma4, isa.fma3, isa.f16c, isa.aes, isa.pclmulqdq,
142                                                isa.prefetch, isa.prefetchw, isa.clflush,
143                                                isa.lzcnt, isa.popcnt, isa.bmi, isa.tbm),
144                                alu_width=128, fpu_width=256, load_with=256, store_width=128)
145excavator = Microarchitecture('Excavator', (isa.cmov, isa.mmx_plus, isa.sse4a, isa.xop, isa.fma4, isa.fma3, isa.f16c,
146                                            isa.avx2, isa.aes, isa.pclmulqdq, isa.rdrand,
147                                            isa.prefetch, isa.prefetchw, isa.clflush,
148                                            isa.lzcnt, isa.popcnt, isa.bmi2, isa.tbm),
149                              alu_width=256, fpu_width=256, load_with=256, store_width=128)
150zen = Microarchitecture('Zen', (isa.cmov, isa.mmx_plus, isa.fma4, isa.fma3, isa.f16c, isa.avx2,
151                                isa.aes, isa.pclmulqdq, isa.rdseed, isa.sha,
152                                isa.prefetch, isa.prefetchw, isa.clflushopt, isa.clzero,
153                                isa.lzcnt, isa.popcnt, isa.bmi2, isa.adx),
154                        alu_width=256, fpu_width=256, load_with=256, store_width=256)
155bonnell = Microarchitecture('Bonnell', (isa.cmov, isa.movbe, isa.mmx_plus, isa.ssse3, isa.clflush),
156                            alu_width=128, fpu_width=64, load_with=128, store_width=128)
157saltwell = Microarchitecture('Saltwell', (isa.cmov, isa.movbe, isa.mmx_plus, isa.ssse3, isa.clflush),
158                             alu_width=128, fpu_width=64, load_with=128, store_width=128)
159silvermont = Microarchitecture('Silvermont', (isa.cmov, isa.movbe, isa.popcnt, isa.clflush,
160                                              isa.mmx_plus, isa.sse4_2, isa.aes, isa.pclmulqdq),
161                               alu_width=128, fpu_width=64, load_with=128, store_width=128)
162airmont = Microarchitecture('Airmont', (isa.cmov, isa.movbe, isa.popcnt,
163                                        isa.mmx_plus, isa.sse4_2,
164                                        isa.aes, isa.pclmulqdq, isa.rdrand,
165                                        isa.prefetchw, isa.clflush, isa.rdtscp),
166                            alu_width=128, fpu_width=64, load_with=128, store_width=128)
167goldmont = Microarchitecture('Goldmont', (isa.cmov, isa.movbe, isa.popcnt, isa.adx,
168                                          isa.mmx_plus, isa.sse4_2, isa.prefetchw, isa.clflushopt,
169                                          isa.aes, isa.pclmulqdq, isa.rdseed, isa.sha,
170                                          isa.rdtscp),
171                             alu_width=128, fpu_width=64, load_with=128, store_width=128)
172bobcat = Microarchitecture('Bobcat', (isa.cmov, isa.mmx_plus, isa.ssse3, isa.sse4a,
173                                      isa.prefetch, isa.prefetchw, isa.clflush, isa.lzcnt, isa.popcnt),
174                           alu_width=64, fpu_width=64, load_with=64, store_width=64)
175jaguar = Microarchitecture('Jaguar', (isa.cmov, isa.mmx_plus, isa.sse4_2, isa.sse4a, isa.avx, isa.f16c,
176                                      isa.prefetch, isa.prefetchw, isa.clflush, isa.lzcnt, isa.popcnt, isa.movbe,
177                                      isa.aes, isa.pclmulqdq),
178                           alu_width=128, fpu_width=128, load_with=128, store_width=128)
179