split out PowerDecode2 into PowerDecodeSubset
[soc.git] / src / soc / decoder / power_enums.py
1 from enum import Enum, unique
2 import csv
3 import os
4 from os.path import dirname, join
5 from collections import namedtuple
6
7
8 def find_wiki_file(name):
9 filedir = os.path.dirname(os.path.abspath(__file__))
10 basedir = dirname(dirname(dirname(filedir)))
11 tabledir = join(basedir, 'libreriscv')
12 tabledir = join(tabledir, 'openpower')
13 tabledir = join(tabledir, 'isatables')
14
15 file_path = join(tabledir, name)
16 return file_path
17
18
19 def get_csv(name):
20 file_path = find_wiki_file(name)
21 with open(file_path, 'r') as csvfile:
22 reader = csv.DictReader(csvfile)
23 return list(reader)
24
25
26 # names of the fields in the tables that don't correspond to an enum
27 single_bit_flags = ['inv A', 'inv out',
28 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
29 'sgn', 'lk', 'sgl pipe']
30
31 # default values for fields in the table
32 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
33 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
34 'CR in': 'NONE',
35 'ldst len': 'NONE',
36 'upd': '0',
37 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
38
39
40 def get_signal_name(name):
41 if name[0].isdigit():
42 name = "is_" + name
43 return name.lower().replace(' ', '_')
44
45 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
46 # is to process and guard the operation. they are roughly divided by having
47 # the same register input/output signature (X-Form, etc.)
48 @unique
49 class Function(Enum):
50 NONE = 0
51 ALU = 1 << 1
52 LDST = 1 << 2
53 SHIFT_ROT = 1 << 3
54 LOGICAL = 1 << 4
55 BRANCH = 1 << 5
56 CR = 1 << 6
57 TRAP = 1 << 7
58 MUL = 1 << 8
59 DIV = 1 << 9
60 SPR = 1 << 10
61
62
63 @unique
64 class Form(Enum):
65 NONE = 0
66 I = 1
67 B = 2
68 SC = 3
69 D = 4
70 DS = 5
71 DQ = 6
72 DX = 7
73 X = 8
74 XL = 9
75 XFX = 10
76 XFL = 11
77 XX1 = 12
78 XX2 = 13
79 XX3 = 14
80 XX4 = 15
81 XS = 16
82 XO = 17
83 A = 18
84 M = 19
85 MD = 20
86 MDS = 21
87 VA = 22
88 VC = 23
89 VX = 24
90 EVX = 25
91 EVS = 26
92 Z22 = 27
93 Z23 = 28
94
95
96 # supported instructions: make sure to keep up-to-date with CSV files
97 # just like everything else
98 _insns = [
99 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
100 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
101 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
102 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
103 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
104 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
105 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
106 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
107 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
108 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
109 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
110 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
111 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
112 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
113 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
114 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
115 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
116 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
117 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
118 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
119 "rlwnm", "setb", "sim_cfg", "sld", "slw", "srad", "sradi", "sraw",
120 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
121 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
122 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
123 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
124 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
125 "tdi", "tw", "twi", "xor", "xori", "xoris",
126 ]
127
128 # two-way lookup of instruction-to-index and vice-versa
129 insns = {}
130 asmidx = {}
131 for i, insn in enumerate(_insns):
132 insns[i] = insn
133 asmidx[insn] = i
134
135 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
136 @unique
137 class MicrOp(Enum):
138 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
139 OP_NOP = 1
140 OP_ADD = 2
141 OP_ADDPCIS = 3
142 OP_AND = 4
143 OP_ATTN = 5
144 OP_B = 6
145 OP_BC = 7
146 OP_BCREG = 8
147 OP_BPERM = 9
148 OP_CMP = 10
149 OP_CMPB = 11
150 OP_CMPEQB = 12
151 OP_CMPRB = 13
152 OP_CNTZ = 14
153 OP_CRAND = 15
154 OP_CRANDC = 16
155 OP_CREQV = 17
156 OP_CRNAND = 18
157 OP_CRNOR = 19
158 OP_CROR = 20
159 OP_CRORC = 21
160 OP_CRXOR = 22
161 OP_DARN = 23
162 OP_DCBF = 24
163 OP_DCBST = 25
164 OP_DCBT = 26
165 OP_DCBTST = 27
166 OP_DCBZ = 28
167 OP_DIV = 29
168 OP_DIVE = 30
169 OP_EXTS = 31
170 OP_EXTSWSLI = 32
171 OP_ICBI = 33
172 OP_ICBT = 34
173 OP_ISEL = 35
174 OP_ISYNC = 36
175 OP_LOAD = 37
176 OP_STORE = 38
177 OP_MADDHD = 39
178 OP_MADDHDU = 40
179 OP_MADDLD = 41
180 OP_MCRF = 42
181 OP_MCRXR = 43
182 OP_MCRXRX = 44
183 OP_MFCR = 45
184 OP_MFSPR = 46
185 OP_MOD = 47
186 OP_MTCRF = 48
187 OP_MTSPR = 49
188 OP_MUL_L64 = 50
189 OP_MUL_H64 = 51
190 OP_MUL_H32 = 52
191 OP_OR = 53
192 OP_POPCNT = 54
193 OP_PRTY = 55
194 OP_RLC = 56
195 OP_RLCL = 57
196 OP_RLCR = 58
197 OP_SETB = 59
198 OP_SHL = 60
199 OP_SHR = 61
200 OP_SYNC = 62
201 OP_TRAP = 63
202 OP_XOR = 67
203 OP_SIM_CONFIG = 68
204 OP_CROP = 69
205 OP_RFID = 70
206 OP_MFMSR = 71
207 OP_MTMSRD = 72
208 OP_SC = 73
209 OP_MTMSR = 74
210
211
212 @unique
213 class In1Sel(Enum):
214 NONE = 0
215 RA = 1
216 RA_OR_ZERO = 2
217 SPR = 3
218 RS = 4 # for some ALU/Logical operations
219
220
221 @unique
222 class In2Sel(Enum):
223 NONE = 0
224 RB = 1
225 CONST_UI = 2
226 CONST_SI = 3
227 CONST_UI_HI = 4
228 CONST_SI_HI = 5
229 CONST_LI = 6
230 CONST_BD = 7
231 CONST_DS = 8
232 CONST_M1 = 9
233 CONST_SH = 10
234 CONST_SH32 = 11
235 SPR = 12
236 RS = 13 # for shiftrot (M-Form)
237
238
239 @unique
240 class In3Sel(Enum):
241 NONE = 0
242 RS = 1
243 RB = 2 # for shiftrot (M-Form)
244
245
246 @unique
247 class OutSel(Enum):
248 NONE = 0
249 RT = 1
250 RA = 2
251 SPR = 3
252
253
254 @unique
255 class LdstLen(Enum):
256 NONE = 0
257 is1B = 1
258 is2B = 2
259 is4B = 4
260 is8B = 8
261
262
263 @unique
264 class LDSTMode(Enum):
265 NONE = 0
266 update = 1
267 cix = 2
268 cx = 3
269
270
271 @unique
272 class RC(Enum):
273 NONE = 0
274 ONE = 1
275 RC = 2
276
277
278 @unique
279 class CryIn(Enum):
280 ZERO = 0
281 ONE = 1
282 CA = 2
283 # TODO OV = 3
284
285
286 @unique
287 class CRInSel(Enum):
288 NONE = 0
289 CR0 = 1
290 BI = 2
291 BFA = 3
292 BA_BB = 4
293 BC = 5
294 WHOLE_REG = 6
295
296
297 @unique
298 class CROutSel(Enum):
299 NONE = 0
300 CR0 = 1
301 BF = 2
302 BT = 3
303 WHOLE_REG = 4
304
305
306 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
307 # http://libre-riscv.org/openpower/isatables/sprs.csv
308 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
309
310 spr_csv = get_csv("sprs.csv")
311 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
312 spr_dict = {}
313 spr_byname = {}
314 for row in spr_csv:
315 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
316 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
317 idx=int(row['Idx']))
318 spr_dict[int(row['Idx'])] = info
319 spr_byname[row['SPR']] = info
320 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
321 SPR = Enum('SPR', fields)
322
323
324 XER_bits = {
325 'SO': 32,
326 'OV': 33,
327 'CA': 34,
328 'OV32': 44,
329 'CA32': 45
330 }
331
332 if __name__ == '__main__':
333 # find out what the heck is in SPR enum :)
334 print("sprs", len(SPR))
335 print(dir(SPR))
336 print(dir(Enum))
337 print(SPR.__members__['TAR'])
338 for x in SPR:
339 print(x, x.value, str(x), x.name)
340
341 print ("function", Function.ALU.name)