map LDST len directly, rather than go through a switch statement
[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
93 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
94 @unique
95 class InternalOp(Enum):
96 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
97 OP_NOP = 1
98 OP_ADD = 2
99 OP_ADDPCIS = 3
100 OP_AND = 4
101 OP_ATTN = 5
102 OP_B = 6
103 OP_BC = 7
104 OP_BCREG = 8
105 OP_BPERM = 9
106 OP_CMP = 10
107 OP_CMPB = 11
108 OP_CMPEQB = 12
109 OP_CMPRB = 13
110 OP_CNTZ = 14
111 OP_CRAND = 15
112 OP_CRANDC = 16
113 OP_CREQV = 17
114 OP_CRNAND = 18
115 OP_CRNOR = 19
116 OP_CROR = 20
117 OP_CRORC = 21
118 OP_CRXOR = 22
119 OP_DARN = 23
120 OP_DCBF = 24
121 OP_DCBST = 25
122 OP_DCBT = 26
123 OP_DCBTST = 27
124 OP_DCBZ = 28
125 OP_DIV = 29
126 OP_DIVE = 30
127 OP_EXTS = 31
128 OP_EXTSWSLI = 32
129 OP_ICBI = 33
130 OP_ICBT = 34
131 OP_ISEL = 35
132 OP_ISYNC = 36
133 OP_LOAD = 37
134 OP_STORE = 38
135 OP_MADDHD = 39
136 OP_MADDHDU = 40
137 OP_MADDLD = 41
138 OP_MCRF = 42
139 OP_MCRXR = 43
140 OP_MCRXRX = 44
141 OP_MFCR = 45
142 OP_MFSPR = 46
143 OP_MOD = 47
144 OP_MTCRF = 48
145 OP_MTSPR = 49
146 OP_MUL_L64 = 50
147 OP_MUL_H64 = 51
148 OP_MUL_H32 = 52
149 OP_OR = 53
150 OP_POPCNT = 54
151 OP_PRTY = 55
152 OP_RLC = 56
153 OP_RLCL = 57
154 OP_RLCR = 58
155 OP_SETB = 59
156 OP_SHL = 60
157 OP_SHR = 61
158 OP_SYNC = 62
159 OP_TRAP = 63
160 OP_XOR = 67
161 OP_SIM_CONFIG = 68
162 OP_CROP = 69
163 OP_RFID = 70
164 OP_MFMSR = 71
165 OP_MTMSRD = 72
166
167
168 @unique
169 class In1Sel(Enum):
170 NONE = 0
171 RA = 1
172 RA_OR_ZERO = 2
173 SPR = 3
174 RS = 4 # for some ALU/Logical operations
175
176
177 @unique
178 class In2Sel(Enum):
179 NONE = 0
180 RB = 1
181 CONST_UI = 2
182 CONST_SI = 3
183 CONST_UI_HI = 4
184 CONST_SI_HI = 5
185 CONST_LI = 6
186 CONST_BD = 7
187 CONST_DS = 8
188 CONST_M1 = 9
189 CONST_SH = 10
190 CONST_SH32 = 11
191 SPR = 12
192 RS = 13 # for shiftrot (M-Form)
193
194
195 @unique
196 class In3Sel(Enum):
197 NONE = 0
198 RS = 1
199 RB = 2 # for shiftrot (M-Form)
200
201
202 @unique
203 class OutSel(Enum):
204 NONE = 0
205 RT = 1
206 RA = 2
207 SPR = 3
208
209
210 @unique
211 class LdstLen(Enum):
212 NONE = 0
213 is1B = 1
214 is2B = 2
215 is4B = 4
216 is8B = 8
217
218
219 @unique
220 class RC(Enum):
221 NONE = 0
222 ONE = 1
223 RC = 2
224
225
226 @unique
227 class CryIn(Enum):
228 ZERO = 0
229 ONE = 1
230 CA = 2
231
232 @unique
233 class CRInSel(Enum):
234 NONE = 0
235 CR0 = 1
236 BI = 2
237 BFA = 3
238 BA_BB = 4
239 BC = 5
240 WHOLE_REG = 6
241
242 @unique
243 class CROutSel(Enum):
244 NONE = 0
245 CR0 = 1
246 BF = 2
247 BT = 3
248 WHOLE_REG = 4
249
250
251 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
252 # http://libre-riscv.org/openpower/isatables/sprs.csv
253 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
254
255 spr_csv = get_csv("sprs.csv")
256 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length')
257 spr_dict = {}
258 for row in spr_csv:
259 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
260 priv_mfspr=row['priv_mfspr'], length=int(row['len']))
261 spr_dict[int(row['Idx'])] = info
262 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
263 SPR = Enum('SPR', fields)
264
265
266 XER_bits = {
267 'SO': 32,
268 'OV': 33,
269 'CA': 34,
270 'OV32': 44,
271 'CA32': 45
272 }
273
274 if __name__ == '__main__':
275 # find out what the heck is in SPR enum :)
276 print ("sprs", len(SPR))
277 print (dir(SPR))
278 print (dir(Enum))
279 print (SPR.__members__['TAR'])
280 for x in SPR:
281 print (x, x.value, str(x), x.name)