add pcdec -- doesn't yet work due to broken ISACaller RT/RS output handling
[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 import re
17 from nmigen.sim import Settle, Delay
18 from functools import wraps
19 from copy import copy, deepcopy
20 from openpower.decoder.orderedset import OrderedSet
21 from openpower.decoder.selectable_int import (
22 FieldSelectableInt,
23 SelectableInt,
24 selectconcat,
25 )
26 from openpower.decoder.power_insn import SVP64Instruction
27 from openpower.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
28 insns, MicrOp,
29 In1Sel, In2Sel, In3Sel,
30 OutSel, CRInSel, CROutSel, LDSTMode,
31 SVP64RMMode, SVP64PredMode,
32 SVP64PredInt, SVP64PredCR,
33 SVP64LDSTmode, FPTRANS_INSNS)
34
35 from openpower.decoder.power_enums import SVPtype
36
37 from openpower.decoder.helpers import (exts, gtu, ltu, undefined,
38 ISACallerHelper, ISAFPHelpers)
39 from openpower.consts import PIb, MSRb # big-endian (PowerISA versions)
40 from openpower.consts import (SVP64MODE,
41 SVP64CROffs,
42 )
43 from openpower.decoder.power_svp64 import SVP64RM, decode_extra
44
45 from openpower.decoder.isa.radixmmu import RADIX
46 from openpower.decoder.isa.mem import Mem, swap_order, MemException
47 from openpower.decoder.isa.svshape import SVSHAPE
48 from openpower.decoder.isa.svstate import SVP64State
49
50
51 from openpower.util import LogKind, log
52
53 from collections import namedtuple
54 import math
55 import sys
56
57 instruction_info = namedtuple('instruction_info',
58 'func read_regs uninit_regs write_regs ' +
59 'special_regs op_fields form asmregs')
60
61 special_sprs = {
62 'LR': 8,
63 'CTR': 9,
64 'TAR': 815,
65 'XER': 1,
66 'VRSAVE': 256}
67
68
69 REG_SORT_ORDER = {
70 # TODO (lkcl): adjust other registers that should be in a particular order
71 # probably CA, CA32, and CR
72 "FRT": 0,
73 "FRA": 0,
74 "FRB": 0,
75 "FRC": 0,
76 "FRS": 0,
77 "RT": 0,
78 "RA": 0,
79 "RB": 0,
80 "RC": 0,
81 "RS": 0,
82 "BI": 0,
83 "CR": 0,
84 "LR": 0,
85 "CTR": 0,
86 "TAR": 0,
87 "MSR": 0,
88 "SVSTATE": 0,
89 "SVSHAPE0": 0,
90 "SVSHAPE1": 0,
91 "SVSHAPE2": 0,
92 "SVSHAPE3": 0,
93
94 "CA": 0,
95 "CA32": 0,
96
97 "overflow": 7, # should definitely be last
98 }
99
100 fregs = ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
101
102
103 def create_args(reglist, extra=None):
104 retval = list(OrderedSet(reglist))
105 retval.sort(key=lambda reg: REG_SORT_ORDER.get(reg, 0))
106 if extra is not None:
107 return [extra] + retval
108 return retval
109
110
111 class GPR(dict):
112 def __init__(self, decoder, isacaller, svstate, regfile):
113 dict.__init__(self)
114 self.sd = decoder
115 self.isacaller = isacaller
116 self.svstate = svstate
117 for i in range(len(regfile)):
118 self[i] = SelectableInt(regfile[i], 64)
119
120 def __call__(self, ridx):
121 if isinstance(ridx, SelectableInt):
122 ridx = ridx.value
123 return self[ridx]
124
125 def set_form(self, form):
126 self.form = form
127
128 def __setitem__(self, rnum, value):
129 # rnum = rnum.value # only SelectableInt allowed
130 log("GPR setitem", rnum, value)
131 if isinstance(rnum, SelectableInt):
132 rnum = rnum.value
133 dict.__setitem__(self, rnum, value)
134
135 def getz(self, rnum):
136 # rnum = rnum.value # only SelectableInt allowed
137 log("GPR getzero?", rnum)
138 if rnum == 0:
139 return SelectableInt(0, 64)
140 return self[rnum]
141
142 def _get_regnum(self, attr):
143 getform = self.sd.sigforms[self.form]
144 rnum = getattr(getform, attr)
145 return rnum
146
147 def ___getitem__(self, attr):
148 """ XXX currently not used
149 """
150 rnum = self._get_regnum(attr)
151 log("GPR getitem", attr, rnum)
152 return self.regfile[rnum]
153
154 def dump(self, printout=True):
155 res = []
156 for i in range(len(self)):
157 res.append(self[i].value)
158 if printout:
159 for i in range(0, len(res), 8):
160 s = []
161 for j in range(8):
162 s.append("%08x" % res[i+j])
163 s = ' '.join(s)
164 print("reg", "%2d" % i, s)
165 return res
166
167
168 class SPR(dict):
169 def __init__(self, dec2, initial_sprs={}):
170 self.sd = dec2
171 dict.__init__(self)
172 for key, v in initial_sprs.items():
173 if isinstance(key, SelectableInt):
174 key = key.value
175 key = special_sprs.get(key, key)
176 if isinstance(key, int):
177 info = spr_dict[key]
178 else:
179 info = spr_byname[key]
180 if not isinstance(v, SelectableInt):
181 v = SelectableInt(v, info.length)
182 self[key] = v
183
184 def __getitem__(self, key):
185 log("get spr", key)
186 log("dict", self.items())
187 # if key in special_sprs get the special spr, otherwise return key
188 if isinstance(key, SelectableInt):
189 key = key.value
190 if isinstance(key, int):
191 key = spr_dict[key].SPR
192 key = special_sprs.get(key, key)
193 if key == 'HSRR0': # HACK!
194 key = 'SRR0'
195 if key == 'HSRR1': # HACK!
196 key = 'SRR1'
197 if key in self:
198 res = dict.__getitem__(self, key)
199 else:
200 if isinstance(key, int):
201 info = spr_dict[key]
202 else:
203 info = spr_byname[key]
204 dict.__setitem__(self, key, SelectableInt(0, info.length))
205 res = dict.__getitem__(self, key)
206 log("spr returning", key, res)
207 return res
208
209 def __setitem__(self, key, value):
210 if isinstance(key, SelectableInt):
211 key = key.value
212 if isinstance(key, int):
213 key = spr_dict[key].SPR
214 log("spr key", key)
215 key = special_sprs.get(key, key)
216 if key == 'HSRR0': # HACK!
217 self.__setitem__('SRR0', value)
218 if key == 'HSRR1': # HACK!
219 self.__setitem__('SRR1', value)
220 log("setting spr", key, value)
221 dict.__setitem__(self, key, value)
222
223 def __call__(self, ridx):
224 return self[ridx]
225
226 def dump(self, printout=True):
227 res = []
228 keys = list(self.keys())
229 # keys.sort()
230 for k in keys:
231 sprname = spr_dict.get(k, None)
232 if sprname is None:
233 sprname = k
234 else:
235 sprname = sprname.SPR
236 res.append((sprname, self[k].value))
237 if printout:
238 for sprname, value in res:
239 print(" ", sprname, hex(value))
240 return res
241
242
243 class PC:
244 def __init__(self, pc_init=0):
245 self.CIA = SelectableInt(pc_init, 64)
246 self.NIA = self.CIA + SelectableInt(4, 64) # only true for v3.0B!
247
248 def update_nia(self, is_svp64):
249 increment = 8 if is_svp64 else 4
250 self.NIA = self.CIA + SelectableInt(increment, 64)
251
252 def update(self, namespace, is_svp64):
253 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
254 """
255 self.CIA = namespace['NIA'].narrow(64)
256 self.update_nia(is_svp64)
257 namespace['CIA'] = self.CIA
258 namespace['NIA'] = self.NIA
259
260
261 # CR register fields
262 # See PowerISA Version 3.0 B Book 1
263 # Section 2.3.1 Condition Register pages 30 - 31
264 class CRFields:
265 LT = FL = 0 # negative, less than, floating-point less than
266 GT = FG = 1 # positive, greater than, floating-point greater than
267 EQ = FE = 2 # equal, floating-point equal
268 SO = FU = 3 # summary overflow, floating-point unordered
269
270 def __init__(self, init=0):
271 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
272 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
273 self.cr = SelectableInt(init, 64) # underlying reg
274 # field-selectable versions of Condition Register TODO check bitranges?
275 self.crl = []
276 for i in range(8):
277 bits = tuple(range(i*4+32, (i+1)*4+32))
278 _cr = FieldSelectableInt(self.cr, bits)
279 self.crl.append(_cr)
280
281 # decode SVP64 predicate integer to reg number and invert
282
283
284 def get_predint(gpr, mask):
285 r10 = gpr(10)
286 r30 = gpr(30)
287 log("get_predint", mask, SVP64PredInt.ALWAYS.value)
288 if mask == SVP64PredInt.ALWAYS.value:
289 return 0xffff_ffff_ffff_ffff # 64 bits of 1
290 if mask == SVP64PredInt.R3_UNARY.value:
291 return 1 << (gpr(3).value & 0b111111)
292 if mask == SVP64PredInt.R3.value:
293 return gpr(3).value
294 if mask == SVP64PredInt.R3_N.value:
295 return ~gpr(3).value
296 if mask == SVP64PredInt.R10.value:
297 return gpr(10).value
298 if mask == SVP64PredInt.R10_N.value:
299 return ~gpr(10).value
300 if mask == SVP64PredInt.R30.value:
301 return gpr(30).value
302 if mask == SVP64PredInt.R30_N.value:
303 return ~gpr(30).value
304
305 # decode SVP64 predicate CR to reg number and invert status
306
307
308 def _get_predcr(mask):
309 if mask == SVP64PredCR.LT.value:
310 return 0, 1
311 if mask == SVP64PredCR.GE.value:
312 return 0, 0
313 if mask == SVP64PredCR.GT.value:
314 return 1, 1
315 if mask == SVP64PredCR.LE.value:
316 return 1, 0
317 if mask == SVP64PredCR.EQ.value:
318 return 2, 1
319 if mask == SVP64PredCR.NE.value:
320 return 2, 0
321 if mask == SVP64PredCR.SO.value:
322 return 3, 1
323 if mask == SVP64PredCR.NS.value:
324 return 3, 0
325
326 # read individual CR fields (0..VL-1), extract the required bit
327 # and construct the mask
328
329
330 def get_predcr(crl, mask, vl):
331 idx, noninv = _get_predcr(mask)
332 mask = 0
333 for i in range(vl):
334 cr = crl[i+SVP64CROffs.CRPred]
335 if cr[idx].value == noninv:
336 mask |= (1 << i)
337 return mask
338
339
340 # TODO, really should just be using PowerDecoder2
341 def get_pdecode_idx_in(dec2, name):
342 op = dec2.dec.op
343 in1_sel = yield op.in1_sel
344 in2_sel = yield op.in2_sel
345 in3_sel = yield op.in3_sel
346 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
347 in1 = yield dec2.e.read_reg1.data
348 in2 = yield dec2.e.read_reg2.data
349 in3 = yield dec2.e.read_reg3.data
350 in1_isvec = yield dec2.in1_isvec
351 in2_isvec = yield dec2.in2_isvec
352 in3_isvec = yield dec2.in3_isvec
353 log("get_pdecode_idx_in in1", name, in1_sel, In1Sel.RA.value,
354 in1, in1_isvec)
355 log("get_pdecode_idx_in in2", name, in2_sel, In2Sel.RB.value,
356 in2, in2_isvec)
357 log("get_pdecode_idx_in in3", name, in3_sel, In3Sel.RS.value,
358 in3, in3_isvec)
359 log("get_pdecode_idx_in FRS in3", name, in3_sel, In3Sel.FRS.value,
360 in3, in3_isvec)
361 log("get_pdecode_idx_in FRB in2", name, in2_sel, In2Sel.FRB.value,
362 in2, in2_isvec)
363 log("get_pdecode_idx_in FRC in3", name, in3_sel, In3Sel.FRC.value,
364 in3, in3_isvec)
365 # identify which regnames map to in1/2/3
366 if name == 'RA' or name == 'RA_OR_ZERO':
367 if (in1_sel == In1Sel.RA.value or
368 (in1_sel == In1Sel.RA_OR_ZERO.value and in1 != 0)):
369 return in1, in1_isvec
370 if in1_sel == In1Sel.RA_OR_ZERO.value:
371 return in1, in1_isvec
372 elif name == 'RB':
373 if in2_sel == In2Sel.RB.value:
374 return in2, in2_isvec
375 if in3_sel == In3Sel.RB.value:
376 return in3, in3_isvec
377 # XXX TODO, RC doesn't exist yet!
378 elif name == 'RC':
379 if in3_sel == In3Sel.RC.value:
380 return in3, in3_isvec
381 assert False, "RC does not exist yet"
382 elif name == 'RS':
383 if in1_sel == In1Sel.RS.value:
384 return in1, in1_isvec
385 if in2_sel == In2Sel.RS.value:
386 return in2, in2_isvec
387 if in3_sel == In3Sel.RS.value:
388 return in3, in3_isvec
389 elif name == 'FRA':
390 if in1_sel == In1Sel.FRA.value:
391 return in1, in1_isvec
392 elif name == 'FRB':
393 if in2_sel == In2Sel.FRB.value:
394 return in2, in2_isvec
395 elif name == 'FRC':
396 if in3_sel == In3Sel.FRC.value:
397 return in3, in3_isvec
398 elif name == 'FRS':
399 if in1_sel == In1Sel.FRS.value:
400 return in1, in1_isvec
401 if in3_sel == In3Sel.FRS.value:
402 return in3, in3_isvec
403 return None, False
404
405
406 # TODO, really should just be using PowerDecoder2
407 def get_pdecode_cr_in(dec2, name):
408 op = dec2.dec.op
409 in_sel = yield op.cr_in
410 in_bitfield = yield dec2.dec_cr_in.cr_bitfield.data
411 sv_cr_in = yield op.sv_cr_in
412 spec = yield dec2.crin_svdec.spec
413 sv_override = yield dec2.dec_cr_in.sv_override
414 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
415 in1 = yield dec2.e.read_cr1.data
416 cr_isvec = yield dec2.cr_in_isvec
417 log("get_pdecode_cr_in", in_sel, CROutSel.CR0.value, in1, cr_isvec)
418 log(" sv_cr_in", sv_cr_in)
419 log(" cr_bf", in_bitfield)
420 log(" spec", spec)
421 log(" override", sv_override)
422 # identify which regnames map to in / o2
423 if name == 'BI':
424 if in_sel == CRInSel.BI.value:
425 return in1, cr_isvec
426 log("get_pdecode_cr_in not found", name)
427 return None, False
428
429
430 # TODO, really should just be using PowerDecoder2
431 def get_pdecode_cr_out(dec2, name):
432 op = dec2.dec.op
433 out_sel = yield op.cr_out
434 out_bitfield = yield dec2.dec_cr_out.cr_bitfield.data
435 sv_cr_out = yield op.sv_cr_out
436 spec = yield dec2.crout_svdec.spec
437 sv_override = yield dec2.dec_cr_out.sv_override
438 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
439 out = yield dec2.e.write_cr.data
440 o_isvec = yield dec2.o_isvec
441 log("get_pdecode_cr_out", out_sel, CROutSel.CR0.value, out, o_isvec)
442 log(" sv_cr_out", sv_cr_out)
443 log(" cr_bf", out_bitfield)
444 log(" spec", spec)
445 log(" override", sv_override)
446 # identify which regnames map to out / o2
447 if name == 'CR0':
448 if out_sel == CROutSel.CR0.value:
449 return out, o_isvec
450 if name == 'CR1': # these are not actually calculated correctly
451 if out_sel == CROutSel.CR1.value:
452 return out, o_isvec
453 log("get_pdecode_cr_out not found", name)
454 return None, False
455
456
457 # TODO, really should just be using PowerDecoder2
458 def get_pdecode_idx_out(dec2, name):
459 op = dec2.dec.op
460 out_sel = yield op.out_sel
461 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
462 out = yield dec2.e.write_reg.data
463 o_isvec = yield dec2.o_isvec
464 # identify which regnames map to out / o2
465 if name == 'RA':
466 log("get_pdecode_idx_out", out_sel, OutSel.RA.value, out, o_isvec)
467 if out_sel == OutSel.RA.value:
468 return out, o_isvec
469 elif name == 'RT':
470 log("get_pdecode_idx_out", out_sel, OutSel.RT.value,
471 OutSel.RT_OR_ZERO.value, out, o_isvec,
472 dec2.dec.RT)
473 if out_sel == OutSel.RT.value:
474 return out, o_isvec
475 if out_sel == OutSel.RT_OR_ZERO.value and out != 0:
476 return out, o_isvec
477 elif name == 'RT_OR_ZERO':
478 log("get_pdecode_idx_out", out_sel, OutSel.RT.value,
479 OutSel.RT_OR_ZERO.value, out, o_isvec,
480 dec2.dec.RT)
481 if out_sel == OutSel.RT_OR_ZERO.value:
482 return out, o_isvec
483 elif name == 'FRA':
484 log("get_pdecode_idx_out", out_sel, OutSel.FRA.value, out, o_isvec)
485 if out_sel == OutSel.FRA.value:
486 return out, o_isvec
487 elif name == 'FRT':
488 log("get_pdecode_idx_out", out_sel, OutSel.FRT.value,
489 OutSel.FRT.value, out, o_isvec)
490 if out_sel == OutSel.FRT.value:
491 return out, o_isvec
492 log("get_pdecode_idx_out not found", name, out_sel, out, o_isvec)
493 return None, False
494
495
496 # TODO, really should just be using PowerDecoder2
497 def get_pdecode_idx_out2(dec2, name):
498 # check first if register is activated for write
499 op = dec2.dec.op
500 out_sel = yield op.out_sel
501 out = yield dec2.e.write_ea.data
502 o_isvec = yield dec2.o2_isvec
503 out_ok = yield dec2.e.write_ea.ok
504 log("get_pdecode_idx_out2", name, out_sel, out, out_ok, o_isvec)
505 if not out_ok:
506 return None, False
507
508 if name == 'RA':
509 if hasattr(op, "upd"):
510 # update mode LD/ST uses read-reg A also as an output
511 upd = yield op.upd
512 log("get_pdecode_idx_out2", upd, LDSTMode.update.value,
513 out_sel, OutSel.RA.value,
514 out, o_isvec)
515 if upd == LDSTMode.update.value:
516 return out, o_isvec
517 if name == 'FRS':
518 int_op = yield dec2.dec.op.internal_op
519 fft_en = yield dec2.use_svp64_fft
520 # if int_op == MicrOp.OP_FP_MADD.value and fft_en:
521 if fft_en:
522 log("get_pdecode_idx_out2", out_sel, OutSel.FRS.value,
523 out, o_isvec)
524 return out, o_isvec
525 return None, False
526
527
528 class StepLoop:
529 """deals with svstate looping.
530 """
531
532 def __init__(self, svstate):
533 self.svstate = svstate
534
535 def get_iterators(self):
536 self.src_it = self.src_iterator()
537 self.dst_it = self.dst_iterator()
538
539 def src_iterator(self):
540 """source-stepping iterator
541 """
542 pack = self.svstate.pack
543
544 # source step
545 if pack:
546 # pack advances subvl in *outer* loop
547 if end_src:
548 if not end_ssub:
549 self.svstate.ssubstep += SelectableInt(1, 2)
550 self.svstate.srcstep = SelectableInt(0, 7) # reset
551 else:
552 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
553 else:
554 # these cannot be done as for-loops because SVSTATE may change
555 # (srcstep/substep may be modified, interrupted, subvl/vl change)
556 # but they *can* be done as while-loops as long as every SVSTATE
557 # "thing" is re-read every single time a yield gives indices
558 while True: # outer vl loop
559 while True: # inner subvl loop
560 subvl = self.subvl
561 srcmask = self.srcmask
562 srcstep = self.svstate.srcstep
563 if self.pred_sz or ((1 << srcstep) & srcmask) != 0:
564 log(" advance src", srcstep, self.svstate.vl,
565 self.svstate.ssubstep, subvl)
566 # yield actual substep/srcstep
567 yield (self.svstate.ssubstep, srcstep)
568 if self.svstate.ssubstep == subvl: # end-point
569 self.svstate.ssubstep = SelectableInt(0, 2) # reset
570 break
571 self.svstate.ssubstep += SelectableInt(1, 2)
572 vl = self.svstate.vl
573 if srcstep == vl-1: # end-point
574 self.svstate.srcstep = SelectableInt(0, 7) # reset
575 break # trigger StopIteration
576 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
577
578 def dst_iterator(self):
579 """dest-stepping iterator
580 """
581 unpack = self.svstate.unpack
582
583 # dest step
584 if unpack:
585 # pack advances subvl in *outer* loop
586 pass # TODO
587 else:
588 # these cannot be done as for-loops because SVSTATE may change
589 # (dststep/substep may be modified, interrupted, subvl/vl change)
590 # but they *can* be done as while-loops as long as every SVSTATE
591 # "thing" is re-read every single time a yield gives indices
592 while True: # outer vl loop
593 while True: # inner subvl loop
594 subvl = self.subvl
595 dstmask = self.dstmask
596 dststep = self.svstate.dststep
597 if self.pred_dz or ((1 << dststep) & dstmask) != 0:
598 log(" advance dst", dststep, self.svstate.vl,
599 self.svstate.dsubstep, subvl)
600 # yield actual substep/dststep
601 yield (self.svstate.dsubstep, dststep)
602 if self.svstate.dsubstep == subvl: # end-point
603 self.svstate.dsubstep = SelectableInt(0, 2) # reset
604 break
605 self.svstate.dsubstep += SelectableInt(1, 2)
606 vl = self.svstate.vl
607 if dststep == vl-1: # end-point
608 self.svstate.dststep = SelectableInt(0, 7) # reset
609 break # trigger StopIteration
610 self.svstate.dststep += SelectableInt(1, 7) # advance dststep
611
612 def src_iterate(self):
613 """source-stepping iterator
614 """
615 end_src = self.end_src
616 subvl = self.subvl
617 pack = self.svstate.pack
618 unpack = self.svstate.unpack
619 ssubstep = self.svstate.ssubstep
620 end_ssub = ssubstep == subvl
621 log(" pack/unpack/subvl", pack, unpack, subvl,
622 "end", end_src,
623 "sub", end_ssub)
624 # first source step
625 srcstep = self.svstate.srcstep
626 if pack:
627 # pack advances subvl in *outer* loop
628 if end_src:
629 if not end_ssub:
630 self.svstate.ssubstep += SelectableInt(1, 2)
631 self.svstate.srcstep = SelectableInt(0, 7) # reset
632 else:
633 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
634 else:
635 # advance subvl in *inner* loop
636 if end_ssub:
637 if not end_src:
638 self.svstate.srcstep += SelectableInt(1, 7)
639 self.svstate.ssubstep = SelectableInt(0, 2) # reset
640 else:
641 # advance ssubstep
642 self.svstate.ssubstep += SelectableInt(1, 2)
643
644 log(" advance src", self.svstate.srcstep, self.svstate.ssubstep)
645
646 def dst_iterate(self):
647 """dest step iterator
648 """
649 end_dst = self.end_dst
650 subvl = self.subvl
651 pack = self.svstate.pack
652 unpack = self.svstate.unpack
653 dsubstep = self.svstate.dsubstep
654 end_dsub = dsubstep == subvl
655 log(" pack/unpack/subvl", pack, unpack, subvl,
656 "end", end_dst,
657 "sub", end_dsub)
658 # now dest step
659 if unpack:
660 # unpack advances subvl in *outer* loop
661 if end_dst:
662 if not end_dsub:
663 self.svstate.dsubstep += SelectableInt(1, 2)
664 self.svstate.dststep = SelectableInt(0, 7) # reset
665 else:
666 self.svstate.dststep += SelectableInt(1, 7) # advance dststep
667 else:
668 # advance subvl in *inner* loop
669 if end_dsub:
670 if not end_dst:
671 self.svstate.dststep += SelectableInt(1, 7)
672 self.svstate.dsubstep = SelectableInt(0, 2) # reset
673 else:
674 # advance ssubstep
675 self.svstate.dsubstep += SelectableInt(1, 2)
676 log(" advance dst", self.svstate.dststep, self.svstate.dsubstep)
677
678 def advance_svstate_steps(self, end_src=False, end_dst=False):
679 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
680 TODO when Pack/Unpack is set, substep becomes the *outer* loop
681 """
682 self.subvl = yield self.dec2.rm_dec.rm_in.subvl
683 self.end_src = end_src
684 self.end_dst = end_dst
685 self.src_iterate()
686 self.dst_iterate()
687
688 def read_src_mask(self):
689 """read/update pred_sz and src mask
690 """
691 # get SVSTATE VL (oh and print out some debug stuff)
692 vl = self.svstate.vl
693 srcstep = self.svstate.srcstep
694 ssubstep = self.svstate.ssubstep
695
696 # get predicate mask (all 64 bits)
697 srcmask = 0xffff_ffff_ffff_ffff
698
699 pmode = yield self.dec2.rm_dec.predmode
700 sv_ptype = yield self.dec2.dec.op.SV_Ptype
701 srcpred = yield self.dec2.rm_dec.srcpred
702 dstpred = yield self.dec2.rm_dec.dstpred
703 pred_sz = yield self.dec2.rm_dec.pred_sz
704 if pmode == SVP64PredMode.INT.value:
705 srcmask = dstmask = get_predint(self.gpr, dstpred)
706 if sv_ptype == SVPtype.P2.value:
707 srcmask = get_predint(self.gpr, srcpred)
708 elif pmode == SVP64PredMode.CR.value:
709 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
710 if sv_ptype == SVPtype.P2.value:
711 srcmask = get_predcr(self.crl, srcpred, vl)
712 # work out if the ssubsteps are completed
713 ssubstart = ssubstep == 0
714 log(" pmode", pmode)
715 log(" ptype", sv_ptype)
716 log(" srcpred", bin(srcpred))
717 log(" srcmask", bin(srcmask))
718 log(" pred_sz", bin(pred_sz))
719 log(" ssubstart", ssubstart)
720
721 # store all that above
722 self.srcstep_skip = False
723 self.srcmask = srcmask
724 self.pred_sz = pred_sz
725 self.new_ssubstep = ssubstep
726 log(" new ssubstep", ssubstep)
727 if ssubstart:
728 # until the predicate mask has a "1" bit... or we run out of VL
729 # let srcstep==VL be the indicator to move to next instruction
730 if not pred_sz:
731 self.srcstep_skip = True
732
733 def read_dst_mask(self):
734 """same as read_src_mask - check and record everything needed
735 """
736 # get SVSTATE VL (oh and print out some debug stuff)
737 # yield Delay(1e-10) # make changes visible
738 vl = self.svstate.vl
739 dststep = self.svstate.dststep
740 dsubstep = self.svstate.dsubstep
741
742 # get predicate mask (all 64 bits)
743 dstmask = 0xffff_ffff_ffff_ffff
744
745 pmode = yield self.dec2.rm_dec.predmode
746 reverse_gear = yield self.dec2.rm_dec.reverse_gear
747 sv_ptype = yield self.dec2.dec.op.SV_Ptype
748 dstpred = yield self.dec2.rm_dec.dstpred
749 pred_dz = yield self.dec2.rm_dec.pred_dz
750 if pmode == SVP64PredMode.INT.value:
751 dstmask = get_predint(self.gpr, dstpred)
752 elif pmode == SVP64PredMode.CR.value:
753 dstmask = get_predcr(self.crl, dstpred, vl)
754 # work out if the ssubsteps are completed
755 dsubstart = dsubstep == 0
756 log(" pmode", pmode)
757 log(" ptype", sv_ptype)
758 log(" dstpred", bin(dstpred))
759 log(" dstmask", bin(dstmask))
760 log(" pred_dz", bin(pred_dz))
761 log(" dsubstart", dsubstart)
762
763 self.dststep_skip = False
764 self.dstmask = dstmask
765 self.pred_dz = pred_dz
766 self.new_dsubstep = dsubstep
767 log(" new dsubstep", dsubstep)
768 if dsubstart:
769 if not pred_dz:
770 self.dststep_skip = True
771
772 def svstate_pre_inc(self):
773 """check if srcstep/dststep need to skip over masked-out predicate bits
774 note that this is not supposed to do anything to substep,
775 it is purely for skipping masked-out bits
776 """
777
778 yield from self.read_src_mask()
779 yield from self.read_dst_mask()
780
781 self.skip_src()
782 self.skip_dst()
783
784 def skip_src(self):
785
786 srcstep = self.svstate.srcstep
787 srcmask = self.srcmask
788 pred_src_zero = self.pred_sz
789 vl = self.svstate.vl
790 # srcstep-skipping opportunity identified
791 if self.srcstep_skip:
792 while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl):
793 log(" sskip", bin(1 << srcstep))
794 srcstep += 1
795
796 # now work out if the relevant mask bits require zeroing
797 if pred_src_zero:
798 pred_src_zero = ((1 << srcstep) & srcmask) == 0
799
800 # store new srcstep / dststep
801 self.new_srcstep = srcstep
802 self.pred_src_zero = pred_src_zero
803 log(" new srcstep", srcstep)
804
805 def skip_dst(self):
806 # dststep-skipping opportunity identified
807 dststep = self.svstate.dststep
808 dstmask = self.dstmask
809 pred_dst_zero = self.pred_dz
810 vl = self.svstate.vl
811 if self.dststep_skip:
812 while (((1 << dststep) & dstmask) == 0) and (dststep != vl):
813 log(" dskip", bin(1 << dststep))
814 dststep += 1
815
816 # now work out if the relevant mask bits require zeroing
817 if pred_dst_zero:
818 pred_dst_zero = ((1 << dststep) & dstmask) == 0
819
820 # store new srcstep / dststep
821 self.new_dststep = dststep
822 self.pred_dst_zero = pred_dst_zero
823 log(" new dststep", dststep)
824
825
826 class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
827 # decoder2 - an instance of power_decoder2
828 # regfile - a list of initial values for the registers
829 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
830 # respect_pc - tracks the program counter. requires initial_insns
831 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
832 initial_mem=None, initial_msr=0,
833 initial_svstate=0,
834 initial_insns=None,
835 fpregfile=None,
836 respect_pc=False,
837 disassembly=None,
838 initial_pc=0,
839 bigendian=False,
840 mmu=False,
841 icachemmu=False):
842
843 self.bigendian = bigendian
844 self.halted = False
845 self.is_svp64_mode = False
846 self.respect_pc = respect_pc
847 if initial_sprs is None:
848 initial_sprs = {}
849 if initial_mem is None:
850 initial_mem = {}
851 if fpregfile is None:
852 fpregfile = [0] * 32
853 if initial_insns is None:
854 initial_insns = {}
855 assert self.respect_pc == False, "instructions required to honor pc"
856
857 log("ISACaller insns", respect_pc, initial_insns, disassembly)
858 log("ISACaller initial_msr", initial_msr)
859
860 # "fake program counter" mode (for unit testing)
861 self.fake_pc = 0
862 disasm_start = 0
863 if not respect_pc:
864 if isinstance(initial_mem, tuple):
865 self.fake_pc = initial_mem[0]
866 disasm_start = self.fake_pc
867 else:
868 disasm_start = initial_pc
869
870 # disassembly: we need this for now (not given from the decoder)
871 self.disassembly = {}
872 if disassembly:
873 for i, code in enumerate(disassembly):
874 self.disassembly[i*4 + disasm_start] = code
875
876 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
877 self.svp64rm = SVP64RM()
878 if initial_svstate is None:
879 initial_svstate = 0
880 if isinstance(initial_svstate, int):
881 initial_svstate = SVP64State(initial_svstate)
882 # SVSTATE, MSR and PC
883 StepLoop.__init__(self, initial_svstate)
884 self.msr = SelectableInt(initial_msr, 64) # underlying reg
885 self.pc = PC()
886 # GPR FPR SPR registers
887 initial_sprs = deepcopy(initial_sprs) # so as not to get modified
888 self.gpr = GPR(decoder2, self, self.svstate, regfile)
889 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
890 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
891
892 # set up 4 dummy SVSHAPEs if they aren't already set up
893 for i in range(4):
894 sname = 'SVSHAPE%d' % i
895 if sname not in self.spr:
896 val = 0
897 else:
898 val = self.spr[sname].value
899 # make sure it's an SVSHAPE
900 self.spr[sname] = SVSHAPE(val, self.gpr)
901 self.last_op_svshape = False
902
903 # "raw" memory
904 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
905 self.mem.log_fancy(kind=LogKind.InstrInOuts)
906 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
907 # MMU mode, redirect underlying Mem through RADIX
908 if mmu:
909 self.mem = RADIX(self.mem, self)
910 if icachemmu:
911 self.imem = RADIX(self.imem, self)
912
913 # TODO, needed here:
914 # FPR (same as GPR except for FP nums)
915 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
916 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
917 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
918 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
919 # -- Done
920 # 2.3.2 LR (actually SPR #8) -- Done
921 # 2.3.3 CTR (actually SPR #9) -- Done
922 # 2.3.4 TAR (actually SPR #815)
923 # 3.2.2 p45 XER (actually SPR #1) -- Done
924 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
925
926 # create CR then allow portions of it to be "selectable" (below)
927 self.cr_fields = CRFields(initial_cr)
928 self.cr = self.cr_fields.cr
929
930 # "undefined", just set to variable-bit-width int (use exts "max")
931 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
932
933 self.namespace = {}
934 self.namespace.update(self.spr)
935 self.namespace.update({'GPR': self.gpr,
936 'FPR': self.fpr,
937 'MEM': self.mem,
938 'SPR': self.spr,
939 'memassign': self.memassign,
940 'NIA': self.pc.NIA,
941 'CIA': self.pc.CIA,
942 'SVSTATE': self.svstate,
943 'SVSHAPE0': self.spr['SVSHAPE0'],
944 'SVSHAPE1': self.spr['SVSHAPE1'],
945 'SVSHAPE2': self.spr['SVSHAPE2'],
946 'SVSHAPE3': self.spr['SVSHAPE3'],
947 'CR': self.cr,
948 'MSR': self.msr,
949 'undefined': undefined,
950 'mode_is_64bit': True,
951 'SO': XER_bits['SO'],
952 'XLEN': 64 # elwidth overrides, later
953 })
954
955 # update pc to requested start point
956 self.set_pc(initial_pc)
957
958 # field-selectable versions of Condition Register
959 self.crl = self.cr_fields.crl
960 for i in range(8):
961 self.namespace["CR%d" % i] = self.crl[i]
962
963 self.decoder = decoder2.dec
964 self.dec2 = decoder2
965
966 super().__init__(XLEN=self.namespace["XLEN"])
967
968 @property
969 def XLEN(self):
970 return self.namespace["XLEN"]
971
972 def call_trap(self, trap_addr, trap_bit):
973 """calls TRAP and sets up NIA to the new execution location.
974 next instruction will begin at trap_addr.
975 """
976 self.TRAP(trap_addr, trap_bit)
977 self.namespace['NIA'] = self.trap_nia
978 self.pc.update(self.namespace, self.is_svp64_mode)
979
980 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
981 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
982
983 TRAP function is callable from inside the pseudocode itself,
984 hence the default arguments. when calling from inside ISACaller
985 it is best to use call_trap()
986 """
987 # https://bugs.libre-soc.org/show_bug.cgi?id=859
988 kaivb = self.spr['KAIVB'].value
989 msr = self.namespace['MSR'].value
990 log("TRAP:", hex(trap_addr), hex(msr), "kaivb", hex(kaivb))
991 # store CIA(+4?) in SRR0, set NIA to 0x700
992 # store MSR in SRR1, set MSR to um errr something, have to check spec
993 # store SVSTATE (if enabled) in SVSRR0
994 self.spr['SRR0'].value = self.pc.CIA.value
995 self.spr['SRR1'].value = msr
996 if self.is_svp64_mode:
997 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
998 self.trap_nia = SelectableInt(trap_addr | (kaivb & ~0x1fff), 64)
999 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
1000
1001 # set exception bits. TODO: this should, based on the address
1002 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1003 # bits appropriately. however it turns out that *for now* in all
1004 # cases (all trap_addrs) the exact same thing is needed.
1005 self.msr[MSRb.IR] = 0
1006 self.msr[MSRb.DR] = 0
1007 self.msr[MSRb.FE0] = 0
1008 self.msr[MSRb.FE1] = 0
1009 self.msr[MSRb.EE] = 0
1010 self.msr[MSRb.RI] = 0
1011 self.msr[MSRb.SF] = 1
1012 self.msr[MSRb.TM] = 0
1013 self.msr[MSRb.VEC] = 0
1014 self.msr[MSRb.VSX] = 0
1015 self.msr[MSRb.PR] = 0
1016 self.msr[MSRb.FP] = 0
1017 self.msr[MSRb.PMM] = 0
1018 self.msr[MSRb.TEs] = 0
1019 self.msr[MSRb.TEe] = 0
1020 self.msr[MSRb.UND] = 0
1021 self.msr[MSRb.LE] = 1
1022
1023 def memassign(self, ea, sz, val):
1024 self.mem.memassign(ea, sz, val)
1025
1026 def prep_namespace(self, insn_name, formname, op_fields):
1027 # TODO: get field names from form in decoder*1* (not decoder2)
1028 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1029 # from spec
1030 # then "yield" fields only from op_fields rather than hard-coded
1031 # list, here.
1032 fields = self.decoder.sigforms[formname]
1033 log("prep_namespace", formname, op_fields, insn_name)
1034 for name in op_fields:
1035 # CR immediates. deal with separately. needs modifying
1036 # pseudocode
1037 if self.is_svp64_mode and name in ['BI']: # TODO, more CRs
1038 # BI is a 5-bit, must reconstruct the value
1039 regnum, is_vec = yield from get_pdecode_cr_in(self.dec2, name)
1040 sig = getattr(fields, name)
1041 val = yield sig
1042 # low 2 LSBs (CR field selector) remain same, CR num extended
1043 assert regnum <= 7, "sigh, TODO, 128 CR fields"
1044 val = (val & 0b11) | (regnum << 2)
1045 else:
1046 sig = getattr(fields, name)
1047 val = yield sig
1048 # these are all opcode fields involved in index-selection of CR,
1049 # and need to do "standard" arithmetic. CR[BA+32] for example
1050 # would, if using SelectableInt, only be 5-bit.
1051 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1052 self.namespace[name] = val
1053 else:
1054 self.namespace[name] = SelectableInt(val, sig.width)
1055
1056 self.namespace['XER'] = self.spr['XER']
1057 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
1058 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
1059
1060 # add some SVSTATE convenience variables
1061 vl = self.svstate.vl
1062 srcstep = self.svstate.srcstep
1063 self.namespace['VL'] = vl
1064 self.namespace['srcstep'] = srcstep
1065
1066 # sv.bc* need some extra fields
1067 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1068 # blegh grab bits manually
1069 mode = yield self.dec2.rm_dec.rm_in.mode
1070 bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0
1071 bc_vli = (mode & SVP64MODE.BC_VLI) != 0
1072 bc_snz = (mode & SVP64MODE.BC_SNZ) != 0
1073 bc_vsb = yield self.dec2.rm_dec.bc_vsb
1074 bc_lru = yield self.dec2.rm_dec.bc_lru
1075 bc_gate = yield self.dec2.rm_dec.bc_gate
1076 sz = yield self.dec2.rm_dec.pred_sz
1077 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
1078 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
1079 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
1080 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
1081 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
1082 self.namespace['sz'] = SelectableInt(sz, 1)
1083 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
1084
1085 def handle_carry_(self, inputs, outputs, already_done):
1086 inv_a = yield self.dec2.e.do.invert_in
1087 if inv_a:
1088 inputs[0] = ~inputs[0]
1089
1090 imm_ok = yield self.dec2.e.do.imm_data.ok
1091 if imm_ok:
1092 imm = yield self.dec2.e.do.imm_data.data
1093 inputs.append(SelectableInt(imm, 64))
1094 assert len(outputs) >= 1
1095 log("outputs", repr(outputs))
1096 if isinstance(outputs, list) or isinstance(outputs, tuple):
1097 output = outputs[0]
1098 else:
1099 output = outputs
1100 gts = []
1101 for x in inputs:
1102 log("gt input", x, output)
1103 gt = (gtu(x, output))
1104 gts.append(gt)
1105 log(gts)
1106 cy = 1 if any(gts) else 0
1107 log("CA", cy, gts)
1108 if not (1 & already_done):
1109 self.spr['XER'][XER_bits['CA']] = cy
1110
1111 log("inputs", already_done, inputs)
1112 # 32 bit carry
1113 # ARGH... different for OP_ADD... *sigh*...
1114 op = yield self.dec2.e.do.insn_type
1115 if op == MicrOp.OP_ADD.value:
1116 res32 = (output.value & (1 << 32)) != 0
1117 a32 = (inputs[0].value & (1 << 32)) != 0
1118 if len(inputs) >= 2:
1119 b32 = (inputs[1].value & (1 << 32)) != 0
1120 else:
1121 b32 = False
1122 cy32 = res32 ^ a32 ^ b32
1123 log("CA32 ADD", cy32)
1124 else:
1125 gts = []
1126 for x in inputs:
1127 log("input", x, output)
1128 log(" x[32:64]", x, x[32:64])
1129 log(" o[32:64]", output, output[32:64])
1130 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
1131 gts.append(gt)
1132 cy32 = 1 if any(gts) else 0
1133 log("CA32", cy32, gts)
1134 if not (2 & already_done):
1135 self.spr['XER'][XER_bits['CA32']] = cy32
1136
1137 def handle_overflow(self, inputs, outputs, div_overflow):
1138 if hasattr(self.dec2.e.do, "invert_in"):
1139 inv_a = yield self.dec2.e.do.invert_in
1140 if inv_a:
1141 inputs[0] = ~inputs[0]
1142
1143 imm_ok = yield self.dec2.e.do.imm_data.ok
1144 if imm_ok:
1145 imm = yield self.dec2.e.do.imm_data.data
1146 inputs.append(SelectableInt(imm, 64))
1147 assert len(outputs) >= 1
1148 log("handle_overflow", inputs, outputs, div_overflow)
1149 if len(inputs) < 2 and div_overflow is None:
1150 return
1151
1152 # div overflow is different: it's returned by the pseudo-code
1153 # because it's more complex than can be done by analysing the output
1154 if div_overflow is not None:
1155 ov, ov32 = div_overflow, div_overflow
1156 # arithmetic overflow can be done by analysing the input and output
1157 elif len(inputs) >= 2:
1158 output = outputs[0]
1159
1160 # OV (64-bit)
1161 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
1162 output_sgn = exts(output.value, output.bits) < 0
1163 ov = 1 if input_sgn[0] == input_sgn[1] and \
1164 output_sgn != input_sgn[0] else 0
1165
1166 # OV (32-bit)
1167 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
1168 output32_sgn = exts(output.value, 32) < 0
1169 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
1170 output32_sgn != input32_sgn[0] else 0
1171
1172 # now update XER OV/OV32/SO
1173 so = self.spr['XER'][XER_bits['SO']]
1174 new_so = so | ov # sticky overflow ORs in old with new
1175 self.spr['XER'][XER_bits['OV']] = ov
1176 self.spr['XER'][XER_bits['OV32']] = ov32
1177 self.spr['XER'][XER_bits['SO']] = new_so
1178 log(" set overflow", ov, ov32, so, new_so)
1179
1180 def handle_comparison(self, outputs, cr_idx=0, overflow=None, no_so=False):
1181 out = outputs[0]
1182 assert isinstance(out, SelectableInt), \
1183 "out zero not a SelectableInt %s" % repr(outputs)
1184 log("handle_comparison", out.bits, hex(out.value))
1185 # TODO - XXX *processor* in 32-bit mode
1186 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1187 # if is_32bit:
1188 # o32 = exts(out.value, 32)
1189 # print ("handle_comparison exts 32 bit", hex(o32))
1190 out = exts(out.value, out.bits)
1191 log("handle_comparison exts", hex(out))
1192 # create the three main CR flags, EQ GT LT
1193 zero = SelectableInt(out == 0, 1)
1194 positive = SelectableInt(out > 0, 1)
1195 negative = SelectableInt(out < 0, 1)
1196 # get (or not) XER.SO. for setvl this is important *not* to read SO
1197 if no_so:
1198 SO = SelectableInt(1, 0)
1199 else:
1200 SO = self.spr['XER'][XER_bits['SO']]
1201 log("handle_comparison SO overflow", SO, overflow)
1202 # alternative overflow checking (setvl mainly at the moment)
1203 if overflow is not None and overflow == 1:
1204 SO = SelectableInt(1, 1)
1205 # create the four CR field values and set the required CR field
1206 cr_field = selectconcat(negative, positive, zero, SO)
1207 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
1208 self.crl[cr_idx].eq(cr_field)
1209
1210 def set_pc(self, pc_val):
1211 self.namespace['NIA'] = SelectableInt(pc_val, 64)
1212 self.pc.update(self.namespace, self.is_svp64_mode)
1213
1214 def get_next_insn(self):
1215 """check instruction
1216 """
1217 if self.respect_pc:
1218 pc = self.pc.CIA.value
1219 else:
1220 pc = self.fake_pc
1221 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
1222 if ins is None:
1223 raise KeyError("no instruction at 0x%x" % pc)
1224 return pc, ins
1225
1226 def setup_one(self):
1227 """set up one instruction
1228 """
1229 pc, insn = self.get_next_insn()
1230 yield from self.setup_next_insn(pc, insn)
1231
1232 def setup_next_insn(self, pc, ins):
1233 """set up next instruction
1234 """
1235 self._pc = pc
1236 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
1237 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
1238
1239 yield self.dec2.sv_rm.eq(0)
1240 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
1241 yield self.dec2.dec.bigendian.eq(self.bigendian)
1242 yield self.dec2.state.msr.eq(self.msr.value)
1243 yield self.dec2.state.pc.eq(pc)
1244 if self.svstate is not None:
1245 yield self.dec2.state.svstate.eq(self.svstate.value)
1246
1247 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1248 yield Settle()
1249 opcode = yield self.dec2.dec.opcode_in
1250 opcode = SelectableInt(value=opcode, bits=32)
1251 pfx = SVP64Instruction.Prefix(opcode)
1252 log("prefix test: opcode:", pfx.po, bin(pfx.po), pfx.id)
1253 self.is_svp64_mode = bool((pfx.po == 0b000001) and (pfx.id == 0b11))
1254 self.pc.update_nia(self.is_svp64_mode)
1255 # set SVP64 decode
1256 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
1257 self.namespace['NIA'] = self.pc.NIA
1258 self.namespace['SVSTATE'] = self.svstate
1259 if not self.is_svp64_mode:
1260 return
1261
1262 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1263 log("svp64.rm", bin(pfx.rm))
1264 log(" svstate.vl", self.svstate.vl)
1265 log(" svstate.mvl", self.svstate.maxvl)
1266 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
1267 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
1268 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
1269 yield self.dec2.sv_rm.eq(int(pfx.rm)) # svp64 prefix
1270 yield Settle()
1271
1272 def execute_one(self):
1273 """execute one instruction
1274 """
1275 # get the disassembly code for this instruction
1276 if self.is_svp64_mode:
1277 if not self.disassembly:
1278 code = yield from self.get_assembly_name()
1279 else:
1280 code = self.disassembly[self._pc+4]
1281 log(" svp64 sim-execute", hex(self._pc), code)
1282 else:
1283 if not self.disassembly:
1284 code = yield from self.get_assembly_name()
1285 else:
1286 code = self.disassembly[self._pc]
1287 log("sim-execute", hex(self._pc), code)
1288 opname = code.split(' ')[0]
1289 try:
1290 yield from self.call(opname) # execute the instruction
1291 except MemException as e: # check for memory errors
1292 if e.args[0] == 'unaligned': # alignment error
1293 # run a Trap but set DAR first
1294 print("memory unaligned exception, DAR", e.dar)
1295 self.spr['DAR'] = SelectableInt(e.dar, 64)
1296 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1297 return
1298 elif e.args[0] == 'invalid': # invalid
1299 # run a Trap but set DAR first
1300 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1301 if e.mode == 'EXECUTE':
1302 # XXX TODO: must set a few bits in SRR1,
1303 # see microwatt loadstore1.vhdl
1304 # if m_in.segerr = '0' then
1305 # v.srr1(47 - 33) := m_in.invalid;
1306 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1307 # v.srr1(47 - 44) := m_in.badtree;
1308 # v.srr1(47 - 45) := m_in.rc_error;
1309 # v.intr_vec := 16#400#;
1310 # else
1311 # v.intr_vec := 16#480#;
1312 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1313 else:
1314 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1315 return
1316 # not supported yet:
1317 raise e # ... re-raise
1318
1319 # don't use this except in special circumstances
1320 if not self.respect_pc:
1321 self.fake_pc += 4
1322
1323 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1324 hex(self.pc.NIA.value))
1325
1326 def get_assembly_name(self):
1327 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1328 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1329 dec_insn = yield self.dec2.e.do.insn
1330 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1331 asmcode = yield self.dec2.dec.op.asmcode
1332 int_op = yield self.dec2.dec.op.internal_op
1333 log("get assembly name asmcode", asmcode, int_op,
1334 hex(dec_insn), bin(insn_1_11))
1335 asmop = insns.get(asmcode, None)
1336
1337 # sigh reconstruct the assembly instruction name
1338 if hasattr(self.dec2.e.do, "oe"):
1339 ov_en = yield self.dec2.e.do.oe.oe
1340 ov_ok = yield self.dec2.e.do.oe.ok
1341 else:
1342 ov_en = False
1343 ov_ok = False
1344 if hasattr(self.dec2.e.do, "rc"):
1345 rc_en = yield self.dec2.e.do.rc.rc
1346 rc_ok = yield self.dec2.e.do.rc.ok
1347 else:
1348 rc_en = False
1349 rc_ok = False
1350 # grrrr have to special-case MUL op (see DecodeOE)
1351 log("ov %d en %d rc %d en %d op %d" %
1352 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1353 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1354 log("mul op")
1355 if rc_en & rc_ok:
1356 asmop += "."
1357 else:
1358 if not asmop.endswith("."): # don't add "." to "andis."
1359 if rc_en & rc_ok:
1360 asmop += "."
1361 if hasattr(self.dec2.e.do, "lk"):
1362 lk = yield self.dec2.e.do.lk
1363 if lk:
1364 asmop += "l"
1365 log("int_op", int_op)
1366 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1367 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1368 log("AA", AA)
1369 if AA:
1370 asmop += "a"
1371 spr_msb = yield from self.get_spr_msb()
1372 if int_op == MicrOp.OP_MFCR.value:
1373 if spr_msb:
1374 asmop = 'mfocrf'
1375 else:
1376 asmop = 'mfcr'
1377 # XXX TODO: for whatever weird reason this doesn't work
1378 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1379 if int_op == MicrOp.OP_MTCRF.value:
1380 if spr_msb:
1381 asmop = 'mtocrf'
1382 else:
1383 asmop = 'mtcrf'
1384 return asmop
1385
1386 def get_remap_indices(self):
1387 """WARNING, this function stores remap_idxs and remap_loopends
1388 in the class for later use. this to avoid problems with yield
1389 """
1390 # go through all iterators in lock-step, advance to next remap_idx
1391 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1392 # get four SVSHAPEs. here we are hard-coding
1393 SVSHAPE0 = self.spr['SVSHAPE0']
1394 SVSHAPE1 = self.spr['SVSHAPE1']
1395 SVSHAPE2 = self.spr['SVSHAPE2']
1396 SVSHAPE3 = self.spr['SVSHAPE3']
1397 # set up the iterators
1398 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1399 (SVSHAPE1, SVSHAPE1.get_iterator()),
1400 (SVSHAPE2, SVSHAPE2.get_iterator()),
1401 (SVSHAPE3, SVSHAPE3.get_iterator()),
1402 ]
1403
1404 self.remap_loopends = [0] * 4
1405 self.remap_idxs = [0, 1, 2, 3]
1406 dbg = []
1407 for i, (shape, remap) in enumerate(remaps):
1408 # zero is "disabled"
1409 if shape.value == 0x0:
1410 self.remap_idxs[i] = 0
1411 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1412 step = dststep if (i in [3, 4]) else srcstep
1413 # this is terrible. O(N^2) looking for the match. but hey.
1414 for idx, (remap_idx, loopends) in enumerate(remap):
1415 if idx == step:
1416 break
1417 self.remap_idxs[i] = remap_idx
1418 self.remap_loopends[i] = loopends
1419 dbg.append((i, step, remap_idx, loopends))
1420 for (i, step, remap_idx, loopends) in dbg:
1421 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1422 return remaps
1423
1424 def get_spr_msb(self):
1425 dec_insn = yield self.dec2.e.do.insn
1426 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1427
1428 def call(self, name):
1429 """call(opcode) - the primary execution point for instructions
1430 """
1431 self.last_st_addr = None # reset the last known store address
1432 self.last_ld_addr = None # etc.
1433
1434 ins_name = name.strip() # remove spaces if not already done so
1435 if self.halted:
1436 log("halted - not executing", ins_name)
1437 return
1438
1439 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1440 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1441 asmop = yield from self.get_assembly_name()
1442 log("call", ins_name, asmop)
1443
1444 # sv.setvl is *not* a loop-function. sigh
1445 log("is_svp64_mode", self.is_svp64_mode, asmop)
1446
1447 # check privileged
1448 int_op = yield self.dec2.dec.op.internal_op
1449 spr_msb = yield from self.get_spr_msb()
1450
1451 instr_is_privileged = False
1452 if int_op in [MicrOp.OP_ATTN.value,
1453 MicrOp.OP_MFMSR.value,
1454 MicrOp.OP_MTMSR.value,
1455 MicrOp.OP_MTMSRD.value,
1456 # TODO: OP_TLBIE
1457 MicrOp.OP_RFID.value]:
1458 instr_is_privileged = True
1459 if int_op in [MicrOp.OP_MFSPR.value,
1460 MicrOp.OP_MTSPR.value] and spr_msb:
1461 instr_is_privileged = True
1462
1463 log("is priv", instr_is_privileged, hex(self.msr.value),
1464 self.msr[MSRb.PR])
1465 # check MSR priv bit and whether op is privileged: if so, throw trap
1466 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1467 self.call_trap(0x700, PIb.PRIV)
1468 return
1469
1470 # check halted condition
1471 if ins_name == 'attn':
1472 self.halted = True
1473 return
1474
1475 # check illegal instruction
1476 illegal = False
1477 if ins_name not in ['mtcrf', 'mtocrf']:
1478 illegal = ins_name != asmop
1479
1480 # list of instructions not being supported by binutils (.long)
1481 dotstrp = asmop[:-1] if asmop[-1] == '.' else asmop
1482 if dotstrp in [*FPTRANS_INSNS,
1483 'ffmadds', 'fdmadds', 'ffadds',
1484 'mins', 'maxs', 'minu', 'maxu',
1485 'setvl', 'svindex', 'svremap', 'svstep',
1486 'svshape', 'svshape2',
1487 'grev', 'ternlogi', 'bmask', 'cprop',
1488 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1489 'fmvis', 'fishmv', 'pcdec'
1490 ]:
1491 illegal = False
1492 ins_name = dotstrp
1493
1494 # branch-conditional redirects to sv.bc
1495 if asmop.startswith('bc') and self.is_svp64_mode:
1496 ins_name = 'sv.%s' % ins_name
1497
1498 log(" post-processed name", dotstrp, ins_name, asmop)
1499
1500 # illegal instructions call TRAP at 0x700
1501 if illegal:
1502 print("illegal", ins_name, asmop)
1503 self.call_trap(0x700, PIb.ILLEG)
1504 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1505 (ins_name, asmop, self.pc.CIA.value))
1506 return
1507
1508 # this is for setvl "Vertical" mode: if set true,
1509 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1510 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1511 self.allow_next_step_inc = False
1512 self.svstate_next_mode = 0
1513
1514 # nop has to be supported, we could let the actual op calculate
1515 # but PowerDecoder has a pattern for nop
1516 if ins_name == 'nop':
1517 self.update_pc_next()
1518 return
1519
1520 # look up instruction in ISA.instrs, prepare namespace
1521 info = self.instrs[ins_name]
1522 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1523
1524 # preserve order of register names
1525 input_names = create_args(list(info.read_regs) +
1526 list(info.uninit_regs))
1527 log("input names", input_names)
1528
1529 # get SVP64 entry for the current instruction
1530 sv_rm = self.svp64rm.instrs.get(ins_name)
1531 if sv_rm is not None:
1532 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1533 else:
1534 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1535 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1536
1537 # see if srcstep/dststep need skipping over masked-out predicate bits
1538 if (self.is_svp64_mode or ins_name in ['setvl', 'svremap', 'svstate']):
1539 yield from self.svstate_pre_inc()
1540 if self.is_svp64_mode:
1541 pre = yield from self.update_new_svstate_steps()
1542 if pre:
1543 self.svp64_reset_loop()
1544 self.update_nia()
1545 self.update_pc_next()
1546 return
1547 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1548 pred_dst_zero = self.pred_dst_zero
1549 pred_src_zero = self.pred_src_zero
1550 vl = self.svstate.vl
1551 subvl = yield self.dec2.rm_dec.rm_in.subvl
1552
1553 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1554 if self.is_svp64_mode and vl == 0:
1555 self.pc.update(self.namespace, self.is_svp64_mode)
1556 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1557 self.namespace['NIA'], kind=LogKind.InstrInOuts)
1558 return
1559
1560 # for when SVREMAP is active, using pre-arranged schedule.
1561 # note: modifying PowerDecoder2 needs to "settle"
1562 remap_en = self.svstate.SVme
1563 persist = self.svstate.RMpst
1564 active = (persist or self.last_op_svshape) and remap_en != 0
1565 if self.is_svp64_mode:
1566 yield self.dec2.remap_active.eq(remap_en if active else 0)
1567 yield Settle()
1568 if persist or self.last_op_svshape:
1569 remaps = self.get_remap_indices()
1570 if self.is_svp64_mode and (persist or self.last_op_svshape):
1571 yield from self.remap_set_steps(remaps)
1572 # after that, settle down (combinatorial) to let Vector reg numbers
1573 # work themselves out
1574 yield Settle()
1575 if self.is_svp64_mode:
1576 remap_active = yield self.dec2.remap_active
1577 else:
1578 remap_active = False
1579 log("remap active", bin(remap_active))
1580
1581 # main input registers (RT, RA ...)
1582 inputs = []
1583 for name in input_names:
1584 log("name", name)
1585 regval = (yield from self.get_input(name))
1586 log("regval", regval)
1587 inputs.append(regval)
1588
1589 # arrrrgh, awful hack, to get _RT into namespace
1590 if ins_name in ['setvl', 'svstep']:
1591 regname = "_RT"
1592 RT = yield self.dec2.dec.RT
1593 self.namespace[regname] = SelectableInt(RT, 5)
1594 if RT == 0:
1595 self.namespace["RT"] = SelectableInt(0, 5)
1596 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1597 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1598
1599 # in SVP64 mode for LD/ST work out immediate
1600 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1601 # use info.form to detect
1602 if self.is_svp64_mode:
1603 yield from self.check_replace_d(info, remap_active)
1604
1605 # "special" registers
1606 for special in info.special_regs:
1607 if special in special_sprs:
1608 inputs.append(self.spr[special])
1609 else:
1610 inputs.append(self.namespace[special])
1611
1612 # clear trap (trap) NIA
1613 self.trap_nia = None
1614
1615 # check if this was an sv.bc* and create an indicator that
1616 # this is the last check to be made as a loop. combined with
1617 # the ALL/ANY mode we can early-exit
1618 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
1619 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
1620 # XXX TODO - pack/unpack here
1621 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
1622 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
1623
1624 # execute actual instruction here (finally)
1625 log("inputs", inputs)
1626 results = info.func(self, *inputs)
1627 log("results", results)
1628
1629 # "inject" decorator takes namespace from function locals: we need to
1630 # overwrite NIA being overwritten (sigh)
1631 if self.trap_nia is not None:
1632 self.namespace['NIA'] = self.trap_nia
1633
1634 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1635
1636 # check if op was a LD/ST so that debugging can check the
1637 # address
1638 if int_op in [MicrOp.OP_STORE.value,
1639 ]:
1640 self.last_st_addr = self.mem.last_st_addr
1641 if int_op in [MicrOp.OP_LOAD.value,
1642 ]:
1643 self.last_ld_addr = self.mem.last_ld_addr
1644 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1645 self.last_st_addr, self.last_ld_addr)
1646
1647 # detect if CA/CA32 already in outputs (sra*, basically)
1648 already_done = 0
1649 output_names = []
1650 if info.write_regs:
1651 output_names = create_args(info.write_regs)
1652 for name in output_names:
1653 if name == 'CA':
1654 already_done |= 1
1655 if name == 'CA32':
1656 already_done |= 2
1657
1658 log("carry already done?", bin(already_done))
1659 carry_en = yield self.dec2.e.do.output_carry
1660 if carry_en:
1661 yield from self.handle_carry_(inputs, results, already_done)
1662
1663 # check if one of the regs was named "overflow"
1664 overflow = None
1665 if info.write_regs:
1666 for name, output in zip(output_names, results):
1667 if name == 'overflow':
1668 overflow = output
1669
1670 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1671 # detect if overflow was in return result
1672 ov_en = yield self.dec2.e.do.oe.oe
1673 ov_ok = yield self.dec2.e.do.oe.ok
1674 log("internal overflow", ins_name, overflow, "en?", ov_en, ov_ok)
1675 if ov_en & ov_ok:
1676 yield from self.handle_overflow(inputs, results, overflow)
1677
1678 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1679 rc_en = False
1680 if not self.is_svp64_mode or not pred_dst_zero:
1681 if hasattr(self.dec2.e.do, "rc"):
1682 rc_en = yield self.dec2.e.do.rc.rc
1683 if rc_en and ins_name not in ['svstep']:
1684 yield from self.do_rc_ov(ins_name, results, overflow)
1685
1686 # any modified return results?
1687 yield from self.do_outregs_nia(asmop, ins_name, info,
1688 output_names, results,
1689 carry_en, rc_en)
1690
1691 def do_rc_ov(self, ins_name, results, overflow):
1692 if ins_name.startswith("f"):
1693 rc_reg = "CR1" # not calculated correctly yet (not FP compares)
1694 else:
1695 rc_reg = "CR0"
1696 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, rc_reg)
1697 cmps = results
1698 # hang on... for `setvl` actually you want to test SVSTATE.VL
1699 is_setvl = ins_name == 'setvl'
1700 if is_setvl:
1701 vl = results[0].vl
1702 cmps = (SelectableInt(vl, 64), overflow,)
1703 else:
1704 overflow = None # do not override overflow except in setvl
1705 self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
1706
1707 def do_outregs_nia(self, asmop, ins_name, info, output_names, results,
1708 carry_en, rc_en):
1709 # write out any regs for this instruction
1710 if info.write_regs:
1711 for name, output in zip(output_names, results):
1712 yield from self.check_write(info, name, output, carry_en)
1713
1714 # check advancement of src/dst/sub-steps and if PC needs updating
1715 nia_update = (yield from self.check_step_increment(results, rc_en,
1716 asmop, ins_name))
1717 if nia_update:
1718 self.update_pc_next()
1719
1720 def check_replace_d(self, info, remap_active):
1721 replace_d = False # update / replace constant in pseudocode
1722 ldstmode = yield self.dec2.rm_dec.ldstmode
1723 vl = self.svstate.vl
1724 subvl = yield self.dec2.rm_dec.rm_in.subvl
1725 srcstep, dststep = self.new_srcstep, self.new_dststep
1726 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1727 if info.form == 'DS':
1728 # DS-Form, multiply by 4 then knock 2 bits off after
1729 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1730 else:
1731 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1732 imm = exts(imm, 16) # sign-extend to integer
1733 # get the right step. LD is from srcstep, ST is dststep
1734 op = yield self.dec2.e.do.insn_type
1735 offsmul = 0
1736 if op == MicrOp.OP_LOAD.value:
1737 if remap_active:
1738 offsmul = yield self.dec2.in1_step
1739 log("D-field REMAP src", imm, offsmul)
1740 else:
1741 offsmul = (srcstep * (subvl+1)) + ssubstep
1742 log("D-field src", imm, offsmul)
1743 elif op == MicrOp.OP_STORE.value:
1744 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1745 offsmul = (dststep * (subvl+1)) + dsubstep
1746 log("D-field dst", imm, offsmul)
1747 # Unit-Strided LD/ST adds offset*width to immediate
1748 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1749 ldst_len = yield self.dec2.e.do.data_len
1750 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1751 replace_d = True
1752 # Element-strided multiplies the immediate by element step
1753 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1754 imm = SelectableInt(imm * offsmul, 32)
1755 replace_d = True
1756 if replace_d:
1757 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1758 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1759 log("LDSTmode", SVP64LDSTmode(ldstmode),
1760 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1761 # new replacement D... errr.. DS
1762 if replace_d:
1763 if info.form == 'DS':
1764 # TODO: assert 2 LSBs are zero?
1765 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1766 imm.value = imm.value >> 2
1767 self.namespace['DS'] = imm
1768 else:
1769 self.namespace['D'] = imm
1770
1771 def get_input(self, name):
1772 # using PowerDecoder2, first, find the decoder index.
1773 # (mapping name RA RB RC RS to in1, in2, in3)
1774 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1775 if regnum is None:
1776 # doing this is not part of svp64, it's because output
1777 # registers, to be modified, need to be in the namespace.
1778 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1779 if regnum is None:
1780 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1781
1782 # in case getting the register number is needed, _RA, _RB
1783 regname = "_" + name
1784 self.namespace[regname] = regnum
1785 if not self.is_svp64_mode or not self.pred_src_zero:
1786 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1787 if name in fregs:
1788 reg_val = SelectableInt(self.fpr(regnum))
1789 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1790 elif name is not None:
1791 reg_val = SelectableInt(self.gpr(regnum))
1792 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1793 else:
1794 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1795 reg_val = 0
1796 return reg_val
1797
1798 def remap_set_steps(self, remaps):
1799 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1800 they work in concert with PowerDecoder2 at the moment,
1801 there is no HDL implementation of REMAP. therefore this
1802 function, because ISACaller still uses PowerDecoder2,
1803 will *explicitly* write the dec2.XX_step values. this has
1804 to get sorted out.
1805 """
1806 # just some convenient debug info
1807 for i in range(4):
1808 sname = 'SVSHAPE%d' % i
1809 shape = self.spr[sname]
1810 log(sname, bin(shape.value))
1811 log(" lims", shape.lims)
1812 log(" mode", shape.mode)
1813 log(" skip", shape.skip)
1814
1815 # set up the list of steps to remap
1816 mi0 = self.svstate.mi0
1817 mi1 = self.svstate.mi1
1818 mi2 = self.svstate.mi2
1819 mo0 = self.svstate.mo0
1820 mo1 = self.svstate.mo1
1821 steps = [(self.dec2.in1_step, mi0), # RA
1822 (self.dec2.in2_step, mi1), # RB
1823 (self.dec2.in3_step, mi2), # RC
1824 (self.dec2.o_step, mo0), # RT
1825 (self.dec2.o2_step, mo1), # EA
1826 ]
1827 remap_idxs = self.remap_idxs
1828 rremaps = []
1829 # now cross-index the required SHAPE for each of 3-in 2-out regs
1830 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1831 for i, (dstep, shape_idx) in enumerate(steps):
1832 (shape, remap) = remaps[shape_idx]
1833 remap_idx = remap_idxs[shape_idx]
1834 # zero is "disabled"
1835 if shape.value == 0x0:
1836 continue
1837 # now set the actual requested step to the current index
1838 yield dstep.eq(remap_idx)
1839
1840 # debug printout info
1841 rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
1842 for x in rremaps:
1843 log("shape remap", x)
1844
1845 def check_write(self, info, name, output, carry_en):
1846 if name == 'overflow': # ignore, done already (above)
1847 return
1848 if isinstance(output, int):
1849 output = SelectableInt(output, 256)
1850 # write carry flafs
1851 if name in ['CA', 'CA32']:
1852 if carry_en:
1853 log("writing %s to XER" % name, output)
1854 log("write XER %s 0x%x" % (name, output.value))
1855 self.spr['XER'][XER_bits[name]] = output.value
1856 else:
1857 log("NOT writing %s to XER" % name, output)
1858 return
1859 # write special SPRs
1860 if name in info.special_regs:
1861 log('writing special %s' % name, output, special_sprs)
1862 log("write reg %s 0x%x" % (name, output.value))
1863 if name in special_sprs:
1864 self.spr[name] = output
1865 else:
1866 self.namespace[name].eq(output)
1867 if name == 'MSR':
1868 log('msr written', hex(self.msr.value))
1869 return
1870 # find out1/out2 PR/FPR
1871 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1872 if regnum is None:
1873 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1874 if regnum is None:
1875 # temporary hack for not having 2nd output
1876 regnum = yield getattr(self.decoder, name)
1877 is_vec = False
1878 # convenient debug prefix
1879 if name in fregs:
1880 reg_prefix = 'f'
1881 else:
1882 reg_prefix = 'r'
1883 # check zeroing due to predicate bit being zero
1884 if self.is_svp64_mode and self.pred_dst_zero:
1885 log('zeroing reg %d %s' % (regnum, str(output)), is_vec)
1886 output = SelectableInt(0, 256)
1887 log("write reg %s%d 0x%x" % (reg_prefix, regnum, output.value),
1888 kind=LogKind.InstrInOuts)
1889 # zero-extend tov64 bit begore storing (should use EXT oh well)
1890 if output.bits > 64:
1891 output = SelectableInt(output.value, 64)
1892 if name in fregs:
1893 self.fpr[regnum] = output
1894 else:
1895 self.gpr[regnum] = output
1896
1897 def check_step_increment(self, results, rc_en, asmop, ins_name):
1898 # check if it is the SVSTATE.src/dest step that needs incrementing
1899 # this is our Sub-Program-Counter loop from 0 to VL-1
1900 if not self.allow_next_step_inc:
1901 if self.is_svp64_mode:
1902 return (yield from self.svstate_post_inc(ins_name))
1903
1904 # XXX only in non-SVP64 mode!
1905 # record state of whether the current operation was an svshape,
1906 # OR svindex!
1907 # to be able to know if it should apply in the next instruction.
1908 # also (if going to use this instruction) should disable ability
1909 # to interrupt in between. sigh.
1910 self.last_op_svshape = asmop in ['svremap', 'svindex',
1911 'svshape2']
1912 return True
1913
1914 pre = False
1915 post = False
1916 nia_update = True
1917 log("SVSTATE_NEXT: inc requested, mode",
1918 self.svstate_next_mode, self.allow_next_step_inc)
1919 yield from self.svstate_pre_inc()
1920 pre = yield from self.update_new_svstate_steps()
1921 if pre:
1922 # reset at end of loop including exit Vertical Mode
1923 log("SVSTATE_NEXT: end of loop, reset")
1924 self.svp64_reset_loop()
1925 self.svstate.vfirst = 0
1926 self.update_nia()
1927 if not rc_en:
1928 return True
1929 results = [SelectableInt(0, 64)]
1930 self.handle_comparison(results) # CR0
1931 return True
1932 if self.allow_next_step_inc == 2:
1933 log("SVSTATE_NEXT: read")
1934 nia_update = (yield from self.svstate_post_inc(ins_name))
1935 else:
1936 log("SVSTATE_NEXT: post-inc")
1937 # use actual src/dst-step here to check end, do NOT
1938 # use bit-reversed version
1939 srcstep, dststep = self.new_srcstep, self.new_dststep
1940 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1941 remaps = self.get_remap_indices()
1942 remap_idxs = self.remap_idxs
1943 vl = self.svstate.vl
1944 subvl = yield self.dec2.rm_dec.rm_in.subvl
1945 end_src = srcstep == vl-1
1946 end_dst = dststep == vl-1
1947 if self.allow_next_step_inc != 2:
1948 yield from self.advance_svstate_steps(end_src, end_dst)
1949 #self.namespace['SVSTATE'] = self.svstate.spr
1950 # set CR0 (if Rc=1) based on end
1951 if rc_en:
1952 endtest = 1 if (end_src or end_dst) else 0
1953 #results = [SelectableInt(endtest, 64)]
1954 # self.handle_comparison(results) # CR0
1955
1956 # see if svstep was requested, if so, which SVSTATE
1957 endings = 0b111
1958 if self.svstate_next_mode > 0:
1959 shape_idx = self.svstate_next_mode.value-1
1960 endings = self.remap_loopends[shape_idx]
1961 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
1962 log("svstep Rc=1, CR0", cr_field)
1963 self.crl[0].eq(cr_field) # CR0
1964 if end_src or end_dst:
1965 # reset at end of loop including exit Vertical Mode
1966 log("SVSTATE_NEXT: after increments, reset")
1967 self.svp64_reset_loop()
1968 self.svstate.vfirst = 0
1969 return nia_update
1970
1971 def SVSTATE_NEXT(self, mode, submode):
1972 """explicitly moves srcstep/dststep on to next element, for
1973 "Vertical-First" mode. this function is called from
1974 setvl pseudo-code, as a pseudo-op "svstep"
1975
1976 WARNING: this function uses information that was created EARLIER
1977 due to it being in the middle of a yield, but this function is
1978 *NOT* called from yield (it's called from compiled pseudocode).
1979 """
1980 self.allow_next_step_inc = submode.value + 1
1981 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
1982 self.svstate_next_mode = mode
1983 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
1984 shape_idx = self.svstate_next_mode.value-1
1985 return SelectableInt(self.remap_idxs[shape_idx], 7)
1986 if self.svstate_next_mode == 5:
1987 self.svstate_next_mode = 0
1988 return SelectableInt(self.svstate.srcstep, 7)
1989 if self.svstate_next_mode == 6:
1990 self.svstate_next_mode = 0
1991 return SelectableInt(self.svstate.dststep, 7)
1992 return SelectableInt(0, 7)
1993
1994 def get_src_dststeps(self):
1995 """gets srcstep, dststep, and ssubstep, dsubstep
1996 """
1997 return (self.new_srcstep, self.new_dststep,
1998 self.new_ssubstep, self.new_dsubstep)
1999
2000 def update_new_svstate_steps(self):
2001 # note, do not get the bit-reversed srcstep here!
2002 srcstep, dststep = self.new_srcstep, self.new_dststep
2003 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
2004
2005 # update SVSTATE with new srcstep
2006 self.svstate.srcstep = srcstep
2007 self.svstate.dststep = dststep
2008 self.svstate.ssubstep = ssubstep
2009 self.svstate.dsubstep = dsubstep
2010 self.namespace['SVSTATE'] = self.svstate
2011 yield self.dec2.state.svstate.eq(self.svstate.value)
2012 yield Settle() # let decoder update
2013 srcstep = self.svstate.srcstep
2014 dststep = self.svstate.dststep
2015 ssubstep = self.svstate.ssubstep
2016 dsubstep = self.svstate.dsubstep
2017 pack = self.svstate.pack
2018 unpack = self.svstate.unpack
2019 vl = self.svstate.vl
2020 subvl = yield self.dec2.rm_dec.rm_in.subvl
2021 log(" srcstep", srcstep)
2022 log(" dststep", dststep)
2023 log(" pack", pack)
2024 log(" unpack", unpack)
2025 log(" ssubstep", ssubstep)
2026 log(" dsubstep", dsubstep)
2027 log(" vl", vl)
2028 log(" subvl", subvl)
2029
2030 # check if end reached (we let srcstep overrun, above)
2031 # nothing needs doing (TODO zeroing): just do next instruction
2032 return ((ssubstep == subvl and srcstep == vl) or
2033 (dsubstep == subvl and dststep == vl))
2034
2035 def svstate_post_inc(self, insn_name, vf=0):
2036 # check if SV "Vertical First" mode is enabled
2037 vfirst = self.svstate.vfirst
2038 log(" SV Vertical First", vf, vfirst)
2039 if not vf and vfirst == 1:
2040 self.update_nia()
2041 return True
2042
2043 # check if it is the SVSTATE.src/dest step that needs incrementing
2044 # this is our Sub-Program-Counter loop from 0 to VL-1
2045 # XXX twin predication TODO
2046 vl = self.svstate.vl
2047 subvl = yield self.dec2.rm_dec.rm_in.subvl
2048 mvl = self.svstate.maxvl
2049 srcstep = self.svstate.srcstep
2050 dststep = self.svstate.dststep
2051 ssubstep = self.svstate.ssubstep
2052 dsubstep = self.svstate.dsubstep
2053 pack = self.svstate.pack
2054 unpack = self.svstate.unpack
2055 rm_mode = yield self.dec2.rm_dec.mode
2056 reverse_gear = yield self.dec2.rm_dec.reverse_gear
2057 sv_ptype = yield self.dec2.dec.op.SV_Ptype
2058 out_vec = not (yield self.dec2.no_out_vec)
2059 in_vec = not (yield self.dec2.no_in_vec)
2060 log(" svstate.vl", vl)
2061 log(" svstate.mvl", mvl)
2062 log(" rm.subvl", subvl)
2063 log(" svstate.srcstep", srcstep)
2064 log(" svstate.dststep", dststep)
2065 log(" svstate.ssubstep", ssubstep)
2066 log(" svstate.dsubstep", dsubstep)
2067 log(" svstate.pack", pack)
2068 log(" svstate.unpack", unpack)
2069 log(" mode", rm_mode)
2070 log(" reverse", reverse_gear)
2071 log(" out_vec", out_vec)
2072 log(" in_vec", in_vec)
2073 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
2074 # check if this was an sv.bc* and if so did it succeed
2075 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
2076 end_loop = self.namespace['end_loop']
2077 log("branch %s end_loop" % insn_name, end_loop)
2078 if end_loop.value:
2079 self.svp64_reset_loop()
2080 self.update_pc_next()
2081 return False
2082 # check if srcstep needs incrementing by one, stop PC advancing
2083 # but for 2-pred both src/dest have to be checked.
2084 # XXX this might not be true! it may just be LD/ST
2085 if sv_ptype == SVPtype.P2.value:
2086 svp64_is_vector = (out_vec or in_vec)
2087 else:
2088 svp64_is_vector = out_vec
2089 # loops end at the first "hit" (source or dest)
2090 end_src = srcstep == vl-1
2091 end_dst = dststep == vl-1
2092 loopend = ((end_src and ssubstep == subvl) or
2093 (end_dst and dsubstep == subvl))
2094 log("loopend", svp64_is_vector, loopend, end_src, end_dst,
2095 ssubstep == subvl, dsubstep == subvl)
2096 if not svp64_is_vector or loopend:
2097 # reset loop to zero and update NIA
2098 self.svp64_reset_loop()
2099 self.update_nia()
2100
2101 return True
2102
2103 # still looping, advance and update NIA
2104 yield from self.advance_svstate_steps(end_src, end_dst)
2105 self.namespace['SVSTATE'] = self.svstate
2106
2107 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2108 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2109 # this way we keep repeating the same instruction (with new steps)
2110 self.pc.NIA.value = self.pc.CIA.value
2111 self.namespace['NIA'] = self.pc.NIA
2112 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
2113 return False # DO NOT allow PC update whilst Sub-PC loop running
2114
2115 def update_pc_next(self):
2116 # UPDATE program counter
2117 self.pc.update(self.namespace, self.is_svp64_mode)
2118 #self.svstate.spr = self.namespace['SVSTATE']
2119 log("end of call", self.namespace['CIA'],
2120 self.namespace['NIA'],
2121 self.namespace['SVSTATE'])
2122
2123 def svp64_reset_loop(self):
2124 self.svstate.srcstep = 0
2125 self.svstate.dststep = 0
2126 self.svstate.ssubstep = 0
2127 self.svstate.dsubstep = 0
2128 log(" svstate.srcstep loop end (PC to update)")
2129 self.namespace['SVSTATE'] = self.svstate
2130
2131 def update_nia(self):
2132 self.pc.update_nia(self.is_svp64_mode)
2133 self.namespace['NIA'] = self.pc.NIA
2134
2135
2136 def inject():
2137 """Decorator factory.
2138
2139 this decorator will "inject" variables into the function's namespace,
2140 from the *dictionary* in self.namespace. it therefore becomes possible
2141 to make it look like a whole stack of variables which would otherwise
2142 need "self." inserted in front of them (*and* for those variables to be
2143 added to the instance) "appear" in the function.
2144
2145 "self.namespace['SI']" for example becomes accessible as just "SI" but
2146 *only* inside the function, when decorated.
2147 """
2148 def variable_injector(func):
2149 @wraps(func)
2150 def decorator(*args, **kwargs):
2151 try:
2152 func_globals = func.__globals__ # Python 2.6+
2153 except AttributeError:
2154 func_globals = func.func_globals # Earlier versions.
2155
2156 context = args[0].namespace # variables to be injected
2157 saved_values = func_globals.copy() # Shallow copy of dict.
2158 log("globals before", context.keys())
2159 func_globals.update(context)
2160 result = func(*args, **kwargs)
2161 log("globals after", func_globals['CIA'], func_globals['NIA'])
2162 log("args[0]", args[0].namespace['CIA'],
2163 args[0].namespace['NIA'],
2164 args[0].namespace['SVSTATE'])
2165 if 'end_loop' in func_globals:
2166 log("args[0] end_loop", func_globals['end_loop'])
2167 args[0].namespace = func_globals
2168 #exec (func.__code__, func_globals)
2169
2170 # finally:
2171 # func_globals = saved_values # Undo changes.
2172
2173 return result
2174
2175 return decorator
2176
2177 return variable_injector