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