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