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