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