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