add OP_SETVL to MicrOp in power_enums.py
[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 OP_SETVL = 76
314
315
316 @unique
317 class In1Sel(Enum):
318 NONE = 0
319 RA = 1
320 RA_OR_ZERO = 2
321 SPR = 3
322 RS = 4 # for some ALU/Logical operations
323
324
325 @unique
326 class In2Sel(Enum):
327 NONE = 0
328 RB = 1
329 CONST_UI = 2
330 CONST_SI = 3
331 CONST_UI_HI = 4
332 CONST_SI_HI = 5
333 CONST_LI = 6
334 CONST_BD = 7
335 CONST_DS = 8
336 CONST_M1 = 9
337 CONST_SH = 10
338 CONST_SH32 = 11
339 SPR = 12
340 RS = 13 # for shiftrot (M-Form)
341
342
343 @unique
344 class In3Sel(Enum):
345 NONE = 0
346 RS = 1
347 RB = 2 # for shiftrot (M-Form)
348
349
350 @unique
351 class OutSel(Enum):
352 NONE = 0
353 RT = 1
354 RA = 2
355 SPR = 3
356 RT_OR_ZERO = 4
357
358
359 @unique
360 class LdstLen(Enum):
361 NONE = 0
362 is1B = 1
363 is2B = 2
364 is4B = 4
365 is8B = 8
366
367
368 @unique
369 class LDSTMode(Enum):
370 NONE = 0
371 update = 1
372 cix = 2
373 cx = 3
374
375
376 @unique
377 class RC(Enum):
378 NONE = 0
379 ONE = 1
380 RC = 2
381
382
383 @unique
384 class CryIn(Enum):
385 ZERO = 0
386 ONE = 1
387 CA = 2
388 # TODO OV = 3
389
390
391 @unique
392 class CRInSel(Enum):
393 NONE = 0
394 CR0 = 1
395 BI = 2
396 BFA = 3
397 BA_BB = 4
398 BC = 5
399 WHOLE_REG = 6
400 CR1 = 7
401
402
403 @unique
404 class CROutSel(Enum):
405 NONE = 0
406 CR0 = 1
407 BF = 2
408 BT = 3
409 WHOLE_REG = 4
410 CR1 = 5
411
412
413 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
414 # http://libre-riscv.org/openpower/isatables/sprs.csv
415 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
416
417 spr_csv = get_csv("sprs.csv")
418 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
419 spr_dict = {}
420 spr_byname = {}
421 for row in spr_csv:
422 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
423 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
424 idx=int(row['Idx']))
425 spr_dict[int(row['Idx'])] = info
426 spr_byname[row['SPR']] = info
427 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
428 SPR = Enum('SPR', fields)
429
430
431 XER_bits = {
432 'SO': 32,
433 'OV': 33,
434 'CA': 34,
435 'OV32': 44,
436 'CA32': 45
437 }
438
439 if __name__ == '__main__':
440 # find out what the heck is in SPR enum :)
441 print("sprs", len(SPR))
442 print(dir(SPR))
443 print(dir(Enum))
444 print(SPR.__members__['TAR'])
445 for x in SPR:
446 print(x, x.value, str(x), x.name)
447
448 print ("function", Function.ALU.name)