update submodule, add hrfid
[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", "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", "sld", "slw", "srad", "sradi", "sraw",
120 "srawi", "srd", "srw", "stb", "stbcx", "stbu", "stbux", "stbx", "std",
121 "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", "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
211
212 @unique
213 class In1Sel(Enum):
214 NONE = 0
215 RA = 1
216 RA_OR_ZERO = 2
217 SPR = 3
218 RS = 4 # for some ALU/Logical operations
219
220
221 @unique
222 class In2Sel(Enum):
223 NONE = 0
224 RB = 1
225 CONST_UI = 2
226 CONST_SI = 3
227 CONST_UI_HI = 4
228 CONST_SI_HI = 5
229 CONST_LI = 6
230 CONST_BD = 7
231 CONST_DS = 8
232 CONST_M1 = 9
233 CONST_SH = 10
234 CONST_SH32 = 11
235 SPR = 12
236 RS = 13 # for shiftrot (M-Form)
237
238
239 @unique
240 class In3Sel(Enum):
241 NONE = 0
242 RS = 1
243 RB = 2 # for shiftrot (M-Form)
244
245
246 @unique
247 class OutSel(Enum):
248 NONE = 0
249 RT = 1
250 RA = 2
251 SPR = 3
252
253
254 @unique
255 class LdstLen(Enum):
256 NONE = 0
257 is1B = 1
258 is2B = 2
259 is4B = 4
260 is8B = 8
261
262
263 @unique
264 class LDSTMode(Enum):
265 NONE = 0
266 update = 1
267 cix = 2
268 cx = 3
269
270
271 @unique
272 class RC(Enum):
273 NONE = 0
274 ONE = 1
275 RC = 2
276
277
278 @unique
279 class CryIn(Enum):
280 ZERO = 0
281 ONE = 1
282 CA = 2
283
284
285 @unique
286 class CRInSel(Enum):
287 NONE = 0
288 CR0 = 1
289 BI = 2
290 BFA = 3
291 BA_BB = 4
292 BC = 5
293 WHOLE_REG = 6
294
295
296 @unique
297 class CROutSel(Enum):
298 NONE = 0
299 CR0 = 1
300 BF = 2
301 BT = 3
302 WHOLE_REG = 4
303
304
305 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
306 # http://libre-riscv.org/openpower/isatables/sprs.csv
307 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
308
309 spr_csv = get_csv("sprs.csv")
310 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
311 spr_dict = {}
312 spr_byname = {}
313 for row in spr_csv:
314 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
315 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
316 idx=int(row['Idx']))
317 spr_dict[int(row['Idx'])] = info
318 spr_byname[row['SPR']] = info
319 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
320 SPR = Enum('SPR', fields)
321
322
323 XER_bits = {
324 'SO': 32,
325 'OV': 33,
326 'CA': 34,
327 'OV32': 44,
328 'CA32': 45
329 }
330
331 if __name__ == '__main__':
332 # find out what the heck is in SPR enum :)
333 print("sprs", len(SPR))
334 print(dir(SPR))
335 print(dir(Enum))
336 print(SPR.__members__['TAR'])
337 for x in SPR:
338 print(x, x.value, str(x), x.name)