add forgotten PO (primary opcode) field to DecodeFields
[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 def find_wiki_file(name):
28 filedir = os.path.dirname(os.path.abspath(__file__))
29 basedir = dirname(dirname(dirname(filedir)))
30 tabledir = join(basedir, 'libreriscv')
31 tabledir = join(tabledir, 'openpower')
32 tabledir = join(tabledir, 'isatables')
33
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 @unique
67 class Function(Enum):
68 NONE = 0
69 ALU = 1 << 1
70 LDST = 1 << 2
71 SHIFT_ROT = 1 << 3
72 LOGICAL = 1 << 4
73 BRANCH = 1 << 5
74 CR = 1 << 6
75 TRAP = 1 << 7
76 MUL = 1 << 8
77 DIV = 1 << 9
78 SPR = 1 << 10
79 MMU = 1 << 11
80 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
81
82
83 @unique
84 class Form(Enum):
85 NONE = 0
86 I = 1
87 B = 2
88 SC = 3
89 D = 4
90 DS = 5
91 DQ = 6
92 DX = 7
93 X = 8
94 XL = 9
95 XFX = 10
96 XFL = 11
97 XX1 = 12
98 XX2 = 13
99 XX3 = 14
100 XX4 = 15
101 XS = 16
102 XO = 17
103 A = 18
104 M = 19
105 MD = 20
106 MDS = 21
107 VA = 22
108 VC = 23
109 VX = 24
110 EVX = 25
111 EVS = 26
112 Z22 = 27
113 Z23 = 28
114 SVL = 29 # Simple-V for setvl instruction
115
116 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
117
118 @unique
119 class SVPtype(Enum):
120 NONE = 0
121 P1 = 1
122 P2 = 2
123
124 @unique
125 class SVEtype(Enum):
126 NONE = 0
127 EXTRA2 = 1
128 EXTRA3 = 2
129
130 @unique
131 class SVEXTRA(Enum):
132 NONE = 0
133 Idx0 = 1
134 Idx1 = 2
135 Idx2 = 3
136 Idx3 = 4
137 Idx_1_2 = 5 # due to weird BA/BB for crops
138
139 @unique
140 class SVP64PredMode(Enum):
141 ALWAYS = 0
142 INT = 1
143 CR = 2
144
145 @unique
146 class SVP64PredInt(Enum):
147 ALWAYS = 0
148 R3_UNARY = 1
149 R3 = 2
150 R3_N = 3
151 R10 = 4
152 R10_N = 5
153 R30 = 6
154 R30_N = 7
155
156 @unique
157 class SVP64PredCR(Enum):
158 LT = 0
159 GE = 1
160 GT = 2
161 LE = 3
162 EQ = 4
163 NE = 5
164 SO = 6
165 NS = 7
166
167 @unique
168 class SVP64RMMode(Enum):
169 NORMAL = 0
170 MAPREDUCE = 1
171 FFIRST = 2
172 SATURATE = 3
173 PREDRES = 4
174
175 @unique
176 class SVP64width(Enum):
177 DEFAULT = 0
178 EW_32 = 1
179 EW_16 = 2
180 EW_8 = 3
181
182 @unique
183 class SVP64subvl(Enum):
184 VEC1 = 0
185 VEC2 = 1
186 VEC3 = 2
187 VEC4 = 3
188
189 @unique
190 class SVP64sat(Enum):
191 NONE = 0
192 SIGNED = 1
193 UNSIGNED = 2
194
195
196 # supported instructions: make sure to keep up-to-date with CSV files
197 # just like everything else
198 _insns = [
199 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
200 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
201 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
202 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
203 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
204 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
205 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
206 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
207 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
208 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
209 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
210 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
211 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
212 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
213 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
214 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
215 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
216 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
217 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
218 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
219 "rlwnm", "setb",
220 "setvl", # https://libre-soc.org/openpower/sv/setvl
221 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
222 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
223 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
224 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
225 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
226 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
227 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
228 ]
229
230 # two-way lookup of instruction-to-index and vice-versa
231 insns = {}
232 asmidx = {}
233 for i, insn in enumerate(_insns):
234 insns[i] = insn
235 asmidx[insn] = i
236
237 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
238 @unique
239 class MicrOp(Enum):
240 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
241 OP_NOP = 1
242 OP_ADD = 2
243 OP_ADDPCIS = 3
244 OP_AND = 4
245 OP_ATTN = 5
246 OP_B = 6
247 OP_BC = 7
248 OP_BCREG = 8
249 OP_BPERM = 9
250 OP_CMP = 10
251 OP_CMPB = 11
252 OP_CMPEQB = 12
253 OP_CMPRB = 13
254 OP_CNTZ = 14
255 OP_CRAND = 15
256 OP_CRANDC = 16
257 OP_CREQV = 17
258 OP_CRNAND = 18
259 OP_CRNOR = 19
260 OP_CROR = 20
261 OP_CRORC = 21
262 OP_CRXOR = 22
263 OP_DARN = 23
264 OP_DCBF = 24
265 OP_DCBST = 25
266 OP_DCBT = 26
267 OP_DCBTST = 27
268 OP_DCBZ = 28
269 OP_DIV = 29
270 OP_DIVE = 30
271 OP_EXTS = 31
272 OP_EXTSWSLI = 32
273 OP_ICBI = 33
274 OP_ICBT = 34
275 OP_ISEL = 35
276 OP_ISYNC = 36
277 OP_LOAD = 37
278 OP_STORE = 38
279 OP_MADDHD = 39
280 OP_MADDHDU = 40
281 OP_MADDLD = 41
282 OP_MCRF = 42
283 OP_MCRXR = 43
284 OP_MCRXRX = 44
285 OP_MFCR = 45
286 OP_MFSPR = 46
287 OP_MOD = 47
288 OP_MTCRF = 48
289 OP_MTSPR = 49
290 OP_MUL_L64 = 50
291 OP_MUL_H64 = 51
292 OP_MUL_H32 = 52
293 OP_OR = 53
294 OP_POPCNT = 54
295 OP_PRTY = 55
296 OP_RLC = 56
297 OP_RLCL = 57
298 OP_RLCR = 58
299 OP_SETB = 59
300 OP_SHL = 60
301 OP_SHR = 61
302 OP_SYNC = 62
303 OP_TRAP = 63
304 OP_XOR = 67
305 OP_SIM_CONFIG = 68
306 OP_CROP = 69
307 OP_RFID = 70
308 OP_MFMSR = 71
309 OP_MTMSRD = 72
310 OP_SC = 73
311 OP_MTMSR = 74
312 OP_TLBIE = 75
313
314
315 @unique
316 class In1Sel(Enum):
317 NONE = 0
318 RA = 1
319 RA_OR_ZERO = 2
320 SPR = 3
321 RS = 4 # for some ALU/Logical operations
322
323
324 @unique
325 class In2Sel(Enum):
326 NONE = 0
327 RB = 1
328 CONST_UI = 2
329 CONST_SI = 3
330 CONST_UI_HI = 4
331 CONST_SI_HI = 5
332 CONST_LI = 6
333 CONST_BD = 7
334 CONST_DS = 8
335 CONST_M1 = 9
336 CONST_SH = 10
337 CONST_SH32 = 11
338 SPR = 12
339 RS = 13 # for shiftrot (M-Form)
340
341
342 @unique
343 class In3Sel(Enum):
344 NONE = 0
345 RS = 1
346 RB = 2 # for shiftrot (M-Form)
347
348
349 @unique
350 class OutSel(Enum):
351 NONE = 0
352 RT = 1
353 RA = 2
354 SPR = 3
355
356
357 @unique
358 class LdstLen(Enum):
359 NONE = 0
360 is1B = 1
361 is2B = 2
362 is4B = 4
363 is8B = 8
364
365
366 @unique
367 class LDSTMode(Enum):
368 NONE = 0
369 update = 1
370 cix = 2
371 cx = 3
372
373
374 @unique
375 class RC(Enum):
376 NONE = 0
377 ONE = 1
378 RC = 2
379
380
381 @unique
382 class CryIn(Enum):
383 ZERO = 0
384 ONE = 1
385 CA = 2
386 # TODO OV = 3
387
388
389 @unique
390 class CRInSel(Enum):
391 NONE = 0
392 CR0 = 1
393 BI = 2
394 BFA = 3
395 BA_BB = 4
396 BC = 5
397 WHOLE_REG = 6
398 CR1 = 7
399
400
401 @unique
402 class CROutSel(Enum):
403 NONE = 0
404 CR0 = 1
405 BF = 2
406 BT = 3
407 WHOLE_REG = 4
408 CR1 = 5
409
410
411 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
412 # http://libre-riscv.org/openpower/isatables/sprs.csv
413 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
414
415 spr_csv = get_csv("sprs.csv")
416 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
417 spr_dict = {}
418 spr_byname = {}
419 for row in spr_csv:
420 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
421 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
422 idx=int(row['Idx']))
423 spr_dict[int(row['Idx'])] = info
424 spr_byname[row['SPR']] = info
425 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
426 SPR = Enum('SPR', fields)
427
428
429 XER_bits = {
430 'SO': 32,
431 'OV': 33,
432 'CA': 34,
433 'OV32': 44,
434 'CA32': 45
435 }
436
437 if __name__ == '__main__':
438 # find out what the heck is in SPR enum :)
439 print("sprs", len(SPR))
440 print(dir(SPR))
441 print(dir(Enum))
442 print(SPR.__members__['TAR'])
443 for x in SPR:
444 print(x, x.value, str(x), x.name)
445
446 print ("function", Function.ALU.name)