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