start adding 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 from enum import Enum, unique
6 import csv
7 import os
8 from os.path import dirname, join
9 from collections import namedtuple
10
11
12 def find_wiki_dir():
13 filedir = os.path.dirname(os.path.abspath(__file__))
14 basedir = dirname(dirname(dirname(filedir)))
15 tabledir = join(basedir, 'libreriscv')
16 tabledir = join(tabledir, 'openpower')
17 return join(tabledir, 'isatables')
18
19 def find_wiki_file(name):
20 filedir = os.path.dirname(os.path.abspath(__file__))
21 basedir = dirname(dirname(dirname(filedir)))
22 tabledir = join(basedir, 'libreriscv')
23 tabledir = join(tabledir, 'openpower')
24 tabledir = join(tabledir, 'isatables')
25
26 return join(find_wiki_dir(), name)
27
28
29 def get_csv(name):
30 file_path = find_wiki_file(name)
31 with open(file_path, 'r') as csvfile:
32 reader = csv.DictReader(csvfile)
33 return list(reader)
34
35
36 # names of the fields in the tables that don't correspond to an enum
37 single_bit_flags = ['inv A', 'inv out',
38 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
39 'sgn', 'lk', 'sgl pipe']
40
41 # default values for fields in the table
42 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
43 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
44 'CR in': 'NONE',
45 'ldst len': 'NONE',
46 'upd': '0',
47 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
48
49
50 def get_signal_name(name):
51 if name[0].isdigit():
52 name = "is_" + name
53 return name.lower().replace(' ', '_')
54
55 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
56 # is to process and guard the operation. they are roughly divided by having
57 # the same register input/output signature (X-Form, etc.)
58 @unique
59 class Function(Enum):
60 NONE = 0
61 ALU = 1 << 1
62 LDST = 1 << 2
63 SHIFT_ROT = 1 << 3
64 LOGICAL = 1 << 4
65 BRANCH = 1 << 5
66 CR = 1 << 6
67 TRAP = 1 << 7
68 MUL = 1 << 8
69 DIV = 1 << 9
70 SPR = 1 << 10
71 MMU = 1 << 11
72 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
73
74
75 @unique
76 class Form(Enum):
77 NONE = 0
78 I = 1
79 B = 2
80 SC = 3
81 D = 4
82 DS = 5
83 DQ = 6
84 DX = 7
85 X = 8
86 XL = 9
87 XFX = 10
88 XFL = 11
89 XX1 = 12
90 XX2 = 13
91 XX3 = 14
92 XX4 = 15
93 XS = 16
94 XO = 17
95 A = 18
96 M = 19
97 MD = 20
98 MDS = 21
99 VA = 22
100 VC = 23
101 VX = 24
102 EVX = 25
103 EVS = 26
104 Z22 = 27
105 Z23 = 28
106
107 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
108
109 @unique
110 class SVPtype(Enum):
111 NONE = 0
112 P1 = 1
113 P2 = 2
114
115 @unique
116 class SVEtype(Enum):
117 NONE = 0
118 EXTRA2 = 1
119 EXTRA3 = 2
120
121 # supported instructions: make sure to keep up-to-date with CSV files
122 # just like everything else
123 _insns = [
124 "NONE", "add", "addc", "addco", "adde", "addeo", "addi", "addic", "addic.",
125 "addis", "addme", "addmeo", "addo", "addze", "addzeo", "and", "andc",
126 "andi.", "andis.", "attn", "b", "bc", "bcctr", "bclr", "bctar",
127 "bpermd", "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
128 "cntlzd", "cntlzw", "cnttzd", "cnttzw", "crand", "crandc", "creqv",
129 "crnand", "crnor", "cror", "crorc", "crxor", "darn", "dcbf", "dcbst",
130 "dcbt", "dcbtst", "dcbz", "divd", "divde", "divdeo", "divdeu",
131 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
132 "divweu", "divweuo", "divwo", "divwu", "divwuo", "eqv", "extsb",
133 "extsh", "extsw", "extswsli", "hrfid", "icbi", "icbt", "isel", "isync",
134 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", "ld", "ldarx", "ldbrx",
135 "ldu", "ldux", "ldx", "lha", "lharx", "lhau", "lhaux", "lhax",
136 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", "lwa", "lwarx", "lwaux",
137 "lwax", "lwbrx", "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", "mcrf", "mcrxr",
138 "mcrxrx", "mfcr/mfocrf", "mfmsr", "mfspr", "modsd", "modsw", "modud",
139 "moduw", "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr", "mulhd", "mulhdu",
140 "mulhw", "mulhwu", "mulld", "mulldo", "mulli", "mullw", "mullwo",
141 "nand", "neg", "nego", "nop", "nor", "or", "orc", "ori", "oris",
142 "popcntb", "popcntd", "popcntw", "prtyd", "prtyw", "rfid", "rldcl",
143 "rldcr", "rldic", "rldicl", "rldicr", "rldimi", "rlwimi", "rlwinm",
144 "rlwnm", "setb",
145 "setvl", # https://libre-soc.org/openpower/sv/setvl
146 "sim_cfg", "slbia", "sld", "slw", "srad", "sradi", "sraw",
147 "srawi", "srd", "srw", "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
148 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx", "sth", "sthbrx", "sthcx",
149 "sthu", "sthux", "sthx", "stw", "stwbrx", "stwcx", "stwu", "stwux",
150 "stwx", "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
151 "subfme", "subfmeo", "subfo", "subfze", "subfzeo", "sync", "td",
152 "tdi", "tlbie", "tlbiel", "tw", "twi", "xor", "xori", "xoris",
153 ]
154
155 # two-way lookup of instruction-to-index and vice-versa
156 insns = {}
157 asmidx = {}
158 for i, insn in enumerate(_insns):
159 insns[i] = insn
160 asmidx[insn] = i
161
162 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
163 @unique
164 class MicrOp(Enum):
165 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
166 OP_NOP = 1
167 OP_ADD = 2
168 OP_ADDPCIS = 3
169 OP_AND = 4
170 OP_ATTN = 5
171 OP_B = 6
172 OP_BC = 7
173 OP_BCREG = 8
174 OP_BPERM = 9
175 OP_CMP = 10
176 OP_CMPB = 11
177 OP_CMPEQB = 12
178 OP_CMPRB = 13
179 OP_CNTZ = 14
180 OP_CRAND = 15
181 OP_CRANDC = 16
182 OP_CREQV = 17
183 OP_CRNAND = 18
184 OP_CRNOR = 19
185 OP_CROR = 20
186 OP_CRORC = 21
187 OP_CRXOR = 22
188 OP_DARN = 23
189 OP_DCBF = 24
190 OP_DCBST = 25
191 OP_DCBT = 26
192 OP_DCBTST = 27
193 OP_DCBZ = 28
194 OP_DIV = 29
195 OP_DIVE = 30
196 OP_EXTS = 31
197 OP_EXTSWSLI = 32
198 OP_ICBI = 33
199 OP_ICBT = 34
200 OP_ISEL = 35
201 OP_ISYNC = 36
202 OP_LOAD = 37
203 OP_STORE = 38
204 OP_MADDHD = 39
205 OP_MADDHDU = 40
206 OP_MADDLD = 41
207 OP_MCRF = 42
208 OP_MCRXR = 43
209 OP_MCRXRX = 44
210 OP_MFCR = 45
211 OP_MFSPR = 46
212 OP_MOD = 47
213 OP_MTCRF = 48
214 OP_MTSPR = 49
215 OP_MUL_L64 = 50
216 OP_MUL_H64 = 51
217 OP_MUL_H32 = 52
218 OP_OR = 53
219 OP_POPCNT = 54
220 OP_PRTY = 55
221 OP_RLC = 56
222 OP_RLCL = 57
223 OP_RLCR = 58
224 OP_SETB = 59
225 OP_SHL = 60
226 OP_SHR = 61
227 OP_SYNC = 62
228 OP_TRAP = 63
229 OP_XOR = 67
230 OP_SIM_CONFIG = 68
231 OP_CROP = 69
232 OP_RFID = 70
233 OP_MFMSR = 71
234 OP_MTMSRD = 72
235 OP_SC = 73
236 OP_MTMSR = 74
237 OP_TLBIE = 75
238
239
240 @unique
241 class In1Sel(Enum):
242 NONE = 0
243 RA = 1
244 RA_OR_ZERO = 2
245 SPR = 3
246 RS = 4 # for some ALU/Logical operations
247
248
249 @unique
250 class In2Sel(Enum):
251 NONE = 0
252 RB = 1
253 CONST_UI = 2
254 CONST_SI = 3
255 CONST_UI_HI = 4
256 CONST_SI_HI = 5
257 CONST_LI = 6
258 CONST_BD = 7
259 CONST_DS = 8
260 CONST_M1 = 9
261 CONST_SH = 10
262 CONST_SH32 = 11
263 SPR = 12
264 RS = 13 # for shiftrot (M-Form)
265
266
267 @unique
268 class In3Sel(Enum):
269 NONE = 0
270 RS = 1
271 RB = 2 # for shiftrot (M-Form)
272
273
274 @unique
275 class OutSel(Enum):
276 NONE = 0
277 RT = 1
278 RA = 2
279 SPR = 3
280
281
282 @unique
283 class LdstLen(Enum):
284 NONE = 0
285 is1B = 1
286 is2B = 2
287 is4B = 4
288 is8B = 8
289
290
291 @unique
292 class LDSTMode(Enum):
293 NONE = 0
294 update = 1
295 cix = 2
296 cx = 3
297
298
299 @unique
300 class RC(Enum):
301 NONE = 0
302 ONE = 1
303 RC = 2
304
305
306 @unique
307 class CryIn(Enum):
308 ZERO = 0
309 ONE = 1
310 CA = 2
311 # TODO OV = 3
312
313
314 @unique
315 class CRInSel(Enum):
316 NONE = 0
317 CR0 = 1
318 BI = 2
319 BFA = 3
320 BA_BB = 4
321 BC = 5
322 WHOLE_REG = 6
323 CR1 = 7
324
325
326 @unique
327 class CROutSel(Enum):
328 NONE = 0
329 CR0 = 1
330 BF = 2
331 BT = 3
332 WHOLE_REG = 4
333 CR1 = 5
334
335
336 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
337 # http://libre-riscv.org/openpower/isatables/sprs.csv
338 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
339
340 spr_csv = get_csv("sprs.csv")
341 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
342 spr_dict = {}
343 spr_byname = {}
344 for row in spr_csv:
345 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
346 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
347 idx=int(row['Idx']))
348 spr_dict[int(row['Idx'])] = info
349 spr_byname[row['SPR']] = info
350 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
351 SPR = Enum('SPR', fields)
352
353
354 XER_bits = {
355 'SO': 32,
356 'OV': 33,
357 'CA': 34,
358 'OV32': 44,
359 'CA32': 45
360 }
361
362 if __name__ == '__main__':
363 # find out what the heck is in SPR enum :)
364 print("sprs", len(SPR))
365 print(dir(SPR))
366 print(dir(Enum))
367 print(SPR.__members__['TAR'])
368 for x in SPR:
369 print(x, x.value, str(x), x.name)
370
371 print ("function", Function.ALU.name)