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