power_enums: addg6s instruction
[openpower-isa.git] / src / openpower / decoder / power_enums.py
1 # SPDX-License: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020, Michael Nolan
4
5 """Enums used in OpenPOWER ISA decoding
6
7 Note: for SV, from v3.1B p12:
8
9 The designated SPR sandbox consists of non-privileged SPRs 704-719 and
10 privileged SPRs 720-735.
11
12 Note: the option exists to select a much shorter list of SPRs, to reduce
13 regfile size in HDL. this is SPRreduced and the supported list is in
14 get_spr_enum
15 """
16
17 from enum import Enum, unique
18 import csv
19 import os
20 from os.path import dirname, join
21 from collections import namedtuple
22
23
24 def find_wiki_dir():
25 filedir = os.path.dirname(os.path.abspath(__file__))
26 basedir = dirname(dirname(dirname(filedir)))
27 tabledir = join(basedir, 'openpower')
28 isatables = join(tabledir, 'isatables')
29 #print ("find_wiki_dir", isatables)
30 return isatables
31
32
33 def find_wiki_file(name):
34 return join(find_wiki_dir(), name)
35
36
37 def get_csv(name):
38 file_path = find_wiki_file(name)
39 with open(file_path, 'r') as csvfile:
40 reader = csv.DictReader(csvfile)
41 return list(reader)
42
43
44 # names of the fields in the tables that don't correspond to an enum
45 single_bit_flags = ['inv A', 'inv out',
46 'cry out', 'BR', 'sgn ext', 'rsrv', '32b',
47 'sgn', 'lk', 'sgl pipe']
48
49 # default values for fields in the table
50 default_values = {'unit': "NONE", 'internal op': "OP_ILLEGAL",
51 'in1': "RA", 'in2': 'NONE', 'in3': 'NONE', 'out': 'NONE',
52 'CR in': 'NONE',
53 'ldst len': 'NONE',
54 'upd': '0',
55 'rc': 'NONE', 'cry in': 'ZERO', 'form': 'NONE'}
56
57
58 def get_signal_name(name):
59 if name[0].isdigit():
60 name = "is_" + name
61 return name.lower().replace(' ', '_')
62
63 # this corresponds to which Function Unit (pipeline-with-Reservation-Stations)
64 # is to process and guard the operation. they are roughly divided by having
65 # the same register input/output signature (X-Form, etc.)
66
67
68 @unique
69 class Function(Enum):
70 NONE = 0
71 ALU = 1 << 1
72 LDST = 1 << 2
73 SHIFT_ROT = 1 << 3
74 LOGICAL = 1 << 4
75 BRANCH = 1 << 5
76 CR = 1 << 6
77 TRAP = 1 << 7
78 MUL = 1 << 8
79 DIV = 1 << 9
80 SPR = 1 << 10
81 MMU = 1 << 11
82 SV = 1 << 12 # Simple-V https://libre-soc.org/openpower/sv
83 VL = 1 << 13 # setvl
84 FPU = 1 << 14 # FPU
85
86
87 @unique
88 class Form(Enum):
89 NONE = 0
90 I = 1
91 B = 2
92 SC = 3
93 D = 4
94 DS = 5
95 DQ = 6
96 DX = 7
97 X = 8
98 XL = 9
99 XFX = 10
100 XFL = 11
101 XX1 = 12
102 XX2 = 13
103 XX3 = 14
104 XX4 = 15
105 XS = 16
106 XO = 17
107 A = 18
108 M = 19
109 MD = 20
110 MDS = 21
111 VA = 22
112 VC = 23
113 VX = 24
114 EVX = 25
115 EVS = 26
116 Z22 = 27
117 Z23 = 28
118 SVL = 29 # Simple-V for setvl instruction
119 SVD = 30 # Simple-V for LD/ST bit-reverse, variant of D-Form
120 SVDS = 31 # Simple-V for LD/ST bit-reverse, variant of DS-Form
121 SVM = 32 # Simple-V SHAPE mode - TEMPORARY TEMPORARY TEMPORARY
122 SVRM = 33 # Simple-V REMAP mode - TEMPORARY TEMPORARY TEMPORARY
123
124 # Simple-V svp64 fields https://libre-soc.org/openpower/sv/svp64/
125
126
127 @unique
128 class SVPtype(Enum):
129 NONE = 0
130 P1 = 1
131 P2 = 2
132
133
134 @unique
135 class SVEtype(Enum):
136 NONE = 0
137 EXTRA2 = 1
138 EXTRA3 = 2
139
140
141 @unique
142 class SVEXTRA(Enum):
143 NONE = 0
144 Idx0 = 1
145 Idx1 = 2
146 Idx2 = 3
147 Idx3 = 4
148 Idx_1_2 = 5 # due to weird BA/BB for crops
149
150
151 @unique
152 class SVP64PredMode(Enum):
153 ALWAYS = 0
154 INT = 1
155 CR = 2
156
157
158 @unique
159 class SVP64PredInt(Enum):
160 ALWAYS = 0
161 R3_UNARY = 1
162 R3 = 2
163 R3_N = 3
164 R10 = 4
165 R10_N = 5
166 R30 = 6
167 R30_N = 7
168
169
170 @unique
171 class SVP64PredCR(Enum):
172 LT = 0
173 GE = 1
174 GT = 2
175 LE = 3
176 EQ = 4
177 NE = 5
178 SO = 6
179 NS = 7
180
181
182 @unique
183 class SVP64RMMode(Enum):
184 NORMAL = 0
185 MAPREDUCE = 1
186 FFIRST = 2
187 SATURATE = 3
188 PREDRES = 4
189
190
191 @unique
192 class SVP64width(Enum):
193 DEFAULT = 0
194 EW_32 = 1
195 EW_16 = 2
196 EW_8 = 3
197
198
199 @unique
200 class SVP64subvl(Enum):
201 VEC1 = 0
202 VEC2 = 1
203 VEC3 = 2
204 VEC4 = 3
205
206
207 @unique
208 class SVP64sat(Enum):
209 NONE = 0
210 SIGNED = 1
211 UNSIGNED = 2
212
213 @unique
214 class SVP64LDSTmode(Enum):
215 NONE = 0
216 INDEXED = 1
217 ELSTRIDE = 2
218 UNITSTRIDE = 3
219 BITREVERSE = 4
220
221
222 # supported instructions: make sure to keep up-to-date with CSV files
223 # just like everything else
224 _insns = [
225 "NONE", "add", "addc", "addco", "adde", "addeo",
226 "addi", "addic", "addic.", "addis",
227 "addme", "addmeo", "addo", "addze", "addzeo",
228 "addg6s",
229 "and", "andc", "andi.", "andis.",
230 "attn",
231 "b", "bc", "bcctr", "bclr", "bctar",
232 "bpermd",
233 "cmp", "cmpb", "cmpeqb", "cmpi", "cmpl", "cmpli", "cmprb",
234 "cntlzd", "cntlzw", "cnttzd", "cnttzw",
235 "crand", "crandc", "creqv",
236 "crnand", "crnor", "cror", "crorc", "crxor",
237 "darn",
238 "dcbf", "dcbst", "dcbt", "dcbtst", "dcbz",
239 "divd", "divde", "divdeo", "divdeu",
240 "divdeuo", "divdo", "divdu", "divduo", "divw", "divwe", "divweo",
241 "divweu", "divweuo", "divwo", "divwu", "divwuo",
242 "eqv",
243 "extsb", "extsh", "extsw", "extswsli",
244 "fadd", "fadds", "fsub", "fsubs", # FP add / sub
245 "fcfids", "fcfidus", "fsqrts", "fres", "frsqrtes", # FP stuff
246 "fdmadds", # DCT FP 3-arg
247 "fmsubs", "fmadds", "fnmsubs", "fnmadds", # FP 3-arg
248 "ffadds", "ffsubs", "ffmuls", "ffdivs", # FFT FP 2-arg
249 "ffmsubs", "ffmadds", "ffnmsubs", "ffnmadds", # FFT FP 3-arg
250 "fmul", "fmuls", "fdiv", "fdivs", # FP mul / div
251 "fmr", "fabs", "fnabs", "fneg", "fcpsgn", # FP move/abs/neg
252 "fsins", "fcoss", # FP SIN/COS
253 "hrfid", "icbi", "icbt", "isel", "isync",
254 "lbarx", "lbz", "lbzu", "lbzux", "lbzx", # load byte
255 "ld", "ldarx", "ldbrx", "ldu", "ldux", "ldx", # load double
256 #"lbzbr", "lbzubr", # load byte SVP64 bit-reversed
257 #"ldbr", "ldubr", # load double SVP64 bit-reversed
258 "lfs", "lfsx", "lfsu", "lfsux", # FP load single
259 "lfd", "lfdx", "lfdu", "lfdux", "lfiwzx", "lfiwax", # FP load double
260 "lha", "lharx", "lhau", "lhaux", "lhax", # load half
261 "lhbrx", "lhz", "lhzu", "lhzux", "lhzx", # more load half
262 #"lhabr", "lhaubr", # load half SVP64 bit-reversed
263 #"lhzbr", "lhzubr", # more load half SVP64 bit-reversed
264 "lwa", "lwarx", "lwaux", "lwax", "lwbrx", # load word
265 "lwz", "lwzcix", "lwzu", "lwzux", "lwzx", # more load word
266 #"lwabr", # load word SVP64 bit-reversed
267 #"lwzbr", "lwzubr", # more load word SVP64 bit-reversed
268 "maddhd", "maddhdu", "maddld", # INT multiply-and-add
269 "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs
270 "mfmsr", "mfspr",
271 "modsd", "modsw", "modud", "moduw",
272 "mtcrf/mtocrf", "mtmsr", "mtmsrd", "mtspr",
273 "mulhd", "mulhdu", "mulhw", "mulhwu", "mulld", "mulldo",
274 "mulli", "mullw", "mullwo",
275 "nand", "neg", "nego",
276 "nop",
277 "nor", "or", "orc", "ori", "oris",
278 "popcntb", "popcntd", "popcntw",
279 "prtyd", "prtyw",
280 "rfid",
281 "rldcl", "rldcr", "rldic", "rldicl", "rldicr", "rldimi",
282 "rlwimi", "rlwinm", "rlwnm",
283 "setb",
284 "setvl", # https://libre-soc.org/openpower/sv/setvl
285 "svremap", # https://libre-soc.org/openpower/sv/remap - TEMPORARY
286 "svshape", # https://libre-soc.org/openpower/sv/remap
287 "svstep", # https://libre-soc.org/openpower/sv/setvl
288 "sim_cfg",
289 "slbia", "sld", "slw", "srad", "sradi",
290 "sraw", "srawi", "srd", "srw",
291 "stb", "stbcix", "stbcx", "stbu", "stbux", "stbx",
292 "std", "stdbrx", "stdcx", "stdu", "stdux", "stdx",
293 "stfs", "stfsx", "stfsu", "stfux", # FP store single
294 "stfd", "stfdx", "stfdu", "stfdux", "stfiwx", # FP store double
295 "sth", "sthbrx", "sthcx", "sthu", "sthux", "sthx",
296 "stw", "stwbrx", "stwcx", "stwu", "stwux", "stwx",
297 "subf", "subfc", "subfco", "subfe", "subfeo", "subfic",
298 "subfme", "subfmeo", "subfo", "subfze", "subfzeo",
299 "sync",
300 "td", "tdi",
301 "tlbie", "tlbiel",
302 "tw", "twi",
303 "xor", "xori", "xoris",
304 ]
305
306 # two-way lookup of instruction-to-index and vice-versa
307 insns = {}
308 asmidx = {}
309 for i, insn in enumerate(_insns):
310 insns[i] = insn
311 asmidx[insn] = i
312
313 # must be long enough to cover all instructions
314 asmlen = len(_insns).bit_length()
315
316 # Internal Operation numbering. Add new opcodes here (FPADD, FPMUL etc.)
317
318
319 @unique
320 class MicrOp(Enum):
321 OP_ILLEGAL = 0 # important that this is zero (see power_decoder.py)
322 OP_NOP = 1
323 OP_ADD = 2
324 OP_ADDPCIS = 3
325 OP_AND = 4
326 OP_ATTN = 5
327 OP_B = 6
328 OP_BC = 7
329 OP_BCREG = 8
330 OP_BPERM = 9
331 OP_CMP = 10
332 OP_CMPB = 11
333 OP_CMPEQB = 12
334 OP_CMPRB = 13
335 OP_CNTZ = 14
336 OP_CRAND = 15
337 OP_CRANDC = 16
338 OP_CREQV = 17
339 OP_CRNAND = 18
340 OP_CRNOR = 19
341 OP_CROR = 20
342 OP_CRORC = 21
343 OP_CRXOR = 22
344 OP_DARN = 23
345 OP_DCBF = 24
346 OP_DCBST = 25
347 OP_DCBT = 26
348 OP_DCBTST = 27
349 OP_DCBZ = 28
350 OP_DIV = 29
351 OP_DIVE = 30
352 OP_EXTS = 31
353 OP_EXTSWSLI = 32
354 OP_ICBI = 33
355 OP_ICBT = 34
356 OP_ISEL = 35
357 OP_ISYNC = 36
358 OP_LOAD = 37
359 OP_STORE = 38
360 OP_MADDHD = 39
361 OP_MADDHDU = 40
362 OP_MADDLD = 41
363 OP_MCRF = 42
364 OP_MCRXR = 43
365 OP_MCRXRX = 44
366 OP_MFCR = 45
367 OP_MFSPR = 46
368 OP_MOD = 47
369 OP_MTCRF = 48
370 OP_MTSPR = 49
371 OP_MUL_L64 = 50
372 OP_MUL_H64 = 51
373 OP_MUL_H32 = 52
374 OP_OR = 53
375 OP_POPCNT = 54
376 OP_PRTY = 55
377 OP_RLC = 56
378 OP_RLCL = 57
379 OP_RLCR = 58
380 OP_SETB = 59
381 OP_SHL = 60
382 OP_SHR = 61
383 OP_SYNC = 62
384 OP_TRAP = 63
385 OP_XOR = 67
386 OP_SIM_CONFIG = 68
387 OP_CROP = 69
388 OP_RFID = 70
389 OP_MFMSR = 71
390 OP_MTMSRD = 72
391 OP_SC = 73
392 OP_MTMSR = 74
393 OP_TLBIE = 75
394 OP_SETVL = 76
395 OP_FPOP = 77 # temporary: replace with actual ops
396 OP_FPOP_I = 78 # temporary: replace with actual ops
397 OP_FP_MADD = 79
398 OP_SVREMAP = 80
399 OP_SVSHAPE = 81
400 OP_SVSTEP = 82
401 OP_ADDG6S = 83
402
403
404 @unique
405 class In1Sel(Enum):
406 NONE = 0
407 RA = 1
408 RA_OR_ZERO = 2
409 SPR = 3
410 RS = 4 # for some ALU/Logical operations
411 FRA = 5
412 FRS = 6
413
414
415 @unique
416 class In2Sel(Enum):
417 NONE = 0
418 RB = 1
419 CONST_UI = 2
420 CONST_SI = 3
421 CONST_UI_HI = 4
422 CONST_SI_HI = 5
423 CONST_LI = 6
424 CONST_BD = 7
425 CONST_DS = 8
426 CONST_M1 = 9
427 CONST_SH = 10
428 CONST_SH32 = 11
429 SPR = 12
430 RS = 13 # for shiftrot (M-Form)
431 FRB = 14
432 CONST_SVD = 15 # for SVD-Form
433 CONST_SVDS = 16 # for SVDS-Form
434
435
436 @unique
437 class In3Sel(Enum):
438 NONE = 0
439 RS = 1
440 RB = 2 # for shiftrot (M-Form)
441 FRS = 3
442 FRC = 4
443 RC = 5 # for SVP64 bit-reverse LD/ST
444
445
446 @unique
447 class OutSel(Enum):
448 NONE = 0
449 RT = 1
450 RA = 2
451 SPR = 3
452 RT_OR_ZERO = 4
453 FRT = 5
454 FRS = 6
455
456
457 @unique
458 class LdstLen(Enum):
459 NONE = 0
460 is1B = 1
461 is2B = 2
462 is4B = 4
463 is8B = 8
464
465
466 @unique
467 class LDSTMode(Enum):
468 NONE = 0
469 update = 1
470 cix = 2
471 cx = 3
472
473
474 @unique
475 class RC(Enum):
476 NONE = 0
477 ONE = 1
478 RC = 2
479
480
481 @unique
482 class CryIn(Enum):
483 ZERO = 0
484 ONE = 1
485 CA = 2
486 # TODO OV = 3
487
488
489 @unique
490 class CRInSel(Enum):
491 NONE = 0
492 CR0 = 1
493 BI = 2
494 BFA = 3
495 BA_BB = 4
496 BC = 5
497 WHOLE_REG = 6
498 CR1 = 7
499
500
501 @unique
502 class CROutSel(Enum):
503 NONE = 0
504 CR0 = 1
505 BF = 2
506 BT = 3
507 WHOLE_REG = 4
508 CR1 = 5
509
510
511 # SPRs - Special-Purpose Registers. See V3.0B Figure 18 p971 and
512 # http://libre-riscv.org/openpower/isatables/sprs.csv
513 # http://bugs.libre-riscv.org/show_bug.cgi?id=261
514
515 def get_spr_enum(full_file):
516 """get_spr_enum - creates an Enum of SPRs, dynamically
517 has the option to reduce the enum to a much shorter list.
518 this saves drastically on the size of the regfile
519 """
520 short_list = {'PIDR', 'DAR', 'PRTBL', 'DSISR', 'SVSRR0', 'SVSTATE',
521 'SVSTATE0', 'SVSTATE1', 'SVSTATE2', 'SVSTATE3',
522 'SPRG0_priv', 'SPRG1_priv', 'SPRG2_priv', 'SPRG3_priv',
523 'SPRG3'
524 }
525 spr_csv = []
526 for row in get_csv("sprs.csv"):
527 if full_file or row['SPR'] in short_list:
528 spr_csv.append(row)
529
530 spr_info = namedtuple('spr_info', 'SPR priv_mtspr priv_mfspr length idx')
531 spr_dict = {}
532 spr_byname = {}
533 for row in spr_csv:
534 info = spr_info(SPR=row['SPR'], priv_mtspr=row['priv_mtspr'],
535 priv_mfspr=row['priv_mfspr'], length=int(row['len']),
536 idx=int(row['Idx']))
537 spr_dict[int(row['Idx'])] = info
538 spr_byname[row['SPR']] = info
539 fields = [(row['SPR'], int(row['Idx'])) for row in spr_csv]
540 SPR = Enum('SPR', fields)
541 return SPR, spr_dict, spr_byname
542
543 SPRfull, spr_dict, spr_byname = get_spr_enum(full_file=True)
544 SPRreduced, _, _ = get_spr_enum(full_file=False)
545
546 XER_bits = {
547 'SO': 32,
548 'OV': 33,
549 'CA': 34,
550 'OV32': 44,
551 'CA32': 45
552 }
553
554 if __name__ == '__main__':
555 # find out what the heck is in SPR enum :)
556 print("sprs full", len(SPRfull))
557 print(dir(SPRfull))
558 print("sprs reduced", len(SPRreduced))
559 print(dir(SPRreduced))
560 print(dir(Enum))
561 print(SPRfull.__members__['TAR'])
562 for x in SPRfull:
563 print("full", x, x.value, str(x), x.name)
564 for x in SPRreduced:
565 print("reduced", x, x.value, str(x), x.name)
566
567 print("function", Function.ALU.name)