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