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
, ewmode
=False):
563 # check first if register is activated for write
565 out_sel
= yield op
.out_sel
566 out
= yield dec2
.e
.write_ea
.data
568 offs
= yield dec2
.e
.write_ea
.offs
569 base
= yield dec2
.e
.write_ea
.base
570 out
= (out
, base
, offs
)
571 o_isvec
= yield dec2
.o2_isvec
572 out_ok
= yield dec2
.e
.write_ea
.ok
573 log("get_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
578 if hasattr(op
, "upd"):
579 # update mode LD/ST uses read-reg A also as an output
581 log("get_idx_out2", upd
, LDSTMode
.update
.value
,
582 out_sel
, OutSel
.RA
.value
,
584 if upd
== LDSTMode
.update
.value
:
587 fft_en
= yield dec2
.implicit_rs
589 log("get_idx_out2", out_sel
, OutSel
.RS
.value
,
593 fft_en
= yield dec2
.implicit_rs
595 log("get_idx_out2", out_sel
, OutSel
.FRS
.value
,
602 """deals with svstate looping.
605 def __init__(self
, svstate
):
606 self
.svstate
= svstate
609 def new_iterators(self
):
610 self
.src_it
= self
.src_iterator()
611 self
.dst_it
= self
.dst_iterator()
615 self
.new_ssubstep
= 0
616 self
.new_dsubstep
= 0
617 self
.pred_dst_zero
= 0
618 self
.pred_src_zero
= 0
620 def src_iterator(self
):
621 """source-stepping iterator
623 pack
= self
.svstate
.pack
627 # pack advances subvl in *outer* loop
628 while True: # outer subvl loop
629 while True: # inner vl loop
632 srcmask
= self
.srcmask
633 srcstep
= self
.svstate
.srcstep
634 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
635 if self
.pred_sz
or pred_src_zero
:
636 self
.pred_src_zero
= not pred_src_zero
637 log(" advance src", srcstep
, vl
,
638 self
.svstate
.ssubstep
, subvl
)
639 # yield actual substep/srcstep
640 yield (self
.svstate
.ssubstep
, srcstep
)
641 # the way yield works these could have been modified.
644 srcstep
= self
.svstate
.srcstep
645 log(" advance src check", srcstep
, vl
,
646 self
.svstate
.ssubstep
, subvl
, srcstep
== vl
-1,
647 self
.svstate
.ssubstep
== subvl
)
648 if srcstep
== vl
-1: # end-point
649 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
650 if self
.svstate
.ssubstep
== subvl
: # end-point
651 log(" advance pack stop")
653 break # exit inner loop
654 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance ss
656 if self
.svstate
.ssubstep
== subvl
: # end-point
657 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
658 log(" advance pack stop")
660 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
663 # these cannot be done as for-loops because SVSTATE may change
664 # (srcstep/substep may be modified, interrupted, subvl/vl change)
665 # but they *can* be done as while-loops as long as every SVSTATE
666 # "thing" is re-read every single time a yield gives indices
667 while True: # outer vl loop
668 while True: # inner subvl loop
671 srcmask
= self
.srcmask
672 srcstep
= self
.svstate
.srcstep
673 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
674 if self
.pred_sz
or pred_src_zero
:
675 self
.pred_src_zero
= not pred_src_zero
676 log(" advance src", srcstep
, vl
,
677 self
.svstate
.ssubstep
, subvl
)
678 # yield actual substep/srcstep
679 yield (self
.svstate
.ssubstep
, srcstep
)
680 if self
.svstate
.ssubstep
== subvl
: # end-point
681 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
682 break # exit inner loop
683 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
685 if srcstep
== vl
-1: # end-point
686 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
689 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
691 def dst_iterator(self
):
692 """dest-stepping iterator
694 unpack
= self
.svstate
.unpack
698 # pack advances subvl in *outer* loop
699 while True: # outer subvl loop
700 while True: # inner vl loop
703 dstmask
= self
.dstmask
704 dststep
= self
.svstate
.dststep
705 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
706 if self
.pred_dz
or pred_dst_zero
:
707 self
.pred_dst_zero
= not pred_dst_zero
708 log(" advance dst", dststep
, vl
,
709 self
.svstate
.dsubstep
, subvl
)
710 # yield actual substep/dststep
711 yield (self
.svstate
.dsubstep
, dststep
)
712 # the way yield works these could have been modified.
714 dststep
= self
.svstate
.dststep
715 log(" advance dst check", dststep
, vl
,
716 self
.svstate
.ssubstep
, subvl
)
717 if dststep
== vl
-1: # end-point
718 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
719 if self
.svstate
.dsubstep
== subvl
: # end-point
720 log(" advance unpack stop")
723 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance ds
725 if self
.svstate
.dsubstep
== subvl
: # end-point
726 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
727 log(" advance unpack stop")
729 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
731 # these cannot be done as for-loops because SVSTATE may change
732 # (dststep/substep may be modified, interrupted, subvl/vl change)
733 # but they *can* be done as while-loops as long as every SVSTATE
734 # "thing" is re-read every single time a yield gives indices
735 while True: # outer vl loop
736 while True: # inner subvl loop
738 dstmask
= self
.dstmask
739 dststep
= self
.svstate
.dststep
740 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
741 if self
.pred_dz
or pred_dst_zero
:
742 self
.pred_dst_zero
= not pred_dst_zero
743 log(" advance dst", dststep
, self
.svstate
.vl
,
744 self
.svstate
.dsubstep
, subvl
)
745 # yield actual substep/dststep
746 yield (self
.svstate
.dsubstep
, dststep
)
747 if self
.svstate
.dsubstep
== subvl
: # end-point
748 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
750 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
753 if dststep
== vl
-1: # end-point
754 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
756 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
758 def src_iterate(self
):
759 """source-stepping iterator
763 pack
= self
.svstate
.pack
764 unpack
= self
.svstate
.unpack
765 ssubstep
= self
.svstate
.ssubstep
766 end_ssub
= ssubstep
== subvl
767 end_src
= self
.svstate
.srcstep
== vl
-1
768 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
772 srcstep
= self
.svstate
.srcstep
773 srcmask
= self
.srcmask
775 # pack advances subvl in *outer* loop
777 assert srcstep
<= vl
-1
778 end_src
= srcstep
== vl
-1
783 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
787 srcstep
+= 1 # advance srcstep
788 if not self
.srcstep_skip
:
790 if ((1 << srcstep
) & srcmask
) != 0:
793 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
795 # advance subvl in *inner* loop
798 assert srcstep
<= vl
-1
799 end_src
= srcstep
== vl
-1
800 if end_src
: # end-point
806 if not self
.srcstep_skip
:
808 if ((1 << srcstep
) & srcmask
) != 0:
811 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
812 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
815 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
817 self
.svstate
.srcstep
= SelectableInt(srcstep
, 7)
818 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
821 def dst_iterate(self
):
822 """dest step iterator
826 pack
= self
.svstate
.pack
827 unpack
= self
.svstate
.unpack
828 dsubstep
= self
.svstate
.dsubstep
829 end_dsub
= dsubstep
== subvl
830 dststep
= self
.svstate
.dststep
831 end_dst
= dststep
== vl
-1
832 dstmask
= self
.dstmask
833 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
838 # unpack advances subvl in *outer* loop
840 assert dststep
<= vl
-1
841 end_dst
= dststep
== vl
-1
846 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
850 dststep
+= 1 # advance dststep
851 if not self
.dststep_skip
:
853 if ((1 << dststep
) & dstmask
) != 0:
856 log(" dskip", bin(dstmask
), bin(1 << dststep
))
858 # advance subvl in *inner* loop
861 assert dststep
<= vl
-1
862 end_dst
= dststep
== vl
-1
863 if end_dst
: # end-point
869 if not self
.dststep_skip
:
871 if ((1 << dststep
) & dstmask
) != 0:
874 log(" dskip", bin(dstmask
), bin(1 << dststep
))
875 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
878 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
880 self
.svstate
.dststep
= SelectableInt(dststep
, 7)
881 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
884 def at_loopend(self
):
885 """tells if this is the last possible element. uses the cached values
886 for src/dst-step and sub-steps
890 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
891 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
892 end_ssub
= ssubstep
== subvl
893 end_dsub
= dsubstep
== subvl
894 if srcstep
== vl
-1 and end_ssub
:
896 if dststep
== vl
-1 and end_dsub
:
900 def advance_svstate_steps(self
):
901 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
902 TODO when Pack/Unpack is set, substep becomes the *outer* loop
904 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
905 if self
.loopend
: # huhn??
910 def read_src_mask(self
):
911 """read/update pred_sz and src mask
913 # get SVSTATE VL (oh and print out some debug stuff)
915 srcstep
= self
.svstate
.srcstep
916 ssubstep
= self
.svstate
.ssubstep
918 # get predicate mask (all 64 bits)
919 srcmask
= 0xffff_ffff_ffff_ffff
921 pmode
= yield self
.dec2
.rm_dec
.predmode
922 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
923 srcpred
= yield self
.dec2
.rm_dec
.srcpred
924 dstpred
= yield self
.dec2
.rm_dec
.dstpred
925 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
926 if pmode
== SVP64PredMode
.INT
.value
:
927 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
928 if sv_ptype
== SVPtype
.P2
.value
:
929 srcmask
= get_predint(self
.gpr
, srcpred
)
930 elif pmode
== SVP64PredMode
.CR
.value
:
931 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
932 if sv_ptype
== SVPtype
.P2
.value
:
933 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
934 # work out if the ssubsteps are completed
935 ssubstart
= ssubstep
== 0
937 log(" ptype", sv_ptype
)
938 log(" srcpred", bin(srcpred
))
939 log(" srcmask", bin(srcmask
))
940 log(" pred_sz", bin(pred_sz
))
941 log(" ssubstart", ssubstart
)
943 # store all that above
944 self
.srcstep_skip
= False
945 self
.srcmask
= srcmask
946 self
.pred_sz
= pred_sz
947 self
.new_ssubstep
= ssubstep
948 log(" new ssubstep", ssubstep
)
949 # until the predicate mask has a "1" bit... or we run out of VL
950 # let srcstep==VL be the indicator to move to next instruction
952 self
.srcstep_skip
= True
954 def read_dst_mask(self
):
955 """same as read_src_mask - check and record everything needed
957 # get SVSTATE VL (oh and print out some debug stuff)
958 # yield Delay(1e-10) # make changes visible
960 dststep
= self
.svstate
.dststep
961 dsubstep
= self
.svstate
.dsubstep
963 # get predicate mask (all 64 bits)
964 dstmask
= 0xffff_ffff_ffff_ffff
966 pmode
= yield self
.dec2
.rm_dec
.predmode
967 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
968 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
969 dstpred
= yield self
.dec2
.rm_dec
.dstpred
970 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
971 if pmode
== SVP64PredMode
.INT
.value
:
972 dstmask
= get_predint(self
.gpr
, dstpred
)
973 elif pmode
== SVP64PredMode
.CR
.value
:
974 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
975 # work out if the ssubsteps are completed
976 dsubstart
= dsubstep
== 0
978 log(" ptype", sv_ptype
)
979 log(" dstpred", bin(dstpred
))
980 log(" dstmask", bin(dstmask
))
981 log(" pred_dz", bin(pred_dz
))
982 log(" dsubstart", dsubstart
)
984 self
.dststep_skip
= False
985 self
.dstmask
= dstmask
986 self
.pred_dz
= pred_dz
987 self
.new_dsubstep
= dsubstep
988 log(" new dsubstep", dsubstep
)
990 self
.dststep_skip
= True
992 def svstate_pre_inc(self
):
993 """check if srcstep/dststep need to skip over masked-out predicate bits
994 note that this is not supposed to do anything to substep,
995 it is purely for skipping masked-out bits
998 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
999 yield from self
.read_src_mask()
1000 yield from self
.read_dst_mask()
1007 srcstep
= self
.svstate
.srcstep
1008 srcmask
= self
.srcmask
1009 pred_src_zero
= self
.pred_sz
1010 vl
= self
.svstate
.vl
1011 # srcstep-skipping opportunity identified
1012 if self
.srcstep_skip
:
1013 # cannot do this with sv.bc - XXX TODO
1016 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1017 log(" sskip", bin(1 << srcstep
))
1020 # now work out if the relevant mask bits require zeroing
1022 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
1024 # store new srcstep / dststep
1025 self
.new_srcstep
= srcstep
1026 self
.pred_src_zero
= pred_src_zero
1027 log(" new srcstep", srcstep
)
1030 # dststep-skipping opportunity identified
1031 dststep
= self
.svstate
.dststep
1032 dstmask
= self
.dstmask
1033 pred_dst_zero
= self
.pred_dz
1034 vl
= self
.svstate
.vl
1035 if self
.dststep_skip
:
1036 # cannot do this with sv.bc - XXX TODO
1039 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1040 log(" dskip", bin(1 << dststep
))
1043 # now work out if the relevant mask bits require zeroing
1045 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
1047 # store new srcstep / dststep
1048 self
.new_dststep
= dststep
1049 self
.pred_dst_zero
= pred_dst_zero
1050 log(" new dststep", dststep
)
1053 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
1054 # decoder2 - an instance of power_decoder2
1055 # regfile - a list of initial values for the registers
1056 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
1057 # respect_pc - tracks the program counter. requires initial_insns
1058 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
1059 initial_mem
=None, initial_msr
=0,
1070 self
.bigendian
= bigendian
1072 self
.is_svp64_mode
= False
1073 self
.respect_pc
= respect_pc
1074 if initial_sprs
is None:
1076 if initial_mem
is None:
1078 if fpregfile
is None:
1079 fpregfile
= [0] * 32
1080 if initial_insns
is None:
1082 assert self
.respect_pc
== False, "instructions required to honor pc"
1084 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
1085 log("ISACaller initial_msr", initial_msr
)
1087 # "fake program counter" mode (for unit testing)
1091 if isinstance(initial_mem
, tuple):
1092 self
.fake_pc
= initial_mem
[0]
1093 disasm_start
= self
.fake_pc
1095 disasm_start
= initial_pc
1097 # disassembly: we need this for now (not given from the decoder)
1098 self
.disassembly
= {}
1100 for i
, code
in enumerate(disassembly
):
1101 self
.disassembly
[i
*4 + disasm_start
] = code
1103 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
1104 self
.svp64rm
= SVP64RM()
1105 if initial_svstate
is None:
1107 if isinstance(initial_svstate
, int):
1108 initial_svstate
= SVP64State(initial_svstate
)
1109 # SVSTATE, MSR and PC
1110 StepLoop
.__init
__(self
, initial_svstate
)
1111 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
1113 # GPR FPR SPR registers
1114 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
1115 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
1116 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
1117 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
1119 # set up 4 dummy SVSHAPEs if they aren't already set up
1121 sname
= 'SVSHAPE%d' % i
1122 val
= self
.spr
.get(sname
, 0)
1123 # make sure it's an SVSHAPE
1124 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
1125 self
.last_op_svshape
= False
1128 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
1129 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
1130 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
1131 # MMU mode, redirect underlying Mem through RADIX
1133 self
.mem
= RADIX(self
.mem
, self
)
1135 self
.imem
= RADIX(self
.imem
, self
)
1137 # TODO, needed here:
1138 # FPR (same as GPR except for FP nums)
1139 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1140 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1141 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1142 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1144 # 2.3.2 LR (actually SPR #8) -- Done
1145 # 2.3.3 CTR (actually SPR #9) -- Done
1146 # 2.3.4 TAR (actually SPR #815)
1147 # 3.2.2 p45 XER (actually SPR #1) -- Done
1148 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1150 # create CR then allow portions of it to be "selectable" (below)
1151 self
.cr_fields
= CRFields(initial_cr
)
1152 self
.cr
= self
.cr_fields
.cr
1153 self
.cr_backup
= 0 # sigh, dreadful hack: for fail-first (VLi)
1155 # "undefined", just set to variable-bit-width int (use exts "max")
1156 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
1159 self
.namespace
.update(self
.spr
)
1160 self
.namespace
.update({'GPR': self
.gpr
,
1164 'memassign': self
.memassign
,
1167 'SVSTATE': self
.svstate
,
1168 'SVSHAPE0': self
.spr
['SVSHAPE0'],
1169 'SVSHAPE1': self
.spr
['SVSHAPE1'],
1170 'SVSHAPE2': self
.spr
['SVSHAPE2'],
1171 'SVSHAPE3': self
.spr
['SVSHAPE3'],
1174 'undefined': undefined
,
1175 'mode_is_64bit': True,
1176 'SO': XER_bits
['SO'],
1177 'XLEN': 64 # elwidth overrides
1180 # update pc to requested start point
1181 self
.set_pc(initial_pc
)
1183 # field-selectable versions of Condition Register
1184 self
.crl
= self
.cr_fields
.crl
1186 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
1188 self
.decoder
= decoder2
.dec
1189 self
.dec2
= decoder2
1191 super().__init
__(XLEN
=self
.namespace
["XLEN"])
1195 return self
.namespace
["XLEN"]
1197 def call_trap(self
, trap_addr
, trap_bit
):
1198 """calls TRAP and sets up NIA to the new execution location.
1199 next instruction will begin at trap_addr.
1201 self
.TRAP(trap_addr
, trap_bit
)
1202 self
.namespace
['NIA'] = self
.trap_nia
1203 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1205 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1206 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1208 TRAP function is callable from inside the pseudocode itself,
1209 hence the default arguments. when calling from inside ISACaller
1210 it is best to use call_trap()
1212 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1213 kaivb
= self
.spr
['KAIVB'].value
1214 msr
= self
.namespace
['MSR'].value
1215 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1216 # store CIA(+4?) in SRR0, set NIA to 0x700
1217 # store MSR in SRR1, set MSR to um errr something, have to check spec
1218 # store SVSTATE (if enabled) in SVSRR0
1219 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1220 self
.spr
['SRR1'].value
= msr
1221 if self
.is_svp64_mode
:
1222 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1223 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1224 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1226 # set exception bits. TODO: this should, based on the address
1227 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1228 # bits appropriately. however it turns out that *for now* in all
1229 # cases (all trap_addrs) the exact same thing is needed.
1230 self
.msr
[MSRb
.IR
] = 0
1231 self
.msr
[MSRb
.DR
] = 0
1232 self
.msr
[MSRb
.FE0
] = 0
1233 self
.msr
[MSRb
.FE1
] = 0
1234 self
.msr
[MSRb
.EE
] = 0
1235 self
.msr
[MSRb
.RI
] = 0
1236 self
.msr
[MSRb
.SF
] = 1
1237 self
.msr
[MSRb
.TM
] = 0
1238 self
.msr
[MSRb
.VEC
] = 0
1239 self
.msr
[MSRb
.VSX
] = 0
1240 self
.msr
[MSRb
.PR
] = 0
1241 self
.msr
[MSRb
.FP
] = 0
1242 self
.msr
[MSRb
.PMM
] = 0
1243 self
.msr
[MSRb
.TEs
] = 0
1244 self
.msr
[MSRb
.TEe
] = 0
1245 self
.msr
[MSRb
.UND
] = 0
1246 self
.msr
[MSRb
.LE
] = 1
1248 def memassign(self
, ea
, sz
, val
):
1249 self
.mem
.memassign(ea
, sz
, val
)
1251 def prep_namespace(self
, insn_name
, formname
, op_fields
, xlen
):
1252 # TODO: get field names from form in decoder*1* (not decoder2)
1253 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1255 # then "yield" fields only from op_fields rather than hard-coded
1257 fields
= self
.decoder
.sigforms
[formname
]
1258 log("prep_namespace", formname
, op_fields
, insn_name
)
1259 for name
in op_fields
:
1260 # CR immediates. deal with separately. needs modifying
1262 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1263 # BI is a 5-bit, must reconstruct the value
1264 regnum
, is_vec
= yield from get_cr_in(self
.dec2
, name
)
1265 sig
= getattr(fields
, name
)
1267 # low 2 LSBs (CR field selector) remain same, CR num extended
1268 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1269 val
= (val
& 0b11) |
(regnum
<< 2)
1270 elif self
.is_svp64_mode
and name
in ['BF']: # TODO, more CRs
1271 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, "BF")
1272 log('hack %s' % name
, regnum
, is_vec
)
1275 sig
= getattr(fields
, name
)
1277 # these are all opcode fields involved in index-selection of CR,
1278 # and need to do "standard" arithmetic. CR[BA+32] for example
1279 # would, if using SelectableInt, only be 5-bit.
1280 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1281 self
.namespace
[name
] = val
1283 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1285 self
.namespace
['XER'] = self
.spr
['XER']
1286 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1287 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1288 self
.namespace
['XLEN'] = xlen
1290 # add some SVSTATE convenience variables
1291 vl
= self
.svstate
.vl
1292 srcstep
= self
.svstate
.srcstep
1293 self
.namespace
['VL'] = vl
1294 self
.namespace
['srcstep'] = srcstep
1296 # take a copy of the CR field value: if non-VLi fail-first fails
1297 # this is because the pseudocode writes *directly* to CR. sigh
1298 self
.cr_backup
= self
.cr
.value
1300 # sv.bc* need some extra fields
1301 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1302 # blegh grab bits manually
1303 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1304 mode
= SelectableInt(mode
, 5) # convert to SelectableInt before test
1305 bc_vlset
= mode
[SVP64MODEb
.BC_VLSET
] != 0
1306 bc_vli
= mode
[SVP64MODEb
.BC_VLI
] != 0
1307 bc_snz
= mode
[SVP64MODEb
.BC_SNZ
] != 0
1308 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1309 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1310 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1311 sz
= yield self
.dec2
.rm_dec
.pred_sz
1312 self
.namespace
['mode'] = SelectableInt(mode
, 5)
1313 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1314 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1315 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1316 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1317 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1318 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1319 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1321 def handle_carry_(self
, inputs
, output
, ca
, ca32
):
1322 inv_a
= yield self
.dec2
.e
.do
.invert_in
1324 inputs
[0] = ~inputs
[0]
1326 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1328 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1329 inputs
.append(SelectableInt(imm
, 64))
1332 log("gt input", x
, output
)
1333 gt
= (gtu(x
, output
))
1336 cy
= 1 if any(gts
) else 0
1338 if ca
is None: # already written
1339 self
.spr
['XER'][XER_bits
['CA']] = cy
1342 # ARGH... different for OP_ADD... *sigh*...
1343 op
= yield self
.dec2
.e
.do
.insn_type
1344 if op
== MicrOp
.OP_ADD
.value
:
1345 res32
= (output
.value
& (1 << 32)) != 0
1346 a32
= (inputs
[0].value
& (1 << 32)) != 0
1347 if len(inputs
) >= 2:
1348 b32
= (inputs
[1].value
& (1 << 32)) != 0
1351 cy32
= res32 ^ a32 ^ b32
1352 log("CA32 ADD", cy32
)
1356 log("input", x
, output
)
1357 log(" x[32:64]", x
, x
[32:64])
1358 log(" o[32:64]", output
, output
[32:64])
1359 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1361 cy32
= 1 if any(gts
) else 0
1362 log("CA32", cy32
, gts
)
1363 if ca32
is None: # already written
1364 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1366 def handle_overflow(self
, inputs
, output
, div_overflow
):
1367 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1368 inv_a
= yield self
.dec2
.e
.do
.invert_in
1370 inputs
[0] = ~inputs
[0]
1372 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1374 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1375 inputs
.append(SelectableInt(imm
, 64))
1376 log("handle_overflow", inputs
, output
, div_overflow
)
1377 if len(inputs
) < 2 and div_overflow
is None:
1380 # div overflow is different: it's returned by the pseudo-code
1381 # because it's more complex than can be done by analysing the output
1382 if div_overflow
is not None:
1383 ov
, ov32
= div_overflow
, div_overflow
1384 # arithmetic overflow can be done by analysing the input and output
1385 elif len(inputs
) >= 2:
1387 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1388 output_sgn
= exts(output
.value
, output
.bits
) < 0
1389 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1390 output_sgn
!= input_sgn
[0] else 0
1393 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1394 output32_sgn
= exts(output
.value
, 32) < 0
1395 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1396 output32_sgn
!= input32_sgn
[0] else 0
1398 # now update XER OV/OV32/SO
1399 so
= self
.spr
['XER'][XER_bits
['SO']]
1400 new_so
= so | ov
# sticky overflow ORs in old with new
1401 self
.spr
['XER'][XER_bits
['OV']] = ov
1402 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1403 self
.spr
['XER'][XER_bits
['SO']] = new_so
1404 log(" set overflow", ov
, ov32
, so
, new_so
)
1406 def handle_comparison(self
, out
, cr_idx
=0, overflow
=None, no_so
=False):
1407 assert isinstance(out
, SelectableInt
), \
1408 "out zero not a SelectableInt %s" % repr(outputs
)
1409 log("handle_comparison", out
.bits
, hex(out
.value
))
1410 # TODO - XXX *processor* in 32-bit mode
1411 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1413 # o32 = exts(out.value, 32)
1414 # print ("handle_comparison exts 32 bit", hex(o32))
1415 out
= exts(out
.value
, out
.bits
)
1416 log("handle_comparison exts", hex(out
))
1417 # create the three main CR flags, EQ GT LT
1418 zero
= SelectableInt(out
== 0, 1)
1419 positive
= SelectableInt(out
> 0, 1)
1420 negative
= SelectableInt(out
< 0, 1)
1421 # get (or not) XER.SO. for setvl this is important *not* to read SO
1423 SO
= SelectableInt(1, 0)
1425 SO
= self
.spr
['XER'][XER_bits
['SO']]
1426 log("handle_comparison SO overflow", SO
, overflow
)
1427 # alternative overflow checking (setvl mainly at the moment)
1428 if overflow
is not None and overflow
== 1:
1429 SO
= SelectableInt(1, 1)
1430 # create the four CR field values and set the required CR field
1431 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1432 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1433 self
.crl
[cr_idx
].eq(cr_field
)
1435 def set_pc(self
, pc_val
):
1436 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1437 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1439 def get_next_insn(self
):
1440 """check instruction
1443 pc
= self
.pc
.CIA
.value
1446 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1448 raise KeyError("no instruction at 0x%x" % pc
)
1451 def setup_one(self
):
1452 """set up one instruction
1454 pc
, insn
= self
.get_next_insn()
1455 yield from self
.setup_next_insn(pc
, insn
)
1457 def setup_next_insn(self
, pc
, ins
):
1458 """set up next instruction
1461 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1462 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1464 yield self
.dec2
.sv_rm
.eq(0)
1465 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1466 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1467 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1468 yield self
.dec2
.state
.pc
.eq(pc
)
1469 if self
.svstate
is not None:
1470 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1472 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1474 opcode
= yield self
.dec2
.dec
.opcode_in
1475 opcode
= SelectableInt(value
=opcode
, bits
=32)
1476 pfx
= SVP64Instruction
.Prefix(opcode
)
1477 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1478 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1479 self
.pc
.update_nia(self
.is_svp64_mode
)
1481 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1482 self
.namespace
['NIA'] = self
.pc
.NIA
1483 self
.namespace
['SVSTATE'] = self
.svstate
1484 if not self
.is_svp64_mode
:
1487 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1488 log("svp64.rm", bin(pfx
.rm
))
1489 log(" svstate.vl", self
.svstate
.vl
)
1490 log(" svstate.mvl", self
.svstate
.maxvl
)
1491 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1492 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1493 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1494 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1497 def execute_one(self
):
1498 """execute one instruction
1500 # get the disassembly code for this instruction
1501 if not self
.disassembly
:
1502 code
= yield from self
.get_assembly_name()
1505 if self
.is_svp64_mode
:
1506 offs
, dbg
= 4, "svp64 "
1507 code
= self
.disassembly
[self
._pc
+offs
]
1508 log(" %s sim-execute" % dbg
, hex(self
._pc
), code
)
1509 opname
= code
.split(' ')[0]
1511 yield from self
.call(opname
) # execute the instruction
1512 except MemException
as e
: # check for memory errors
1513 if e
.args
[0] == 'unaligned': # alignment error
1514 # run a Trap but set DAR first
1515 print("memory unaligned exception, DAR", e
.dar
)
1516 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1517 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1519 elif e
.args
[0] == 'invalid': # invalid
1520 # run a Trap but set DAR first
1521 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1522 if e
.mode
== 'EXECUTE':
1523 # XXX TODO: must set a few bits in SRR1,
1524 # see microwatt loadstore1.vhdl
1525 # if m_in.segerr = '0' then
1526 # v.srr1(47 - 33) := m_in.invalid;
1527 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1528 # v.srr1(47 - 44) := m_in.badtree;
1529 # v.srr1(47 - 45) := m_in.rc_error;
1530 # v.intr_vec := 16#400#;
1532 # v.intr_vec := 16#480#;
1533 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1535 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1537 # not supported yet:
1538 raise e
# ... re-raise
1540 log("gprs after code", code
)
1543 for i
in range(len(self
.crl
)):
1544 crs
.append(bin(self
.crl
[i
].asint()))
1545 log("crs", " ".join(crs
))
1546 log("vl,maxvl", self
.svstate
.vl
, self
.svstate
.maxvl
)
1548 # don't use this except in special circumstances
1549 if not self
.respect_pc
:
1552 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1553 hex(self
.pc
.NIA
.value
))
1555 def get_assembly_name(self
):
1556 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1557 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1558 dec_insn
= yield self
.dec2
.e
.do
.insn
1559 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1560 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1561 int_op
= yield self
.dec2
.dec
.op
.internal_op
1562 log("get assembly name asmcode", asmcode
, int_op
,
1563 hex(dec_insn
), bin(insn_1_11
))
1564 asmop
= insns
.get(asmcode
, None)
1566 # sigh reconstruct the assembly instruction name
1567 if hasattr(self
.dec2
.e
.do
, "oe"):
1568 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1569 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1573 if hasattr(self
.dec2
.e
.do
, "rc"):
1574 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1575 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1579 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1580 RC1
= yield self
.dec2
.rm_dec
.RC1
1584 # grrrr have to special-case MUL op (see DecodeOE)
1585 log("ov %d en %d rc %d en %d op %d" %
1586 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1587 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1592 if not asmop
.endswith("."): # don't add "." to "andis."
1595 if hasattr(self
.dec2
.e
.do
, "lk"):
1596 lk
= yield self
.dec2
.e
.do
.lk
1599 log("int_op", int_op
)
1600 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1601 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1605 spr_msb
= yield from self
.get_spr_msb()
1606 if int_op
== MicrOp
.OP_MFCR
.value
:
1611 # XXX TODO: for whatever weird reason this doesn't work
1612 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1613 if int_op
== MicrOp
.OP_MTCRF
.value
:
1620 def reset_remaps(self
):
1621 self
.remap_loopends
= [0] * 4
1622 self
.remap_idxs
= [0, 1, 2, 3]
1624 def get_remap_indices(self
):
1625 """WARNING, this function stores remap_idxs and remap_loopends
1626 in the class for later use. this to avoid problems with yield
1628 # go through all iterators in lock-step, advance to next remap_idx
1629 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1630 # get four SVSHAPEs. here we are hard-coding
1632 SVSHAPE0
= self
.spr
['SVSHAPE0']
1633 SVSHAPE1
= self
.spr
['SVSHAPE1']
1634 SVSHAPE2
= self
.spr
['SVSHAPE2']
1635 SVSHAPE3
= self
.spr
['SVSHAPE3']
1636 # set up the iterators
1637 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1638 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1639 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1640 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1644 for i
, (shape
, remap
) in enumerate(remaps
):
1645 # zero is "disabled"
1646 if shape
.value
== 0x0:
1647 self
.remap_idxs
[i
] = 0
1648 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1649 step
= dststep
if (i
in [3, 4]) else srcstep
1650 # this is terrible. O(N^2) looking for the match. but hey.
1651 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1654 self
.remap_idxs
[i
] = remap_idx
1655 self
.remap_loopends
[i
] = loopends
1656 dbg
.append((i
, step
, remap_idx
, loopends
))
1657 for (i
, step
, remap_idx
, loopends
) in dbg
:
1658 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1661 def get_spr_msb(self
):
1662 dec_insn
= yield self
.dec2
.e
.do
.insn
1663 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1665 def call(self
, name
):
1666 """call(opcode) - the primary execution point for instructions
1668 self
.last_st_addr
= None # reset the last known store address
1669 self
.last_ld_addr
= None # etc.
1671 ins_name
= name
.strip() # remove spaces if not already done so
1673 log("halted - not executing", ins_name
)
1676 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1677 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1678 asmop
= yield from self
.get_assembly_name()
1679 log("call", ins_name
, asmop
)
1681 # sv.setvl is *not* a loop-function. sigh
1682 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1685 int_op
= yield self
.dec2
.dec
.op
.internal_op
1686 spr_msb
= yield from self
.get_spr_msb()
1688 instr_is_privileged
= False
1689 if int_op
in [MicrOp
.OP_ATTN
.value
,
1690 MicrOp
.OP_MFMSR
.value
,
1691 MicrOp
.OP_MTMSR
.value
,
1692 MicrOp
.OP_MTMSRD
.value
,
1694 MicrOp
.OP_RFID
.value
]:
1695 instr_is_privileged
= True
1696 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1697 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1698 instr_is_privileged
= True
1700 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1702 # check MSR priv bit and whether op is privileged: if so, throw trap
1703 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1704 self
.call_trap(0x700, PIb
.PRIV
)
1707 # check halted condition
1708 if ins_name
== 'attn':
1712 # check illegal instruction
1714 if ins_name
not in ['mtcrf', 'mtocrf']:
1715 illegal
= ins_name
!= asmop
1717 # list of instructions not being supported by binutils (.long)
1718 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1719 if dotstrp
in [*FPTRANS_INSNS
,
1720 'ffmadds', 'fdmadds', 'ffadds',
1721 'mins', 'maxs', 'minu', 'maxu',
1722 'setvl', 'svindex', 'svremap', 'svstep',
1723 'svshape', 'svshape2',
1724 'grev', 'ternlogi', 'bmask', 'cprop',
1725 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1726 'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
1732 # branch-conditional redirects to sv.bc
1733 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1734 ins_name
= 'sv.%s' % ins_name
1736 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1738 # illegal instructions call TRAP at 0x700
1740 print("illegal", ins_name
, asmop
)
1741 self
.call_trap(0x700, PIb
.ILLEG
)
1742 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1743 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1746 # this is for setvl "Vertical" mode: if set true,
1747 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1748 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1749 self
.allow_next_step_inc
= False
1750 self
.svstate_next_mode
= 0
1752 # nop has to be supported, we could let the actual op calculate
1753 # but PowerDecoder has a pattern for nop
1754 if ins_name
== 'nop':
1755 self
.update_pc_next()
1758 # get elwidths, defaults to 64
1762 if self
.is_svp64_mode
:
1763 ew_src
= yield self
.dec2
.rm_dec
.ew_src
1764 ew_dst
= yield self
.dec2
.rm_dec
.ew_dst
1765 ew_src
= 8 << (3-int(ew_src
)) # convert to bitlength
1766 ew_dst
= 8 << (3-int(ew_dst
)) # convert to bitlength
1767 xlen
= max(ew_src
, ew_dst
)
1768 log("elwdith", ew_src
, ew_dst
)
1769 log("XLEN:", self
.is_svp64_mode
, xlen
)
1771 # look up instruction in ISA.instrs, prepare namespace
1772 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1773 info
= self
.instrs
[ins_name
+"."]
1775 info
= self
.instrs
[ins_name
]
1776 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
,
1779 # preserve order of register names
1780 input_names
= create_args(list(info
.read_regs
) +
1781 list(info
.uninit_regs
))
1782 log("input names", input_names
)
1784 # get SVP64 entry for the current instruction
1785 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1786 if sv_rm
is not None:
1787 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1789 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1790 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1792 # see if srcstep/dststep need skipping over masked-out predicate bits
1793 # svstep also needs advancement because it calls SVSTATE_NEXT.
1794 # bit the remaps get computed just after pre_inc moves them on
1795 # with remap_set_steps substituting for PowerDecider2 not doing it,
1796 # and SVSTATE_NEXT not being able to.use yield, the preinc on
1797 # svstep is necessary for now.
1799 if (self
.is_svp64_mode
or ins_name
in ['svstep']):
1800 yield from self
.svstate_pre_inc()
1801 if self
.is_svp64_mode
:
1802 pre
= yield from self
.update_new_svstate_steps()
1804 self
.svp64_reset_loop()
1806 self
.update_pc_next()
1808 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1809 pred_dst_zero
= self
.pred_dst_zero
1810 pred_src_zero
= self
.pred_src_zero
1811 vl
= self
.svstate
.vl
1812 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1814 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1815 if self
.is_svp64_mode
and vl
== 0:
1816 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1817 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1818 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1821 # for when SVREMAP is active, using pre-arranged schedule.
1822 # note: modifying PowerDecoder2 needs to "settle"
1823 remap_en
= self
.svstate
.SVme
1824 persist
= self
.svstate
.RMpst
1825 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1826 if self
.is_svp64_mode
:
1827 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1829 if persist
or self
.last_op_svshape
:
1830 remaps
= self
.get_remap_indices()
1831 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1832 yield from self
.remap_set_steps(remaps
)
1833 # after that, settle down (combinatorial) to let Vector reg numbers
1834 # work themselves out
1836 if self
.is_svp64_mode
:
1837 remap_active
= yield self
.dec2
.remap_active
1839 remap_active
= False
1840 log("remap active", bin(remap_active
))
1842 # main input registers (RT, RA ...)
1844 for name
in input_names
:
1845 regval
= (yield from self
.get_input(name
, ew_src
))
1846 log("regval name", name
, regval
)
1847 inputs
.append(regval
)
1849 # arrrrgh, awful hack, to get _RT into namespace
1850 if ins_name
in ['setvl', 'svstep']:
1852 RT
= yield self
.dec2
.dec
.RT
1853 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1855 self
.namespace
["RT"] = SelectableInt(0, 5)
1856 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, "RT")
1857 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1859 # in SVP64 mode for LD/ST work out immediate
1860 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1861 # use info.form to detect
1862 if self
.is_svp64_mode
:
1863 yield from self
.check_replace_d(info
, remap_active
)
1865 # "special" registers
1866 for special
in info
.special_regs
:
1867 if special
in special_sprs
:
1868 inputs
.append(self
.spr
[special
])
1870 inputs
.append(self
.namespace
[special
])
1872 # clear trap (trap) NIA
1873 self
.trap_nia
= None
1875 # check if this was an sv.bc* and create an indicator that
1876 # this is the last check to be made as a loop. combined with
1877 # the ALL/ANY mode we can early-exit
1878 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1879 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1880 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1881 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1883 # execute actual instruction here (finally)
1884 log("inputs", inputs
)
1885 results
= info
.func(self
, *inputs
)
1886 output_names
= create_args(info
.write_regs
)
1888 for out
, n
in zip(results
or [], output_names
):
1890 log("results", outs
)
1892 # "inject" decorator takes namespace from function locals: we need to
1893 # overwrite NIA being overwritten (sigh)
1894 if self
.trap_nia
is not None:
1895 self
.namespace
['NIA'] = self
.trap_nia
1897 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1899 # check if op was a LD/ST so that debugging can check the
1901 if int_op
in [MicrOp
.OP_STORE
.value
,
1903 self
.last_st_addr
= self
.mem
.last_st_addr
1904 if int_op
in [MicrOp
.OP_LOAD
.value
,
1906 self
.last_ld_addr
= self
.mem
.last_ld_addr
1907 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1908 self
.last_st_addr
, self
.last_ld_addr
)
1910 # detect if CA/CA32 already in outputs (sra*, basically)
1912 ca32
= outs
.get("CA32 ")
1914 log("carry already done?", ca
, ca32
, output_names
)
1915 carry_en
= yield self
.dec2
.e
.do
.output_carry
1917 yield from self
.handle_carry_(inputs
, results
[0], ca
, ca32
)
1919 # get outout named "overflow" and "CR0"
1920 overflow
= outs
.get('overflow')
1921 cr0
= outs
.get('CR0')
1923 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1924 # detect if overflow was in return result
1925 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1926 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1927 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1929 yield from self
.handle_overflow(inputs
, results
[0], overflow
)
1931 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1933 if not self
.is_svp64_mode
or not pred_dst_zero
:
1934 if hasattr(self
.dec2
.e
.do
, "rc"):
1935 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1936 # don't do Rc=1 for svstep it is handled explicitly.
1937 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1938 # to write directly to CR0 instead of in ISACaller. hooyahh.
1939 if rc_en
and ins_name
not in ['svstep']:
1940 yield from self
.do_rc_ov(ins_name
, results
[0], overflow
, cr0
)
1943 ffirst_hit
= False, False
1944 if self
.is_svp64_mode
:
1945 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
1946 is_cr
= sv_mode
== SVMode
.CROP
.value
1947 chk
= rc_en
or is_cr
1948 ffirst_hit
= (yield from self
.check_ffirst(info
, chk
, srcstep
))
1950 # any modified return results?
1951 yield from self
.do_outregs_nia(asmop
, ins_name
, info
, outs
,
1952 carry_en
, rc_en
, ffirst_hit
, ew_dst
)
1954 def check_ffirst(self
, info
, rc_en
, srcstep
):
1955 """fail-first mode: checks a bit of Rc Vector, truncates VL
1957 rm_mode
= yield self
.dec2
.rm_dec
.mode
1958 ff_inv
= yield self
.dec2
.rm_dec
.inv
1959 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
1960 RC1
= yield self
.dec2
.rm_dec
.RC1
1961 vli_
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
1962 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
1966 log(" cr_bit", cr_bit
)
1967 log(" rc_en", rc_en
)
1968 if not rc_en
or rm_mode
!= SVP64RMMode
.FFIRST
.value
:
1970 # get the CR vevtor, do BO-test
1972 log("asmregs", info
.asmregs
[0], info
.write_regs
)
1973 if 'CR' in info
.write_regs
and 'BF' in info
.asmregs
[0]:
1975 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, crf
)
1976 crtest
= self
.crl
[regnum
]
1977 ffirst_hit
= crtest
[cr_bit
] != ff_inv
1978 log("cr test", crf
, regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
1979 log("cr test?", ffirst_hit
)
1982 # Fail-first activated, truncate VL
1983 vli
= SelectableInt(int(vli_
), 7)
1984 self
.svstate
.vl
= srcstep
+ vli
1985 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1986 yield Settle() # let decoder update
1989 def do_rc_ov(self
, ins_name
, result
, overflow
, cr0
):
1990 if ins_name
.startswith("f"):
1991 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1994 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, rc_reg
)
1995 # hang on... for `setvl` actually you want to test SVSTATE.VL
1996 is_setvl
= ins_name
in ('svstep', 'setvl')
1998 result
= SelectableInt(result
.vl
, 64)
2000 overflow
= None # do not override overflow except in setvl
2002 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
2004 self
.handle_comparison(result
, regnum
, overflow
, no_so
=is_setvl
)
2006 # otherwise we just blat CR0 into the required regnum
2007 log("explicit rc0", cr0
)
2008 self
.crl
[regnum
].eq(cr0
)
2010 def do_outregs_nia(self
, asmop
, ins_name
, info
, outs
,
2011 carry_en
, rc_en
, ffirst_hit
, ew_dst
):
2012 ffirst_hit
, vli
= ffirst_hit
2013 # write out any regs for this instruction
2014 for name
, output
in outs
.items():
2015 yield from self
.check_write(info
, name
, output
, carry_en
, ew_dst
)
2016 # restore the CR value on non-VLI failfirst (from sv.cmp and others
2017 # which write directly to CR in the pseudocode (gah, what a mess)
2018 #if ffirst_hit and not vli:
2019 # self.cr.value = self.cr_backup
2022 self
.svp64_reset_loop()
2025 # check advancement of src/dst/sub-steps and if PC needs updating
2026 nia_update
= (yield from self
.check_step_increment(rc_en
,
2029 self
.update_pc_next()
2031 def check_replace_d(self
, info
, remap_active
):
2032 replace_d
= False # update / replace constant in pseudocode
2033 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
2034 vl
= self
.svstate
.vl
2035 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2036 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2037 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2038 if info
.form
== 'DS':
2039 # DS-Form, multiply by 4 then knock 2 bits off after
2040 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
2042 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
2043 imm
= exts(imm
, 16) # sign-extend to integer
2044 # get the right step. LD is from srcstep, ST is dststep
2045 op
= yield self
.dec2
.e
.do
.insn_type
2047 if op
== MicrOp
.OP_LOAD
.value
:
2049 offsmul
= yield self
.dec2
.in1_step
2050 log("D-field REMAP src", imm
, offsmul
)
2052 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
2053 log("D-field src", imm
, offsmul
)
2054 elif op
== MicrOp
.OP_STORE
.value
:
2055 # XXX NOTE! no bit-reversed STORE! this should not ever be used
2056 offsmul
= (dststep
* (subvl
+1)) + dsubstep
2057 log("D-field dst", imm
, offsmul
)
2058 # Unit-Strided LD/ST adds offset*width to immediate
2059 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
2060 ldst_len
= yield self
.dec2
.e
.do
.data_len
2061 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
2063 # Element-strided multiplies the immediate by element step
2064 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
2065 imm
= SelectableInt(imm
* offsmul
, 32)
2068 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
2069 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
2070 log("LDSTmode", SVP64LDSTmode(ldstmode
),
2071 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
2072 # new replacement D... errr.. DS
2074 if info
.form
== 'DS':
2075 # TODO: assert 2 LSBs are zero?
2076 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
2077 imm
.value
= imm
.value
>> 2
2078 self
.namespace
['DS'] = imm
2080 self
.namespace
['D'] = imm
2082 def get_input(self
, name
, ew_src
):
2083 # using PowerDecoder2, first, find the decoder index.
2084 # (mapping name RA RB RC RS to in1, in2, in3)
2085 regnum
, is_vec
= yield from get_idx_in(self
.dec2
, name
, True)
2087 # doing this is not part of svp64, it's because output
2088 # registers, to be modified, need to be in the namespace.
2089 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2091 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
, True)
2093 if isinstance(regnum
, tuple):
2094 (regnum
, base
, offs
) = regnum
2096 base
, offs
= regnum
, 0 # temporary HACK
2098 # in case getting the register number is needed, _RA, _RB
2099 # (HACK: only in straight non-svp64-mode for now, or elwidth == 64)
2100 regname
= "_" + name
2101 if not self
.is_svp64_mode
or ew_src
== 64:
2102 self
.namespace
[regname
] = regnum
2103 elif regname
in self
.namespace
:
2104 del self
.namespace
[regname
]
2106 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
2107 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
2109 reg_val
= SelectableInt(self
.fpr(base
, is_vec
, offs
, ew_src
))
2110 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2111 elif name
is not None:
2112 reg_val
= SelectableInt(self
.gpr(base
, is_vec
, offs
, ew_src
))
2113 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2115 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
2119 def remap_set_steps(self
, remaps
):
2120 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
2121 they work in concert with PowerDecoder2 at the moment,
2122 there is no HDL implementation of REMAP. therefore this
2123 function, because ISACaller still uses PowerDecoder2,
2124 will *explicitly* write the dec2.XX_step values. this has
2127 # just some convenient debug info
2129 sname
= 'SVSHAPE%d' % i
2130 shape
= self
.spr
[sname
]
2131 log(sname
, bin(shape
.value
))
2132 log(" lims", shape
.lims
)
2133 log(" mode", shape
.mode
)
2134 log(" skip", shape
.skip
)
2136 # set up the list of steps to remap
2137 mi0
= self
.svstate
.mi0
2138 mi1
= self
.svstate
.mi1
2139 mi2
= self
.svstate
.mi2
2140 mo0
= self
.svstate
.mo0
2141 mo1
= self
.svstate
.mo1
2142 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
2143 (self
.dec2
.in2_step
, mi1
), # RB
2144 (self
.dec2
.in3_step
, mi2
), # RC
2145 (self
.dec2
.o_step
, mo0
), # RT
2146 (self
.dec2
.o2_step
, mo1
), # EA
2148 remap_idxs
= self
.remap_idxs
2150 # now cross-index the required SHAPE for each of 3-in 2-out regs
2151 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
2152 for i
, (dstep
, shape_idx
) in enumerate(steps
):
2153 (shape
, remap
) = remaps
[shape_idx
]
2154 remap_idx
= remap_idxs
[shape_idx
]
2155 # zero is "disabled"
2156 if shape
.value
== 0x0:
2158 # now set the actual requested step to the current index
2159 yield dstep
.eq(remap_idx
)
2161 # debug printout info
2162 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
2164 log("shape remap", x
)
2166 def check_write(self
, info
, name
, output
, carry_en
, ew_dst
):
2167 if name
== 'overflow': # ignore, done already (above)
2169 if name
== 'CR0': # ignore, done already (above)
2171 if isinstance(output
, int):
2172 output
= SelectableInt(output
, 256)
2174 if name
in ['CA', 'CA32']:
2176 log("writing %s to XER" % name
, output
)
2177 log("write XER %s 0x%x" % (name
, output
.value
))
2178 self
.spr
['XER'][XER_bits
[name
]] = output
.value
2180 log("NOT writing %s to XER" % name
, output
)
2182 # write special SPRs
2183 if name
in info
.special_regs
:
2184 log('writing special %s' % name
, output
, special_sprs
)
2185 log("write reg %s 0x%x" % (name
, output
.value
))
2186 if name
in special_sprs
:
2187 self
.spr
[name
] = output
2189 self
.namespace
[name
].eq(output
)
2191 log('msr written', hex(self
.msr
.value
))
2193 # find out1/out2 PR/FPR
2194 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2196 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
, True)
2198 # temporary hack for not having 2nd output
2199 regnum
= yield getattr(self
.decoder
, name
)
2201 # convenient debug prefix
2206 # check zeroing due to predicate bit being zero
2207 if self
.is_svp64_mode
and self
.pred_dst_zero
:
2208 log('zeroing reg %s %s' % (str(regnum
), str(output
)), is_vec
)
2209 output
= SelectableInt(0, 256)
2210 log("write reg %s%s 0x%x ew %d" % (reg_prefix
, str(regnum
),
2211 output
.value
, ew_dst
),
2212 kind
=LogKind
.InstrInOuts
)
2213 # zero-extend tov64 bit begore storing (should use EXT oh well)
2214 if output
.bits
> 64:
2215 output
= SelectableInt(output
.value
, 64)
2217 self
.fpr
.write(regnum
, output
, is_vec
, ew_dst
)
2219 self
.gpr
.write(regnum
, output
, is_vec
, ew_dst
)
2221 def check_step_increment(self
, rc_en
, asmop
, ins_name
):
2222 # check if it is the SVSTATE.src/dest step that needs incrementing
2223 # this is our Sub-Program-Counter loop from 0 to VL-1
2224 if not self
.allow_next_step_inc
:
2225 if self
.is_svp64_mode
:
2226 return (yield from self
.svstate_post_inc(ins_name
))
2228 # XXX only in non-SVP64 mode!
2229 # record state of whether the current operation was an svshape,
2231 # to be able to know if it should apply in the next instruction.
2232 # also (if going to use this instruction) should disable ability
2233 # to interrupt in between. sigh.
2234 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2241 log("SVSTATE_NEXT: inc requested, mode",
2242 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2243 yield from self
.svstate_pre_inc()
2244 pre
= yield from self
.update_new_svstate_steps()
2246 # reset at end of loop including exit Vertical Mode
2247 log("SVSTATE_NEXT: end of loop, reset")
2248 self
.svp64_reset_loop()
2249 self
.svstate
.vfirst
= 0
2253 self
.handle_comparison(SelectableInt(0, 64)) # CR0
2255 if self
.allow_next_step_inc
== 2:
2256 log("SVSTATE_NEXT: read")
2257 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2259 log("SVSTATE_NEXT: post-inc")
2260 # use actual (cached) src/dst-step here to check end
2261 remaps
= self
.get_remap_indices()
2262 remap_idxs
= self
.remap_idxs
2263 vl
= self
.svstate
.vl
2264 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2265 if self
.allow_next_step_inc
!= 2:
2266 yield from self
.advance_svstate_steps()
2267 #self.namespace['SVSTATE'] = self.svstate.spr
2268 # set CR0 (if Rc=1) based on end
2269 endtest
= 1 if self
.at_loopend() else 0
2271 #results = [SelectableInt(endtest, 64)]
2272 # self.handle_comparison(results) # CR0
2274 # see if svstep was requested, if so, which SVSTATE
2276 if self
.svstate_next_mode
> 0:
2277 shape_idx
= self
.svstate_next_mode
.value
-1
2278 endings
= self
.remap_loopends
[shape_idx
]
2279 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2280 log("svstep Rc=1, CR0", cr_field
, endtest
)
2281 self
.crl
[0].eq(cr_field
) # CR0
2283 # reset at end of loop including exit Vertical Mode
2284 log("SVSTATE_NEXT: after increments, reset")
2285 self
.svp64_reset_loop()
2286 self
.svstate
.vfirst
= 0
2289 def SVSTATE_NEXT(self
, mode
, submode
):
2290 """explicitly moves srcstep/dststep on to next element, for
2291 "Vertical-First" mode. this function is called from
2292 setvl pseudo-code, as a pseudo-op "svstep"
2294 WARNING: this function uses information that was created EARLIER
2295 due to it being in the middle of a yield, but this function is
2296 *NOT* called from yield (it's called from compiled pseudocode).
2298 self
.allow_next_step_inc
= submode
.value
+ 1
2299 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2300 self
.svstate_next_mode
= mode
2301 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2302 shape_idx
= self
.svstate_next_mode
.value
-1
2303 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2304 if self
.svstate_next_mode
== 5:
2305 self
.svstate_next_mode
= 0
2306 return SelectableInt(self
.svstate
.srcstep
, 7)
2307 if self
.svstate_next_mode
== 6:
2308 self
.svstate_next_mode
= 0
2309 return SelectableInt(self
.svstate
.dststep
, 7)
2310 if self
.svstate_next_mode
== 7:
2311 self
.svstate_next_mode
= 0
2312 return SelectableInt(self
.svstate
.ssubstep
, 7)
2313 if self
.svstate_next_mode
== 8:
2314 self
.svstate_next_mode
= 0
2315 return SelectableInt(self
.svstate
.dsubstep
, 7)
2316 return SelectableInt(0, 7)
2318 def get_src_dststeps(self
):
2319 """gets srcstep, dststep, and ssubstep, dsubstep
2321 return (self
.new_srcstep
, self
.new_dststep
,
2322 self
.new_ssubstep
, self
.new_dsubstep
)
2324 def update_svstate_namespace(self
, overwrite_svstate
=True):
2325 if overwrite_svstate
:
2326 # note, do not get the bit-reversed srcstep here!
2327 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2328 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2330 # update SVSTATE with new srcstep
2331 self
.svstate
.srcstep
= srcstep
2332 self
.svstate
.dststep
= dststep
2333 self
.svstate
.ssubstep
= ssubstep
2334 self
.svstate
.dsubstep
= dsubstep
2335 self
.namespace
['SVSTATE'] = self
.svstate
2336 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2337 yield Settle() # let decoder update
2339 def update_new_svstate_steps(self
, overwrite_svstate
=True):
2340 yield from self
.update_svstate_namespace(overwrite_svstate
)
2341 srcstep
= self
.svstate
.srcstep
2342 dststep
= self
.svstate
.dststep
2343 ssubstep
= self
.svstate
.ssubstep
2344 dsubstep
= self
.svstate
.dsubstep
2345 pack
= self
.svstate
.pack
2346 unpack
= self
.svstate
.unpack
2347 vl
= self
.svstate
.vl
2348 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
2349 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2350 rm_mode
= yield self
.dec2
.rm_dec
.mode
2351 ff_inv
= yield self
.dec2
.rm_dec
.inv
2352 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2353 log(" srcstep", srcstep
)
2354 log(" dststep", dststep
)
2356 log(" unpack", unpack
)
2357 log(" ssubstep", ssubstep
)
2358 log(" dsubstep", dsubstep
)
2360 log(" subvl", subvl
)
2361 log(" rm_mode", rm_mode
)
2362 log(" sv_mode", sv_mode
)
2364 log(" cr_bit", cr_bit
)
2366 # check if end reached (we let srcstep overrun, above)
2367 # nothing needs doing (TODO zeroing): just do next instruction
2370 return ((ssubstep
== subvl
and srcstep
== vl
) or
2371 (dsubstep
== subvl
and dststep
== vl
))
2373 def svstate_post_inc(self
, insn_name
, vf
=0):
2374 # check if SV "Vertical First" mode is enabled
2375 vfirst
= self
.svstate
.vfirst
2376 log(" SV Vertical First", vf
, vfirst
)
2377 if not vf
and vfirst
== 1:
2381 # check if it is the SVSTATE.src/dest step that needs incrementing
2382 # this is our Sub-Program-Counter loop from 0 to VL-1
2383 # XXX twin predication TODO
2384 vl
= self
.svstate
.vl
2385 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2386 mvl
= self
.svstate
.maxvl
2387 srcstep
= self
.svstate
.srcstep
2388 dststep
= self
.svstate
.dststep
2389 ssubstep
= self
.svstate
.ssubstep
2390 dsubstep
= self
.svstate
.dsubstep
2391 pack
= self
.svstate
.pack
2392 unpack
= self
.svstate
.unpack
2393 rm_mode
= yield self
.dec2
.rm_dec
.mode
2394 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2395 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2396 out_vec
= not (yield self
.dec2
.no_out_vec
)
2397 in_vec
= not (yield self
.dec2
.no_in_vec
)
2398 log(" svstate.vl", vl
)
2399 log(" svstate.mvl", mvl
)
2400 log(" rm.subvl", subvl
)
2401 log(" svstate.srcstep", srcstep
)
2402 log(" svstate.dststep", dststep
)
2403 log(" svstate.ssubstep", ssubstep
)
2404 log(" svstate.dsubstep", dsubstep
)
2405 log(" svstate.pack", pack
)
2406 log(" svstate.unpack", unpack
)
2407 log(" mode", rm_mode
)
2408 log(" reverse", reverse_gear
)
2409 log(" out_vec", out_vec
)
2410 log(" in_vec", in_vec
)
2411 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2412 # check if this was an sv.bc* and if so did it succeed
2413 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2414 end_loop
= self
.namespace
['end_loop']
2415 log("branch %s end_loop" % insn_name
, end_loop
)
2417 self
.svp64_reset_loop()
2418 self
.update_pc_next()
2420 # check if srcstep needs incrementing by one, stop PC advancing
2421 # but for 2-pred both src/dest have to be checked.
2422 # XXX this might not be true! it may just be LD/ST
2423 if sv_ptype
== SVPtype
.P2
.value
:
2424 svp64_is_vector
= (out_vec
or in_vec
)
2426 svp64_is_vector
= out_vec
2427 # loops end at the first "hit" (source or dest)
2428 yield from self
.advance_svstate_steps()
2429 loopend
= self
.loopend
2430 log("loopend", svp64_is_vector
, loopend
)
2431 if not svp64_is_vector
or loopend
:
2432 # reset loop to zero and update NIA
2433 self
.svp64_reset_loop()
2438 # still looping, advance and update NIA
2439 self
.namespace
['SVSTATE'] = self
.svstate
2441 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2442 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2443 # this way we keep repeating the same instruction (with new steps)
2444 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2445 self
.namespace
['NIA'] = self
.pc
.NIA
2446 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2447 return False # DO NOT allow PC update whilst Sub-PC loop running
2449 def update_pc_next(self
):
2450 # UPDATE program counter
2451 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2452 #self.svstate.spr = self.namespace['SVSTATE']
2453 log("end of call", self
.namespace
['CIA'],
2454 self
.namespace
['NIA'],
2455 self
.namespace
['SVSTATE'])
2457 def svp64_reset_loop(self
):
2458 self
.svstate
.srcstep
= 0
2459 self
.svstate
.dststep
= 0
2460 self
.svstate
.ssubstep
= 0
2461 self
.svstate
.dsubstep
= 0
2462 self
.loopend
= False
2463 log(" svstate.srcstep loop end (PC to update)")
2464 self
.namespace
['SVSTATE'] = self
.svstate
2466 def update_nia(self
):
2467 self
.pc
.update_nia(self
.is_svp64_mode
)
2468 self
.namespace
['NIA'] = self
.pc
.NIA
2472 """Decorator factory.
2474 this decorator will "inject" variables into the function's namespace,
2475 from the *dictionary* in self.namespace. it therefore becomes possible
2476 to make it look like a whole stack of variables which would otherwise
2477 need "self." inserted in front of them (*and* for those variables to be
2478 added to the instance) "appear" in the function.
2480 "self.namespace['SI']" for example becomes accessible as just "SI" but
2481 *only* inside the function, when decorated.
2483 def variable_injector(func
):
2485 def decorator(*args
, **kwargs
):
2487 func_globals
= func
.__globals
__ # Python 2.6+
2488 except AttributeError:
2489 func_globals
= func
.func_globals
# Earlier versions.
2491 context
= args
[0].namespace
# variables to be injected
2492 saved_values
= func_globals
.copy() # Shallow copy of dict.
2493 log("globals before", context
.keys())
2494 func_globals
.update(context
)
2495 result
= func(*args
, **kwargs
)
2496 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2497 log("args[0]", args
[0].namespace
['CIA'],
2498 args
[0].namespace
['NIA'],
2499 args
[0].namespace
['SVSTATE'])
2500 if 'end_loop' in func_globals
:
2501 log("args[0] end_loop", func_globals
['end_loop'])
2502 args
[0].namespace
= func_globals
2503 #exec (func.__code__, func_globals)
2506 # func_globals = saved_values # Undo changes.
2512 return variable_injector