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