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