bf5738997b4b08eae72f732b458e0fd24f73cb6f
[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 FPU = 1 << 14 # FPU
85
86
87 @unique
88 class Form(Enum):
89 NONE = 0
90 I = 1
91 B = 2
92 SC = 3
93 D = 4
94 DS = 5
95 DQ = 6
96 DX = 7
97 X = 8
98 XL = 9
99 XFX = 10
100 XFL = 11
101 XX1 = 12
102 XX2 = 13
103 XX3 = 14
104 XX4 = 15
105 XS = 16
106 XO = 17
107 A = 18
108 M = 19
109 MD = 20
110 MDS = 21
111 VA = 22
112 VC = 23
113 VX = 24
114 EVX = 25
115 EVS = 26
116 Z22 = 27
117 Z23 = 28
118 SVL = 29 # Simple-V for setvl instruction
119 SVD = 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
120 SVDS = 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
121
122 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
123
124
125 @unique
126 class SVPtype(Enum):
127 NONE = 0
128 P1 = 1
129 P2 = 2
130
131
132 @unique
133 class SVEtype(Enum):
134 NONE = 0
135 EXTRA2 = 1
136 EXTRA3 = 2
137
138
139 @unique
140 class SVEXTRA(Enum):
141 NONE = 0
142 Idx0 = 1
143 Idx1 = 2
144 Idx2 = 3
145 Idx3 = 4
146 Idx_1_2 = 5 # due to weird BA/BB for crops
147
148
149 @unique
150 class SVP64PredMode(Enum):
151 ALWAYS = 0
152 INT = 1
153 CR = 2
154
155
156 @unique
157 class SVP64PredInt(Enum):
158 ALWAYS = 0
159 R3_UNARY = 1
160 R3 = 2
161 R3_N = 3
162 R10 = 4
163 R10_N = 5
164 R30 = 6
165 R30_N = 7
166
167
168 @unique
169 class SVP64PredCR(Enum):
170 LT = 0
171 GE = 1
172 GT = 2
173 LE = 3
174 EQ = 4
175 NE = 5
176 SO = 6
177 NS = 7
178
179
180 @unique
181 class SVP64RMMode(Enum):
182 NORMAL = 0
183 MAPREDUCE = 1
184 FFIRST = 2
185 SATURATE = 3
186 PREDRES = 4
187
188
189 @unique
190 class SVP64width(Enum):
191 DEFAULT = 0
192 EW_32 = 1
193 EW_16 = 2
194 EW_8 = 3
195
196
197 @unique
198 class SVP64subvl(Enum):
199 VEC1 = 0
200 VEC2 = 1
201 VEC3 = 2
202 VEC4 = 3
203
204
205 @unique
206 class SVP64sat(Enum):
207 NONE = 0
208 SIGNED = 1
209 UNSIGNED = 2
210
211 @unique
212 class SVP64LDSTmode(Enum):
213 NONE = 0
214 INDEXED = 1
215 ELSTRIDE = 2
216 UNITSTRIDE = 3
217 BITREVERSE = 4
218
219
220 # supported instructions: make sure to keep up-to-date with CSV files
221 # just like everything else
222 _insns = [
223 "NONE", "add", "addc", "addco", "adde", "addeo",
224 "addi", "addic", "addic.", "addis",
225 "addme", "addmeo", "addo", "addze", "addzeo",
226 "and", "andc", "andi.", "andis.",
227 "attn",
228 "b", "bc", "bcctr", "bclr", "bctar",
229 "bpermd",
230 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
231 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
232 "crand", "crandc", "creqv",
233 "crnand", "crnor", "cror", "crorc", "crxor",
234 "darn",
235 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
236 "divd", "divde", "divdeo", "divdeu",
237 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
238 "divweu", "divweuo", "divwo", "divwu", "divwuo",
239 "eqv",
240 "extsb", "extsh", "extsw", "extswsli",
241 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
242 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
243 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
244 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
245 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
246 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
247 "hrfid", "icbi", "icbt", "isel", "isync",
248 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
249 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
250 #"lbzbr", "lbzubr", # load byte SVP64 bit-reversed
251 #"ldbr", "ldubr", # load double SVP64 bit-reversed
252 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
253 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
254 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
255 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
256 #"lhabr", "lhaubr", # load half SVP64 bit-reversed
257 #"lhzbr", "lhzubr", # more load half SVP64 bit-reversed
258 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
259 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
260 #"lwabr", # load word SVP64 bit-reversed
261 #"lwzbr", "lwzubr", # more load word SVP64 bit-reversed
262 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
263 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
264 "mfmsr", "mfspr",
265 "modsd", "modsw", "modud", "moduw",
266 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
267 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
268 "mulli", "mullw", "mullwo",
269 "nand", "neg", "nego",
270 "nop",
271 "nor", "or", "orc", "ori", "oris",
272 "popcntb", "popcntd", "popcntw",
273 "prtyd", "prtyw",
274 "rfid",
275 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
276 "rlwimi", "rlwinm", "rlwnm",
277 "setb",
278 "setvl", # https://libre-soc.org/openpower/sv/setvl
279 "sim_cfg",
280 "slbia", "sld", "slw", "srad", "sradi",
281 "sraw", "srawi", "srd", "srw",
282 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
283 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
284 "stfs", "stfsx", "stfsu", "stfux", # FP store single
285 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
286 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
287 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
288 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
289 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
290 "sync",
291 "td", "tdi",
292 "tlbie", "tlbiel",
293 "tw", "twi",
294 "xor", "xori", "xoris",
295 ]
296
297 # two-way lookup of instruction-to-index and vice-versa
298 insns = {}
299 asmidx = {}
300 for i, insn in enumerate(_insns):
301 insns[i] = insn
302 asmidx[insn] = i
303
304 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
305
306
307 @unique
308 class MicrOp(Enum):
309 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
310 OP_NOP = 1
311 OP_ADD = 2
312 OP_ADDPCIS = 3
313 OP_AND = 4
314 OP_ATTN = 5
315 OP_B = 6
316 OP_BC = 7
317 OP_BCREG = 8
318 OP_BPERM = 9
319 OP_CMP = 10
320 OP_CMPB = 11
321 OP_CMPEQB = 12
322 OP_CMPRB = 13
323 OP_CNTZ = 14
324 OP_CRAND = 15
325 OP_CRANDC = 16
326 OP_CREQV = 17
327 OP_CRNAND = 18
328 OP_CRNOR = 19
329 OP_CROR = 20
330 OP_CRORC = 21
331 OP_CRXOR = 22
332 OP_DARN = 23
333 OP_DCBF = 24
334 OP_DCBST = 25
335 OP_DCBT = 26
336 OP_DCBTST = 27
337 OP_DCBZ = 28
338 OP_DIV = 29
339 OP_DIVE = 30
340 OP_EXTS = 31
341 OP_EXTSWSLI = 32
342 OP_ICBI = 33
343 OP_ICBT = 34
344 OP_ISEL = 35
345 OP_ISYNC = 36
346 OP_LOAD = 37
347 OP_STORE = 38
348 OP_MADDHD = 39
349 OP_MADDHDU = 40
350 OP_MADDLD = 41
351 OP_MCRF = 42
352 OP_MCRXR = 43
353 OP_MCRXRX = 44
354 OP_MFCR = 45
355 OP_MFSPR = 46
356 OP_MOD = 47
357 OP_MTCRF = 48
358 OP_MTSPR = 49
359 OP_MUL_L64 = 50
360 OP_MUL_H64 = 51
361 OP_MUL_H32 = 52
362 OP_OR = 53
363 OP_POPCNT = 54
364 OP_PRTY = 55
365 OP_RLC = 56
366 OP_RLCL = 57
367 OP_RLCR = 58
368 OP_SETB = 59
369 OP_SHL = 60
370 OP_SHR = 61
371 OP_SYNC = 62
372 OP_TRAP = 63
373 OP_XOR = 67
374 OP_SIM_CONFIG = 68
375 OP_CROP = 69
376 OP_RFID = 70
377 OP_MFMSR = 71
378 OP_MTMSRD = 72
379 OP_SC = 73
380 OP_MTMSR = 74
381 OP_TLBIE = 75
382 OP_SETVL = 76
383 OP_FPOP = 77 # temporary: replace with actual ops
384 OP_FPOP_I = 78 # temporary: replace with actual ops
385 OP_FP_MADD = 79
386
387
388 @unique
389 class In1Sel(Enum):
390 NONE = 0
391 RA = 1
392 RA_OR_ZERO = 2
393 SPR = 3
394 RS = 4 # for some ALU/Logical operations
395 FRA = 5
396 FRS = 6
397
398
399 @unique
400 class In2Sel(Enum):
401 NONE = 0
402 RB = 1
403 CONST_UI = 2
404 CONST_SI = 3
405 CONST_UI_HI = 4
406 CONST_SI_HI = 5
407 CONST_LI = 6
408 CONST_BD = 7
409 CONST_DS = 8
410 CONST_M1 = 9
411 CONST_SH = 10
412 CONST_SH32 = 11
413 SPR = 12
414 RS = 13 # for shiftrot (M-Form)
415 FRB = 14
416 CONST_SVD = 15 # for SVD-Form
417 CONST_SVDS = 16 # for SVDS-Form
418
419
420 @unique
421 class In3Sel(Enum):
422 NONE = 0
423 RS = 1
424 RB = 2 # for shiftrot (M-Form)
425 FRS = 3
426 FRC = 4
427 RC = 5 # for SVP64 bit-reverse LD/ST
428
429
430 @unique
431 class OutSel(Enum):
432 NONE = 0
433 RT = 1
434 RA = 2
435 SPR = 3
436 RT_OR_ZERO = 4
437 FRT = 5
438 FRS = 6
439
440
441 @unique
442 class LdstLen(Enum):
443 NONE = 0
444 is1B = 1
445 is2B = 2
446 is4B = 4
447 is8B = 8
448
449
450 @unique
451 class LDSTMode(Enum):
452 NONE = 0
453 update = 1
454 cix = 2
455 cx = 3
456
457
458 @unique
459 class RC(Enum):
460 NONE = 0
461 ONE = 1
462 RC = 2
463
464
465 @unique
466 class CryIn(Enum):
467 ZERO = 0
468 ONE = 1
469 CA = 2
470 # TODO OV = 3
471
472
473 @unique
474 class CRInSel(Enum):
475 NONE = 0
476 CR0 = 1
477 BI = 2
478 BFA = 3
479 BA_BB = 4
480 BC = 5
481 WHOLE_REG = 6
482 CR1 = 7
483
484
485 @unique
486 class CROutSel(Enum):
487 NONE = 0
488 CR0 = 1
489 BF = 2
490 BT = 3
491 WHOLE_REG = 4
492 CR1 = 5
493
494
495 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
496 # http://libre-riscv.org/openpower/isatables/sprs.csv
497 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
498
499 def get_spr_enum(full_file):
500 """get_spr_enum - creates an Enum of SPRs, dynamically
501 has the option to reduce the enum to a much shorter list.
502 this saves drastically on the size of the regfile
503 """
504 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
505 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
506 'SPRG3'
507 }
508 spr_csv = []
509 for row in get_csv("sprs.csv"):
510 if full_file or row['SPR'] in short_list:
511 spr_csv.append(row)
512
513 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
514 spr_dict = {}
515 spr_byname = {}
516 for row in spr_csv:
517 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
518 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
519 idx=int(row['Idx']))
520 spr_dict[int(row['Idx'])] = info
521 spr_byname[row['SPR']] = info
522 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
523 SPR = Enum('SPR', fields)
524 return SPR, spr_dict, spr_byname
525
526 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
527 SPRreduced, _, _ = get_spr_enum(full_file=False)
528
529 XER_bits = {
530 'SO': 32,
531 'OV': 33,
532 'CA': 34,
533 'OV32': 44,
534 'CA32': 45
535 }
536
537 if __name__ == '__main__':
538 # find out what the heck is in SPR enum :)
539 print("sprs full", len(SPRfull))
540 print(dir(SPRfull))
541 print("sprs reduced", len(SPRreduced))
542 print(dir(SPRreduced))
543 print(dir(Enum))
544 print(SPRfull.__members__['TAR'])
545 for x in SPRfull:
546 print("full", x, x.value, str(x), x.name)
547 for x in SPRreduced:
548 print("reduced", x, x.value, str(x), x.name)
549
550 print("function", Function.ALU.name)