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
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.
13 * https://bugs.libre-soc.org/show_bug.cgi?id=424
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 (
26 from openpower
.decoder
.power_insn
import SVP64Instruction
27 from openpower
.decoder
.power_enums
import (spr_dict
, spr_byname
, XER_bits
,
29 In1Sel
, In2Sel
, In3Sel
,
30 OutSel
, CRInSel
, CROutSel
, LDSTMode
,
32 SVP64RMMode
, SVP64PredMode
,
33 SVP64PredInt
, SVP64PredCR
,
34 SVP64LDSTmode
, FPTRANS_INSNS
)
36 from openpower
.decoder
.power_enums
import SVPtype
38 from openpower
.decoder
.helpers
import (exts
, gtu
, ltu
, undefined
,
39 ISACallerHelper
, ISAFPHelpers
)
40 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
41 from openpower
.consts
import (SVP64MODE
, SVP64MODEb
,
44 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
46 from openpower
.decoder
.isa
.radixmmu
import RADIX
47 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
48 from openpower
.decoder
.isa
.svshape
import SVSHAPE
49 from openpower
.decoder
.isa
.svstate
import SVP64State
52 from openpower
.util
import LogKind
, log
54 from collections
import namedtuple
58 instruction_info
= namedtuple('instruction_info',
59 'func read_regs uninit_regs write_regs ' +
60 'special_regs op_fields form asmregs')
70 # rrright. this is here basically because the compiler pywriter returns
71 # results in a specific priority order. to make sure regs match up they
72 # need partial sorting. sigh.
74 # TODO (lkcl): adjust other registers that should be in a particular order
75 # probably CA, CA32, and CR
101 "overflow": 7, # should definitely be last
105 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
108 def create_args(reglist
, extra
=None):
109 retval
= list(OrderedSet(reglist
))
110 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
111 if extra
is not None:
112 return [extra
] + retval
117 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
120 self
.isacaller
= isacaller
121 self
.svstate
= svstate
122 for i
in range(len(regfile
)):
123 self
[i
] = SelectableInt(regfile
[i
], 64)
125 def __call__(self
, ridx
, is_vec
=False, offs
=0, elwidth
=64):
126 if isinstance(ridx
, SelectableInt
):
129 return self
[ridx
+offs
]
130 # rrrright. start by breaking down into row/col, based on elwidth
131 gpr_offs
= offs
// (64//elwidth
)
132 gpr_col
= offs
% (64//elwidth
)
133 # now select the 64-bit register, but get its value (easier)
134 val
= self
[ridx
+gpr_offs
].value
135 # now shift down and mask out
136 val
= val
>> (gpr_col
*elwidth
) & ((1<<elwidth
)-1)
137 # finally, return a SelectableInt at the required elwidth
138 log("GPR call", ridx
, "isvec", is_vec
, "offs", offs
,
139 "elwid", elwidth
, "offs/col", gpr_offs
, gpr_col
, "val", hex(val
))
140 return SelectableInt(val
, elwidth
)
142 def set_form(self
, form
):
145 def write(self
, rnum
, value
, is_vec
=False, elwidth
=64):
147 if isinstance(rnum
, SelectableInt
):
149 if isinstance(value
, SelectableInt
):
152 if isinstance(rnum
, tuple):
153 rnum
, base
, offs
= rnum
156 # rrrright. start by breaking down into row/col, based on elwidth
157 gpr_offs
= offs
// (64//elwidth
)
158 gpr_col
= offs
% (64//elwidth
)
159 # compute the mask based on elwidth
160 mask
= (1<<elwidth
)-1
161 # now select the 64-bit register, but get its value (easier)
162 val
= self
[base
+gpr_offs
].value
163 # now mask out the bit we don't want
164 val
= val
& ~
(mask
<< (gpr_col
*elwidth
))
165 # then wipe the bit we don't want from the value
167 # OR the new value in, shifted up
168 val |
= value
<< (gpr_col
*elwidth
)
169 # finally put the damn value into the regfile
170 log("GPR write", base
, "isvec", is_vec
, "offs", offs
,
171 "elwid", elwidth
, "offs/col", gpr_offs
, gpr_col
, "val", hex(val
),
173 dict.__setitem
__(self
, base
+gpr_offs
, SelectableInt(val
, 64))
175 def __setitem__(self
, rnum
, value
):
176 # rnum = rnum.value # only SelectableInt allowed
177 log("GPR setitem", rnum
, value
)
178 if isinstance(rnum
, SelectableInt
):
180 dict.__setitem
__(self
, rnum
, value
)
182 def getz(self
, rnum
):
183 # rnum = rnum.value # only SelectableInt allowed
184 log("GPR getzero?", rnum
)
186 return SelectableInt(0, 64)
189 def _get_regnum(self
, attr
):
190 getform
= self
.sd
.sigforms
[self
.form
]
191 rnum
= getattr(getform
, attr
)
194 def ___getitem__(self
, attr
):
195 """ XXX currently not used
197 rnum
= self
._get
_regnum
(attr
)
198 log("GPR getitem", attr
, rnum
)
199 return self
.regfile
[rnum
]
201 def dump(self
, printout
=True):
203 for i
in range(len(self
)):
204 res
.append(self
[i
].value
)
206 for i
in range(0, len(res
), 8):
209 s
.append("%08x" % res
[i
+j
])
211 print("reg", "%2d" % i
, s
)
216 def __init__(self
, dec2
, initial_sprs
={}):
219 for key
, v
in initial_sprs
.items():
220 if isinstance(key
, SelectableInt
):
222 key
= special_sprs
.get(key
, key
)
223 if isinstance(key
, int):
226 info
= spr_byname
[key
]
227 if not isinstance(v
, SelectableInt
):
228 v
= SelectableInt(v
, info
.length
)
231 def __getitem__(self
, key
):
233 log("dict", self
.items())
234 # if key in special_sprs get the special spr, otherwise return key
235 if isinstance(key
, SelectableInt
):
237 if isinstance(key
, int):
238 key
= spr_dict
[key
].SPR
239 key
= special_sprs
.get(key
, key
)
240 if key
== 'HSRR0': # HACK!
242 if key
== 'HSRR1': # HACK!
245 res
= dict.__getitem
__(self
, key
)
247 if isinstance(key
, int):
250 info
= spr_byname
[key
]
251 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
252 res
= dict.__getitem
__(self
, key
)
253 log("spr returning", key
, res
)
256 def __setitem__(self
, key
, value
):
257 if isinstance(key
, SelectableInt
):
259 if isinstance(key
, int):
260 key
= spr_dict
[key
].SPR
262 key
= special_sprs
.get(key
, key
)
263 if key
== 'HSRR0': # HACK!
264 self
.__setitem
__('SRR0', value
)
265 if key
== 'HSRR1': # HACK!
266 self
.__setitem
__('SRR1', value
)
267 log("setting spr", key
, value
)
268 dict.__setitem
__(self
, key
, value
)
270 def __call__(self
, ridx
):
273 def dump(self
, printout
=True):
275 keys
= list(self
.keys())
278 sprname
= spr_dict
.get(k
, None)
282 sprname
= sprname
.SPR
283 res
.append((sprname
, self
[k
].value
))
285 for sprname
, value
in res
:
286 print(" ", sprname
, hex(value
))
291 def __init__(self
, pc_init
=0):
292 self
.CIA
= SelectableInt(pc_init
, 64)
293 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
295 def update_nia(self
, is_svp64
):
296 increment
= 8 if is_svp64
else 4
297 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
299 def update(self
, namespace
, is_svp64
):
300 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
302 self
.CIA
= namespace
['NIA'].narrow(64)
303 self
.update_nia(is_svp64
)
304 namespace
['CIA'] = self
.CIA
305 namespace
['NIA'] = self
.NIA
309 # See PowerISA Version 3.0 B Book 1
310 # Section 2.3.1 Condition Register pages 30 - 31
312 LT
= FL
= 0 # negative, less than, floating-point less than
313 GT
= FG
= 1 # positive, greater than, floating-point greater than
314 EQ
= FE
= 2 # equal, floating-point equal
315 SO
= FU
= 3 # summary overflow, floating-point unordered
317 def __init__(self
, init
=0):
318 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
319 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
320 self
.cr
= SelectableInt(init
, 64) # underlying reg
321 # field-selectable versions of Condition Register TODO check bitranges?
324 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
325 _cr
= FieldSelectableInt(self
.cr
, bits
)
329 # decode SVP64 predicate integer to reg number and invert
330 def get_predint(gpr
, mask
):
334 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
335 if mask
== SVP64PredInt
.ALWAYS
.value
:
336 return 0xffff_ffff_ffff_ffff # 64 bits of 1
337 if mask
== SVP64PredInt
.R3_UNARY
.value
:
338 return 1 << (r3
.value
& 0b111111)
339 if mask
== SVP64PredInt
.R3
.value
:
341 if mask
== SVP64PredInt
.R3_N
.value
:
343 if mask
== SVP64PredInt
.R10
.value
:
345 if mask
== SVP64PredInt
.R10_N
.value
:
347 if mask
== SVP64PredInt
.R30
.value
:
349 if mask
== SVP64PredInt
.R30_N
.value
:
353 # decode SVP64 predicate CR to reg number and invert status
354 def _get_predcr(mask
):
355 if mask
== SVP64PredCR
.LT
.value
:
357 if mask
== SVP64PredCR
.GE
.value
:
359 if mask
== SVP64PredCR
.GT
.value
:
361 if mask
== SVP64PredCR
.LE
.value
:
363 if mask
== SVP64PredCR
.EQ
.value
:
365 if mask
== SVP64PredCR
.NE
.value
:
367 if mask
== SVP64PredCR
.SO
.value
:
369 if mask
== SVP64PredCR
.NS
.value
:
373 # read individual CR fields (0..VL-1), extract the required bit
374 # and construct the mask
375 def get_predcr(crl
, mask
, vl
):
376 idx
, noninv
= _get_predcr(mask
)
379 cr
= crl
[i
+SVP64CROffs
.CRPred
]
380 if cr
[idx
].value
== noninv
:
385 # TODO, really should just be using PowerDecoder2
386 def get_idx_in(dec2
, name
, ewmode
=False):
388 in1_sel
= yield op
.in1_sel
389 in2_sel
= yield op
.in2_sel
390 in3_sel
= yield op
.in3_sel
391 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
392 in1
= yield dec2
.e
.read_reg1
.data
393 in2
= yield dec2
.e
.read_reg2
.data
394 in3
= yield dec2
.e
.read_reg3
.data
396 in1_base
= yield dec2
.e
.read_reg1
.base
397 in2_base
= yield dec2
.e
.read_reg2
.base
398 in3_base
= yield dec2
.e
.read_reg3
.base
399 in1_offs
= yield dec2
.e
.read_reg1
.offs
400 in2_offs
= yield dec2
.e
.read_reg2
.offs
401 in3_offs
= yield dec2
.e
.read_reg3
.offs
402 in1
= (in1
, in1_base
, in1_offs
)
403 in2
= (in2
, in2_base
, in2_offs
)
404 in3
= (in3
, in3_base
, in3_offs
)
406 in1_isvec
= yield dec2
.in1_isvec
407 in2_isvec
= yield dec2
.in2_isvec
408 in3_isvec
= yield dec2
.in3_isvec
409 log("get_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
411 log("get_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
413 log("get_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
415 log("get_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
417 log("get_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
419 log("get_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
421 # identify which regnames map to in1/2/3
422 if name
== 'RA' or name
== 'RA_OR_ZERO':
423 if (in1_sel
== In1Sel
.RA
.value
or
424 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
425 return in1
, in1_isvec
426 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
427 return in1
, in1_isvec
429 if in2_sel
== In2Sel
.RB
.value
:
430 return in2
, in2_isvec
431 if in3_sel
== In3Sel
.RB
.value
:
432 return in3
, in3_isvec
433 # XXX TODO, RC doesn't exist yet!
435 if in3_sel
== In3Sel
.RC
.value
:
436 return in3
, in3_isvec
437 assert False, "RC does not exist yet"
439 if in1_sel
== In1Sel
.RS
.value
:
440 return in1
, in1_isvec
441 if in2_sel
== In2Sel
.RS
.value
:
442 return in2
, in2_isvec
443 if in3_sel
== In3Sel
.RS
.value
:
444 return in3
, in3_isvec
446 if in1_sel
== In1Sel
.FRA
.value
:
447 return in1
, in1_isvec
449 if in2_sel
== In2Sel
.FRB
.value
:
450 return in2
, in2_isvec
452 if in3_sel
== In3Sel
.FRC
.value
:
453 return in3
, in3_isvec
455 if in1_sel
== In1Sel
.FRS
.value
:
456 return in1
, in1_isvec
457 if in3_sel
== In3Sel
.FRS
.value
:
458 return in3
, in3_isvec
462 # TODO, really should just be using PowerDecoder2
463 def get_cr_in(dec2
, name
):
465 in_sel
= yield op
.cr_in
466 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
467 sv_cr_in
= yield op
.sv_cr_in
468 spec
= yield dec2
.crin_svdec
.spec
469 sv_override
= yield dec2
.dec_cr_in
.sv_override
470 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
471 in1
= yield dec2
.e
.read_cr1
.data
472 cr_isvec
= yield dec2
.cr_in_isvec
473 log("get_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
474 log(" sv_cr_in", sv_cr_in
)
475 log(" cr_bf", in_bitfield
)
477 log(" override", sv_override
)
478 # identify which regnames map to in / o2
480 if in_sel
== CRInSel
.BI
.value
:
482 log("get_cr_in not found", name
)
486 # TODO, really should just be using PowerDecoder2
487 def get_cr_out(dec2
, name
):
489 out_sel
= yield op
.cr_out
490 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
491 sv_cr_out
= yield op
.sv_cr_out
492 spec
= yield dec2
.crout_svdec
.spec
493 sv_override
= yield dec2
.dec_cr_out
.sv_override
494 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
495 out
= yield dec2
.e
.write_cr
.data
496 o_isvec
= yield dec2
.cr_out_isvec
497 log("get_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
498 log(" sv_cr_out", sv_cr_out
)
499 log(" cr_bf", out_bitfield
)
501 log(" override", sv_override
)
502 # identify which regnames map to out / o2
504 if out_sel
== CROutSel
.BF
.value
:
507 if out_sel
== CROutSel
.CR0
.value
:
509 if name
== 'CR1': # these are not actually calculated correctly
510 if out_sel
== CROutSel
.CR1
.value
:
512 log("get_cr_out not found", name
)
516 # TODO, really should just be using PowerDecoder2
517 def get_idx_out(dec2
, name
, ewmode
=False):
519 out_sel
= yield op
.out_sel
520 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
521 out
= yield dec2
.e
.write_reg
.data
522 o_isvec
= yield dec2
.o_isvec
524 offs
= yield dec2
.e
.write_reg
.offs
525 base
= yield dec2
.e
.write_reg
.base
526 out
= (out
, base
, offs
)
527 # identify which regnames map to out / o2
529 log("get_idx_out", out_sel
, out
, o_isvec
)
531 log("get_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
532 if out_sel
== OutSel
.RA
.value
:
535 log("get_idx_out", out_sel
, OutSel
.RT
.value
,
536 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
538 if out_sel
== OutSel
.RT
.value
:
540 if out_sel
== OutSel
.RT_OR_ZERO
.value
and out
!= 0:
542 elif name
== 'RT_OR_ZERO':
543 log("get_idx_out", out_sel
, OutSel
.RT
.value
,
544 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
546 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
549 log("get_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
550 if out_sel
== OutSel
.FRA
.value
:
553 log("get_idx_out", out_sel
, OutSel
.FRT
.value
,
554 OutSel
.FRT
.value
, out
, o_isvec
)
555 if out_sel
== OutSel
.FRT
.value
:
557 log("get_idx_out not found", name
, out_sel
, out
, o_isvec
)
561 # TODO, really should just be using PowerDecoder2
562 def get_idx_out2(dec2
, name
):
563 # check first if register is activated for write
565 out_sel
= yield op
.out_sel
566 out
= yield dec2
.e
.write_ea
.data
567 o_isvec
= yield dec2
.o2_isvec
568 out_ok
= yield dec2
.e
.write_ea
.ok
569 log("get_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
574 if hasattr(op
, "upd"):
575 # update mode LD/ST uses read-reg A also as an output
577 log("get_idx_out2", upd
, LDSTMode
.update
.value
,
578 out_sel
, OutSel
.RA
.value
,
580 if upd
== LDSTMode
.update
.value
:
583 fft_en
= yield dec2
.implicit_rs
585 log("get_idx_out2", out_sel
, OutSel
.RS
.value
,
589 fft_en
= yield dec2
.implicit_rs
591 log("get_idx_out2", out_sel
, OutSel
.FRS
.value
,
598 """deals with svstate looping.
601 def __init__(self
, svstate
):
602 self
.svstate
= svstate
605 def new_iterators(self
):
606 self
.src_it
= self
.src_iterator()
607 self
.dst_it
= self
.dst_iterator()
611 self
.new_ssubstep
= 0
612 self
.new_dsubstep
= 0
613 self
.pred_dst_zero
= 0
614 self
.pred_src_zero
= 0
616 def src_iterator(self
):
617 """source-stepping iterator
619 pack
= self
.svstate
.pack
623 # pack advances subvl in *outer* loop
624 while True: # outer subvl loop
625 while True: # inner vl loop
628 srcmask
= self
.srcmask
629 srcstep
= self
.svstate
.srcstep
630 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
631 if self
.pred_sz
or pred_src_zero
:
632 self
.pred_src_zero
= not pred_src_zero
633 log(" advance src", srcstep
, vl
,
634 self
.svstate
.ssubstep
, subvl
)
635 # yield actual substep/srcstep
636 yield (self
.svstate
.ssubstep
, srcstep
)
637 # the way yield works these could have been modified.
640 srcstep
= self
.svstate
.srcstep
641 log(" advance src check", srcstep
, vl
,
642 self
.svstate
.ssubstep
, subvl
, srcstep
== vl
-1,
643 self
.svstate
.ssubstep
== subvl
)
644 if srcstep
== vl
-1: # end-point
645 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
646 if self
.svstate
.ssubstep
== subvl
: # end-point
647 log(" advance pack stop")
649 break # exit inner loop
650 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance ss
652 if self
.svstate
.ssubstep
== subvl
: # end-point
653 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
654 log(" advance pack stop")
656 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
659 # these cannot be done as for-loops because SVSTATE may change
660 # (srcstep/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
667 srcmask
= self
.srcmask
668 srcstep
= self
.svstate
.srcstep
669 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
670 if self
.pred_sz
or pred_src_zero
:
671 self
.pred_src_zero
= not pred_src_zero
672 log(" advance src", srcstep
, vl
,
673 self
.svstate
.ssubstep
, subvl
)
674 # yield actual substep/srcstep
675 yield (self
.svstate
.ssubstep
, srcstep
)
676 if self
.svstate
.ssubstep
== subvl
: # end-point
677 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
678 break # exit inner loop
679 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
681 if srcstep
== vl
-1: # end-point
682 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
685 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
687 def dst_iterator(self
):
688 """dest-stepping iterator
690 unpack
= self
.svstate
.unpack
694 # pack advances subvl in *outer* loop
695 while True: # outer subvl loop
696 while True: # inner vl loop
699 dstmask
= self
.dstmask
700 dststep
= self
.svstate
.dststep
701 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
702 if self
.pred_dz
or pred_dst_zero
:
703 self
.pred_dst_zero
= not pred_dst_zero
704 log(" advance dst", dststep
, vl
,
705 self
.svstate
.dsubstep
, subvl
)
706 # yield actual substep/dststep
707 yield (self
.svstate
.dsubstep
, dststep
)
708 # the way yield works these could have been modified.
710 dststep
= self
.svstate
.dststep
711 log(" advance dst check", dststep
, vl
,
712 self
.svstate
.ssubstep
, subvl
)
713 if dststep
== vl
-1: # end-point
714 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
715 if self
.svstate
.dsubstep
== subvl
: # end-point
716 log(" advance unpack stop")
719 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance ds
721 if self
.svstate
.dsubstep
== subvl
: # end-point
722 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
723 log(" advance unpack stop")
725 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
727 # these cannot be done as for-loops because SVSTATE may change
728 # (dststep/substep may be modified, interrupted, subvl/vl change)
729 # but they *can* be done as while-loops as long as every SVSTATE
730 # "thing" is re-read every single time a yield gives indices
731 while True: # outer vl loop
732 while True: # inner subvl loop
734 dstmask
= self
.dstmask
735 dststep
= self
.svstate
.dststep
736 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
737 if self
.pred_dz
or pred_dst_zero
:
738 self
.pred_dst_zero
= not pred_dst_zero
739 log(" advance dst", dststep
, self
.svstate
.vl
,
740 self
.svstate
.dsubstep
, subvl
)
741 # yield actual substep/dststep
742 yield (self
.svstate
.dsubstep
, dststep
)
743 if self
.svstate
.dsubstep
== subvl
: # end-point
744 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
746 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
749 if dststep
== vl
-1: # end-point
750 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
752 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
754 def src_iterate(self
):
755 """source-stepping iterator
759 pack
= self
.svstate
.pack
760 unpack
= self
.svstate
.unpack
761 ssubstep
= self
.svstate
.ssubstep
762 end_ssub
= ssubstep
== subvl
763 end_src
= self
.svstate
.srcstep
== vl
-1
764 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
768 srcstep
= self
.svstate
.srcstep
769 srcmask
= self
.srcmask
771 # pack advances subvl in *outer* loop
773 assert srcstep
<= vl
-1
774 end_src
= srcstep
== vl
-1
779 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
783 srcstep
+= 1 # advance srcstep
784 if not self
.srcstep_skip
:
786 if ((1 << srcstep
) & srcmask
) != 0:
789 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
791 # advance subvl in *inner* loop
794 assert srcstep
<= vl
-1
795 end_src
= srcstep
== vl
-1
796 if end_src
: # end-point
802 if not self
.srcstep_skip
:
804 if ((1 << srcstep
) & srcmask
) != 0:
807 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
808 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
811 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
813 self
.svstate
.srcstep
= SelectableInt(srcstep
, 7)
814 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
817 def dst_iterate(self
):
818 """dest step iterator
822 pack
= self
.svstate
.pack
823 unpack
= self
.svstate
.unpack
824 dsubstep
= self
.svstate
.dsubstep
825 end_dsub
= dsubstep
== subvl
826 dststep
= self
.svstate
.dststep
827 end_dst
= dststep
== vl
-1
828 dstmask
= self
.dstmask
829 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
834 # unpack advances subvl in *outer* loop
836 assert dststep
<= vl
-1
837 end_dst
= dststep
== vl
-1
842 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
846 dststep
+= 1 # advance dststep
847 if not self
.dststep_skip
:
849 if ((1 << dststep
) & dstmask
) != 0:
852 log(" dskip", bin(dstmask
), bin(1 << dststep
))
854 # advance subvl in *inner* loop
857 assert dststep
<= vl
-1
858 end_dst
= dststep
== vl
-1
859 if end_dst
: # end-point
865 if not self
.dststep_skip
:
867 if ((1 << dststep
) & dstmask
) != 0:
870 log(" dskip", bin(dstmask
), bin(1 << dststep
))
871 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
874 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
876 self
.svstate
.dststep
= SelectableInt(dststep
, 7)
877 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
880 def at_loopend(self
):
881 """tells if this is the last possible element. uses the cached values
882 for src/dst-step and sub-steps
886 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
887 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
888 end_ssub
= ssubstep
== subvl
889 end_dsub
= dsubstep
== subvl
890 if srcstep
== vl
-1 and end_ssub
:
892 if dststep
== vl
-1 and end_dsub
:
896 def advance_svstate_steps(self
):
897 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
898 TODO when Pack/Unpack is set, substep becomes the *outer* loop
900 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
901 if self
.loopend
: # huhn??
906 def read_src_mask(self
):
907 """read/update pred_sz and src mask
909 # get SVSTATE VL (oh and print out some debug stuff)
911 srcstep
= self
.svstate
.srcstep
912 ssubstep
= self
.svstate
.ssubstep
914 # get predicate mask (all 64 bits)
915 srcmask
= 0xffff_ffff_ffff_ffff
917 pmode
= yield self
.dec2
.rm_dec
.predmode
918 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
919 srcpred
= yield self
.dec2
.rm_dec
.srcpred
920 dstpred
= yield self
.dec2
.rm_dec
.dstpred
921 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
922 if pmode
== SVP64PredMode
.INT
.value
:
923 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
924 if sv_ptype
== SVPtype
.P2
.value
:
925 srcmask
= get_predint(self
.gpr
, srcpred
)
926 elif pmode
== SVP64PredMode
.CR
.value
:
927 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
928 if sv_ptype
== SVPtype
.P2
.value
:
929 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
930 # work out if the ssubsteps are completed
931 ssubstart
= ssubstep
== 0
933 log(" ptype", sv_ptype
)
934 log(" srcpred", bin(srcpred
))
935 log(" srcmask", bin(srcmask
))
936 log(" pred_sz", bin(pred_sz
))
937 log(" ssubstart", ssubstart
)
939 # store all that above
940 self
.srcstep_skip
= False
941 self
.srcmask
= srcmask
942 self
.pred_sz
= pred_sz
943 self
.new_ssubstep
= ssubstep
944 log(" new ssubstep", ssubstep
)
945 # until the predicate mask has a "1" bit... or we run out of VL
946 # let srcstep==VL be the indicator to move to next instruction
948 self
.srcstep_skip
= True
950 def read_dst_mask(self
):
951 """same as read_src_mask - check and record everything needed
953 # get SVSTATE VL (oh and print out some debug stuff)
954 # yield Delay(1e-10) # make changes visible
956 dststep
= self
.svstate
.dststep
957 dsubstep
= self
.svstate
.dsubstep
959 # get predicate mask (all 64 bits)
960 dstmask
= 0xffff_ffff_ffff_ffff
962 pmode
= yield self
.dec2
.rm_dec
.predmode
963 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
964 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
965 dstpred
= yield self
.dec2
.rm_dec
.dstpred
966 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
967 if pmode
== SVP64PredMode
.INT
.value
:
968 dstmask
= get_predint(self
.gpr
, dstpred
)
969 elif pmode
== SVP64PredMode
.CR
.value
:
970 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
971 # work out if the ssubsteps are completed
972 dsubstart
= dsubstep
== 0
974 log(" ptype", sv_ptype
)
975 log(" dstpred", bin(dstpred
))
976 log(" dstmask", bin(dstmask
))
977 log(" pred_dz", bin(pred_dz
))
978 log(" dsubstart", dsubstart
)
980 self
.dststep_skip
= False
981 self
.dstmask
= dstmask
982 self
.pred_dz
= pred_dz
983 self
.new_dsubstep
= dsubstep
984 log(" new dsubstep", dsubstep
)
986 self
.dststep_skip
= True
988 def svstate_pre_inc(self
):
989 """check if srcstep/dststep need to skip over masked-out predicate bits
990 note that this is not supposed to do anything to substep,
991 it is purely for skipping masked-out bits
994 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
995 yield from self
.read_src_mask()
996 yield from self
.read_dst_mask()
1003 srcstep
= self
.svstate
.srcstep
1004 srcmask
= self
.srcmask
1005 pred_src_zero
= self
.pred_sz
1006 vl
= self
.svstate
.vl
1007 # srcstep-skipping opportunity identified
1008 if self
.srcstep_skip
:
1009 # cannot do this with sv.bc - XXX TODO
1012 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1013 log(" sskip", bin(1 << srcstep
))
1016 # now work out if the relevant mask bits require zeroing
1018 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
1020 # store new srcstep / dststep
1021 self
.new_srcstep
= srcstep
1022 self
.pred_src_zero
= pred_src_zero
1023 log(" new srcstep", srcstep
)
1026 # dststep-skipping opportunity identified
1027 dststep
= self
.svstate
.dststep
1028 dstmask
= self
.dstmask
1029 pred_dst_zero
= self
.pred_dz
1030 vl
= self
.svstate
.vl
1031 if self
.dststep_skip
:
1032 # cannot do this with sv.bc - XXX TODO
1035 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1036 log(" dskip", bin(1 << dststep
))
1039 # now work out if the relevant mask bits require zeroing
1041 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
1043 # store new srcstep / dststep
1044 self
.new_dststep
= dststep
1045 self
.pred_dst_zero
= pred_dst_zero
1046 log(" new dststep", dststep
)
1049 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
1050 # decoder2 - an instance of power_decoder2
1051 # regfile - a list of initial values for the registers
1052 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
1053 # respect_pc - tracks the program counter. requires initial_insns
1054 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
1055 initial_mem
=None, initial_msr
=0,
1066 self
.bigendian
= bigendian
1068 self
.is_svp64_mode
= False
1069 self
.respect_pc
= respect_pc
1070 if initial_sprs
is None:
1072 if initial_mem
is None:
1074 if fpregfile
is None:
1075 fpregfile
= [0] * 32
1076 if initial_insns
is None:
1078 assert self
.respect_pc
== False, "instructions required to honor pc"
1080 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
1081 log("ISACaller initial_msr", initial_msr
)
1083 # "fake program counter" mode (for unit testing)
1087 if isinstance(initial_mem
, tuple):
1088 self
.fake_pc
= initial_mem
[0]
1089 disasm_start
= self
.fake_pc
1091 disasm_start
= initial_pc
1093 # disassembly: we need this for now (not given from the decoder)
1094 self
.disassembly
= {}
1096 for i
, code
in enumerate(disassembly
):
1097 self
.disassembly
[i
*4 + disasm_start
] = code
1099 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
1100 self
.svp64rm
= SVP64RM()
1101 if initial_svstate
is None:
1103 if isinstance(initial_svstate
, int):
1104 initial_svstate
= SVP64State(initial_svstate
)
1105 # SVSTATE, MSR and PC
1106 StepLoop
.__init
__(self
, initial_svstate
)
1107 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
1109 # GPR FPR SPR registers
1110 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
1111 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
1112 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
1113 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
1115 # set up 4 dummy SVSHAPEs if they aren't already set up
1117 sname
= 'SVSHAPE%d' % i
1118 val
= self
.spr
.get(sname
, 0)
1119 # make sure it's an SVSHAPE
1120 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
1121 self
.last_op_svshape
= False
1124 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
1125 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
1126 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
1127 # MMU mode, redirect underlying Mem through RADIX
1129 self
.mem
= RADIX(self
.mem
, self
)
1131 self
.imem
= RADIX(self
.imem
, self
)
1133 # TODO, needed here:
1134 # FPR (same as GPR except for FP nums)
1135 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1136 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1137 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1138 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1140 # 2.3.2 LR (actually SPR #8) -- Done
1141 # 2.3.3 CTR (actually SPR #9) -- Done
1142 # 2.3.4 TAR (actually SPR #815)
1143 # 3.2.2 p45 XER (actually SPR #1) -- Done
1144 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1146 # create CR then allow portions of it to be "selectable" (below)
1147 self
.cr_fields
= CRFields(initial_cr
)
1148 self
.cr
= self
.cr_fields
.cr
1149 self
.cr_backup
= 0 # sigh, dreadful hack: for fail-first (VLi)
1151 # "undefined", just set to variable-bit-width int (use exts "max")
1152 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
1155 self
.namespace
.update(self
.spr
)
1156 self
.namespace
.update({'GPR': self
.gpr
,
1160 'memassign': self
.memassign
,
1163 'SVSTATE': self
.svstate
,
1164 'SVSHAPE0': self
.spr
['SVSHAPE0'],
1165 'SVSHAPE1': self
.spr
['SVSHAPE1'],
1166 'SVSHAPE2': self
.spr
['SVSHAPE2'],
1167 'SVSHAPE3': self
.spr
['SVSHAPE3'],
1170 'undefined': undefined
,
1171 'mode_is_64bit': True,
1172 'SO': XER_bits
['SO'],
1173 'XLEN': 64 # elwidth overrides
1176 # update pc to requested start point
1177 self
.set_pc(initial_pc
)
1179 # field-selectable versions of Condition Register
1180 self
.crl
= self
.cr_fields
.crl
1182 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
1184 self
.decoder
= decoder2
.dec
1185 self
.dec2
= decoder2
1187 super().__init
__(XLEN
=self
.namespace
["XLEN"])
1191 return self
.namespace
["XLEN"]
1193 def call_trap(self
, trap_addr
, trap_bit
):
1194 """calls TRAP and sets up NIA to the new execution location.
1195 next instruction will begin at trap_addr.
1197 self
.TRAP(trap_addr
, trap_bit
)
1198 self
.namespace
['NIA'] = self
.trap_nia
1199 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1201 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1202 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1204 TRAP function is callable from inside the pseudocode itself,
1205 hence the default arguments. when calling from inside ISACaller
1206 it is best to use call_trap()
1208 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1209 kaivb
= self
.spr
['KAIVB'].value
1210 msr
= self
.namespace
['MSR'].value
1211 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1212 # store CIA(+4?) in SRR0, set NIA to 0x700
1213 # store MSR in SRR1, set MSR to um errr something, have to check spec
1214 # store SVSTATE (if enabled) in SVSRR0
1215 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1216 self
.spr
['SRR1'].value
= msr
1217 if self
.is_svp64_mode
:
1218 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1219 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1220 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1222 # set exception bits. TODO: this should, based on the address
1223 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1224 # bits appropriately. however it turns out that *for now* in all
1225 # cases (all trap_addrs) the exact same thing is needed.
1226 self
.msr
[MSRb
.IR
] = 0
1227 self
.msr
[MSRb
.DR
] = 0
1228 self
.msr
[MSRb
.FE0
] = 0
1229 self
.msr
[MSRb
.FE1
] = 0
1230 self
.msr
[MSRb
.EE
] = 0
1231 self
.msr
[MSRb
.RI
] = 0
1232 self
.msr
[MSRb
.SF
] = 1
1233 self
.msr
[MSRb
.TM
] = 0
1234 self
.msr
[MSRb
.VEC
] = 0
1235 self
.msr
[MSRb
.VSX
] = 0
1236 self
.msr
[MSRb
.PR
] = 0
1237 self
.msr
[MSRb
.FP
] = 0
1238 self
.msr
[MSRb
.PMM
] = 0
1239 self
.msr
[MSRb
.TEs
] = 0
1240 self
.msr
[MSRb
.TEe
] = 0
1241 self
.msr
[MSRb
.UND
] = 0
1242 self
.msr
[MSRb
.LE
] = 1
1244 def memassign(self
, ea
, sz
, val
):
1245 self
.mem
.memassign(ea
, sz
, val
)
1247 def prep_namespace(self
, insn_name
, formname
, op_fields
, xlen
):
1248 # TODO: get field names from form in decoder*1* (not decoder2)
1249 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1251 # then "yield" fields only from op_fields rather than hard-coded
1253 fields
= self
.decoder
.sigforms
[formname
]
1254 log("prep_namespace", formname
, op_fields
, insn_name
)
1255 for name
in op_fields
:
1256 # CR immediates. deal with separately. needs modifying
1258 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1259 # BI is a 5-bit, must reconstruct the value
1260 regnum
, is_vec
= yield from get_cr_in(self
.dec2
, name
)
1261 sig
= getattr(fields
, name
)
1263 # low 2 LSBs (CR field selector) remain same, CR num extended
1264 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1265 val
= (val
& 0b11) |
(regnum
<< 2)
1266 elif self
.is_svp64_mode
and name
in ['BF']: # TODO, more CRs
1267 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, "BF")
1268 log('hack %s' % name
, regnum
, is_vec
)
1271 sig
= getattr(fields
, name
)
1273 # these are all opcode fields involved in index-selection of CR,
1274 # and need to do "standard" arithmetic. CR[BA+32] for example
1275 # would, if using SelectableInt, only be 5-bit.
1276 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1277 self
.namespace
[name
] = val
1279 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1281 self
.namespace
['XER'] = self
.spr
['XER']
1282 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1283 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1284 self
.namespace
['XLEN'] = xlen
1286 # add some SVSTATE convenience variables
1287 vl
= self
.svstate
.vl
1288 srcstep
= self
.svstate
.srcstep
1289 self
.namespace
['VL'] = vl
1290 self
.namespace
['srcstep'] = srcstep
1292 # take a copy of the CR field value: if non-VLi fail-first fails
1293 # this is because the pseudocode writes *directly* to CR. sigh
1294 self
.cr_backup
= self
.cr
.value
1296 # sv.bc* need some extra fields
1297 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1298 # blegh grab bits manually
1299 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1300 mode
= SelectableInt(mode
, 5) # convert to SelectableInt before test
1301 bc_vlset
= mode
[SVP64MODEb
.BC_VLSET
] != 0
1302 bc_vli
= mode
[SVP64MODEb
.BC_VLI
] != 0
1303 bc_snz
= mode
[SVP64MODEb
.BC_SNZ
] != 0
1304 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1305 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1306 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1307 sz
= yield self
.dec2
.rm_dec
.pred_sz
1308 self
.namespace
['mode'] = SelectableInt(mode
, 5)
1309 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1310 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1311 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1312 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1313 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1314 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1315 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1317 def handle_carry_(self
, inputs
, output
, ca
, ca32
):
1318 inv_a
= yield self
.dec2
.e
.do
.invert_in
1320 inputs
[0] = ~inputs
[0]
1322 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1324 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1325 inputs
.append(SelectableInt(imm
, 64))
1328 log("gt input", x
, output
)
1329 gt
= (gtu(x
, output
))
1332 cy
= 1 if any(gts
) else 0
1334 if ca
is None: # already written
1335 self
.spr
['XER'][XER_bits
['CA']] = cy
1338 # ARGH... different for OP_ADD... *sigh*...
1339 op
= yield self
.dec2
.e
.do
.insn_type
1340 if op
== MicrOp
.OP_ADD
.value
:
1341 res32
= (output
.value
& (1 << 32)) != 0
1342 a32
= (inputs
[0].value
& (1 << 32)) != 0
1343 if len(inputs
) >= 2:
1344 b32
= (inputs
[1].value
& (1 << 32)) != 0
1347 cy32
= res32 ^ a32 ^ b32
1348 log("CA32 ADD", cy32
)
1352 log("input", x
, output
)
1353 log(" x[32:64]", x
, x
[32:64])
1354 log(" o[32:64]", output
, output
[32:64])
1355 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1357 cy32
= 1 if any(gts
) else 0
1358 log("CA32", cy32
, gts
)
1359 if ca32
is None: # already written
1360 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1362 def handle_overflow(self
, inputs
, output
, div_overflow
):
1363 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1364 inv_a
= yield self
.dec2
.e
.do
.invert_in
1366 inputs
[0] = ~inputs
[0]
1368 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1370 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1371 inputs
.append(SelectableInt(imm
, 64))
1372 log("handle_overflow", inputs
, output
, div_overflow
)
1373 if len(inputs
) < 2 and div_overflow
is None:
1376 # div overflow is different: it's returned by the pseudo-code
1377 # because it's more complex than can be done by analysing the output
1378 if div_overflow
is not None:
1379 ov
, ov32
= div_overflow
, div_overflow
1380 # arithmetic overflow can be done by analysing the input and output
1381 elif len(inputs
) >= 2:
1383 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1384 output_sgn
= exts(output
.value
, output
.bits
) < 0
1385 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1386 output_sgn
!= input_sgn
[0] else 0
1389 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1390 output32_sgn
= exts(output
.value
, 32) < 0
1391 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1392 output32_sgn
!= input32_sgn
[0] else 0
1394 # now update XER OV/OV32/SO
1395 so
= self
.spr
['XER'][XER_bits
['SO']]
1396 new_so
= so | ov
# sticky overflow ORs in old with new
1397 self
.spr
['XER'][XER_bits
['OV']] = ov
1398 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1399 self
.spr
['XER'][XER_bits
['SO']] = new_so
1400 log(" set overflow", ov
, ov32
, so
, new_so
)
1402 def handle_comparison(self
, out
, cr_idx
=0, overflow
=None, no_so
=False):
1403 assert isinstance(out
, SelectableInt
), \
1404 "out zero not a SelectableInt %s" % repr(outputs
)
1405 log("handle_comparison", out
.bits
, hex(out
.value
))
1406 # TODO - XXX *processor* in 32-bit mode
1407 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1409 # o32 = exts(out.value, 32)
1410 # print ("handle_comparison exts 32 bit", hex(o32))
1411 out
= exts(out
.value
, out
.bits
)
1412 log("handle_comparison exts", hex(out
))
1413 # create the three main CR flags, EQ GT LT
1414 zero
= SelectableInt(out
== 0, 1)
1415 positive
= SelectableInt(out
> 0, 1)
1416 negative
= SelectableInt(out
< 0, 1)
1417 # get (or not) XER.SO. for setvl this is important *not* to read SO
1419 SO
= SelectableInt(1, 0)
1421 SO
= self
.spr
['XER'][XER_bits
['SO']]
1422 log("handle_comparison SO overflow", SO
, overflow
)
1423 # alternative overflow checking (setvl mainly at the moment)
1424 if overflow
is not None and overflow
== 1:
1425 SO
= SelectableInt(1, 1)
1426 # create the four CR field values and set the required CR field
1427 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1428 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1429 self
.crl
[cr_idx
].eq(cr_field
)
1431 def set_pc(self
, pc_val
):
1432 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1433 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1435 def get_next_insn(self
):
1436 """check instruction
1439 pc
= self
.pc
.CIA
.value
1442 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1444 raise KeyError("no instruction at 0x%x" % pc
)
1447 def setup_one(self
):
1448 """set up one instruction
1450 pc
, insn
= self
.get_next_insn()
1451 yield from self
.setup_next_insn(pc
, insn
)
1453 def setup_next_insn(self
, pc
, ins
):
1454 """set up next instruction
1457 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1458 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1460 yield self
.dec2
.sv_rm
.eq(0)
1461 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1462 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1463 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1464 yield self
.dec2
.state
.pc
.eq(pc
)
1465 if self
.svstate
is not None:
1466 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1468 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1470 opcode
= yield self
.dec2
.dec
.opcode_in
1471 opcode
= SelectableInt(value
=opcode
, bits
=32)
1472 pfx
= SVP64Instruction
.Prefix(opcode
)
1473 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1474 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1475 self
.pc
.update_nia(self
.is_svp64_mode
)
1477 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1478 self
.namespace
['NIA'] = self
.pc
.NIA
1479 self
.namespace
['SVSTATE'] = self
.svstate
1480 if not self
.is_svp64_mode
:
1483 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1484 log("svp64.rm", bin(pfx
.rm
))
1485 log(" svstate.vl", self
.svstate
.vl
)
1486 log(" svstate.mvl", self
.svstate
.maxvl
)
1487 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1488 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1489 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1490 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1493 def execute_one(self
):
1494 """execute one instruction
1496 # get the disassembly code for this instruction
1497 if not self
.disassembly
:
1498 code
= yield from self
.get_assembly_name()
1501 if self
.is_svp64_mode
:
1502 offs
, dbg
= 4, "svp64 "
1503 code
= self
.disassembly
[self
._pc
+offs
]
1504 log(" %s sim-execute" % dbg
, hex(self
._pc
), code
)
1505 opname
= code
.split(' ')[0]
1507 yield from self
.call(opname
) # execute the instruction
1508 except MemException
as e
: # check for memory errors
1509 if e
.args
[0] == 'unaligned': # alignment error
1510 # run a Trap but set DAR first
1511 print("memory unaligned exception, DAR", e
.dar
)
1512 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1513 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1515 elif e
.args
[0] == 'invalid': # invalid
1516 # run a Trap but set DAR first
1517 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1518 if e
.mode
== 'EXECUTE':
1519 # XXX TODO: must set a few bits in SRR1,
1520 # see microwatt loadstore1.vhdl
1521 # if m_in.segerr = '0' then
1522 # v.srr1(47 - 33) := m_in.invalid;
1523 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1524 # v.srr1(47 - 44) := m_in.badtree;
1525 # v.srr1(47 - 45) := m_in.rc_error;
1526 # v.intr_vec := 16#400#;
1528 # v.intr_vec := 16#480#;
1529 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1531 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1533 # not supported yet:
1534 raise e
# ... re-raise
1536 log("gprs after code", code
)
1539 for i
in range(len(self
.crl
)):
1540 crs
.append(bin(self
.crl
[i
].asint()))
1541 log("crs", " ".join(crs
))
1542 log("vl,maxvl", self
.svstate
.vl
, self
.svstate
.maxvl
)
1544 # don't use this except in special circumstances
1545 if not self
.respect_pc
:
1548 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1549 hex(self
.pc
.NIA
.value
))
1551 def get_assembly_name(self
):
1552 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1553 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1554 dec_insn
= yield self
.dec2
.e
.do
.insn
1555 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1556 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1557 int_op
= yield self
.dec2
.dec
.op
.internal_op
1558 log("get assembly name asmcode", asmcode
, int_op
,
1559 hex(dec_insn
), bin(insn_1_11
))
1560 asmop
= insns
.get(asmcode
, None)
1562 # sigh reconstruct the assembly instruction name
1563 if hasattr(self
.dec2
.e
.do
, "oe"):
1564 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1565 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1569 if hasattr(self
.dec2
.e
.do
, "rc"):
1570 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1571 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1575 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1576 RC1
= yield self
.dec2
.rm_dec
.RC1
1580 # grrrr have to special-case MUL op (see DecodeOE)
1581 log("ov %d en %d rc %d en %d op %d" %
1582 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1583 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1588 if not asmop
.endswith("."): # don't add "." to "andis."
1591 if hasattr(self
.dec2
.e
.do
, "lk"):
1592 lk
= yield self
.dec2
.e
.do
.lk
1595 log("int_op", int_op
)
1596 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1597 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1601 spr_msb
= yield from self
.get_spr_msb()
1602 if int_op
== MicrOp
.OP_MFCR
.value
:
1607 # XXX TODO: for whatever weird reason this doesn't work
1608 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1609 if int_op
== MicrOp
.OP_MTCRF
.value
:
1616 def reset_remaps(self
):
1617 self
.remap_loopends
= [0] * 4
1618 self
.remap_idxs
= [0, 1, 2, 3]
1620 def get_remap_indices(self
):
1621 """WARNING, this function stores remap_idxs and remap_loopends
1622 in the class for later use. this to avoid problems with yield
1624 # go through all iterators in lock-step, advance to next remap_idx
1625 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1626 # get four SVSHAPEs. here we are hard-coding
1628 SVSHAPE0
= self
.spr
['SVSHAPE0']
1629 SVSHAPE1
= self
.spr
['SVSHAPE1']
1630 SVSHAPE2
= self
.spr
['SVSHAPE2']
1631 SVSHAPE3
= self
.spr
['SVSHAPE3']
1632 # set up the iterators
1633 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1634 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1635 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1636 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1640 for i
, (shape
, remap
) in enumerate(remaps
):
1641 # zero is "disabled"
1642 if shape
.value
== 0x0:
1643 self
.remap_idxs
[i
] = 0
1644 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1645 step
= dststep
if (i
in [3, 4]) else srcstep
1646 # this is terrible. O(N^2) looking for the match. but hey.
1647 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1650 self
.remap_idxs
[i
] = remap_idx
1651 self
.remap_loopends
[i
] = loopends
1652 dbg
.append((i
, step
, remap_idx
, loopends
))
1653 for (i
, step
, remap_idx
, loopends
) in dbg
:
1654 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1657 def get_spr_msb(self
):
1658 dec_insn
= yield self
.dec2
.e
.do
.insn
1659 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1661 def call(self
, name
):
1662 """call(opcode) - the primary execution point for instructions
1664 self
.last_st_addr
= None # reset the last known store address
1665 self
.last_ld_addr
= None # etc.
1667 ins_name
= name
.strip() # remove spaces if not already done so
1669 log("halted - not executing", ins_name
)
1672 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1673 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1674 asmop
= yield from self
.get_assembly_name()
1675 log("call", ins_name
, asmop
)
1677 # sv.setvl is *not* a loop-function. sigh
1678 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1681 int_op
= yield self
.dec2
.dec
.op
.internal_op
1682 spr_msb
= yield from self
.get_spr_msb()
1684 instr_is_privileged
= False
1685 if int_op
in [MicrOp
.OP_ATTN
.value
,
1686 MicrOp
.OP_MFMSR
.value
,
1687 MicrOp
.OP_MTMSR
.value
,
1688 MicrOp
.OP_MTMSRD
.value
,
1690 MicrOp
.OP_RFID
.value
]:
1691 instr_is_privileged
= True
1692 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1693 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1694 instr_is_privileged
= True
1696 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1698 # check MSR priv bit and whether op is privileged: if so, throw trap
1699 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1700 self
.call_trap(0x700, PIb
.PRIV
)
1703 # check halted condition
1704 if ins_name
== 'attn':
1708 # check illegal instruction
1710 if ins_name
not in ['mtcrf', 'mtocrf']:
1711 illegal
= ins_name
!= asmop
1713 # list of instructions not being supported by binutils (.long)
1714 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1715 if dotstrp
in [*FPTRANS_INSNS
,
1716 'ffmadds', 'fdmadds', 'ffadds',
1717 'mins', 'maxs', 'minu', 'maxu',
1718 'setvl', 'svindex', 'svremap', 'svstep',
1719 'svshape', 'svshape2',
1720 'grev', 'ternlogi', 'bmask', 'cprop',
1721 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1722 'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
1728 # branch-conditional redirects to sv.bc
1729 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1730 ins_name
= 'sv.%s' % ins_name
1732 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1734 # illegal instructions call TRAP at 0x700
1736 print("illegal", ins_name
, asmop
)
1737 self
.call_trap(0x700, PIb
.ILLEG
)
1738 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1739 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1742 # this is for setvl "Vertical" mode: if set true,
1743 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1744 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1745 self
.allow_next_step_inc
= False
1746 self
.svstate_next_mode
= 0
1748 # nop has to be supported, we could let the actual op calculate
1749 # but PowerDecoder has a pattern for nop
1750 if ins_name
== 'nop':
1751 self
.update_pc_next()
1754 # get elwidths, defaults to 64
1758 if self
.is_svp64_mode
:
1759 ew_src
= yield self
.dec2
.rm_dec
.ew_src
1760 ew_dst
= yield self
.dec2
.rm_dec
.ew_dst
1761 ew_src
= 8 << (3-int(ew_src
)) # convert to bitlength
1762 ew_dst
= 8 << (3-int(ew_dst
)) # convert to bitlength
1763 xlen
= max(ew_src
, ew_dst
)
1764 log("elwdith", ew_src
, ew_dst
)
1765 log("XLEN:", self
.is_svp64_mode
, xlen
)
1767 # look up instruction in ISA.instrs, prepare namespace
1768 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1769 info
= self
.instrs
[ins_name
+"."]
1771 info
= self
.instrs
[ins_name
]
1772 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
,
1775 # preserve order of register names
1776 input_names
= create_args(list(info
.read_regs
) +
1777 list(info
.uninit_regs
))
1778 log("input names", input_names
)
1780 # get SVP64 entry for the current instruction
1781 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1782 if sv_rm
is not None:
1783 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1785 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1786 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1788 # see if srcstep/dststep need skipping over masked-out predicate bits
1789 # svstep also needs advancement because it calls SVSTATE_NEXT.
1790 # bit the remaps get computed just after pre_inc moves them on
1791 # with remap_set_steps substituting for PowerDecider2 not doing it,
1792 # and SVSTATE_NEXT not being able to.use yield, the preinc on
1793 # svstep is necessary for now.
1795 if (self
.is_svp64_mode
or ins_name
in ['svstep']):
1796 yield from self
.svstate_pre_inc()
1797 if self
.is_svp64_mode
:
1798 pre
= yield from self
.update_new_svstate_steps()
1800 self
.svp64_reset_loop()
1802 self
.update_pc_next()
1804 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1805 pred_dst_zero
= self
.pred_dst_zero
1806 pred_src_zero
= self
.pred_src_zero
1807 vl
= self
.svstate
.vl
1808 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1810 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1811 if self
.is_svp64_mode
and vl
== 0:
1812 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1813 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1814 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1817 # for when SVREMAP is active, using pre-arranged schedule.
1818 # note: modifying PowerDecoder2 needs to "settle"
1819 remap_en
= self
.svstate
.SVme
1820 persist
= self
.svstate
.RMpst
1821 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1822 if self
.is_svp64_mode
:
1823 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1825 if persist
or self
.last_op_svshape
:
1826 remaps
= self
.get_remap_indices()
1827 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1828 yield from self
.remap_set_steps(remaps
)
1829 # after that, settle down (combinatorial) to let Vector reg numbers
1830 # work themselves out
1832 if self
.is_svp64_mode
:
1833 remap_active
= yield self
.dec2
.remap_active
1835 remap_active
= False
1836 log("remap active", bin(remap_active
))
1838 # main input registers (RT, RA ...)
1840 for name
in input_names
:
1841 regval
= (yield from self
.get_input(name
, ew_src
))
1842 log("regval name", name
, regval
)
1843 inputs
.append(regval
)
1845 # arrrrgh, awful hack, to get _RT into namespace
1846 if ins_name
in ['setvl', 'svstep']:
1848 RT
= yield self
.dec2
.dec
.RT
1849 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1851 self
.namespace
["RT"] = SelectableInt(0, 5)
1852 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, "RT")
1853 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1855 # in SVP64 mode for LD/ST work out immediate
1856 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1857 # use info.form to detect
1858 if self
.is_svp64_mode
:
1859 yield from self
.check_replace_d(info
, remap_active
)
1861 # "special" registers
1862 for special
in info
.special_regs
:
1863 if special
in special_sprs
:
1864 inputs
.append(self
.spr
[special
])
1866 inputs
.append(self
.namespace
[special
])
1868 # clear trap (trap) NIA
1869 self
.trap_nia
= None
1871 # check if this was an sv.bc* and create an indicator that
1872 # this is the last check to be made as a loop. combined with
1873 # the ALL/ANY mode we can early-exit
1874 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1875 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1876 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1877 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1879 # execute actual instruction here (finally)
1880 log("inputs", inputs
)
1881 results
= info
.func(self
, *inputs
)
1882 output_names
= create_args(info
.write_regs
)
1884 for out
, n
in zip(results
or [], output_names
):
1886 log("results", outs
)
1888 # "inject" decorator takes namespace from function locals: we need to
1889 # overwrite NIA being overwritten (sigh)
1890 if self
.trap_nia
is not None:
1891 self
.namespace
['NIA'] = self
.trap_nia
1893 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1895 # check if op was a LD/ST so that debugging can check the
1897 if int_op
in [MicrOp
.OP_STORE
.value
,
1899 self
.last_st_addr
= self
.mem
.last_st_addr
1900 if int_op
in [MicrOp
.OP_LOAD
.value
,
1902 self
.last_ld_addr
= self
.mem
.last_ld_addr
1903 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1904 self
.last_st_addr
, self
.last_ld_addr
)
1906 # detect if CA/CA32 already in outputs (sra*, basically)
1908 ca32
= outs
.get("CA32 ")
1910 log("carry already done?", ca
, ca32
, output_names
)
1911 carry_en
= yield self
.dec2
.e
.do
.output_carry
1913 yield from self
.handle_carry_(inputs
, results
[0], ca
, ca32
)
1915 # get outout named "overflow" and "CR0"
1916 overflow
= outs
.get('overflow')
1917 cr0
= outs
.get('CR0')
1919 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1920 # detect if overflow was in return result
1921 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1922 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1923 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1925 yield from self
.handle_overflow(inputs
, results
[0], overflow
)
1927 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1929 if not self
.is_svp64_mode
or not pred_dst_zero
:
1930 if hasattr(self
.dec2
.e
.do
, "rc"):
1931 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1932 # don't do Rc=1 for svstep it is handled explicitly.
1933 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1934 # to write directly to CR0 instead of in ISACaller. hooyahh.
1935 if rc_en
and ins_name
not in ['svstep']:
1936 yield from self
.do_rc_ov(ins_name
, results
[0], overflow
, cr0
)
1939 ffirst_hit
= False, False
1940 if self
.is_svp64_mode
:
1941 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
1942 is_cr
= sv_mode
== SVMode
.CROP
.value
1943 chk
= rc_en
or is_cr
1944 ffirst_hit
= (yield from self
.check_ffirst(info
, chk
, srcstep
))
1946 # any modified return results?
1947 yield from self
.do_outregs_nia(asmop
, ins_name
, info
, outs
,
1948 carry_en
, rc_en
, ffirst_hit
, ew_dst
)
1950 def check_ffirst(self
, info
, rc_en
, srcstep
):
1951 """fail-first mode: checks a bit of Rc Vector, truncates VL
1953 rm_mode
= yield self
.dec2
.rm_dec
.mode
1954 ff_inv
= yield self
.dec2
.rm_dec
.inv
1955 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
1956 RC1
= yield self
.dec2
.rm_dec
.RC1
1957 vli_
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
1958 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
1962 log(" cr_bit", cr_bit
)
1963 log(" rc_en", rc_en
)
1964 if not rc_en
or rm_mode
!= SVP64RMMode
.FFIRST
.value
:
1966 # get the CR vevtor, do BO-test
1968 log("asmregs", info
.asmregs
[0], info
.write_regs
)
1969 if 'CR' in info
.write_regs
and 'BF' in info
.asmregs
[0]:
1971 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, crf
)
1972 crtest
= self
.crl
[regnum
]
1973 ffirst_hit
= crtest
[cr_bit
] != ff_inv
1974 log("cr test", crf
, regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
1975 log("cr test?", ffirst_hit
)
1978 # Fail-first activated, truncate VL
1979 vli
= SelectableInt(int(vli_
), 7)
1980 self
.svstate
.vl
= srcstep
+ vli
1981 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1982 yield Settle() # let decoder update
1985 def do_rc_ov(self
, ins_name
, result
, overflow
, cr0
):
1986 if ins_name
.startswith("f"):
1987 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1990 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, rc_reg
)
1991 # hang on... for `setvl` actually you want to test SVSTATE.VL
1992 is_setvl
= ins_name
in ('svstep', 'setvl')
1994 result
= SelectableInt(result
.vl
, 64)
1996 overflow
= None # do not override overflow except in setvl
1998 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
2000 self
.handle_comparison(result
, regnum
, overflow
, no_so
=is_setvl
)
2002 # otherwise we just blat CR0 into the required regnum
2003 log("explicit rc0", cr0
)
2004 self
.crl
[regnum
].eq(cr0
)
2006 def do_outregs_nia(self
, asmop
, ins_name
, info
, outs
,
2007 carry_en
, rc_en
, ffirst_hit
, ew_dst
):
2008 ffirst_hit
, vli
= ffirst_hit
2009 # write out any regs for this instruction
2010 for name
, output
in outs
.items():
2011 yield from self
.check_write(info
, name
, output
, carry_en
, ew_dst
)
2012 # restore the CR value on non-VLI failfirst (from sv.cmp and others
2013 # which write directly to CR in the pseudocode (gah, what a mess)
2014 #if ffirst_hit and not vli:
2015 # self.cr.value = self.cr_backup
2018 self
.svp64_reset_loop()
2021 # check advancement of src/dst/sub-steps and if PC needs updating
2022 nia_update
= (yield from self
.check_step_increment(rc_en
,
2025 self
.update_pc_next()
2027 def check_replace_d(self
, info
, remap_active
):
2028 replace_d
= False # update / replace constant in pseudocode
2029 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
2030 vl
= self
.svstate
.vl
2031 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2032 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2033 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2034 if info
.form
== 'DS':
2035 # DS-Form, multiply by 4 then knock 2 bits off after
2036 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
2038 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
2039 imm
= exts(imm
, 16) # sign-extend to integer
2040 # get the right step. LD is from srcstep, ST is dststep
2041 op
= yield self
.dec2
.e
.do
.insn_type
2043 if op
== MicrOp
.OP_LOAD
.value
:
2045 offsmul
= yield self
.dec2
.in1_step
2046 log("D-field REMAP src", imm
, offsmul
)
2048 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
2049 log("D-field src", imm
, offsmul
)
2050 elif op
== MicrOp
.OP_STORE
.value
:
2051 # XXX NOTE! no bit-reversed STORE! this should not ever be used
2052 offsmul
= (dststep
* (subvl
+1)) + dsubstep
2053 log("D-field dst", imm
, offsmul
)
2054 # Unit-Strided LD/ST adds offset*width to immediate
2055 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
2056 ldst_len
= yield self
.dec2
.e
.do
.data_len
2057 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
2059 # Element-strided multiplies the immediate by element step
2060 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
2061 imm
= SelectableInt(imm
* offsmul
, 32)
2064 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
2065 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
2066 log("LDSTmode", SVP64LDSTmode(ldstmode
),
2067 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
2068 # new replacement D... errr.. DS
2070 if info
.form
== 'DS':
2071 # TODO: assert 2 LSBs are zero?
2072 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
2073 imm
.value
= imm
.value
>> 2
2074 self
.namespace
['DS'] = imm
2076 self
.namespace
['D'] = imm
2078 def get_input(self
, name
, ew_src
):
2079 # using PowerDecoder2, first, find the decoder index.
2080 # (mapping name RA RB RC RS to in1, in2, in3)
2081 regnum
, is_vec
= yield from get_idx_in(self
.dec2
, name
, True)
2083 # doing this is not part of svp64, it's because output
2084 # registers, to be modified, need to be in the namespace.
2085 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2087 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
)
2089 if isinstance(regnum
, tuple):
2090 (regnum
, base
, offs
) = regnum
2092 base
, offs
= regnum
, 0 # temporary HACK
2094 # in case getting the register number is needed, _RA, _RB
2095 # (HACK: only in straight non-svp64-mode for now, or elwidth == 64)
2096 regname
= "_" + name
2097 if not self
.is_svp64_mode
or ew_src
== 64:
2098 self
.namespace
[regname
] = regnum
2099 elif regname
in self
.namespace
:
2100 del self
.namespace
[regname
]
2102 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
2103 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
2105 reg_val
= SelectableInt(self
.fpr(base
, is_vec
, offs
, ew_src
))
2106 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2107 elif name
is not None:
2108 reg_val
= SelectableInt(self
.gpr(base
, is_vec
, offs
, ew_src
))
2109 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2111 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
2115 def remap_set_steps(self
, remaps
):
2116 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
2117 they work in concert with PowerDecoder2 at the moment,
2118 there is no HDL implementation of REMAP. therefore this
2119 function, because ISACaller still uses PowerDecoder2,
2120 will *explicitly* write the dec2.XX_step values. this has
2123 # just some convenient debug info
2125 sname
= 'SVSHAPE%d' % i
2126 shape
= self
.spr
[sname
]
2127 log(sname
, bin(shape
.value
))
2128 log(" lims", shape
.lims
)
2129 log(" mode", shape
.mode
)
2130 log(" skip", shape
.skip
)
2132 # set up the list of steps to remap
2133 mi0
= self
.svstate
.mi0
2134 mi1
= self
.svstate
.mi1
2135 mi2
= self
.svstate
.mi2
2136 mo0
= self
.svstate
.mo0
2137 mo1
= self
.svstate
.mo1
2138 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
2139 (self
.dec2
.in2_step
, mi1
), # RB
2140 (self
.dec2
.in3_step
, mi2
), # RC
2141 (self
.dec2
.o_step
, mo0
), # RT
2142 (self
.dec2
.o2_step
, mo1
), # EA
2144 remap_idxs
= self
.remap_idxs
2146 # now cross-index the required SHAPE for each of 3-in 2-out regs
2147 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
2148 for i
, (dstep
, shape_idx
) in enumerate(steps
):
2149 (shape
, remap
) = remaps
[shape_idx
]
2150 remap_idx
= remap_idxs
[shape_idx
]
2151 # zero is "disabled"
2152 if shape
.value
== 0x0:
2154 # now set the actual requested step to the current index
2155 yield dstep
.eq(remap_idx
)
2157 # debug printout info
2158 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
2160 log("shape remap", x
)
2162 def check_write(self
, info
, name
, output
, carry_en
, ew_dst
):
2163 if name
== 'overflow': # ignore, done already (above)
2165 if name
== 'CR0': # ignore, done already (above)
2167 if isinstance(output
, int):
2168 output
= SelectableInt(output
, 256)
2170 if name
in ['CA', 'CA32']:
2172 log("writing %s to XER" % name
, output
)
2173 log("write XER %s 0x%x" % (name
, output
.value
))
2174 self
.spr
['XER'][XER_bits
[name
]] = output
.value
2176 log("NOT writing %s to XER" % name
, output
)
2178 # write special SPRs
2179 if name
in info
.special_regs
:
2180 log('writing special %s' % name
, output
, special_sprs
)
2181 log("write reg %s 0x%x" % (name
, output
.value
))
2182 if name
in special_sprs
:
2183 self
.spr
[name
] = output
2185 self
.namespace
[name
].eq(output
)
2187 log('msr written', hex(self
.msr
.value
))
2189 # find out1/out2 PR/FPR
2190 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2192 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
)
2194 # temporary hack for not having 2nd output
2195 regnum
= yield getattr(self
.decoder
, name
)
2197 # convenient debug prefix
2202 # check zeroing due to predicate bit being zero
2203 if self
.is_svp64_mode
and self
.pred_dst_zero
:
2204 log('zeroing reg %s %s' % (str(regnum
), str(output
)), is_vec
)
2205 output
= SelectableInt(0, 256)
2206 log("write reg %s%s 0x%x ew %d" % (reg_prefix
, str(regnum
),
2207 output
.value
, ew_dst
),
2208 kind
=LogKind
.InstrInOuts
)
2209 # zero-extend tov64 bit begore storing (should use EXT oh well)
2210 if output
.bits
> 64:
2211 output
= SelectableInt(output
.value
, 64)
2213 self
.fpr
.write(regnum
, output
, is_vec
, ew_dst
)
2215 self
.gpr
.write(regnum
, output
, is_vec
, ew_dst
)
2217 def check_step_increment(self
, rc_en
, asmop
, ins_name
):
2218 # check if it is the SVSTATE.src/dest step that needs incrementing
2219 # this is our Sub-Program-Counter loop from 0 to VL-1
2220 if not self
.allow_next_step_inc
:
2221 if self
.is_svp64_mode
:
2222 return (yield from self
.svstate_post_inc(ins_name
))
2224 # XXX only in non-SVP64 mode!
2225 # record state of whether the current operation was an svshape,
2227 # to be able to know if it should apply in the next instruction.
2228 # also (if going to use this instruction) should disable ability
2229 # to interrupt in between. sigh.
2230 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2237 log("SVSTATE_NEXT: inc requested, mode",
2238 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2239 yield from self
.svstate_pre_inc()
2240 pre
= yield from self
.update_new_svstate_steps()
2242 # reset at end of loop including exit Vertical Mode
2243 log("SVSTATE_NEXT: end of loop, reset")
2244 self
.svp64_reset_loop()
2245 self
.svstate
.vfirst
= 0
2249 self
.handle_comparison(SelectableInt(0, 64)) # CR0
2251 if self
.allow_next_step_inc
== 2:
2252 log("SVSTATE_NEXT: read")
2253 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2255 log("SVSTATE_NEXT: post-inc")
2256 # use actual (cached) src/dst-step here to check end
2257 remaps
= self
.get_remap_indices()
2258 remap_idxs
= self
.remap_idxs
2259 vl
= self
.svstate
.vl
2260 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2261 if self
.allow_next_step_inc
!= 2:
2262 yield from self
.advance_svstate_steps()
2263 #self.namespace['SVSTATE'] = self.svstate.spr
2264 # set CR0 (if Rc=1) based on end
2265 endtest
= 1 if self
.at_loopend() else 0
2267 #results = [SelectableInt(endtest, 64)]
2268 # self.handle_comparison(results) # CR0
2270 # see if svstep was requested, if so, which SVSTATE
2272 if self
.svstate_next_mode
> 0:
2273 shape_idx
= self
.svstate_next_mode
.value
-1
2274 endings
= self
.remap_loopends
[shape_idx
]
2275 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2276 log("svstep Rc=1, CR0", cr_field
, endtest
)
2277 self
.crl
[0].eq(cr_field
) # CR0
2279 # reset at end of loop including exit Vertical Mode
2280 log("SVSTATE_NEXT: after increments, reset")
2281 self
.svp64_reset_loop()
2282 self
.svstate
.vfirst
= 0
2285 def SVSTATE_NEXT(self
, mode
, submode
):
2286 """explicitly moves srcstep/dststep on to next element, for
2287 "Vertical-First" mode. this function is called from
2288 setvl pseudo-code, as a pseudo-op "svstep"
2290 WARNING: this function uses information that was created EARLIER
2291 due to it being in the middle of a yield, but this function is
2292 *NOT* called from yield (it's called from compiled pseudocode).
2294 self
.allow_next_step_inc
= submode
.value
+ 1
2295 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2296 self
.svstate_next_mode
= mode
2297 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2298 shape_idx
= self
.svstate_next_mode
.value
-1
2299 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2300 if self
.svstate_next_mode
== 5:
2301 self
.svstate_next_mode
= 0
2302 return SelectableInt(self
.svstate
.srcstep
, 7)
2303 if self
.svstate_next_mode
== 6:
2304 self
.svstate_next_mode
= 0
2305 return SelectableInt(self
.svstate
.dststep
, 7)
2306 if self
.svstate_next_mode
== 7:
2307 self
.svstate_next_mode
= 0
2308 return SelectableInt(self
.svstate
.ssubstep
, 7)
2309 if self
.svstate_next_mode
== 8:
2310 self
.svstate_next_mode
= 0
2311 return SelectableInt(self
.svstate
.dsubstep
, 7)
2312 return SelectableInt(0, 7)
2314 def get_src_dststeps(self
):
2315 """gets srcstep, dststep, and ssubstep, dsubstep
2317 return (self
.new_srcstep
, self
.new_dststep
,
2318 self
.new_ssubstep
, self
.new_dsubstep
)
2320 def update_svstate_namespace(self
, overwrite_svstate
=True):
2321 if overwrite_svstate
:
2322 # note, do not get the bit-reversed srcstep here!
2323 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2324 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2326 # update SVSTATE with new srcstep
2327 self
.svstate
.srcstep
= srcstep
2328 self
.svstate
.dststep
= dststep
2329 self
.svstate
.ssubstep
= ssubstep
2330 self
.svstate
.dsubstep
= dsubstep
2331 self
.namespace
['SVSTATE'] = self
.svstate
2332 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2333 yield Settle() # let decoder update
2335 def update_new_svstate_steps(self
, overwrite_svstate
=True):
2336 yield from self
.update_svstate_namespace(overwrite_svstate
)
2337 srcstep
= self
.svstate
.srcstep
2338 dststep
= self
.svstate
.dststep
2339 ssubstep
= self
.svstate
.ssubstep
2340 dsubstep
= self
.svstate
.dsubstep
2341 pack
= self
.svstate
.pack
2342 unpack
= self
.svstate
.unpack
2343 vl
= self
.svstate
.vl
2344 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
2345 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2346 rm_mode
= yield self
.dec2
.rm_dec
.mode
2347 ff_inv
= yield self
.dec2
.rm_dec
.inv
2348 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2349 log(" srcstep", srcstep
)
2350 log(" dststep", dststep
)
2352 log(" unpack", unpack
)
2353 log(" ssubstep", ssubstep
)
2354 log(" dsubstep", dsubstep
)
2356 log(" subvl", subvl
)
2357 log(" rm_mode", rm_mode
)
2358 log(" sv_mode", sv_mode
)
2360 log(" cr_bit", cr_bit
)
2362 # check if end reached (we let srcstep overrun, above)
2363 # nothing needs doing (TODO zeroing): just do next instruction
2366 return ((ssubstep
== subvl
and srcstep
== vl
) or
2367 (dsubstep
== subvl
and dststep
== vl
))
2369 def svstate_post_inc(self
, insn_name
, vf
=0):
2370 # check if SV "Vertical First" mode is enabled
2371 vfirst
= self
.svstate
.vfirst
2372 log(" SV Vertical First", vf
, vfirst
)
2373 if not vf
and vfirst
== 1:
2377 # check if it is the SVSTATE.src/dest step that needs incrementing
2378 # this is our Sub-Program-Counter loop from 0 to VL-1
2379 # XXX twin predication TODO
2380 vl
= self
.svstate
.vl
2381 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2382 mvl
= self
.svstate
.maxvl
2383 srcstep
= self
.svstate
.srcstep
2384 dststep
= self
.svstate
.dststep
2385 ssubstep
= self
.svstate
.ssubstep
2386 dsubstep
= self
.svstate
.dsubstep
2387 pack
= self
.svstate
.pack
2388 unpack
= self
.svstate
.unpack
2389 rm_mode
= yield self
.dec2
.rm_dec
.mode
2390 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2391 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2392 out_vec
= not (yield self
.dec2
.no_out_vec
)
2393 in_vec
= not (yield self
.dec2
.no_in_vec
)
2394 log(" svstate.vl", vl
)
2395 log(" svstate.mvl", mvl
)
2396 log(" rm.subvl", subvl
)
2397 log(" svstate.srcstep", srcstep
)
2398 log(" svstate.dststep", dststep
)
2399 log(" svstate.ssubstep", ssubstep
)
2400 log(" svstate.dsubstep", dsubstep
)
2401 log(" svstate.pack", pack
)
2402 log(" svstate.unpack", unpack
)
2403 log(" mode", rm_mode
)
2404 log(" reverse", reverse_gear
)
2405 log(" out_vec", out_vec
)
2406 log(" in_vec", in_vec
)
2407 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2408 # check if this was an sv.bc* and if so did it succeed
2409 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2410 end_loop
= self
.namespace
['end_loop']
2411 log("branch %s end_loop" % insn_name
, end_loop
)
2413 self
.svp64_reset_loop()
2414 self
.update_pc_next()
2416 # check if srcstep needs incrementing by one, stop PC advancing
2417 # but for 2-pred both src/dest have to be checked.
2418 # XXX this might not be true! it may just be LD/ST
2419 if sv_ptype
== SVPtype
.P2
.value
:
2420 svp64_is_vector
= (out_vec
or in_vec
)
2422 svp64_is_vector
= out_vec
2423 # loops end at the first "hit" (source or dest)
2424 yield from self
.advance_svstate_steps()
2425 loopend
= self
.loopend
2426 log("loopend", svp64_is_vector
, loopend
)
2427 if not svp64_is_vector
or loopend
:
2428 # reset loop to zero and update NIA
2429 self
.svp64_reset_loop()
2434 # still looping, advance and update NIA
2435 self
.namespace
['SVSTATE'] = self
.svstate
2437 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2438 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2439 # this way we keep repeating the same instruction (with new steps)
2440 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2441 self
.namespace
['NIA'] = self
.pc
.NIA
2442 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2443 return False # DO NOT allow PC update whilst Sub-PC loop running
2445 def update_pc_next(self
):
2446 # UPDATE program counter
2447 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2448 #self.svstate.spr = self.namespace['SVSTATE']
2449 log("end of call", self
.namespace
['CIA'],
2450 self
.namespace
['NIA'],
2451 self
.namespace
['SVSTATE'])
2453 def svp64_reset_loop(self
):
2454 self
.svstate
.srcstep
= 0
2455 self
.svstate
.dststep
= 0
2456 self
.svstate
.ssubstep
= 0
2457 self
.svstate
.dsubstep
= 0
2458 self
.loopend
= False
2459 log(" svstate.srcstep loop end (PC to update)")
2460 self
.namespace
['SVSTATE'] = self
.svstate
2462 def update_nia(self
):
2463 self
.pc
.update_nia(self
.is_svp64_mode
)
2464 self
.namespace
['NIA'] = self
.pc
.NIA
2468 """Decorator factory.
2470 this decorator will "inject" variables into the function's namespace,
2471 from the *dictionary* in self.namespace. it therefore becomes possible
2472 to make it look like a whole stack of variables which would otherwise
2473 need "self." inserted in front of them (*and* for those variables to be
2474 added to the instance) "appear" in the function.
2476 "self.namespace['SI']" for example becomes accessible as just "SI" but
2477 *only* inside the function, when decorated.
2479 def variable_injector(func
):
2481 def decorator(*args
, **kwargs
):
2483 func_globals
= func
.__globals
__ # Python 2.6+
2484 except AttributeError:
2485 func_globals
= func
.func_globals
# Earlier versions.
2487 context
= args
[0].namespace
# variables to be injected
2488 saved_values
= func_globals
.copy() # Shallow copy of dict.
2489 log("globals before", context
.keys())
2490 func_globals
.update(context
)
2491 result
= func(*args
, **kwargs
)
2492 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2493 log("args[0]", args
[0].namespace
['CIA'],
2494 args
[0].namespace
['NIA'],
2495 args
[0].namespace
['SVSTATE'])
2496 if 'end_loop' in func_globals
:
2497 log("args[0] end_loop", func_globals
['end_loop'])
2498 args
[0].namespace
= func_globals
2499 #exec (func.__code__, func_globals)
2502 # func_globals = saved_values # Undo changes.
2508 return variable_injector