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