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