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