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