add SVREMAP SPR
[openpower-isa.git] / src / openpower / decoder / isa / caller.py
1 # SPDX-License-Identifier: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020 Michael Nolan
4 # Funded by NLnet http://nlnet.nl
5 """core of the python-based POWER9 simulator
6
7 this is part of a cycle-accurate POWER9 simulator. its primary purpose is
8 not speed, it is for both learning and educational purposes, as well as
9 a method of verifying the HDL.
10
11 related bugs:
12
13 * https://bugs.libre-soc.org/show_bug.cgi?id=424
14 """
15
16 from nmigen.back.pysim import Settle
17 from functools import wraps
18 from copy import copy
19 from openpower.decoder.orderedset import OrderedSet
20 from openpower.decoder.selectable_int import (FieldSelectableInt, SelectableInt,
21 selectconcat)
22 from openpower.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
23 insns, MicrOp, In1Sel, In2Sel, In3Sel,
24 OutSel, CROutSel, LDSTMode,
25 SVP64RMMode, SVP64PredMode,
26 SVP64PredInt, SVP64PredCR,
27 SVP64LDSTmode)
28
29 from openpower.decoder.power_enums import SVPtype
30
31 from openpower.decoder.helpers import (exts, gtu, ltu, undefined, bitrev)
32 from openpower.consts import PIb, MSRb # big-endian (PowerISA versions)
33 from openpower.consts import SVP64CROffs
34 from openpower.decoder.power_svp64 import SVP64RM, decode_extra
35
36 from openpower.decoder.isa.radixmmu import RADIX
37 from openpower.decoder.isa.mem import Mem, swap_order, MemException
38 from openpower.decoder.isa.svshape import SVSHAPE
39
40 from openpower.util import log
41
42 from collections import namedtuple
43 import math
44 import sys
45
46 instruction_info = namedtuple('instruction_info',
47 'func read_regs uninit_regs write_regs ' +
48 'special_regs op_fields form asmregs')
49
50 special_sprs = {
51 'LR': 8,
52 'CTR': 9,
53 'TAR': 815,
54 'XER': 1,
55 'VRSAVE': 256}
56
57
58 REG_SORT_ORDER = {
59 # TODO (lkcl): adjust other registers that should be in a particular order
60 # probably CA, CA32, and CR
61 "FRT": 0,
62 "FRA": 0,
63 "FRB": 0,
64 "FRC": 0,
65 "FRS": 0,
66 "RT": 0,
67 "RA": 0,
68 "RB": 0,
69 "RC": 0,
70 "RS": 0,
71 "CR": 0,
72 "LR": 0,
73 "CTR": 0,
74 "TAR": 0,
75 "MSR": 0,
76 "SVSTATE": 0,
77 "SVREMAP": 0,
78 "SVSHAPE0": 0,
79 "SVSHAPE1": 0,
80 "SVSHAPE2": 0,
81 "SVSHAPE3": 0,
82
83 "CA": 0,
84 "CA32": 0,
85
86 "overflow": 7, # should definitely be last
87 }
88
89 fregs = ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
90
91
92 def create_args(reglist, extra=None):
93 retval = list(OrderedSet(reglist))
94 retval.sort(key=lambda reg: REG_SORT_ORDER.get(reg, 0))
95 if extra is not None:
96 return [extra] + retval
97 return retval
98
99
100
101 class GPR(dict):
102 def __init__(self, decoder, isacaller, svstate, regfile):
103 dict.__init__(self)
104 self.sd = decoder
105 self.isacaller = isacaller
106 self.svstate = svstate
107 for i in range(len(regfile)):
108 self[i] = SelectableInt(regfile[i], 64)
109
110 def __call__(self, ridx):
111 if isinstance(ridx, SelectableInt):
112 ridx = ridx.value
113 return self[ridx]
114
115 def set_form(self, form):
116 self.form = form
117
118 def __setitem__(self, rnum, value):
119 # rnum = rnum.value # only SelectableInt allowed
120 log("GPR setitem", rnum, value)
121 if isinstance(rnum, SelectableInt):
122 rnum = rnum.value
123 dict.__setitem__(self, rnum, value)
124
125 def getz(self, rnum):
126 # rnum = rnum.value # only SelectableInt allowed
127 log("GPR getzero?", rnum)
128 if rnum == 0:
129 return SelectableInt(0, 64)
130 return self[rnum]
131
132 def _get_regnum(self, attr):
133 getform = self.sd.sigforms[self.form]
134 rnum = getattr(getform, attr)
135 return rnum
136
137 def ___getitem__(self, attr):
138 """ XXX currently not used
139 """
140 rnum = self._get_regnum(attr)
141 log("GPR getitem", attr, rnum)
142 return self.regfile[rnum]
143
144 def dump(self, printout=True):
145 res = []
146 for i in range(len(self)):
147 res.append(self[i].value)
148 if printout:
149 for i in range(0, len(res), 8):
150 s = []
151 for j in range(8):
152 s.append("%08x" % res[i+j])
153 s = ' '.join(s)
154 print("reg", "%2d" % i, s)
155 return res
156
157
158 class SPR(dict):
159 def __init__(self, dec2, initial_sprs={}):
160 self.sd = dec2
161 dict.__init__(self)
162 for key, v in initial_sprs.items():
163 if isinstance(key, SelectableInt):
164 key = key.value
165 key = special_sprs.get(key, key)
166 if isinstance(key, int):
167 info = spr_dict[key]
168 else:
169 info = spr_byname[key]
170 if not isinstance(v, SelectableInt):
171 v = SelectableInt(v, info.length)
172 self[key] = v
173
174 def __getitem__(self, key):
175 log("get spr", key)
176 log("dict", self.items())
177 # if key in special_sprs get the special spr, otherwise return key
178 if isinstance(key, SelectableInt):
179 key = key.value
180 if isinstance(key, int):
181 key = spr_dict[key].SPR
182 key = special_sprs.get(key, key)
183 if key == 'HSRR0': # HACK!
184 key = 'SRR0'
185 if key == 'HSRR1': # HACK!
186 key = 'SRR1'
187 if key in self:
188 res = dict.__getitem__(self, key)
189 else:
190 if isinstance(key, int):
191 info = spr_dict[key]
192 else:
193 info = spr_byname[key]
194 dict.__setitem__(self, key, SelectableInt(0, info.length))
195 res = dict.__getitem__(self, key)
196 log("spr returning", key, res)
197 return res
198
199 def __setitem__(self, key, value):
200 if isinstance(key, SelectableInt):
201 key = key.value
202 if isinstance(key, int):
203 key = spr_dict[key].SPR
204 log("spr key", key)
205 key = special_sprs.get(key, key)
206 if key == 'HSRR0': # HACK!
207 self.__setitem__('SRR0', value)
208 if key == 'HSRR1': # HACK!
209 self.__setitem__('SRR1', value)
210 log("setting spr", key, value)
211 dict.__setitem__(self, key, value)
212
213 def __call__(self, ridx):
214 return self[ridx]
215
216 def dump(self, printout=True):
217 res = []
218 keys = list(self.keys())
219 #keys.sort()
220 for k in keys:
221 sprname = spr_dict.get(k, None)
222 if sprname is None:
223 sprname = k
224 else:
225 sprname = sprname.SPR
226 res.append((sprname, self[k].value))
227 if printout:
228 for sprname, value in res:
229 print(" ", sprname, hex(value))
230 return res
231
232
233 class PC:
234 def __init__(self, pc_init=0):
235 self.CIA = SelectableInt(pc_init, 64)
236 self.NIA = self.CIA + SelectableInt(4, 64) # only true for v3.0B!
237
238 def update_nia(self, is_svp64):
239 increment = 8 if is_svp64 else 4
240 self.NIA = self.CIA + SelectableInt(increment, 64)
241
242 def update(self, namespace, is_svp64):
243 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
244 """
245 self.CIA = namespace['NIA'].narrow(64)
246 self.update_nia(is_svp64)
247 namespace['CIA'] = self.CIA
248 namespace['NIA'] = self.NIA
249
250
251 # Simple-V: see https://libre-soc.org/openpower/sv
252 class SVP64State:
253 def __init__(self, init=0):
254 self.spr = SelectableInt(init, 32)
255 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
256 self.maxvl = FieldSelectableInt(self.spr, tuple(range(0,7)))
257 self.vl = FieldSelectableInt(self.spr, tuple(range(7,14)))
258 self.srcstep = FieldSelectableInt(self.spr, tuple(range(14,21)))
259 self.dststep = FieldSelectableInt(self.spr, tuple(range(21,28)))
260 self.subvl = FieldSelectableInt(self.spr, tuple(range(28,30)))
261 self.svstep = FieldSelectableInt(self.spr, tuple(range(30,32)))
262
263
264 # SVP64 ReMap field
265 class SVP64RMFields:
266 def __init__(self, init=0):
267 self.spr = SelectableInt(init, 24)
268 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
269 self.mmode = FieldSelectableInt(self.spr, [0])
270 self.mask = FieldSelectableInt(self.spr, tuple(range(1,4)))
271 self.elwidth = FieldSelectableInt(self.spr, tuple(range(4,6)))
272 self.ewsrc = FieldSelectableInt(self.spr, tuple(range(6,8)))
273 self.subvl = FieldSelectableInt(self.spr, tuple(range(8,10)))
274 self.extra = FieldSelectableInt(self.spr, tuple(range(10,19)))
275 self.mode = FieldSelectableInt(self.spr, tuple(range(19,24)))
276 # these cover the same extra field, split into parts as EXTRA2
277 self.extra2 = list(range(4))
278 self.extra2[0] = FieldSelectableInt(self.spr, tuple(range(10,12)))
279 self.extra2[1] = FieldSelectableInt(self.spr, tuple(range(12,14)))
280 self.extra2[2] = FieldSelectableInt(self.spr, tuple(range(14,16)))
281 self.extra2[3] = FieldSelectableInt(self.spr, tuple(range(16,18)))
282 self.smask = FieldSelectableInt(self.spr, tuple(range(16,19)))
283 # and here as well, but EXTRA3
284 self.extra3 = list(range(3))
285 self.extra3[0] = FieldSelectableInt(self.spr, tuple(range(10,13)))
286 self.extra3[1] = FieldSelectableInt(self.spr, tuple(range(13,16)))
287 self.extra3[2] = FieldSelectableInt(self.spr, tuple(range(16,19)))
288
289
290 SVP64RM_MMODE_SIZE = len(SVP64RMFields().mmode.br)
291 SVP64RM_MASK_SIZE = len(SVP64RMFields().mask.br)
292 SVP64RM_ELWIDTH_SIZE = len(SVP64RMFields().elwidth.br)
293 SVP64RM_EWSRC_SIZE = len(SVP64RMFields().ewsrc.br)
294 SVP64RM_SUBVL_SIZE = len(SVP64RMFields().subvl.br)
295 SVP64RM_EXTRA2_SPEC_SIZE = len(SVP64RMFields().extra2[0].br)
296 SVP64RM_EXTRA3_SPEC_SIZE = len(SVP64RMFields().extra3[0].br)
297 SVP64RM_SMASK_SIZE = len(SVP64RMFields().smask.br)
298 SVP64RM_MODE_SIZE = len(SVP64RMFields().mode.br)
299
300
301 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
302 class SVP64PrefixFields:
303 def __init__(self):
304 self.insn = SelectableInt(0, 32)
305 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
306 self.major = FieldSelectableInt(self.insn, tuple(range(0,6)))
307 self.pid = FieldSelectableInt(self.insn, (7, 9)) # must be 0b11
308 rmfields = [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
309 self.rm = FieldSelectableInt(self.insn, rmfields)
310
311
312 SV64P_MAJOR_SIZE = len(SVP64PrefixFields().major.br)
313 SV64P_PID_SIZE = len(SVP64PrefixFields().pid.br)
314 SV64P_RM_SIZE = len(SVP64PrefixFields().rm.br)
315
316
317 # CR register fields
318 # See PowerISA Version 3.0 B Book 1
319 # Section 2.3.1 Condition Register pages 30 - 31
320 class CRFields:
321 LT = FL = 0 # negative, less than, floating-point less than
322 GT = FG = 1 # positive, greater than, floating-point greater than
323 EQ = FE = 2 # equal, floating-point equal
324 SO = FU = 3 # summary overflow, floating-point unordered
325
326 def __init__(self, init=0):
327 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
328 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
329 self.cr = SelectableInt(init, 64) # underlying reg
330 # field-selectable versions of Condition Register TODO check bitranges?
331 self.crl = []
332 for i in range(8):
333 bits = tuple(range(i*4+32, (i+1)*4+32))
334 _cr = FieldSelectableInt(self.cr, bits)
335 self.crl.append(_cr)
336
337 # decode SVP64 predicate integer to reg number and invert
338 def get_predint(gpr, mask):
339 r10 = gpr(10)
340 r30 = gpr(30)
341 log ("get_predint", mask, SVP64PredInt.ALWAYS.value)
342 if mask == SVP64PredInt.ALWAYS.value:
343 return 0xffff_ffff_ffff_ffff
344 if mask == SVP64PredInt.R3_UNARY.value:
345 return 1 << (gpr(3).value & 0b111111)
346 if mask == SVP64PredInt.R3.value:
347 return gpr(3).value
348 if mask == SVP64PredInt.R3_N.value:
349 return ~gpr(3).value
350 if mask == SVP64PredInt.R10.value:
351 return gpr(10).value
352 if mask == SVP64PredInt.R10_N.value:
353 return ~gpr(10).value
354 if mask == SVP64PredInt.R30.value:
355 return gpr(30).value
356 if mask == SVP64PredInt.R30_N.value:
357 return ~gpr(30).value
358
359 # decode SVP64 predicate CR to reg number and invert status
360 def _get_predcr(mask):
361 if mask == SVP64PredCR.LT.value:
362 return 0, 1
363 if mask == SVP64PredCR.GE.value:
364 return 0, 0
365 if mask == SVP64PredCR.GT.value:
366 return 1, 1
367 if mask == SVP64PredCR.LE.value:
368 return 1, 0
369 if mask == SVP64PredCR.EQ.value:
370 return 2, 1
371 if mask == SVP64PredCR.NE.value:
372 return 2, 0
373 if mask == SVP64PredCR.SO.value:
374 return 3, 1
375 if mask == SVP64PredCR.NS.value:
376 return 3, 0
377
378 # read individual CR fields (0..VL-1), extract the required bit
379 # and construct the mask
380 def get_predcr(crl, mask, vl):
381 idx, noninv = _get_predcr(mask)
382 mask = 0
383 for i in range(vl):
384 cr = crl[i+SVP64CROffs.CRPred]
385 if cr[idx].value == noninv:
386 mask |= (1<<i)
387 return mask
388
389
390 # TODO, really should just be using PowerDecoder2
391 def get_pdecode_idx_in(dec2, name):
392 op = dec2.dec.op
393 in1_sel = yield op.in1_sel
394 in2_sel = yield op.in2_sel
395 in3_sel = yield op.in3_sel
396 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
397 in1 = yield dec2.e.read_reg1.data
398 in2 = yield dec2.e.read_reg2.data
399 in3 = yield dec2.e.read_reg3.data
400 in1_isvec = yield dec2.in1_isvec
401 in2_isvec = yield dec2.in2_isvec
402 in3_isvec = yield dec2.in3_isvec
403 log ("get_pdecode_idx_in in1", name, in1_sel, In1Sel.RA.value,
404 in1, in1_isvec)
405 log ("get_pdecode_idx_in in2", name, in2_sel, In2Sel.RB.value,
406 in2, in2_isvec)
407 log ("get_pdecode_idx_in in3", name, in3_sel, In3Sel.RS.value,
408 in3, in3_isvec)
409 log ("get_pdecode_idx_in FRS in3", name, in3_sel, In3Sel.FRS.value,
410 in3, in3_isvec)
411 log ("get_pdecode_idx_in FRB in2", name, in2_sel, In2Sel.FRB.value,
412 in2, in2_isvec)
413 log ("get_pdecode_idx_in FRC in3", name, in3_sel, In3Sel.FRC.value,
414 in3, in3_isvec)
415 # identify which regnames map to in1/2/3
416 if name == 'RA':
417 if (in1_sel == In1Sel.RA.value or
418 (in1_sel == In1Sel.RA_OR_ZERO.value and in1 != 0)):
419 return in1, in1_isvec
420 if in1_sel == In1Sel.RA_OR_ZERO.value:
421 return in1, in1_isvec
422 elif name == 'RB':
423 if in2_sel == In2Sel.RB.value:
424 return in2, in2_isvec
425 if in3_sel == In3Sel.RB.value:
426 return in3, in3_isvec
427 # XXX TODO, RC doesn't exist yet!
428 elif name == 'RC':
429 assert False, "RC does not exist yet"
430 elif name == 'RS':
431 if in1_sel == In1Sel.RS.value:
432 return in1, in1_isvec
433 if in2_sel == In2Sel.RS.value:
434 return in2, in2_isvec
435 if in3_sel == In3Sel.RS.value:
436 return in3, in3_isvec
437 elif name == 'FRA':
438 if in1_sel == In1Sel.FRA.value:
439 return in1, in1_isvec
440 elif name == 'FRB':
441 if in2_sel == In2Sel.FRB.value:
442 return in2, in2_isvec
443 elif name == 'FRC':
444 if in3_sel == In3Sel.FRC.value:
445 return in3, in3_isvec
446 elif name == 'FRS':
447 if in1_sel == In1Sel.FRS.value:
448 return in1, in1_isvec
449 if in3_sel == In3Sel.FRS.value:
450 return in3, in3_isvec
451 return None, False
452
453
454 # TODO, really should just be using PowerDecoder2
455 def get_pdecode_cr_out(dec2, name):
456 op = dec2.dec.op
457 out_sel = yield op.cr_out
458 out_bitfield = yield dec2.dec_cr_out.cr_bitfield.data
459 sv_cr_out = yield op.sv_cr_out
460 spec = yield dec2.crout_svdec.spec
461 sv_override = yield dec2.dec_cr_out.sv_override
462 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
463 out = yield dec2.e.write_cr.data
464 o_isvec = yield dec2.o_isvec
465 log ("get_pdecode_cr_out", out_sel, CROutSel.CR0.value, out, o_isvec)
466 log (" sv_cr_out", sv_cr_out)
467 log (" cr_bf", out_bitfield)
468 log (" spec", spec)
469 log (" override", sv_override)
470 # identify which regnames map to out / o2
471 if name == 'CR0':
472 if out_sel == CROutSel.CR0.value:
473 return out, o_isvec
474 log ("get_pdecode_cr_out not found", name)
475 return None, False
476
477
478 # TODO, really should just be using PowerDecoder2
479 def get_pdecode_idx_out(dec2, name):
480 op = dec2.dec.op
481 out_sel = yield op.out_sel
482 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
483 out = yield dec2.e.write_reg.data
484 o_isvec = yield dec2.o_isvec
485 # identify which regnames map to out / o2
486 if name == 'RA':
487 log ("get_pdecode_idx_out", out_sel, OutSel.RA.value, out, o_isvec)
488 if out_sel == OutSel.RA.value:
489 return out, o_isvec
490 elif name == 'RT':
491 log ("get_pdecode_idx_out", out_sel, OutSel.RT.value,
492 OutSel.RT_OR_ZERO.value, out, o_isvec,
493 dec2.dec.RT)
494 if out_sel == OutSel.RT.value:
495 return out, o_isvec
496 elif name == 'FRA':
497 log ("get_pdecode_idx_out", out_sel, OutSel.FRA.value, out, o_isvec)
498 if out_sel == OutSel.FRA.value:
499 return out, o_isvec
500 elif name == 'FRT':
501 log ("get_pdecode_idx_out", out_sel, OutSel.FRT.value,
502 OutSel.FRT.value, out, o_isvec)
503 if out_sel == OutSel.FRT.value:
504 return out, o_isvec
505 log ("get_pdecode_idx_out not found", name, out_sel, out, o_isvec)
506 return None, False
507
508
509 # TODO, really should just be using PowerDecoder2
510 def get_pdecode_idx_out2(dec2, name):
511 # check first if register is activated for write
512 op = dec2.dec.op
513 out_sel = yield op.out_sel
514 out = yield dec2.e.write_ea.data
515 o_isvec = yield dec2.o2_isvec
516 out_ok = yield dec2.e.write_ea.ok
517 log ("get_pdecode_idx_out2", name, out_sel, out, out_ok, o_isvec)
518 if not out_ok:
519 return None, False
520
521 if name == 'RA':
522 if hasattr(op, "upd"):
523 # update mode LD/ST uses read-reg A also as an output
524 upd = yield op.upd
525 log ("get_pdecode_idx_out2", upd, LDSTMode.update.value,
526 out_sel, OutSel.RA.value,
527 out, o_isvec)
528 if upd == LDSTMode.update.value:
529 return out, o_isvec
530 if name == 'FRS':
531 int_op = yield dec2.dec.op.internal_op
532 fft_en = yield dec2.use_svp64_fft
533 #if int_op == MicrOp.OP_FP_MADD.value and fft_en:
534 if fft_en:
535 log ("get_pdecode_idx_out2", out_sel, OutSel.FRS.value,
536 out, o_isvec)
537 return out, o_isvec
538 return None, False
539
540
541 class ISACaller:
542 # decoder2 - an instance of power_decoder2
543 # regfile - a list of initial values for the registers
544 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
545 # respect_pc - tracks the program counter. requires initial_insns
546 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
547 initial_mem=None, initial_msr=0,
548 initial_svstate=0,
549 initial_insns=None,
550 fpregfile=None,
551 respect_pc=False,
552 disassembly=None,
553 initial_pc=0,
554 bigendian=False,
555 mmu=False,
556 icachemmu=False):
557
558 self.bigendian = bigendian
559 self.halted = False
560 self.is_svp64_mode = False
561 self.respect_pc = respect_pc
562 if initial_sprs is None:
563 initial_sprs = {}
564 if initial_mem is None:
565 initial_mem = {}
566 if fpregfile is None:
567 fpregfile = [0] * 32
568 if initial_insns is None:
569 initial_insns = {}
570 assert self.respect_pc == False, "instructions required to honor pc"
571
572 log("ISACaller insns", respect_pc, initial_insns, disassembly)
573 log("ISACaller initial_msr", initial_msr)
574
575 # "fake program counter" mode (for unit testing)
576 self.fake_pc = 0
577 disasm_start = 0
578 if not respect_pc:
579 if isinstance(initial_mem, tuple):
580 self.fake_pc = initial_mem[0]
581 disasm_start = self.fake_pc
582 else:
583 disasm_start = initial_pc
584
585 # disassembly: we need this for now (not given from the decoder)
586 self.disassembly = {}
587 if disassembly:
588 for i, code in enumerate(disassembly):
589 self.disassembly[i*4 + disasm_start] = code
590
591 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
592 self.svp64rm = SVP64RM()
593 if initial_svstate is None:
594 initial_svstate = 0
595 if isinstance(initial_svstate, int):
596 initial_svstate = SVP64State(initial_svstate)
597 # SVSTATE, MSR and PC
598 self.svstate = initial_svstate
599 self.msr = SelectableInt(initial_msr, 64) # underlying reg
600 self.pc = PC()
601 # GPR FPR SPR registers
602 self.gpr = GPR(decoder2, self, self.svstate, regfile)
603 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
604 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
605
606 # set up 4 dummy SVSHAPEs if they aren't already set up
607 for i in range(4):
608 sname = 'SVSHAPE%d' % i
609 if sname not in self.spr:
610 self.spr[sname] = SVSHAPE(0)
611 else:
612 # make sure it's an SVSHAPE
613 val = self.spr[sname].value
614 self.spr[sname] = SVSHAPE(val)
615 self.last_op_svshape = False
616
617 # "raw" memory
618 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
619 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
620 # MMU mode, redirect underlying Mem through RADIX
621 if mmu:
622 self.mem = RADIX(self.mem, self)
623 if icachemmu:
624 self.imem = RADIX(self.imem, self)
625
626 # TODO, needed here:
627 # FPR (same as GPR except for FP nums)
628 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
629 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
630 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
631 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
632 # -- Done
633 # 2.3.2 LR (actually SPR #8) -- Done
634 # 2.3.3 CTR (actually SPR #9) -- Done
635 # 2.3.4 TAR (actually SPR #815)
636 # 3.2.2 p45 XER (actually SPR #1) -- Done
637 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
638
639 # create CR then allow portions of it to be "selectable" (below)
640 self.cr_fields = CRFields(initial_cr)
641 self.cr = self.cr_fields.cr
642
643 # "undefined", just set to variable-bit-width int (use exts "max")
644 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
645
646 self.namespace = {}
647 self.namespace.update(self.spr)
648 self.namespace.update({'GPR': self.gpr,
649 'FPR': self.fpr,
650 'MEM': self.mem,
651 'SPR': self.spr,
652 'memassign': self.memassign,
653 'NIA': self.pc.NIA,
654 'CIA': self.pc.CIA,
655 'SVSTATE': self.svstate.spr,
656 'SVSHAPE0': self.spr['SVSHAPE0'],
657 'SVSHAPE1': self.spr['SVSHAPE1'],
658 'SVSHAPE2': self.spr['SVSHAPE2'],
659 'SVSHAPE3': self.spr['SVSHAPE3'],
660 'CR': self.cr,
661 'MSR': self.msr,
662 'undefined': undefined,
663 'mode_is_64bit': True,
664 'SO': XER_bits['SO']
665 })
666
667 # update pc to requested start point
668 self.set_pc(initial_pc)
669
670 # field-selectable versions of Condition Register
671 self.crl = self.cr_fields.crl
672 for i in range(8):
673 self.namespace["CR%d" % i] = self.crl[i]
674
675 self.decoder = decoder2.dec
676 self.dec2 = decoder2
677
678 def call_trap(self, trap_addr, trap_bit):
679 """calls TRAP and sets up NIA to the new execution location.
680 next instruction will begin at trap_addr.
681 """
682 self.TRAP(trap_addr, trap_bit)
683 self.namespace['NIA'] = self.trap_nia
684 self.pc.update(self.namespace, self.is_svp64_mode)
685
686 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
687 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
688
689 TRAP function is callable from inside the pseudocode itself,
690 hence the default arguments. when calling from inside ISACaller
691 it is best to use call_trap()
692 """
693 log("TRAP:", hex(trap_addr), hex(self.namespace['MSR'].value))
694 # store CIA(+4?) in SRR0, set NIA to 0x700
695 # store MSR in SRR1, set MSR to um errr something, have to check spec
696 # store SVSTATE (if enabled) in SVSRR0
697 self.spr['SRR0'].value = self.pc.CIA.value
698 self.spr['SRR1'].value = self.namespace['MSR'].value
699 if self.is_svp64_mode:
700 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
701 self.trap_nia = SelectableInt(trap_addr, 64)
702 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
703
704 # set exception bits. TODO: this should, based on the address
705 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
706 # bits appropriately. however it turns out that *for now* in all
707 # cases (all trap_addrs) the exact same thing is needed.
708 self.msr[MSRb.IR] = 0
709 self.msr[MSRb.DR] = 0
710 self.msr[MSRb.FE0] = 0
711 self.msr[MSRb.FE1] = 0
712 self.msr[MSRb.EE] = 0
713 self.msr[MSRb.RI] = 0
714 self.msr[MSRb.SF] = 1
715 self.msr[MSRb.TM] = 0
716 self.msr[MSRb.VEC] = 0
717 self.msr[MSRb.VSX] = 0
718 self.msr[MSRb.PR] = 0
719 self.msr[MSRb.FP] = 0
720 self.msr[MSRb.PMM] = 0
721 self.msr[MSRb.TEs] = 0
722 self.msr[MSRb.TEe] = 0
723 self.msr[MSRb.UND] = 0
724 self.msr[MSRb.LE] = 1
725
726 def memassign(self, ea, sz, val):
727 self.mem.memassign(ea, sz, val)
728
729 def prep_namespace(self, formname, op_fields):
730 # TODO: get field names from form in decoder*1* (not decoder2)
731 # decoder2 is hand-created, and decoder1.sigform is auto-generated
732 # from spec
733 # then "yield" fields only from op_fields rather than hard-coded
734 # list, here.
735 fields = self.decoder.sigforms[formname]
736 for name in op_fields:
737 if name == 'spr':
738 sig = getattr(fields, name.upper())
739 else:
740 sig = getattr(fields, name)
741 val = yield sig
742 # these are all opcode fields involved in index-selection of CR,
743 # and need to do "standard" arithmetic. CR[BA+32] for example
744 # would, if using SelectableInt, only be 5-bit.
745 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
746 self.namespace[name] = val
747 else:
748 self.namespace[name] = SelectableInt(val, sig.width)
749
750 self.namespace['XER'] = self.spr['XER']
751 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
752 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
753
754 # add some SVSTATE convenience variables
755 vl = self.svstate.vl.asint(msb0=True)
756 srcstep = self.svstate.srcstep.asint(msb0=True)
757 self.namespace['VL'] = vl
758 self.namespace['srcstep'] = srcstep
759
760 def handle_carry_(self, inputs, outputs, already_done):
761 inv_a = yield self.dec2.e.do.invert_in
762 if inv_a:
763 inputs[0] = ~inputs[0]
764
765 imm_ok = yield self.dec2.e.do.imm_data.ok
766 if imm_ok:
767 imm = yield self.dec2.e.do.imm_data.data
768 inputs.append(SelectableInt(imm, 64))
769 assert len(outputs) >= 1
770 log("outputs", repr(outputs))
771 if isinstance(outputs, list) or isinstance(outputs, tuple):
772 output = outputs[0]
773 else:
774 output = outputs
775 gts = []
776 for x in inputs:
777 log("gt input", x, output)
778 gt = (gtu(x, output))
779 gts.append(gt)
780 log(gts)
781 cy = 1 if any(gts) else 0
782 log("CA", cy, gts)
783 if not (1 & already_done):
784 self.spr['XER'][XER_bits['CA']] = cy
785
786 log("inputs", already_done, inputs)
787 # 32 bit carry
788 # ARGH... different for OP_ADD... *sigh*...
789 op = yield self.dec2.e.do.insn_type
790 if op == MicrOp.OP_ADD.value:
791 res32 = (output.value & (1 << 32)) != 0
792 a32 = (inputs[0].value & (1 << 32)) != 0
793 if len(inputs) >= 2:
794 b32 = (inputs[1].value & (1 << 32)) != 0
795 else:
796 b32 = False
797 cy32 = res32 ^ a32 ^ b32
798 log("CA32 ADD", cy32)
799 else:
800 gts = []
801 for x in inputs:
802 log("input", x, output)
803 log(" x[32:64]", x, x[32:64])
804 log(" o[32:64]", output, output[32:64])
805 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
806 gts.append(gt)
807 cy32 = 1 if any(gts) else 0
808 log("CA32", cy32, gts)
809 if not (2 & already_done):
810 self.spr['XER'][XER_bits['CA32']] = cy32
811
812 def handle_overflow(self, inputs, outputs, div_overflow):
813 if hasattr(self.dec2.e.do, "invert_in"):
814 inv_a = yield self.dec2.e.do.invert_in
815 if inv_a:
816 inputs[0] = ~inputs[0]
817
818 imm_ok = yield self.dec2.e.do.imm_data.ok
819 if imm_ok:
820 imm = yield self.dec2.e.do.imm_data.data
821 inputs.append(SelectableInt(imm, 64))
822 assert len(outputs) >= 1
823 log("handle_overflow", inputs, outputs, div_overflow)
824 if len(inputs) < 2 and div_overflow is None:
825 return
826
827 # div overflow is different: it's returned by the pseudo-code
828 # because it's more complex than can be done by analysing the output
829 if div_overflow is not None:
830 ov, ov32 = div_overflow, div_overflow
831 # arithmetic overflow can be done by analysing the input and output
832 elif len(inputs) >= 2:
833 output = outputs[0]
834
835 # OV (64-bit)
836 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
837 output_sgn = exts(output.value, output.bits) < 0
838 ov = 1 if input_sgn[0] == input_sgn[1] and \
839 output_sgn != input_sgn[0] else 0
840
841 # OV (32-bit)
842 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
843 output32_sgn = exts(output.value, 32) < 0
844 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
845 output32_sgn != input32_sgn[0] else 0
846
847 self.spr['XER'][XER_bits['OV']] = ov
848 self.spr['XER'][XER_bits['OV32']] = ov32
849 so = self.spr['XER'][XER_bits['SO']]
850 so = so | ov
851 self.spr['XER'][XER_bits['SO']] = so
852
853 def handle_comparison(self, outputs, cr_idx=0):
854 out = outputs[0]
855 assert isinstance(out, SelectableInt), \
856 "out zero not a SelectableInt %s" % repr(outputs)
857 log("handle_comparison", out.bits, hex(out.value))
858 # TODO - XXX *processor* in 32-bit mode
859 # https://bugs.libre-soc.org/show_bug.cgi?id=424
860 # if is_32bit:
861 # o32 = exts(out.value, 32)
862 # print ("handle_comparison exts 32 bit", hex(o32))
863 out = exts(out.value, out.bits)
864 log("handle_comparison exts", hex(out))
865 zero = SelectableInt(out == 0, 1)
866 positive = SelectableInt(out > 0, 1)
867 negative = SelectableInt(out < 0, 1)
868 SO = self.spr['XER'][XER_bits['SO']]
869 log("handle_comparison SO", SO)
870 cr_field = selectconcat(negative, positive, zero, SO)
871 self.crl[cr_idx].eq(cr_field)
872
873 def set_pc(self, pc_val):
874 self.namespace['NIA'] = SelectableInt(pc_val, 64)
875 self.pc.update(self.namespace, self.is_svp64_mode)
876
877 def get_next_insn(self):
878 """check instruction
879 """
880 if self.respect_pc:
881 pc = self.pc.CIA.value
882 else:
883 pc = self.fake_pc
884 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
885 if ins is None:
886 raise KeyError("no instruction at 0x%x" % pc)
887 return pc, ins
888
889 def setup_one(self):
890 """set up one instruction
891 """
892 pc, insn = self.get_next_insn()
893 yield from self.setup_next_insn(pc, insn)
894
895 def setup_next_insn(self, pc, ins):
896 """set up next instruction
897 """
898 self._pc = pc
899 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
900 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
901
902 yield self.dec2.sv_rm.eq(0)
903 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
904 yield self.dec2.dec.bigendian.eq(self.bigendian)
905 yield self.dec2.state.msr.eq(self.msr.value)
906 yield self.dec2.state.pc.eq(pc)
907 if self.svstate is not None:
908 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
909
910 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
911 yield Settle()
912 opcode = yield self.dec2.dec.opcode_in
913 pfx = SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
914 pfx.insn.value = opcode
915 major = pfx.major.asint(msb0=True) # MSB0 inversion
916 log ("prefix test: opcode:", major, bin(major),
917 pfx.insn[7] == 0b1, pfx.insn[9] == 0b1)
918 self.is_svp64_mode = ((major == 0b000001) and
919 pfx.insn[7].value == 0b1 and
920 pfx.insn[9].value == 0b1)
921 self.pc.update_nia(self.is_svp64_mode)
922 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode) # set SVP64 decode
923 self.namespace['NIA'] = self.pc.NIA
924 self.namespace['SVSTATE'] = self.svstate.spr
925 if not self.is_svp64_mode:
926 return
927
928 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
929 log ("svp64.rm", bin(pfx.rm.asint(msb0=True)))
930 log (" svstate.vl", self.svstate.vl.asint(msb0=True))
931 log (" svstate.mvl", self.svstate.maxvl.asint(msb0=True))
932 sv_rm = pfx.rm.asint(msb0=True)
933 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
934 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
935 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
936 yield self.dec2.sv_rm.eq(sv_rm) # svp64 prefix
937 yield Settle()
938
939 def execute_one(self):
940 """execute one instruction
941 """
942 # get the disassembly code for this instruction
943 if self.is_svp64_mode:
944 if not self.disassembly:
945 code = yield from self.get_assembly_name()
946 else:
947 code = self.disassembly[self._pc+4]
948 log(" svp64 sim-execute", hex(self._pc), code)
949 else:
950 if not self.disassembly:
951 code = yield from self.get_assembly_name()
952 else:
953 code = self.disassembly[self._pc]
954 log("sim-execute", hex(self._pc), code)
955 opname = code.split(' ')[0]
956 try:
957 yield from self.call(opname) # execute the instruction
958 except MemException as e: # check for memory errors
959 if e.args[0] != 'unaligned': # only doing aligned at the mo
960 raise e # ... re-raise
961 # run a Trap but set DAR first
962 print ("memory unaligned exception, DAR", e.dar)
963 self.spr['DAR'] = SelectableInt(e.dar, 64)
964 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
965 return
966
967 # don't use this except in special circumstances
968 if not self.respect_pc:
969 self.fake_pc += 4
970
971 log("execute one, CIA NIA", self.pc.CIA.value, self.pc.NIA.value)
972
973 def get_assembly_name(self):
974 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
975 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
976 dec_insn = yield self.dec2.e.do.insn
977 insn_1_11 = yield self.dec2.e.do.insn[1:11]
978 asmcode = yield self.dec2.dec.op.asmcode
979 int_op = yield self.dec2.dec.op.internal_op
980 log("get assembly name asmcode", asmcode, int_op,
981 hex(dec_insn), bin(insn_1_11))
982 asmop = insns.get(asmcode, None)
983
984 # sigh reconstruct the assembly instruction name
985 if hasattr(self.dec2.e.do, "oe"):
986 ov_en = yield self.dec2.e.do.oe.oe
987 ov_ok = yield self.dec2.e.do.oe.ok
988 else:
989 ov_en = False
990 ov_ok = False
991 if hasattr(self.dec2.e.do, "rc"):
992 rc_en = yield self.dec2.e.do.rc.rc
993 rc_ok = yield self.dec2.e.do.rc.ok
994 else:
995 rc_en = False
996 rc_ok = False
997 # grrrr have to special-case MUL op (see DecodeOE)
998 log("ov %d en %d rc %d en %d op %d" %
999 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1000 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1001 log("mul op")
1002 if rc_en & rc_ok:
1003 asmop += "."
1004 else:
1005 if not asmop.endswith("."): # don't add "." to "andis."
1006 if rc_en & rc_ok:
1007 asmop += "."
1008 if hasattr(self.dec2.e.do, "lk"):
1009 lk = yield self.dec2.e.do.lk
1010 if lk:
1011 asmop += "l"
1012 log("int_op", int_op)
1013 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1014 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1015 log("AA", AA)
1016 if AA:
1017 asmop += "a"
1018 spr_msb = yield from self.get_spr_msb()
1019 if int_op == MicrOp.OP_MFCR.value:
1020 if spr_msb:
1021 asmop = 'mfocrf'
1022 else:
1023 asmop = 'mfcr'
1024 # XXX TODO: for whatever weird reason this doesn't work
1025 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1026 if int_op == MicrOp.OP_MTCRF.value:
1027 if spr_msb:
1028 asmop = 'mtocrf'
1029 else:
1030 asmop = 'mtcrf'
1031 return asmop
1032
1033 def get_spr_msb(self):
1034 dec_insn = yield self.dec2.e.do.insn
1035 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1036
1037 def call(self, name):
1038 """call(opcode) - the primary execution point for instructions
1039 """
1040 self.last_st_addr = None # reset the last known store address
1041 self.last_ld_addr = None # etc.
1042
1043 name = name.strip() # remove spaces if not already done so
1044 if self.halted:
1045 log("halted - not executing", name)
1046 return
1047
1048 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1049 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1050 asmop = yield from self.get_assembly_name()
1051 log("call", name, asmop)
1052
1053 # check privileged
1054 int_op = yield self.dec2.dec.op.internal_op
1055 spr_msb = yield from self.get_spr_msb()
1056
1057 instr_is_privileged = False
1058 if int_op in [MicrOp.OP_ATTN.value,
1059 MicrOp.OP_MFMSR.value,
1060 MicrOp.OP_MTMSR.value,
1061 MicrOp.OP_MTMSRD.value,
1062 # TODO: OP_TLBIE
1063 MicrOp.OP_RFID.value]:
1064 instr_is_privileged = True
1065 if int_op in [MicrOp.OP_MFSPR.value,
1066 MicrOp.OP_MTSPR.value] and spr_msb:
1067 instr_is_privileged = True
1068
1069 log("is priv", instr_is_privileged, hex(self.msr.value),
1070 self.msr[MSRb.PR])
1071 # check MSR priv bit and whether op is privileged: if so, throw trap
1072 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1073 self.call_trap(0x700, PIb.PRIV)
1074 return
1075
1076 # check halted condition
1077 if name == 'attn':
1078 self.halted = True
1079 return
1080
1081 # check illegal instruction
1082 illegal = False
1083 if name not in ['mtcrf', 'mtocrf']:
1084 illegal = name != asmop
1085
1086 # sigh deal with setvl not being supported by binutils (.long)
1087 if asmop.startswith('setvl'):
1088 illegal = False
1089 name = 'setvl'
1090
1091 # and svshape not being supported by binutils (.long)
1092 if asmop.startswith('svshape'):
1093 illegal = False
1094 name = 'svshape'
1095
1096 # sigh also deal with ffmadds not being supported by binutils (.long)
1097 if asmop == 'ffmadds':
1098 illegal = False
1099 name = 'ffmadds'
1100
1101 # and ffadds not being supported by binutils (.long)
1102 if asmop == 'ffadds':
1103 illegal = False
1104 name = 'ffadds'
1105
1106 if illegal:
1107 print("illegal", name, asmop)
1108 self.call_trap(0x700, PIb.ILLEG)
1109 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1110 (name, asmop, self.pc.CIA.value))
1111 return
1112
1113 # this is for setvl "Vertical" mode: if set true,
1114 # srcstep/dststep is explicitly advanced
1115 self.allow_next_step_inc = False
1116
1117 # nop has to be supported, we could let the actual op calculate
1118 # but PowerDecoder has a pattern for nop
1119 if name is 'nop':
1120 self.update_pc_next()
1121 return
1122
1123 info = self.instrs[name]
1124 yield from self.prep_namespace(info.form, info.op_fields)
1125
1126 # preserve order of register names
1127 input_names = create_args(list(info.read_regs) +
1128 list(info.uninit_regs))
1129 log(input_names)
1130
1131 # get SVP64 entry for the current instruction
1132 sv_rm = self.svp64rm.instrs.get(name)
1133 if sv_rm is not None:
1134 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1135 else:
1136 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1137 log ("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1138
1139 # see if srcstep/dststep need skipping over masked-out predicate bits
1140 if self.is_svp64_mode:
1141 yield from self.svstate_pre_inc()
1142 pre = yield from self.update_new_svstate_steps()
1143 if pre:
1144 self.svp64_reset_loop()
1145 self.update_nia()
1146 self.update_pc_next()
1147 return
1148 srcstep, dststep = self.new_srcstep, self.new_dststep
1149 pred_dst_zero = self.pred_dst_zero
1150 pred_src_zero = self.pred_src_zero
1151 vl = self.svstate.vl.asint(msb0=True)
1152
1153 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1154 if self.is_svp64_mode and vl == 0:
1155 self.pc.update(self.namespace, self.is_svp64_mode)
1156 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1157 self.namespace['NIA'])
1158 return
1159
1160 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1161 # using pre-arranged schedule. all of this is awful but it is a
1162 # start. next job will be to put the proper activation in place
1163 yield self.dec2.remap_active.eq(1 if self.last_op_svshape else 0)
1164 yield Settle()
1165 if self.is_svp64_mode and self.last_op_svshape:
1166 # get four SVSHAPEs. here we are hard-coding
1167 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1168 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1169 SVSHAPE0 = self.spr['SVSHAPE0']
1170 SVSHAPE1 = self.spr['SVSHAPE1']
1171 SVSHAPE2 = self.spr['SVSHAPE2']
1172 SVSHAPE3 = self.spr['SVSHAPE3']
1173 for i in range(4):
1174 sname = 'SVSHAPE%d' % i
1175 shape = self.spr[sname]
1176 print (sname, bin(shape.value))
1177 print (" lims", shape.lims)
1178 print (" mode", shape.mode)
1179 print (" skip", shape.skip)
1180
1181 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1182 (SVSHAPE1, SVSHAPE1.get_iterator()),
1183 (SVSHAPE2, SVSHAPE2.get_iterator()),
1184 (SVSHAPE3, SVSHAPE3.get_iterator()),
1185 ]
1186 rremaps = []
1187 for i, (shape, remap) in enumerate(remaps):
1188 # zero is "disabled"
1189 if shape.value == 0x0:
1190 continue
1191 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1192 if shape.mode == 0b00: # multiply mode
1193 step = dststep if (i == 0) else srcstep
1194 if shape.mode == 0b01: # FFT butterfly mode
1195 step = srcstep # XXX HACK - for now only use srcstep
1196 # this is terrible. O(N^2) looking for the match. but hey.
1197 for idx, remap_idx in enumerate(remap):
1198 if idx == step:
1199 break
1200 # multiply mode
1201 if shape.mode == 0b00:
1202 if i == 0:
1203 yield self.dec2.o_step.eq(remap_idx) # RT
1204 yield self.dec2.o2_step.eq(remap_idx) # EA
1205 elif i == 1:
1206 yield self.dec2.in1_step.eq(remap_idx) # RA
1207 elif i == 2:
1208 yield self.dec2.in3_step.eq(remap_idx) # RB
1209 elif i == 3:
1210 yield self.dec2.in2_step.eq(remap_idx) # RC
1211 # FFT butterfly mode
1212 if shape.mode == 0b01:
1213 if i == 0:
1214 yield self.dec2.o_step.eq(remap_idx) # RT
1215 yield self.dec2.in2_step.eq(remap_idx) # RB
1216 elif i == 1:
1217 yield self.dec2.in1_step.eq(remap_idx) # RA
1218 yield self.dec2.o2_step.eq(remap_idx) # EA (FRS)
1219 elif i == 2:
1220 yield self.dec2.in3_step.eq(remap_idx) # RC
1221 elif i == 3:
1222 pass # no SVSHAPE3
1223 rremaps.append((shape.mode, i, idx, remap_idx)) # debug printing
1224 for x in rremaps:
1225 print ("shape remap", x)
1226 # after that, settle down (combinatorial) to let Vector reg numbers
1227 # work themselves out
1228 yield Settle()
1229 remap_active = yield self.dec2.remap_active
1230 print ("remap active", remap_active)
1231
1232 # main input registers (RT, RA ...)
1233 inputs = []
1234 for name in input_names:
1235 # using PowerDecoder2, first, find the decoder index.
1236 # (mapping name RA RB RC RS to in1, in2, in3)
1237 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1238 if regnum is None:
1239 # doing this is not part of svp64, it's because output
1240 # registers, to be modified, need to be in the namespace.
1241 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1242 if regnum is None:
1243 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2,
1244 name)
1245
1246 # in case getting the register number is needed, _RA, _RB
1247 regname = "_" + name
1248 self.namespace[regname] = regnum
1249 if not self.is_svp64_mode or not pred_src_zero:
1250 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1251 if name in fregs:
1252 reg_val = self.fpr(regnum)
1253 elif name is not None:
1254 reg_val = self.gpr(regnum)
1255 else:
1256 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1257 reg_val = 0
1258 inputs.append(reg_val)
1259 # arrrrgh, awful hack, to get _RT into namespace
1260 if asmop == 'setvl':
1261 regname = "_RT"
1262 RT = yield self.dec2.dec.RT
1263 self.namespace[regname] = SelectableInt(RT, 5)
1264
1265 # in SVP64 mode for LD/ST work out immediate
1266 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1267 # use info.form to detect
1268 replace_d = False # update / replace constant in pseudocode
1269 if self.is_svp64_mode:
1270 ldstmode = yield self.dec2.rm_dec.ldstmode
1271 # bitreverse mode reads SVD (or SVDS - TODO)
1272 # *BUT*... because this is "overloading" of LD operations,
1273 # it gets *STORED* into D (or DS, TODO)
1274 if ldstmode == SVP64LDSTmode.BITREVERSE.value:
1275 imm = yield self.dec2.dec.fields.FormSVD.SVD[0:11]
1276 imm = exts(imm, 11) # sign-extend to integer
1277 print ("bitrev SVD", imm)
1278 replace_d = True
1279 else:
1280 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1281 imm = exts(imm, 16) # sign-extend to integer
1282 # get the right step. LD is from srcstep, ST is dststep
1283 op = yield self.dec2.e.do.insn_type
1284 offsmul = 0
1285 if op == MicrOp.OP_LOAD.value:
1286 offsmul = srcstep
1287 log("D-field src", imm, offsmul)
1288 elif op == MicrOp.OP_STORE.value:
1289 offsmul = dststep
1290 log("D-field dst", imm, offsmul)
1291 # bit-reverse mode
1292 if ldstmode == SVP64LDSTmode.BITREVERSE.value:
1293 # manually look up RC, sigh
1294 RC = yield self.dec2.dec.RC[0:5]
1295 RC = self.gpr(RC)
1296 log ("RC", RC.value, "imm", imm, "offs", bin(offsmul),
1297 "rev", bin(bitrev(offsmul, vl)))
1298 imm = SelectableInt((imm * bitrev(offsmul, vl)) << RC.value, 32)
1299 # Unit-Strided LD/ST adds offset*width to immediate
1300 elif ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1301 ldst_len = yield self.dec2.e.do.data_len
1302 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1303 replace_d = True
1304 # Element-strided multiplies the immediate by element step
1305 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1306 imm = SelectableInt(imm * offsmul, 32)
1307 replace_d = True
1308 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1309 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1310 log("LDSTmode", ldstmode, SVP64LDSTmode.BITREVERSE.value,
1311 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1312 # new replacement D
1313 if replace_d:
1314 self.namespace['D'] = imm
1315
1316 # "special" registers
1317 for special in info.special_regs:
1318 if special in special_sprs:
1319 inputs.append(self.spr[special])
1320 else:
1321 inputs.append(self.namespace[special])
1322
1323 # clear trap (trap) NIA
1324 self.trap_nia = None
1325
1326 # execute actual instruction here (finally)
1327 log("inputs", inputs)
1328 results = info.func(self, *inputs)
1329 log("results", results)
1330
1331 # "inject" decorator takes namespace from function locals: we need to
1332 # overwrite NIA being overwritten (sigh)
1333 if self.trap_nia is not None:
1334 self.namespace['NIA'] = self.trap_nia
1335
1336 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1337
1338 # check if op was a LD/ST so that debugging can check the
1339 # address
1340 if int_op in [MicrOp.OP_STORE.value,
1341 ]:
1342 self.last_st_addr = self.mem.last_st_addr
1343 if int_op in [MicrOp.OP_LOAD.value,
1344 ]:
1345 self.last_ld_addr = self.mem.last_ld_addr
1346 log ("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1347 self.last_st_addr, self.last_ld_addr)
1348
1349 # detect if CA/CA32 already in outputs (sra*, basically)
1350 already_done = 0
1351 if info.write_regs:
1352 output_names = create_args(info.write_regs)
1353 for name in output_names:
1354 if name == 'CA':
1355 already_done |= 1
1356 if name == 'CA32':
1357 already_done |= 2
1358
1359 log("carry already done?", bin(already_done))
1360 if hasattr(self.dec2.e.do, "output_carry"):
1361 carry_en = yield self.dec2.e.do.output_carry
1362 else:
1363 carry_en = False
1364 if carry_en:
1365 yield from self.handle_carry_(inputs, results, already_done)
1366
1367 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1368 # detect if overflow was in return result
1369 overflow = None
1370 if info.write_regs:
1371 for name, output in zip(output_names, results):
1372 if name == 'overflow':
1373 overflow = output
1374
1375 if hasattr(self.dec2.e.do, "oe"):
1376 ov_en = yield self.dec2.e.do.oe.oe
1377 ov_ok = yield self.dec2.e.do.oe.ok
1378 else:
1379 ov_en = False
1380 ov_ok = False
1381 log("internal overflow", overflow, ov_en, ov_ok)
1382 if ov_en & ov_ok:
1383 yield from self.handle_overflow(inputs, results, overflow)
1384
1385 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1386 rc_en = False
1387 if not self.is_svp64_mode or not pred_dst_zero:
1388 if hasattr(self.dec2.e.do, "rc"):
1389 rc_en = yield self.dec2.e.do.rc.rc
1390 if rc_en:
1391 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1392 self.handle_comparison(results, regnum)
1393
1394 # any modified return results?
1395 if info.write_regs:
1396 for name, output in zip(output_names, results):
1397 if name == 'overflow': # ignore, done already (above)
1398 continue
1399 if isinstance(output, int):
1400 output = SelectableInt(output, 256)
1401 if name in ['CA', 'CA32']:
1402 if carry_en:
1403 log("writing %s to XER" % name, output)
1404 self.spr['XER'][XER_bits[name]] = output.value
1405 else:
1406 log("NOT writing %s to XER" % name, output)
1407 elif name in info.special_regs:
1408 log('writing special %s' % name, output, special_sprs)
1409 if name in special_sprs:
1410 self.spr[name] = output
1411 else:
1412 self.namespace[name].eq(output)
1413 if name == 'MSR':
1414 log('msr written', hex(self.msr.value))
1415 else:
1416 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2,
1417 name)
1418 if regnum is None:
1419 regnum, is_vec = yield from get_pdecode_idx_out2(
1420 self.dec2, name)
1421 if regnum is None:
1422 # temporary hack for not having 2nd output
1423 regnum = yield getattr(self.decoder, name)
1424 is_vec = False
1425 if self.is_svp64_mode and pred_dst_zero:
1426 log('zeroing reg %d %s' % (regnum, str(output)),
1427 is_vec)
1428 output = SelectableInt(0, 256)
1429 else:
1430 if name in fregs:
1431 ftype = 'fpr'
1432 else:
1433 ftype = 'gpr'
1434 log('writing %s %s %s' % (regnum, ftype, str(output)),
1435 is_vec)
1436 if output.bits > 64:
1437 output = SelectableInt(output.value, 64)
1438 if name in fregs:
1439 self.fpr[regnum] = output
1440 else:
1441 self.gpr[regnum] = output
1442
1443 # check if it is the SVSTATE.src/dest step that needs incrementing
1444 # this is our Sub-Program-Counter loop from 0 to VL-1
1445 pre = False
1446 post = False
1447 if self.allow_next_step_inc:
1448 log("SVSTATE_NEXT: inc requested")
1449 yield from self.svstate_pre_inc()
1450 pre = yield from self.update_new_svstate_steps()
1451 if pre:
1452 # reset at end of loop including exit Vertical Mode
1453 log ("SVSTATE_NEXT: end of loop, reset")
1454 self.svp64_reset_loop()
1455 self.msr[MSRb.SVF] = 0
1456 self.update_nia()
1457 if rc_en:
1458 results = [SelectableInt(0, 64)]
1459 self.handle_comparison(results) # CR0
1460 else:
1461 log ("SVSTATE_NEXT: post-inc")
1462 srcstep, dststep = self.new_srcstep, self.new_dststep
1463 vl = self.svstate.vl.asint(msb0=True)
1464 end_src = srcstep == vl-1
1465 end_dst = dststep == vl-1
1466 if not end_src:
1467 self.svstate.srcstep += SelectableInt(1, 7)
1468 if not end_dst:
1469 self.svstate.dststep += SelectableInt(1, 7)
1470 self.namespace['SVSTATE'] = self.svstate.spr
1471 # set CR0 (if Rc=1) based on end
1472 if rc_en:
1473 srcstep = self.svstate.srcstep.asint(msb0=True)
1474 dststep = self.svstate.srcstep.asint(msb0=True)
1475 endtest = 0 if (end_src or end_dst) else 1
1476 results = [SelectableInt(endtest, 64)]
1477 self.handle_comparison(results) # CR0
1478 if end_src or end_dst:
1479 # reset at end of loop including exit Vertical Mode
1480 log ("SVSTATE_NEXT: after increments, reset")
1481 self.svp64_reset_loop()
1482 self.msr[MSRb.SVF] = 0
1483
1484 elif self.is_svp64_mode:
1485 yield from self.svstate_post_inc()
1486 else:
1487 # XXX only in non-SVP64 mode!
1488 # record state of whether the current operation was an svshape,
1489 # to be able to know if it should apply in the next instruction.
1490 # also (if going to use this instruction) should disable ability
1491 # to interrupt in between. sigh.
1492 self.last_op_svshape = asmop == 'svshape'
1493
1494 self.update_pc_next()
1495
1496 def SVSTATE_NEXT(self):
1497 """explicitly moves srcstep/dststep on to next element, for
1498 "Vertical-First" mode. this function is called from
1499 setvl pseudo-code, as a pseudo-op "svstep"
1500 """
1501 log("SVSTATE_NEXT")
1502 self.allow_next_step_inc = True
1503
1504 def svstate_pre_inc(self):
1505 """check if srcstep/dststep need to skip over masked-out predicate bits
1506 """
1507 # get SVSTATE VL (oh and print out some debug stuff)
1508 vl = self.svstate.vl.asint(msb0=True)
1509 srcstep = self.svstate.srcstep.asint(msb0=True)
1510 dststep = self.svstate.dststep.asint(msb0=True)
1511 sv_a_nz = yield self.dec2.sv_a_nz
1512 fft_mode = yield self.dec2.use_svp64_fft
1513 in1 = yield self.dec2.e.read_reg1.data
1514 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1515 vl, srcstep, dststep, sv_a_nz, in1, fft_mode)
1516
1517 # get predicate mask
1518 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1519
1520 pmode = yield self.dec2.rm_dec.predmode
1521 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1522 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1523 srcpred = yield self.dec2.rm_dec.srcpred
1524 dstpred = yield self.dec2.rm_dec.dstpred
1525 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1526 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1527 if pmode == SVP64PredMode.INT.value:
1528 srcmask = dstmask = get_predint(self.gpr, dstpred)
1529 if sv_ptype == SVPtype.P2.value:
1530 srcmask = get_predint(self.gpr, srcpred)
1531 elif pmode == SVP64PredMode.CR.value:
1532 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1533 if sv_ptype == SVPtype.P2.value:
1534 srcmask = get_predcr(self.crl, srcpred, vl)
1535 log (" pmode", pmode)
1536 log (" reverse", reverse_gear)
1537 log (" ptype", sv_ptype)
1538 log (" srcpred", bin(srcpred))
1539 log (" dstpred", bin(dstpred))
1540 log (" srcmask", bin(srcmask))
1541 log (" dstmask", bin(dstmask))
1542 log (" pred_sz", bin(pred_src_zero))
1543 log (" pred_dz", bin(pred_dst_zero))
1544
1545 # okaaay, so here we simply advance srcstep (TODO dststep)
1546 # until the predicate mask has a "1" bit... or we run out of VL
1547 # let srcstep==VL be the indicator to move to next instruction
1548 if not pred_src_zero:
1549 while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
1550 log (" skip", bin(1<<srcstep))
1551 srcstep += 1
1552 # same for dststep
1553 if not pred_dst_zero:
1554 while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
1555 log (" skip", bin(1<<dststep))
1556 dststep += 1
1557
1558 # now work out if the relevant mask bits require zeroing
1559 if pred_dst_zero:
1560 pred_dst_zero = ((1<<dststep) & dstmask) == 0
1561 if pred_src_zero:
1562 pred_src_zero = ((1<<srcstep) & srcmask) == 0
1563
1564 # store new srcstep / dststep
1565 self.new_srcstep, self.new_dststep = srcstep, dststep
1566 self.pred_dst_zero, self.pred_src_zero = pred_dst_zero, pred_src_zero
1567 log (" new srcstep", srcstep)
1568 log (" new dststep", dststep)
1569
1570 def update_new_svstate_steps(self):
1571 srcstep, dststep = self.new_srcstep, self.new_dststep
1572
1573 # update SVSTATE with new srcstep
1574 self.svstate.srcstep[0:7] = srcstep
1575 self.svstate.dststep[0:7] = dststep
1576 self.namespace['SVSTATE'] = self.svstate.spr
1577 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
1578 yield Settle() # let decoder update
1579 srcstep = self.svstate.srcstep.asint(msb0=True)
1580 dststep = self.svstate.dststep.asint(msb0=True)
1581 vl = self.svstate.vl.asint(msb0=True)
1582 log (" srcstep", srcstep)
1583 log (" dststep", dststep)
1584
1585 # check if end reached (we let srcstep overrun, above)
1586 # nothing needs doing (TODO zeroing): just do next instruction
1587 return srcstep == vl or dststep == vl
1588
1589 def svstate_post_inc(self, vf=0):
1590 # check if SV "Vertical First" mode is enabled
1591 log (" SV Vertical First", vf, self.msr[MSRb.SVF].value)
1592 if not vf and self.msr[MSRb.SVF].value == 1:
1593 self.update_nia()
1594 return True
1595
1596 # check if it is the SVSTATE.src/dest step that needs incrementing
1597 # this is our Sub-Program-Counter loop from 0 to VL-1
1598 # XXX twin predication TODO
1599 vl = self.svstate.vl.asint(msb0=True)
1600 mvl = self.svstate.maxvl.asint(msb0=True)
1601 srcstep = self.svstate.srcstep.asint(msb0=True)
1602 dststep = self.svstate.dststep.asint(msb0=True)
1603 rm_mode = yield self.dec2.rm_dec.mode
1604 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1605 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1606 out_vec = not (yield self.dec2.no_out_vec)
1607 in_vec = not (yield self.dec2.no_in_vec)
1608 log (" svstate.vl", vl)
1609 log (" svstate.mvl", mvl)
1610 log (" svstate.srcstep", srcstep)
1611 log (" svstate.dststep", dststep)
1612 log (" mode", rm_mode)
1613 log (" reverse", reverse_gear)
1614 log (" out_vec", out_vec)
1615 log (" in_vec", in_vec)
1616 log (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1617 # check if srcstep needs incrementing by one, stop PC advancing
1618 # svp64 loop can end early if the dest is scalar for single-pred
1619 # but for 2-pred both src/dest have to be checked.
1620 # XXX this might not be true! it may just be LD/ST
1621 if sv_ptype == SVPtype.P2.value:
1622 svp64_is_vector = (out_vec or in_vec)
1623 else:
1624 svp64_is_vector = out_vec
1625 if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
1626 self.svstate.srcstep += SelectableInt(1, 7)
1627 self.svstate.dststep += SelectableInt(1, 7)
1628 self.pc.NIA.value = self.pc.CIA.value
1629 self.namespace['NIA'] = self.pc.NIA
1630 self.namespace['SVSTATE'] = self.svstate.spr
1631 log("end of sub-pc call", self.namespace['CIA'],
1632 self.namespace['NIA'])
1633 return False # DO NOT allow PC update whilst Sub-PC loop running
1634
1635 # reset loop to zero and update NIA
1636 self.svp64_reset_loop()
1637 self.update_nia()
1638
1639 return True
1640
1641 def update_pc_next(self):
1642 # UPDATE program counter
1643 self.pc.update(self.namespace, self.is_svp64_mode)
1644 self.svstate.spr = self.namespace['SVSTATE']
1645 log("end of call", self.namespace['CIA'],
1646 self.namespace['NIA'],
1647 self.namespace['SVSTATE'])
1648
1649 def svp64_reset_loop(self):
1650 self.svstate.srcstep[0:7] = 0
1651 self.svstate.dststep[0:7] = 0
1652 log (" svstate.srcstep loop end (PC to update)")
1653 self.namespace['SVSTATE'] = self.svstate.spr
1654
1655 def update_nia(self):
1656 self.pc.update_nia(self.is_svp64_mode)
1657 self.namespace['NIA'] = self.pc.NIA
1658
1659 def inject():
1660 """Decorator factory.
1661
1662 this decorator will "inject" variables into the function's namespace,
1663 from the *dictionary* in self.namespace. it therefore becomes possible
1664 to make it look like a whole stack of variables which would otherwise
1665 need "self." inserted in front of them (*and* for those variables to be
1666 added to the instance) "appear" in the function.
1667
1668 "self.namespace['SI']" for example becomes accessible as just "SI" but
1669 *only* inside the function, when decorated.
1670 """
1671 def variable_injector(func):
1672 @wraps(func)
1673 def decorator(*args, **kwargs):
1674 try:
1675 func_globals = func.__globals__ # Python 2.6+
1676 except AttributeError:
1677 func_globals = func.func_globals # Earlier versions.
1678
1679 context = args[0].namespace # variables to be injected
1680 saved_values = func_globals.copy() # Shallow copy of dict.
1681 func_globals.update(context)
1682 result = func(*args, **kwargs)
1683 log("globals after", func_globals['CIA'], func_globals['NIA'])
1684 log("args[0]", args[0].namespace['CIA'],
1685 args[0].namespace['NIA'],
1686 args[0].namespace['SVSTATE'])
1687 args[0].namespace = func_globals
1688 #exec (func.__code__, func_globals)
1689
1690 # finally:
1691 # func_globals = saved_values # Undo changes.
1692
1693 return result
1694
1695 return decorator
1696
1697 return variable_injector
1698
1699