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