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