autoformat code
[soc.git] / src / soc / 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
13 from enum import Enum, unique
14 import csv
15 import os
16 from os.path import dirname, join
17 from collections import namedtuple
18
19
20 def find_wiki_dir():
21 filedir = os.path.dirname(os.path.abspath(__file__))
22 basedir = dirname(dirname(dirname(filedir)))
23 tabledir = join(basedir, 'libreriscv')
24 tabledir = join(tabledir, 'openpower')
25 return join(tabledir, 'isatables')
26
27
28 def find_wiki_file(name):
29 filedir = os.path.dirname(os.path.abspath(__file__))
30 basedir = dirname(dirname(dirname(filedir)))
31 tabledir = join(basedir, 'libreriscv')
32 tabledir = join(tabledir, 'openpower')
33 tabledir = join(tabledir, 'isatables')
34
35 return join(find_wiki_dir(), name)
36
37
38 def get_csv(name):
39 file_path = find_wiki_file(name)
40 with open(file_path, 'r') as csvfile:
41 reader = csv.DictReader(csvfile)
42 return list(reader)
43
44
45 # names of the fields in the tables that don't correspond to an enum
46 single_bit_flags = ['inv A', 'inv out',
47 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
48 'sgn', 'lk', 'sgl pipe']
49
50 # default values for fields in the table
51 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
52 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
53 'CR in': 'NONE',
54 'ldst len': 'NONE',
55 'upd': '0',
56 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
57
58
59 def get_signal_name(name):
60 if name[0].isdigit():
61 name = "is_" + name
62 return name.lower().replace(' ', '_')
63
64 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
65 # is to process and guard the operation. they are roughly divided by having
66 # the same register input/output signature (X-Form, etc.)
67
68
69 @unique
70 class Function(Enum):
71 NONE = 0
72 ALU = 1 << 1
73 LDST = 1 << 2
74 SHIFT_ROT = 1 << 3
75 LOGICAL = 1 << 4
76 BRANCH = 1 << 5
77 CR = 1 << 6
78 TRAP = 1 << 7
79 MUL = 1 << 8
80 DIV = 1 << 9
81 SPR = 1 << 10
82 MMU = 1 << 11
83 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
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", "ld", "ldarx", "ldbrx",
223 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
224 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
225 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
226 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
227 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
228 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
229 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
230 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
231 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
232 "rlwnm", "setb",
233 "setvl", # https://libre-soc.org/openpower/sv/setvl
234 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
235 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
236 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
237 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
238 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
239 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
240 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
241 ]
242
243 # two-way lookup of instruction-to-index and vice-versa
244 insns = {}
245 asmidx = {}
246 for i, insn in enumerate(_insns):
247 insns[i] = insn
248 asmidx[insn] = i
249
250 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
251
252
253 @unique
254 class MicrOp(Enum):
255 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
256 OP_NOP = 1
257 OP_ADD = 2
258 OP_ADDPCIS = 3
259 OP_AND = 4
260 OP_ATTN = 5
261 OP_B = 6
262 OP_BC = 7
263 OP_BCREG = 8
264 OP_BPERM = 9
265 OP_CMP = 10
266 OP_CMPB = 11
267 OP_CMPEQB = 12
268 OP_CMPRB = 13
269 OP_CNTZ = 14
270 OP_CRAND = 15
271 OP_CRANDC = 16
272 OP_CREQV = 17
273 OP_CRNAND = 18
274 OP_CRNOR = 19
275 OP_CROR = 20
276 OP_CRORC = 21
277 OP_CRXOR = 22
278 OP_DARN = 23
279 OP_DCBF = 24
280 OP_DCBST = 25
281 OP_DCBT = 26
282 OP_DCBTST = 27
283 OP_DCBZ = 28
284 OP_DIV = 29
285 OP_DIVE = 30
286 OP_EXTS = 31
287 OP_EXTSWSLI = 32
288 OP_ICBI = 33
289 OP_ICBT = 34
290 OP_ISEL = 35
291 OP_ISYNC = 36
292 OP_LOAD = 37
293 OP_STORE = 38
294 OP_MADDHD = 39
295 OP_MADDHDU = 40
296 OP_MADDLD = 41
297 OP_MCRF = 42
298 OP_MCRXR = 43
299 OP_MCRXRX = 44
300 OP_MFCR = 45
301 OP_MFSPR = 46
302 OP_MOD = 47
303 OP_MTCRF = 48
304 OP_MTSPR = 49
305 OP_MUL_L64 = 50
306 OP_MUL_H64 = 51
307 OP_MUL_H32 = 52
308 OP_OR = 53
309 OP_POPCNT = 54
310 OP_PRTY = 55
311 OP_RLC = 56
312 OP_RLCL = 57
313 OP_RLCR = 58
314 OP_SETB = 59
315 OP_SHL = 60
316 OP_SHR = 61
317 OP_SYNC = 62
318 OP_TRAP = 63
319 OP_XOR = 67
320 OP_SIM_CONFIG = 68
321 OP_CROP = 69
322 OP_RFID = 70
323 OP_MFMSR = 71
324 OP_MTMSRD = 72
325 OP_SC = 73
326 OP_MTMSR = 74
327 OP_TLBIE = 75
328 OP_SETVL = 76
329
330
331 @unique
332 class In1Sel(Enum):
333 NONE = 0
334 RA = 1
335 RA_OR_ZERO = 2
336 SPR = 3
337 RS = 4 # for some ALU/Logical operations
338
339
340 @unique
341 class In2Sel(Enum):
342 NONE = 0
343 RB = 1
344 CONST_UI = 2
345 CONST_SI = 3
346 CONST_UI_HI = 4
347 CONST_SI_HI = 5
348 CONST_LI = 6
349 CONST_BD = 7
350 CONST_DS = 8
351 CONST_M1 = 9
352 CONST_SH = 10
353 CONST_SH32 = 11
354 SPR = 12
355 RS = 13 # for shiftrot (M-Form)
356
357
358 @unique
359 class In3Sel(Enum):
360 NONE = 0
361 RS = 1
362 RB = 2 # for shiftrot (M-Form)
363
364
365 @unique
366 class OutSel(Enum):
367 NONE = 0
368 RT = 1
369 RA = 2
370 SPR = 3
371 RT_OR_ZERO = 4
372
373
374 @unique
375 class LdstLen(Enum):
376 NONE = 0
377 is1B = 1
378 is2B = 2
379 is4B = 4
380 is8B = 8
381
382
383 @unique
384 class LDSTMode(Enum):
385 NONE = 0
386 update = 1
387 cix = 2
388 cx = 3
389
390
391 @unique
392 class RC(Enum):
393 NONE = 0
394 ONE = 1
395 RC = 2
396
397
398 @unique
399 class CryIn(Enum):
400 ZERO = 0
401 ONE = 1
402 CA = 2
403 # TODO OV = 3
404
405
406 @unique
407 class CRInSel(Enum):
408 NONE = 0
409 CR0 = 1
410 BI = 2
411 BFA = 3
412 BA_BB = 4
413 BC = 5
414 WHOLE_REG = 6
415 CR1 = 7
416
417
418 @unique
419 class CROutSel(Enum):
420 NONE = 0
421 CR0 = 1
422 BF = 2
423 BT = 3
424 WHOLE_REG = 4
425 CR1 = 5
426
427
428 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
429 # http://libre-riscv.org/openpower/isatables/sprs.csv
430 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
431
432 spr_csv = get_csv("sprs.csv")
433 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
434 spr_dict = {}
435 spr_byname = {}
436 for row in spr_csv:
437 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
438 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
439 idx=int(row['Idx']))
440 spr_dict[int(row['Idx'])] = info
441 spr_byname[row['SPR']] = info
442 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
443 SPR = Enum('SPR', fields)
444
445
446 XER_bits = {
447 'SO': 32,
448 'OV': 33,
449 'CA': 34,
450 'OV32': 44,
451 'CA32': 45
452 }
453
454 if __name__ == '__main__':
455 # find out what the heck is in SPR enum :)
456 print("sprs", len(SPR))
457 print(dir(SPR))
458 print(dir(Enum))
459 print(SPR.__members__['TAR'])
460 for x in SPR:
461 print(x, x.value, str(x), x.name)
462
463 print("function", Function.ALU.name)