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