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