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