4b94527392b8f2d24dceda93c84479eb1a5bb148
[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",
213 "addi", "addic", "addic.", "addis",
214 "addme", "addmeo", "addo", "addze", "addzeo",
215 "and", "andc", "andi.", "andis.",
216 "attn",
217 "b", "bc", "bcctr", "bclr", "bctar",
218 "bpermd",
219 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
220 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
221 "crand", "crandc", "creqv",
222 "crnand", "crnor", "cror", "crorc", "crxor",
223 "darn",
224 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
225 "divd", "divde", "divdeo", "divdeu",
226 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
227 "divweu", "divweuo", "divwo", "divwu", "divwuo",
228 "eqv",
229 "extsb", "extsh", "extsw", "extswsli",
230 "hrfid", "icbi", "icbt", "isel", "isync",
231 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
232 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
233 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
234 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
235 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
236 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
237 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
238 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
239 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
240 "mfmsr", "mfspr",
241 "modsd", "modsw", "modud", "moduw",
242 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
243 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
244 "mulli", "mullw", "mullwo",
245 "nand", "neg", "nego",
246 "nop",
247 "nor", "or", "orc", "ori", "oris",
248 "popcntb", "popcntd", "popcntw",
249 "prtyd", "prtyw",
250 "rfid",
251 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
252 "rlwimi", "rlwinm", "rlwnm",
253 "setb",
254 "setvl", # https://libre-soc.org/openpower/sv/setvl
255 "sim_cfg",
256 "slbia", "sld", "slw", "srad", "sradi",
257 "sraw", "srawi", "srd", "srw",
258 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
259 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
260 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
261 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
262 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
263 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
264 "sync",
265 "td", "tdi",
266 "tlbie", "tlbiel",
267 "tw", "twi",
268 "xor", "xori", "xoris",
269 ]
270
271 # two-way lookup of instruction-to-index and vice-versa
272 insns = {}
273 asmidx = {}
274 for i, insn in enumerate(_insns):
275 insns[i] = insn
276 asmidx[insn] = i
277
278 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
279
280
281 @unique
282 class MicrOp(Enum):
283 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
284 OP_NOP = 1
285 OP_ADD = 2
286 OP_ADDPCIS = 3
287 OP_AND = 4
288 OP_ATTN = 5
289 OP_B = 6
290 OP_BC = 7
291 OP_BCREG = 8
292 OP_BPERM = 9
293 OP_CMP = 10
294 OP_CMPB = 11
295 OP_CMPEQB = 12
296 OP_CMPRB = 13
297 OP_CNTZ = 14
298 OP_CRAND = 15
299 OP_CRANDC = 16
300 OP_CREQV = 17
301 OP_CRNAND = 18
302 OP_CRNOR = 19
303 OP_CROR = 20
304 OP_CRORC = 21
305 OP_CRXOR = 22
306 OP_DARN = 23
307 OP_DCBF = 24
308 OP_DCBST = 25
309 OP_DCBT = 26
310 OP_DCBTST = 27
311 OP_DCBZ = 28
312 OP_DIV = 29
313 OP_DIVE = 30
314 OP_EXTS = 31
315 OP_EXTSWSLI = 32
316 OP_ICBI = 33
317 OP_ICBT = 34
318 OP_ISEL = 35
319 OP_ISYNC = 36
320 OP_LOAD = 37
321 OP_STORE = 38
322 OP_MADDHD = 39
323 OP_MADDHDU = 40
324 OP_MADDLD = 41
325 OP_MCRF = 42
326 OP_MCRXR = 43
327 OP_MCRXRX = 44
328 OP_MFCR = 45
329 OP_MFSPR = 46
330 OP_MOD = 47
331 OP_MTCRF = 48
332 OP_MTSPR = 49
333 OP_MUL_L64 = 50
334 OP_MUL_H64 = 51
335 OP_MUL_H32 = 52
336 OP_OR = 53
337 OP_POPCNT = 54
338 OP_PRTY = 55
339 OP_RLC = 56
340 OP_RLCL = 57
341 OP_RLCR = 58
342 OP_SETB = 59
343 OP_SHL = 60
344 OP_SHR = 61
345 OP_SYNC = 62
346 OP_TRAP = 63
347 OP_XOR = 67
348 OP_SIM_CONFIG = 68
349 OP_CROP = 69
350 OP_RFID = 70
351 OP_MFMSR = 71
352 OP_MTMSRD = 72
353 OP_SC = 73
354 OP_MTMSR = 74
355 OP_TLBIE = 75
356 OP_SETVL = 76
357
358
359 @unique
360 class In1Sel(Enum):
361 NONE = 0
362 RA = 1
363 RA_OR_ZERO = 2
364 SPR = 3
365 RS = 4 # for some ALU/Logical operations
366 FRA = 5
367 FRS = 6
368
369
370 @unique
371 class In2Sel(Enum):
372 NONE = 0
373 RB = 1
374 CONST_UI = 2
375 CONST_SI = 3
376 CONST_UI_HI = 4
377 CONST_SI_HI = 5
378 CONST_LI = 6
379 CONST_BD = 7
380 CONST_DS = 8
381 CONST_M1 = 9
382 CONST_SH = 10
383 CONST_SH32 = 11
384 SPR = 12
385 RS = 13 # for shiftrot (M-Form)
386 FRB = 14
387
388
389 @unique
390 class In3Sel(Enum):
391 NONE = 0
392 RS = 1
393 RB = 2 # for shiftrot (M-Form)
394 FRS = 3
395 FRC = 4
396
397
398 @unique
399 class OutSel(Enum):
400 NONE = 0
401 RT = 1
402 RA = 2
403 SPR = 3
404 RT_OR_ZERO = 4
405 FRT = 5
406
407
408 @unique
409 class LdstLen(Enum):
410 NONE = 0
411 is1B = 1
412 is2B = 2
413 is4B = 4
414 is8B = 8
415
416
417 @unique
418 class LDSTMode(Enum):
419 NONE = 0
420 update = 1
421 cix = 2
422 cx = 3
423
424
425 @unique
426 class RC(Enum):
427 NONE = 0
428 ONE = 1
429 RC = 2
430
431
432 @unique
433 class CryIn(Enum):
434 ZERO = 0
435 ONE = 1
436 CA = 2
437 # TODO OV = 3
438
439
440 @unique
441 class CRInSel(Enum):
442 NONE = 0
443 CR0 = 1
444 BI = 2
445 BFA = 3
446 BA_BB = 4
447 BC = 5
448 WHOLE_REG = 6
449 CR1 = 7
450
451
452 @unique
453 class CROutSel(Enum):
454 NONE = 0
455 CR0 = 1
456 BF = 2
457 BT = 3
458 WHOLE_REG = 4
459 CR1 = 5
460
461
462 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
463 # http://libre-riscv.org/openpower/isatables/sprs.csv
464 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
465
466 def get_spr_enum(full_file):
467 """get_spr_enum - creates an Enum of SPRs, dynamically
468 has the option to reduce the enum to a much shorter list.
469 this saves drastically on the size of the regfile
470 """
471 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
472 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
473 'SPRG3'
474 }
475 spr_csv = []
476 for row in get_csv("sprs.csv"):
477 if full_file or row['SPR'] in short_list:
478 spr_csv.append(row)
479
480 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
481 spr_dict = {}
482 spr_byname = {}
483 for row in spr_csv:
484 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
485 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
486 idx=int(row['Idx']))
487 spr_dict[int(row['Idx'])] = info
488 spr_byname[row['SPR']] = info
489 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
490 SPR = Enum('SPR', fields)
491 return SPR, spr_dict, spr_byname
492
493 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
494 SPRreduced, _, _ = get_spr_enum(full_file=False)
495
496 XER_bits = {
497 'SO': 32,
498 'OV': 33,
499 'CA': 34,
500 'OV32': 44,
501 'CA32': 45
502 }
503
504 if __name__ == '__main__':
505 # find out what the heck is in SPR enum :)
506 print("sprs full", len(SPRfull))
507 print(dir(SPRfull))
508 print("sprs reduced", len(SPRreduced))
509 print(dir(SPRreduced))
510 print(dir(Enum))
511 print(SPRfull.__members__['TAR'])
512 for x in SPRfull:
513 print("full", x, x.value, str(x), x.name)
514 for x in SPRreduced:
515 print("reduced", x, x.value, str(x), x.name)
516
517 print("function", Function.ALU.name)