f7e8ce1c97abdd031cae12f60a5e2c89b7b1a83f
[openpower-isa.git] / src / openpower / decoder / power_enums.py
1 # SPDX-License: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020, Michael Nolan
4
5 """Enums used in OpenPOWER ISA decoding
6
7 Note: for SV, from v3.1B p12:
8
9 The designated SPR sandbox consists of non-privileged SPRs 704-719 and
10 privileged SPRs 720-735.
11
12 Note: the option exists to select a much shorter list of SPRs, to reduce
13 regfile size in HDL. this is SPRreduced and the supported list is in
14 get_spr_enum
15 """
16
17 from enum import Enum, unique
18 import csv
19 import os
20 from os.path import dirname, join
21 from collections import namedtuple
22
23
24 def find_wiki_dir():
25 filedir = os.path.dirname(os.path.abspath(__file__))
26 basedir = dirname(dirname(dirname(filedir)))
27 tabledir = join(basedir, 'openpower')
28 isatables = join(tabledir, 'isatables')
29 #print ("find_wiki_dir", isatables)
30 return isatables
31
32
33 def find_wiki_file(name):
34 return join(find_wiki_dir(), name)
35
36
37 def get_csv(name):
38 file_path = find_wiki_file(name)
39 with open(file_path, 'r') as csvfile:
40 reader = csv.DictReader(csvfile)
41 return list(reader)
42
43
44 # names of the fields in the tables that don't correspond to an enum
45 single_bit_flags = ['inv A', 'inv out',
46 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
47 'sgn', 'lk', 'sgl pipe']
48
49 # default values for fields in the table
50 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
51 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
52 'CR in': 'NONE',
53 'ldst len': 'NONE',
54 'upd': '0',
55 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
56
57
58 def get_signal_name(name):
59 if name[0].isdigit():
60 name = "is_" + name
61 return name.lower().replace(' ', '_')
62
63 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
64 # is to process and guard the operation. they are roughly divided by having
65 # the same register input/output signature (X-Form, etc.)
66
67
68 @unique
69 class Function(Enum):
70 NONE = 0
71 ALU = 1 << 1
72 LDST = 1 << 2
73 SHIFT_ROT = 1 << 3
74 LOGICAL = 1 << 4
75 BRANCH = 1 << 5
76 CR = 1 << 6
77 TRAP = 1 << 7
78 MUL = 1 << 8
79 DIV = 1 << 9
80 SPR = 1 << 10
81 MMU = 1 << 11
82 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
83 VL = 1 << 13 # setvl
84
85
86 @unique
87 class Form(Enum):
88 NONE = 0
89 I = 1
90 B = 2
91 SC = 3
92 D = 4
93 DS = 5
94 DQ = 6
95 DX = 7
96 X = 8
97 XL = 9
98 XFX = 10
99 XFL = 11
100 XX1 = 12
101 XX2 = 13
102 XX3 = 14
103 XX4 = 15
104 XS = 16
105 XO = 17
106 A = 18
107 M = 19
108 MD = 20
109 MDS = 21
110 VA = 22
111 VC = 23
112 VX = 24
113 EVX = 25
114 EVS = 26
115 Z22 = 27
116 Z23 = 28
117 SVL = 29 # Simple-V for setvl instruction
118
119 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
120
121
122 @unique
123 class SVPtype(Enum):
124 NONE = 0
125 P1 = 1
126 P2 = 2
127
128
129 @unique
130 class SVEtype(Enum):
131 NONE = 0
132 EXTRA2 = 1
133 EXTRA3 = 2
134
135
136 @unique
137 class SVEXTRA(Enum):
138 NONE = 0
139 Idx0 = 1
140 Idx1 = 2
141 Idx2 = 3
142 Idx3 = 4
143 Idx_1_2 = 5 # due to weird BA/BB for crops
144
145
146 @unique
147 class SVP64PredMode(Enum):
148 ALWAYS = 0
149 INT = 1
150 CR = 2
151
152
153 @unique
154 class SVP64PredInt(Enum):
155 ALWAYS = 0
156 R3_UNARY = 1
157 R3 = 2
158 R3_N = 3
159 R10 = 4
160 R10_N = 5
161 R30 = 6
162 R30_N = 7
163
164
165 @unique
166 class SVP64PredCR(Enum):
167 LT = 0
168 GE = 1
169 GT = 2
170 LE = 3
171 EQ = 4
172 NE = 5
173 SO = 6
174 NS = 7
175
176
177 @unique
178 class SVP64RMMode(Enum):
179 NORMAL = 0
180 MAPREDUCE = 1
181 FFIRST = 2
182 SATURATE = 3
183 PREDRES = 4
184
185
186 @unique
187 class SVP64width(Enum):
188 DEFAULT = 0
189 EW_32 = 1
190 EW_16 = 2
191 EW_8 = 3
192
193
194 @unique
195 class SVP64subvl(Enum):
196 VEC1 = 0
197 VEC2 = 1
198 VEC3 = 2
199 VEC4 = 3
200
201
202 @unique
203 class SVP64sat(Enum):
204 NONE = 0
205 SIGNED = 1
206 UNSIGNED = 2
207
208
209 # supported instructions: make sure to keep up-to-date with CSV files
210 # just like everything else
211 _insns = [
212 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
213 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
214 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
215 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
216 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
217 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
218 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
219 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
220 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
221 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
222 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
223 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
224 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
225 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
226 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
227 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
228 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
229 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
230 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf",
231 "mfmsr", "mfspr", "modsd", "modsw", "modud",
232 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
233 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
234 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
235 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
236 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
237 "rlwnm", "setb",
238 "setvl", # https://libre-soc.org/openpower/sv/setvl
239 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
240 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
241 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
242 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
243 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
244 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
245 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
246 ]
247
248 # two-way lookup of instruction-to-index and vice-versa
249 insns = {}
250 asmidx = {}
251 for i, insn in enumerate(_insns):
252 insns[i] = insn
253 asmidx[insn] = i
254
255 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
256
257
258 @unique
259 class MicrOp(Enum):
260 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
261 OP_NOP = 1
262 OP_ADD = 2
263 OP_ADDPCIS = 3
264 OP_AND = 4
265 OP_ATTN = 5
266 OP_B = 6
267 OP_BC = 7
268 OP_BCREG = 8
269 OP_BPERM = 9
270 OP_CMP = 10
271 OP_CMPB = 11
272 OP_CMPEQB = 12
273 OP_CMPRB = 13
274 OP_CNTZ = 14
275 OP_CRAND = 15
276 OP_CRANDC = 16
277 OP_CREQV = 17
278 OP_CRNAND = 18
279 OP_CRNOR = 19
280 OP_CROR = 20
281 OP_CRORC = 21
282 OP_CRXOR = 22
283 OP_DARN = 23
284 OP_DCBF = 24
285 OP_DCBST = 25
286 OP_DCBT = 26
287 OP_DCBTST = 27
288 OP_DCBZ = 28
289 OP_DIV = 29
290 OP_DIVE = 30
291 OP_EXTS = 31
292 OP_EXTSWSLI = 32
293 OP_ICBI = 33
294 OP_ICBT = 34
295 OP_ISEL = 35
296 OP_ISYNC = 36
297 OP_LOAD = 37
298 OP_STORE = 38
299 OP_MADDHD = 39
300 OP_MADDHDU = 40
301 OP_MADDLD = 41
302 OP_MCRF = 42
303 OP_MCRXR = 43
304 OP_MCRXRX = 44
305 OP_MFCR = 45
306 OP_MFSPR = 46
307 OP_MOD = 47
308 OP_MTCRF = 48
309 OP_MTSPR = 49
310 OP_MUL_L64 = 50
311 OP_MUL_H64 = 51
312 OP_MUL_H32 = 52
313 OP_OR = 53
314 OP_POPCNT = 54
315 OP_PRTY = 55
316 OP_RLC = 56
317 OP_RLCL = 57
318 OP_RLCR = 58
319 OP_SETB = 59
320 OP_SHL = 60
321 OP_SHR = 61
322 OP_SYNC = 62
323 OP_TRAP = 63
324 OP_XOR = 67
325 OP_SIM_CONFIG = 68
326 OP_CROP = 69
327 OP_RFID = 70
328 OP_MFMSR = 71
329 OP_MTMSRD = 72
330 OP_SC = 73
331 OP_MTMSR = 74
332 OP_TLBIE = 75
333 OP_SETVL = 76
334
335
336 @unique
337 class In1Sel(Enum):
338 NONE = 0
339 RA = 1
340 RA_OR_ZERO = 2
341 SPR = 3
342 RS = 4 # for some ALU/Logical operations
343
344
345 @unique
346 class In2Sel(Enum):
347 NONE = 0
348 RB = 1
349 CONST_UI = 2
350 CONST_SI = 3
351 CONST_UI_HI = 4
352 CONST_SI_HI = 5
353 CONST_LI = 6
354 CONST_BD = 7
355 CONST_DS = 8
356 CONST_M1 = 9
357 CONST_SH = 10
358 CONST_SH32 = 11
359 SPR = 12
360 RS = 13 # for shiftrot (M-Form)
361
362
363 @unique
364 class In3Sel(Enum):
365 NONE = 0
366 RS = 1
367 RB = 2 # for shiftrot (M-Form)
368
369
370 @unique
371 class OutSel(Enum):
372 NONE = 0
373 RT = 1
374 RA = 2
375 SPR = 3
376 RT_OR_ZERO = 4
377
378
379 @unique
380 class LdstLen(Enum):
381 NONE = 0
382 is1B = 1
383 is2B = 2
384 is4B = 4
385 is8B = 8
386
387
388 @unique
389 class LDSTMode(Enum):
390 NONE = 0
391 update = 1
392 cix = 2
393 cx = 3
394
395
396 @unique
397 class RC(Enum):
398 NONE = 0
399 ONE = 1
400 RC = 2
401
402
403 @unique
404 class CryIn(Enum):
405 ZERO = 0
406 ONE = 1
407 CA = 2
408 # TODO OV = 3
409
410
411 @unique
412 class CRInSel(Enum):
413 NONE = 0
414 CR0 = 1
415 BI = 2
416 BFA = 3
417 BA_BB = 4
418 BC = 5
419 WHOLE_REG = 6
420 CR1 = 7
421
422
423 @unique
424 class CROutSel(Enum):
425 NONE = 0
426 CR0 = 1
427 BF = 2
428 BT = 3
429 WHOLE_REG = 4
430 CR1 = 5
431
432
433 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
434 # http://libre-riscv.org/openpower/isatables/sprs.csv
435 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
436
437 def get_spr_enum(full_file):
438 """get_spr_enum - creates an Enum of SPRs, dynamically
439 has the option to reduce the enum to a much shorter list.
440 this saves drastically on the size of the regfile
441 """
442 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
443 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
444 'SPRG3'
445 }
446 spr_csv = []
447 for row in get_csv("sprs.csv"):
448 if full_file or row['SPR'] in short_list:
449 spr_csv.append(row)
450
451 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
452 spr_dict = {}
453 spr_byname = {}
454 for row in spr_csv:
455 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
456 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
457 idx=int(row['Idx']))
458 spr_dict[int(row['Idx'])] = info
459 spr_byname[row['SPR']] = info
460 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
461 SPR = Enum('SPR', fields)
462 return SPR, spr_dict, spr_byname
463
464 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
465 SPRreduced, _, _ = get_spr_enum(full_file=False)
466
467 XER_bits = {
468 'SO': 32,
469 'OV': 33,
470 'CA': 34,
471 'OV32': 44,
472 'CA32': 45
473 }
474
475 if __name__ == '__main__':
476 # find out what the heck is in SPR enum :)
477 print("sprs full", len(SPRfull))
478 print(dir(SPRfull))
479 print("sprs reduced", len(SPRreduced))
480 print(dir(SPRreduced))
481 print(dir(Enum))
482 print(SPRfull.__members__['TAR'])
483 for x in SPRfull:
484 print("full", x, x.value, str(x), x.name)
485 for x in SPRreduced:
486 print("reduced", x, x.value, str(x), x.name)
487
488 print("function", Function.ALU.name)