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