add cache cx to LDSTMode
[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 MicrOp(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 cx = 3
267
268
269 @unique
270 class RC(Enum):
271 NONE = 0
272 ONE = 1
273 RC = 2
274
275
276 @unique
277 class CryIn(Enum):
278 ZERO = 0
279 ONE = 1
280 CA = 2
281
282 @unique
283 class CRInSel(Enum):
284 NONE = 0
285 CR0 = 1
286 BI = 2
287 BFA = 3
288 BA_BB = 4
289 BC = 5
290 WHOLE_REG = 6
291
292 @unique
293 class CROutSel(Enum):
294 NONE = 0
295 CR0 = 1
296 BF = 2
297 BT = 3
298 WHOLE_REG = 4
299
300
301 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
302 # http://libre-riscv.org/openpower/isatables/sprs.csv
303 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
304
305 spr_csv = get_csv("sprs.csv")
306 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
307 spr_dict = {}
308 spr_byname = {}
309 for row in spr_csv:
310 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
311 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
312 idx=int(row['Idx']))
313 spr_dict[int(row['Idx'])] = info
314 spr_byname[row['SPR']] = info
315 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
316 SPR = Enum('SPR', fields)
317
318
319 XER_bits = {
320 'SO': 32,
321 'OV': 33,
322 'CA': 34,
323 'OV32': 44,
324 'CA32': 45
325 }
326
327 if __name__ == '__main__':
328 # find out what the heck is in SPR enum :)
329 print ("sprs", len(SPR))
330 print (dir(SPR))
331 print (dir(Enum))
332 print (SPR.__members__['TAR'])
333 for x in SPR:
334 print (x, x.value, str(x), x.name)