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