23845911cf99a6774e79c26a592c034788b104eb
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
,
31 SVP64RMMode
, SVP64PredMode
,
32 SVP64PredInt
, SVP64PredCR
,
33 SVP64LDSTmode
, FPTRANS_INSNS
)
35 from openpower
.decoder
.power_enums
import SVPtype
37 from openpower
.decoder
.helpers
import (exts
, gtu
, ltu
, undefined
,
38 ISACallerHelper
, ISAFPHelpers
)
39 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
40 from openpower
.consts
import (SVP64MODE
,
43 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
45 from openpower
.decoder
.isa
.radixmmu
import RADIX
46 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
47 from openpower
.decoder
.isa
.svshape
import SVSHAPE
48 from openpower
.decoder
.isa
.svstate
import SVP64State
51 from openpower
.util
import LogKind
, log
53 from collections
import namedtuple
57 instruction_info
= namedtuple('instruction_info',
58 'func read_regs uninit_regs write_regs ' +
59 'special_regs op_fields form asmregs')
70 # TODO (lkcl): adjust other registers that should be in a particular order
71 # probably CA, CA32, and CR
97 "overflow": 7, # should definitely be last
101 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
104 def create_args(reglist
, extra
=None):
105 retval
= list(OrderedSet(reglist
))
106 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
107 if extra
is not None:
108 return [extra
] + retval
113 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
116 self
.isacaller
= isacaller
117 self
.svstate
= svstate
118 for i
in range(len(regfile
)):
119 self
[i
] = SelectableInt(regfile
[i
], 64)
121 def __call__(self
, ridx
):
122 if isinstance(ridx
, SelectableInt
):
126 def set_form(self
, form
):
129 def __setitem__(self
, rnum
, value
):
130 # rnum = rnum.value # only SelectableInt allowed
131 log("GPR setitem", rnum
, value
)
132 if isinstance(rnum
, SelectableInt
):
134 dict.__setitem
__(self
, rnum
, value
)
136 def getz(self
, rnum
):
137 # rnum = rnum.value # only SelectableInt allowed
138 log("GPR getzero?", rnum
)
140 return SelectableInt(0, 64)
143 def _get_regnum(self
, attr
):
144 getform
= self
.sd
.sigforms
[self
.form
]
145 rnum
= getattr(getform
, attr
)
148 def ___getitem__(self
, attr
):
149 """ XXX currently not used
151 rnum
= self
._get
_regnum
(attr
)
152 log("GPR getitem", attr
, rnum
)
153 return self
.regfile
[rnum
]
155 def dump(self
, printout
=True):
157 for i
in range(len(self
)):
158 res
.append(self
[i
].value
)
160 for i
in range(0, len(res
), 8):
163 s
.append("%08x" % res
[i
+j
])
165 print("reg", "%2d" % i
, s
)
170 def __init__(self
, dec2
, initial_sprs
={}):
173 for key
, v
in initial_sprs
.items():
174 if isinstance(key
, SelectableInt
):
176 key
= special_sprs
.get(key
, key
)
177 if isinstance(key
, int):
180 info
= spr_byname
[key
]
181 if not isinstance(v
, SelectableInt
):
182 v
= SelectableInt(v
, info
.length
)
185 def __getitem__(self
, key
):
187 log("dict", self
.items())
188 # if key in special_sprs get the special spr, otherwise return key
189 if isinstance(key
, SelectableInt
):
191 if isinstance(key
, int):
192 key
= spr_dict
[key
].SPR
193 key
= special_sprs
.get(key
, key
)
194 if key
== 'HSRR0': # HACK!
196 if key
== 'HSRR1': # HACK!
199 res
= dict.__getitem
__(self
, key
)
201 if isinstance(key
, int):
204 info
= spr_byname
[key
]
205 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
206 res
= dict.__getitem
__(self
, key
)
207 log("spr returning", key
, res
)
210 def __setitem__(self
, key
, value
):
211 if isinstance(key
, SelectableInt
):
213 if isinstance(key
, int):
214 key
= spr_dict
[key
].SPR
216 key
= special_sprs
.get(key
, key
)
217 if key
== 'HSRR0': # HACK!
218 self
.__setitem
__('SRR0', value
)
219 if key
== 'HSRR1': # HACK!
220 self
.__setitem
__('SRR1', value
)
221 log("setting spr", key
, value
)
222 dict.__setitem
__(self
, key
, value
)
224 def __call__(self
, ridx
):
227 def dump(self
, printout
=True):
229 keys
= list(self
.keys())
232 sprname
= spr_dict
.get(k
, None)
236 sprname
= sprname
.SPR
237 res
.append((sprname
, self
[k
].value
))
239 for sprname
, value
in res
:
240 print(" ", sprname
, hex(value
))
245 def __init__(self
, pc_init
=0):
246 self
.CIA
= SelectableInt(pc_init
, 64)
247 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
249 def update_nia(self
, is_svp64
):
250 increment
= 8 if is_svp64
else 4
251 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
253 def update(self
, namespace
, is_svp64
):
254 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
256 self
.CIA
= namespace
['NIA'].narrow(64)
257 self
.update_nia(is_svp64
)
258 namespace
['CIA'] = self
.CIA
259 namespace
['NIA'] = self
.NIA
263 # See PowerISA Version 3.0 B Book 1
264 # Section 2.3.1 Condition Register pages 30 - 31
266 LT
= FL
= 0 # negative, less than, floating-point less than
267 GT
= FG
= 1 # positive, greater than, floating-point greater than
268 EQ
= FE
= 2 # equal, floating-point equal
269 SO
= FU
= 3 # summary overflow, floating-point unordered
271 def __init__(self
, init
=0):
272 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
273 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
274 self
.cr
= SelectableInt(init
, 64) # underlying reg
275 # field-selectable versions of Condition Register TODO check bitranges?
278 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
279 _cr
= FieldSelectableInt(self
.cr
, bits
)
282 # decode SVP64 predicate integer to reg number and invert
285 def get_predint(gpr
, mask
):
288 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
289 if mask
== SVP64PredInt
.ALWAYS
.value
:
290 return 0xffff_ffff_ffff_ffff # 64 bits of 1
291 if mask
== SVP64PredInt
.R3_UNARY
.value
:
292 return 1 << (gpr(3).value
& 0b111111)
293 if mask
== SVP64PredInt
.R3
.value
:
295 if mask
== SVP64PredInt
.R3_N
.value
:
297 if mask
== SVP64PredInt
.R10
.value
:
299 if mask
== SVP64PredInt
.R10_N
.value
:
300 return ~
gpr(10).value
301 if mask
== SVP64PredInt
.R30
.value
:
303 if mask
== SVP64PredInt
.R30_N
.value
:
304 return ~
gpr(30).value
306 # decode SVP64 predicate CR to reg number and invert status
309 def _get_predcr(mask
):
310 if mask
== SVP64PredCR
.LT
.value
:
312 if mask
== SVP64PredCR
.GE
.value
:
314 if mask
== SVP64PredCR
.GT
.value
:
316 if mask
== SVP64PredCR
.LE
.value
:
318 if mask
== SVP64PredCR
.EQ
.value
:
320 if mask
== SVP64PredCR
.NE
.value
:
322 if mask
== SVP64PredCR
.SO
.value
:
324 if mask
== SVP64PredCR
.NS
.value
:
327 # read individual CR fields (0..VL-1), extract the required bit
328 # and construct the mask
331 def get_predcr(crl
, mask
, vl
):
332 idx
, noninv
= _get_predcr(mask
)
335 cr
= crl
[i
+SVP64CROffs
.CRPred
]
336 if cr
[idx
].value
== noninv
:
341 # TODO, really should just be using PowerDecoder2
342 def get_pdecode_idx_in(dec2
, name
):
344 in1_sel
= yield op
.in1_sel
345 in2_sel
= yield op
.in2_sel
346 in3_sel
= yield op
.in3_sel
347 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
348 in1
= yield dec2
.e
.read_reg1
.data
349 in2
= yield dec2
.e
.read_reg2
.data
350 in3
= yield dec2
.e
.read_reg3
.data
351 in1_isvec
= yield dec2
.in1_isvec
352 in2_isvec
= yield dec2
.in2_isvec
353 in3_isvec
= yield dec2
.in3_isvec
354 log("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
356 log("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
358 log("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
360 log("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
362 log("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
364 log("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
366 # identify which regnames map to in1/2/3
367 if name
== 'RA' or name
== 'RA_OR_ZERO':
368 if (in1_sel
== In1Sel
.RA
.value
or
369 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
370 return in1
, in1_isvec
371 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
372 return in1
, in1_isvec
374 if in2_sel
== In2Sel
.RB
.value
:
375 return in2
, in2_isvec
376 if in3_sel
== In3Sel
.RB
.value
:
377 return in3
, in3_isvec
378 # XXX TODO, RC doesn't exist yet!
380 if in3_sel
== In3Sel
.RC
.value
:
381 return in3
, in3_isvec
382 assert False, "RC does not exist yet"
384 if in1_sel
== In1Sel
.RS
.value
:
385 return in1
, in1_isvec
386 if in2_sel
== In2Sel
.RS
.value
:
387 return in2
, in2_isvec
388 if in3_sel
== In3Sel
.RS
.value
:
389 return in3
, in3_isvec
391 if in1_sel
== In1Sel
.FRA
.value
:
392 return in1
, in1_isvec
394 if in2_sel
== In2Sel
.FRB
.value
:
395 return in2
, in2_isvec
397 if in3_sel
== In3Sel
.FRC
.value
:
398 return in3
, in3_isvec
400 if in1_sel
== In1Sel
.FRS
.value
:
401 return in1
, in1_isvec
402 if in3_sel
== In3Sel
.FRS
.value
:
403 return in3
, in3_isvec
407 # TODO, really should just be using PowerDecoder2
408 def get_pdecode_cr_in(dec2
, name
):
410 in_sel
= yield op
.cr_in
411 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
412 sv_cr_in
= yield op
.sv_cr_in
413 spec
= yield dec2
.crin_svdec
.spec
414 sv_override
= yield dec2
.dec_cr_in
.sv_override
415 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
416 in1
= yield dec2
.e
.read_cr1
.data
417 cr_isvec
= yield dec2
.cr_in_isvec
418 log("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
419 log(" sv_cr_in", sv_cr_in
)
420 log(" cr_bf", in_bitfield
)
422 log(" override", sv_override
)
423 # identify which regnames map to in / o2
425 if in_sel
== CRInSel
.BI
.value
:
427 log("get_pdecode_cr_in not found", name
)
431 # TODO, really should just be using PowerDecoder2
432 def get_pdecode_cr_out(dec2
, name
):
434 out_sel
= yield op
.cr_out
435 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
436 sv_cr_out
= yield op
.sv_cr_out
437 spec
= yield dec2
.crout_svdec
.spec
438 sv_override
= yield dec2
.dec_cr_out
.sv_override
439 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
440 out
= yield dec2
.e
.write_cr
.data
441 o_isvec
= yield dec2
.o_isvec
442 log("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
443 log(" sv_cr_out", sv_cr_out
)
444 log(" cr_bf", out_bitfield
)
446 log(" override", sv_override
)
447 # identify which regnames map to out / o2
449 if out_sel
== CROutSel
.CR0
.value
:
451 if name
== 'CR1': # these are not actually calculated correctly
452 if out_sel
== CROutSel
.CR1
.value
:
454 log("get_pdecode_cr_out not found", name
)
458 # TODO, really should just be using PowerDecoder2
459 def get_pdecode_idx_out(dec2
, name
):
461 out_sel
= yield op
.out_sel
462 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
463 out
= yield dec2
.e
.write_reg
.data
464 o_isvec
= yield dec2
.o_isvec
465 # identify which regnames map to out / o2
467 log("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
468 if out_sel
== OutSel
.RA
.value
:
471 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
472 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
474 if out_sel
== OutSel
.RT
.value
:
476 if out_sel
== OutSel
.RT_OR_ZERO
.value
and out
!= 0:
478 elif name
== 'RT_OR_ZERO':
479 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
480 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
482 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
485 log("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
486 if out_sel
== OutSel
.FRA
.value
:
489 log("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
490 OutSel
.FRT
.value
, out
, o_isvec
)
491 if out_sel
== OutSel
.FRT
.value
:
493 log("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
497 # TODO, really should just be using PowerDecoder2
498 def get_pdecode_idx_out2(dec2
, name
):
499 # check first if register is activated for write
501 out_sel
= yield op
.out_sel
502 out
= yield dec2
.e
.write_ea
.data
503 o_isvec
= yield dec2
.o2_isvec
504 out_ok
= yield dec2
.e
.write_ea
.ok
505 log("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
510 if hasattr(op
, "upd"):
511 # update mode LD/ST uses read-reg A also as an output
513 log("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
514 out_sel
, OutSel
.RA
.value
,
516 if upd
== LDSTMode
.update
.value
:
519 fft_en
= yield dec2
.implicit_rs
521 log("get_pdecode_idx_out2", out_sel
, OutSel
.RS
.value
,
525 fft_en
= yield dec2
.implicit_rs
527 log("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
534 """deals with svstate looping.
537 def __init__(self
, svstate
):
538 self
.svstate
= svstate
541 def get_iterators(self
):
542 self
.src_it
= self
.src_iterator()
543 self
.dst_it
= self
.dst_iterator()
545 def src_iterator(self
):
546 """source-stepping iterator
548 pack
= self
.svstate
.pack
552 # pack advances subvl in *outer* loop
555 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
556 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
558 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
560 # these cannot be done as for-loops because SVSTATE may change
561 # (srcstep/substep may be modified, interrupted, subvl/vl change)
562 # but they *can* be done as while-loops as long as every SVSTATE
563 # "thing" is re-read every single time a yield gives indices
564 while True: # outer vl loop
565 while True: # inner subvl loop
567 srcmask
= self
.srcmask
568 srcstep
= self
.svstate
.srcstep
569 if self
.pred_sz
or ((1 << srcstep
) & srcmask
) != 0:
570 log(" advance src", srcstep
, self
.svstate
.vl
,
571 self
.svstate
.ssubstep
, subvl
)
572 # yield actual substep/srcstep
573 yield (self
.svstate
.ssubstep
, srcstep
)
574 if self
.svstate
.ssubstep
== subvl
: # end-point
575 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
577 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
579 if srcstep
== vl
-1: # end-point
580 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
581 break # trigger StopIteration
582 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
584 def dst_iterator(self
):
585 """dest-stepping iterator
587 unpack
= self
.svstate
.unpack
591 # pack advances subvl in *outer* loop
594 # these cannot be done as for-loops because SVSTATE may change
595 # (dststep/substep may be modified, interrupted, subvl/vl change)
596 # but they *can* be done as while-loops as long as every SVSTATE
597 # "thing" is re-read every single time a yield gives indices
598 while True: # outer vl loop
599 while True: # inner subvl loop
601 dstmask
= self
.dstmask
602 dststep
= self
.svstate
.dststep
603 if self
.pred_dz
or ((1 << dststep
) & dstmask
) != 0:
604 log(" advance dst", dststep
, self
.svstate
.vl
,
605 self
.svstate
.dsubstep
, subvl
)
606 # yield actual substep/dststep
607 yield (self
.svstate
.dsubstep
, dststep
)
608 if self
.svstate
.dsubstep
== subvl
: # end-point
609 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
611 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
613 if dststep
== vl
-1: # end-point
614 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
615 break # trigger StopIteration
616 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
618 def src_iterate(self
):
619 """source-stepping iterator
623 pack
= self
.svstate
.pack
624 unpack
= self
.svstate
.unpack
625 ssubstep
= self
.svstate
.ssubstep
626 end_ssub
= ssubstep
== subvl
627 end_src
= self
.svstate
.srcstep
== vl
-1
628 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
632 srcstep
= self
.svstate
.srcstep
634 # pack advances subvl in *outer* loop
637 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
638 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
640 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
642 # advance subvl in *inner* loop
644 if end_src
: # end-point
647 self
.svstate
.srcstep
+= SelectableInt(1, 7)
648 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
651 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
653 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
656 def at_loopend(self
):
657 """tells if this is the last possible element. uses the cached values
658 for src/dst-step and sub-steps
662 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
663 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
664 end_ssub
= ssubstep
== subvl
665 end_dsub
= dsubstep
== subvl
666 if srcstep
== vl
-1 and end_ssub
:
668 if dststep
== vl
-1 and end_dsub
:
672 def dst_iterate(self
):
673 """dest step iterator
677 pack
= self
.svstate
.pack
678 unpack
= self
.svstate
.unpack
679 dsubstep
= self
.svstate
.dsubstep
680 end_dsub
= dsubstep
== subvl
681 end_dst
= self
.svstate
.dststep
== vl
-1
682 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
687 # unpack advances subvl in *outer* loop
690 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
691 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
693 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
695 # advance subvl in *inner* loop
697 if end_dst
: # end-point
700 self
.svstate
.dststep
+= SelectableInt(1, 7)
701 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
704 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
705 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
708 def advance_svstate_steps(self
):
709 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
710 TODO when Pack/Unpack is set, substep becomes the *outer* loop
712 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
716 def read_src_mask(self
):
717 """read/update pred_sz and src mask
719 # get SVSTATE VL (oh and print out some debug stuff)
721 srcstep
= self
.svstate
.srcstep
722 ssubstep
= self
.svstate
.ssubstep
724 # get predicate mask (all 64 bits)
725 srcmask
= 0xffff_ffff_ffff_ffff
727 pmode
= yield self
.dec2
.rm_dec
.predmode
728 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
729 srcpred
= yield self
.dec2
.rm_dec
.srcpred
730 dstpred
= yield self
.dec2
.rm_dec
.dstpred
731 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
732 if pmode
== SVP64PredMode
.INT
.value
:
733 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
734 if sv_ptype
== SVPtype
.P2
.value
:
735 srcmask
= get_predint(self
.gpr
, srcpred
)
736 elif pmode
== SVP64PredMode
.CR
.value
:
737 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
738 if sv_ptype
== SVPtype
.P2
.value
:
739 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
740 # work out if the ssubsteps are completed
741 ssubstart
= ssubstep
== 0
743 log(" ptype", sv_ptype
)
744 log(" srcpred", bin(srcpred
))
745 log(" srcmask", bin(srcmask
))
746 log(" pred_sz", bin(pred_sz
))
747 log(" ssubstart", ssubstart
)
749 # store all that above
750 self
.srcstep_skip
= False
751 self
.srcmask
= srcmask
752 self
.pred_sz
= pred_sz
753 self
.new_ssubstep
= ssubstep
754 log(" new ssubstep", ssubstep
)
756 # until the predicate mask has a "1" bit... or we run out of VL
757 # let srcstep==VL be the indicator to move to next instruction
759 self
.srcstep_skip
= True
761 def read_dst_mask(self
):
762 """same as read_src_mask - check and record everything needed
764 # get SVSTATE VL (oh and print out some debug stuff)
765 # yield Delay(1e-10) # make changes visible
767 dststep
= self
.svstate
.dststep
768 dsubstep
= self
.svstate
.dsubstep
770 # get predicate mask (all 64 bits)
771 dstmask
= 0xffff_ffff_ffff_ffff
773 pmode
= yield self
.dec2
.rm_dec
.predmode
774 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
775 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
776 dstpred
= yield self
.dec2
.rm_dec
.dstpred
777 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
778 if pmode
== SVP64PredMode
.INT
.value
:
779 dstmask
= get_predint(self
.gpr
, dstpred
)
780 elif pmode
== SVP64PredMode
.CR
.value
:
781 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
782 # work out if the ssubsteps are completed
783 dsubstart
= dsubstep
== 0
785 log(" ptype", sv_ptype
)
786 log(" dstpred", bin(dstpred
))
787 log(" dstmask", bin(dstmask
))
788 log(" pred_dz", bin(pred_dz
))
789 log(" dsubstart", dsubstart
)
791 self
.dststep_skip
= False
792 self
.dstmask
= dstmask
793 self
.pred_dz
= pred_dz
794 self
.new_dsubstep
= dsubstep
795 log(" new dsubstep", dsubstep
)
798 self
.dststep_skip
= True
800 def svstate_pre_inc(self
):
801 """check if srcstep/dststep need to skip over masked-out predicate bits
802 note that this is not supposed to do anything to substep,
803 it is purely for skipping masked-out bits
806 yield from self
.read_src_mask()
807 yield from self
.read_dst_mask()
814 srcstep
= self
.svstate
.srcstep
815 srcmask
= self
.srcmask
816 pred_src_zero
= self
.pred_sz
818 # srcstep-skipping opportunity identified
819 if self
.srcstep_skip
:
820 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
821 log(" sskip", bin(1 << srcstep
))
824 # now work out if the relevant mask bits require zeroing
826 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
828 # store new srcstep / dststep
829 self
.new_srcstep
= srcstep
830 self
.pred_src_zero
= pred_src_zero
831 log(" new srcstep", srcstep
)
834 # dststep-skipping opportunity identified
835 dststep
= self
.svstate
.dststep
836 dstmask
= self
.dstmask
837 pred_dst_zero
= self
.pred_dz
839 if self
.dststep_skip
:
840 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
841 log(" dskip", bin(1 << dststep
))
844 # now work out if the relevant mask bits require zeroing
846 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
848 # store new srcstep / dststep
849 self
.new_dststep
= dststep
850 self
.pred_dst_zero
= pred_dst_zero
851 log(" new dststep", dststep
)
854 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
855 # decoder2 - an instance of power_decoder2
856 # regfile - a list of initial values for the registers
857 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
858 # respect_pc - tracks the program counter. requires initial_insns
859 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
860 initial_mem
=None, initial_msr
=0,
871 self
.bigendian
= bigendian
873 self
.is_svp64_mode
= False
874 self
.respect_pc
= respect_pc
875 if initial_sprs
is None:
877 if initial_mem
is None:
879 if fpregfile
is None:
881 if initial_insns
is None:
883 assert self
.respect_pc
== False, "instructions required to honor pc"
885 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
886 log("ISACaller initial_msr", initial_msr
)
888 # "fake program counter" mode (for unit testing)
892 if isinstance(initial_mem
, tuple):
893 self
.fake_pc
= initial_mem
[0]
894 disasm_start
= self
.fake_pc
896 disasm_start
= initial_pc
898 # disassembly: we need this for now (not given from the decoder)
899 self
.disassembly
= {}
901 for i
, code
in enumerate(disassembly
):
902 self
.disassembly
[i
*4 + disasm_start
] = code
904 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
905 self
.svp64rm
= SVP64RM()
906 if initial_svstate
is None:
908 if isinstance(initial_svstate
, int):
909 initial_svstate
= SVP64State(initial_svstate
)
910 # SVSTATE, MSR and PC
911 StepLoop
.__init
__(self
, initial_svstate
)
912 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
914 # GPR FPR SPR registers
915 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
916 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
917 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
918 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
920 # set up 4 dummy SVSHAPEs if they aren't already set up
922 sname
= 'SVSHAPE%d' % i
923 if sname
not in self
.spr
:
926 val
= self
.spr
[sname
].value
927 # make sure it's an SVSHAPE
928 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
929 self
.last_op_svshape
= False
932 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
933 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
934 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
935 # MMU mode, redirect underlying Mem through RADIX
937 self
.mem
= RADIX(self
.mem
, self
)
939 self
.imem
= RADIX(self
.imem
, self
)
942 # FPR (same as GPR except for FP nums)
943 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
944 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
945 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
946 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
948 # 2.3.2 LR (actually SPR #8) -- Done
949 # 2.3.3 CTR (actually SPR #9) -- Done
950 # 2.3.4 TAR (actually SPR #815)
951 # 3.2.2 p45 XER (actually SPR #1) -- Done
952 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
954 # create CR then allow portions of it to be "selectable" (below)
955 self
.cr_fields
= CRFields(initial_cr
)
956 self
.cr
= self
.cr_fields
.cr
958 # "undefined", just set to variable-bit-width int (use exts "max")
959 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
962 self
.namespace
.update(self
.spr
)
963 self
.namespace
.update({'GPR': self
.gpr
,
967 'memassign': self
.memassign
,
970 'SVSTATE': self
.svstate
,
971 'SVSHAPE0': self
.spr
['SVSHAPE0'],
972 'SVSHAPE1': self
.spr
['SVSHAPE1'],
973 'SVSHAPE2': self
.spr
['SVSHAPE2'],
974 'SVSHAPE3': self
.spr
['SVSHAPE3'],
977 'undefined': undefined
,
978 'mode_is_64bit': True,
979 'SO': XER_bits
['SO'],
980 'XLEN': 64 # elwidth overrides, later
983 # update pc to requested start point
984 self
.set_pc(initial_pc
)
986 # field-selectable versions of Condition Register
987 self
.crl
= self
.cr_fields
.crl
989 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
991 self
.decoder
= decoder2
.dec
994 super().__init
__(XLEN
=self
.namespace
["XLEN"])
998 return self
.namespace
["XLEN"]
1000 def call_trap(self
, trap_addr
, trap_bit
):
1001 """calls TRAP and sets up NIA to the new execution location.
1002 next instruction will begin at trap_addr.
1004 self
.TRAP(trap_addr
, trap_bit
)
1005 self
.namespace
['NIA'] = self
.trap_nia
1006 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1008 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1009 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1011 TRAP function is callable from inside the pseudocode itself,
1012 hence the default arguments. when calling from inside ISACaller
1013 it is best to use call_trap()
1015 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1016 kaivb
= self
.spr
['KAIVB'].value
1017 msr
= self
.namespace
['MSR'].value
1018 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1019 # store CIA(+4?) in SRR0, set NIA to 0x700
1020 # store MSR in SRR1, set MSR to um errr something, have to check spec
1021 # store SVSTATE (if enabled) in SVSRR0
1022 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1023 self
.spr
['SRR1'].value
= msr
1024 if self
.is_svp64_mode
:
1025 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1026 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1027 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1029 # set exception bits. TODO: this should, based on the address
1030 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1031 # bits appropriately. however it turns out that *for now* in all
1032 # cases (all trap_addrs) the exact same thing is needed.
1033 self
.msr
[MSRb
.IR
] = 0
1034 self
.msr
[MSRb
.DR
] = 0
1035 self
.msr
[MSRb
.FE0
] = 0
1036 self
.msr
[MSRb
.FE1
] = 0
1037 self
.msr
[MSRb
.EE
] = 0
1038 self
.msr
[MSRb
.RI
] = 0
1039 self
.msr
[MSRb
.SF
] = 1
1040 self
.msr
[MSRb
.TM
] = 0
1041 self
.msr
[MSRb
.VEC
] = 0
1042 self
.msr
[MSRb
.VSX
] = 0
1043 self
.msr
[MSRb
.PR
] = 0
1044 self
.msr
[MSRb
.FP
] = 0
1045 self
.msr
[MSRb
.PMM
] = 0
1046 self
.msr
[MSRb
.TEs
] = 0
1047 self
.msr
[MSRb
.TEe
] = 0
1048 self
.msr
[MSRb
.UND
] = 0
1049 self
.msr
[MSRb
.LE
] = 1
1051 def memassign(self
, ea
, sz
, val
):
1052 self
.mem
.memassign(ea
, sz
, val
)
1054 def prep_namespace(self
, insn_name
, formname
, op_fields
):
1055 # TODO: get field names from form in decoder*1* (not decoder2)
1056 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1058 # then "yield" fields only from op_fields rather than hard-coded
1060 fields
= self
.decoder
.sigforms
[formname
]
1061 log("prep_namespace", formname
, op_fields
, insn_name
)
1062 for name
in op_fields
:
1063 # CR immediates. deal with separately. needs modifying
1065 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1066 # BI is a 5-bit, must reconstruct the value
1067 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
1068 sig
= getattr(fields
, name
)
1070 # low 2 LSBs (CR field selector) remain same, CR num extended
1071 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1072 val
= (val
& 0b11) |
(regnum
<< 2)
1074 sig
= getattr(fields
, name
)
1076 # these are all opcode fields involved in index-selection of CR,
1077 # and need to do "standard" arithmetic. CR[BA+32] for example
1078 # would, if using SelectableInt, only be 5-bit.
1079 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1080 self
.namespace
[name
] = val
1082 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1084 self
.namespace
['XER'] = self
.spr
['XER']
1085 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1086 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1088 # add some SVSTATE convenience variables
1089 vl
= self
.svstate
.vl
1090 srcstep
= self
.svstate
.srcstep
1091 self
.namespace
['VL'] = vl
1092 self
.namespace
['srcstep'] = srcstep
1094 # sv.bc* need some extra fields
1095 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1096 # blegh grab bits manually
1097 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1098 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
1099 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
1100 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
1101 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1102 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1103 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1104 sz
= yield self
.dec2
.rm_dec
.pred_sz
1105 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1106 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1107 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1108 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1109 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1110 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1111 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1113 def handle_carry_(self
, inputs
, outputs
, already_done
):
1114 inv_a
= yield self
.dec2
.e
.do
.invert_in
1116 inputs
[0] = ~inputs
[0]
1118 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1120 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1121 inputs
.append(SelectableInt(imm
, 64))
1122 assert len(outputs
) >= 1
1123 log("outputs", repr(outputs
))
1124 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
1130 log("gt input", x
, output
)
1131 gt
= (gtu(x
, output
))
1134 cy
= 1 if any(gts
) else 0
1136 if not (1 & already_done
):
1137 self
.spr
['XER'][XER_bits
['CA']] = cy
1139 log("inputs", already_done
, inputs
)
1141 # ARGH... different for OP_ADD... *sigh*...
1142 op
= yield self
.dec2
.e
.do
.insn_type
1143 if op
== MicrOp
.OP_ADD
.value
:
1144 res32
= (output
.value
& (1 << 32)) != 0
1145 a32
= (inputs
[0].value
& (1 << 32)) != 0
1146 if len(inputs
) >= 2:
1147 b32
= (inputs
[1].value
& (1 << 32)) != 0
1150 cy32
= res32 ^ a32 ^ b32
1151 log("CA32 ADD", cy32
)
1155 log("input", x
, output
)
1156 log(" x[32:64]", x
, x
[32:64])
1157 log(" o[32:64]", output
, output
[32:64])
1158 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1160 cy32
= 1 if any(gts
) else 0
1161 log("CA32", cy32
, gts
)
1162 if not (2 & already_done
):
1163 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1165 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
1166 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1167 inv_a
= yield self
.dec2
.e
.do
.invert_in
1169 inputs
[0] = ~inputs
[0]
1171 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1173 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1174 inputs
.append(SelectableInt(imm
, 64))
1175 assert len(outputs
) >= 1
1176 log("handle_overflow", inputs
, outputs
, div_overflow
)
1177 if len(inputs
) < 2 and div_overflow
is None:
1180 # div overflow is different: it's returned by the pseudo-code
1181 # because it's more complex than can be done by analysing the output
1182 if div_overflow
is not None:
1183 ov
, ov32
= div_overflow
, div_overflow
1184 # arithmetic overflow can be done by analysing the input and output
1185 elif len(inputs
) >= 2:
1189 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1190 output_sgn
= exts(output
.value
, output
.bits
) < 0
1191 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1192 output_sgn
!= input_sgn
[0] else 0
1195 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1196 output32_sgn
= exts(output
.value
, 32) < 0
1197 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1198 output32_sgn
!= input32_sgn
[0] else 0
1200 # now update XER OV/OV32/SO
1201 so
= self
.spr
['XER'][XER_bits
['SO']]
1202 new_so
= so | ov
# sticky overflow ORs in old with new
1203 self
.spr
['XER'][XER_bits
['OV']] = ov
1204 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1205 self
.spr
['XER'][XER_bits
['SO']] = new_so
1206 log(" set overflow", ov
, ov32
, so
, new_so
)
1208 def handle_comparison(self
, outputs
, cr_idx
=0, overflow
=None, no_so
=False):
1210 assert isinstance(out
, SelectableInt
), \
1211 "out zero not a SelectableInt %s" % repr(outputs
)
1212 log("handle_comparison", out
.bits
, hex(out
.value
))
1213 # TODO - XXX *processor* in 32-bit mode
1214 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1216 # o32 = exts(out.value, 32)
1217 # print ("handle_comparison exts 32 bit", hex(o32))
1218 out
= exts(out
.value
, out
.bits
)
1219 log("handle_comparison exts", hex(out
))
1220 # create the three main CR flags, EQ GT LT
1221 zero
= SelectableInt(out
== 0, 1)
1222 positive
= SelectableInt(out
> 0, 1)
1223 negative
= SelectableInt(out
< 0, 1)
1224 # get (or not) XER.SO. for setvl this is important *not* to read SO
1226 SO
= SelectableInt(1, 0)
1228 SO
= self
.spr
['XER'][XER_bits
['SO']]
1229 log("handle_comparison SO overflow", SO
, overflow
)
1230 # alternative overflow checking (setvl mainly at the moment)
1231 if overflow
is not None and overflow
== 1:
1232 SO
= SelectableInt(1, 1)
1233 # create the four CR field values and set the required CR field
1234 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1235 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1236 self
.crl
[cr_idx
].eq(cr_field
)
1238 def set_pc(self
, pc_val
):
1239 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1240 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1242 def get_next_insn(self
):
1243 """check instruction
1246 pc
= self
.pc
.CIA
.value
1249 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1251 raise KeyError("no instruction at 0x%x" % pc
)
1254 def setup_one(self
):
1255 """set up one instruction
1257 pc
, insn
= self
.get_next_insn()
1258 yield from self
.setup_next_insn(pc
, insn
)
1260 def setup_next_insn(self
, pc
, ins
):
1261 """set up next instruction
1264 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1265 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1267 yield self
.dec2
.sv_rm
.eq(0)
1268 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1269 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1270 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1271 yield self
.dec2
.state
.pc
.eq(pc
)
1272 if self
.svstate
is not None:
1273 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1275 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1277 opcode
= yield self
.dec2
.dec
.opcode_in
1278 opcode
= SelectableInt(value
=opcode
, bits
=32)
1279 pfx
= SVP64Instruction
.Prefix(opcode
)
1280 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1281 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1282 self
.pc
.update_nia(self
.is_svp64_mode
)
1284 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1285 self
.namespace
['NIA'] = self
.pc
.NIA
1286 self
.namespace
['SVSTATE'] = self
.svstate
1287 if not self
.is_svp64_mode
:
1290 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1291 log("svp64.rm", bin(pfx
.rm
))
1292 log(" svstate.vl", self
.svstate
.vl
)
1293 log(" svstate.mvl", self
.svstate
.maxvl
)
1294 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1295 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1296 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1297 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1300 def execute_one(self
):
1301 """execute one instruction
1303 # get the disassembly code for this instruction
1304 if self
.is_svp64_mode
:
1305 if not self
.disassembly
:
1306 code
= yield from self
.get_assembly_name()
1308 code
= self
.disassembly
[self
._pc
+4]
1309 log(" svp64 sim-execute", hex(self
._pc
), code
)
1311 if not self
.disassembly
:
1312 code
= yield from self
.get_assembly_name()
1314 code
= self
.disassembly
[self
._pc
]
1315 log("sim-execute", hex(self
._pc
), code
)
1316 opname
= code
.split(' ')[0]
1318 yield from self
.call(opname
) # execute the instruction
1319 except MemException
as e
: # check for memory errors
1320 if e
.args
[0] == 'unaligned': # alignment error
1321 # run a Trap but set DAR first
1322 print("memory unaligned exception, DAR", e
.dar
)
1323 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1324 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1326 elif e
.args
[0] == 'invalid': # invalid
1327 # run a Trap but set DAR first
1328 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1329 if e
.mode
== 'EXECUTE':
1330 # XXX TODO: must set a few bits in SRR1,
1331 # see microwatt loadstore1.vhdl
1332 # if m_in.segerr = '0' then
1333 # v.srr1(47 - 33) := m_in.invalid;
1334 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1335 # v.srr1(47 - 44) := m_in.badtree;
1336 # v.srr1(47 - 45) := m_in.rc_error;
1337 # v.intr_vec := 16#400#;
1339 # v.intr_vec := 16#480#;
1340 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1342 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1344 # not supported yet:
1345 raise e
# ... re-raise
1347 # don't use this except in special circumstances
1348 if not self
.respect_pc
:
1351 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1352 hex(self
.pc
.NIA
.value
))
1354 def get_assembly_name(self
):
1355 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1356 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1357 dec_insn
= yield self
.dec2
.e
.do
.insn
1358 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1359 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1360 int_op
= yield self
.dec2
.dec
.op
.internal_op
1361 log("get assembly name asmcode", asmcode
, int_op
,
1362 hex(dec_insn
), bin(insn_1_11
))
1363 asmop
= insns
.get(asmcode
, None)
1365 # sigh reconstruct the assembly instruction name
1366 if hasattr(self
.dec2
.e
.do
, "oe"):
1367 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1368 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1372 if hasattr(self
.dec2
.e
.do
, "rc"):
1373 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1374 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1378 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1379 RC1
= yield self
.dec2
.rm_dec
.RC1
1383 # grrrr have to special-case MUL op (see DecodeOE)
1384 log("ov %d en %d rc %d en %d op %d" %
1385 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1386 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1391 if not asmop
.endswith("."): # don't add "." to "andis."
1394 if hasattr(self
.dec2
.e
.do
, "lk"):
1395 lk
= yield self
.dec2
.e
.do
.lk
1398 log("int_op", int_op
)
1399 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1400 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1404 spr_msb
= yield from self
.get_spr_msb()
1405 if int_op
== MicrOp
.OP_MFCR
.value
:
1410 # XXX TODO: for whatever weird reason this doesn't work
1411 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1412 if int_op
== MicrOp
.OP_MTCRF
.value
:
1419 def get_remap_indices(self
):
1420 """WARNING, this function stores remap_idxs and remap_loopends
1421 in the class for later use. this to avoid problems with yield
1423 # go through all iterators in lock-step, advance to next remap_idx
1424 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1425 # get four SVSHAPEs. here we are hard-coding
1426 SVSHAPE0
= self
.spr
['SVSHAPE0']
1427 SVSHAPE1
= self
.spr
['SVSHAPE1']
1428 SVSHAPE2
= self
.spr
['SVSHAPE2']
1429 SVSHAPE3
= self
.spr
['SVSHAPE3']
1430 # set up the iterators
1431 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1432 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1433 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1434 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1437 self
.remap_loopends
= [0] * 4
1438 self
.remap_idxs
= [0, 1, 2, 3]
1440 for i
, (shape
, remap
) in enumerate(remaps
):
1441 # zero is "disabled"
1442 if shape
.value
== 0x0:
1443 self
.remap_idxs
[i
] = 0
1444 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1445 step
= dststep
if (i
in [3, 4]) else srcstep
1446 # this is terrible. O(N^2) looking for the match. but hey.
1447 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1450 self
.remap_idxs
[i
] = remap_idx
1451 self
.remap_loopends
[i
] = loopends
1452 dbg
.append((i
, step
, remap_idx
, loopends
))
1453 for (i
, step
, remap_idx
, loopends
) in dbg
:
1454 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1457 def get_spr_msb(self
):
1458 dec_insn
= yield self
.dec2
.e
.do
.insn
1459 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1461 def call(self
, name
):
1462 """call(opcode) - the primary execution point for instructions
1464 self
.last_st_addr
= None # reset the last known store address
1465 self
.last_ld_addr
= None # etc.
1467 ins_name
= name
.strip() # remove spaces if not already done so
1469 log("halted - not executing", ins_name
)
1472 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1473 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1474 asmop
= yield from self
.get_assembly_name()
1475 log("call", ins_name
, asmop
)
1477 # sv.setvl is *not* a loop-function. sigh
1478 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1481 int_op
= yield self
.dec2
.dec
.op
.internal_op
1482 spr_msb
= yield from self
.get_spr_msb()
1484 instr_is_privileged
= False
1485 if int_op
in [MicrOp
.OP_ATTN
.value
,
1486 MicrOp
.OP_MFMSR
.value
,
1487 MicrOp
.OP_MTMSR
.value
,
1488 MicrOp
.OP_MTMSRD
.value
,
1490 MicrOp
.OP_RFID
.value
]:
1491 instr_is_privileged
= True
1492 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1493 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1494 instr_is_privileged
= True
1496 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1498 # check MSR priv bit and whether op is privileged: if so, throw trap
1499 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1500 self
.call_trap(0x700, PIb
.PRIV
)
1503 # check halted condition
1504 if ins_name
== 'attn':
1508 # check illegal instruction
1510 if ins_name
not in ['mtcrf', 'mtocrf']:
1511 illegal
= ins_name
!= asmop
1513 # list of instructions not being supported by binutils (.long)
1514 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1515 if dotstrp
in [*FPTRANS_INSNS
,
1516 'ffmadds', 'fdmadds', 'ffadds',
1517 'mins', 'maxs', 'minu', 'maxu',
1518 'setvl', 'svindex', 'svremap', 'svstep',
1519 'svshape', 'svshape2',
1520 'grev', 'ternlogi', 'bmask', 'cprop',
1521 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1522 'fmvis', 'fishmv', 'pcdec'
1527 # branch-conditional redirects to sv.bc
1528 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1529 ins_name
= 'sv.%s' % ins_name
1531 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1533 # illegal instructions call TRAP at 0x700
1535 print("illegal", ins_name
, asmop
)
1536 self
.call_trap(0x700, PIb
.ILLEG
)
1537 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1538 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1541 # this is for setvl "Vertical" mode: if set true,
1542 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1543 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1544 self
.allow_next_step_inc
= False
1545 self
.svstate_next_mode
= 0
1547 # nop has to be supported, we could let the actual op calculate
1548 # but PowerDecoder has a pattern for nop
1549 if ins_name
== 'nop':
1550 self
.update_pc_next()
1553 # look up instruction in ISA.instrs, prepare namespace
1554 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1555 info
= self
.instrs
[ins_name
+"."]
1557 info
= self
.instrs
[ins_name
]
1558 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1560 # preserve order of register names
1561 input_names
= create_args(list(info
.read_regs
) +
1562 list(info
.uninit_regs
))
1563 log("input names", input_names
)
1565 # get SVP64 entry for the current instruction
1566 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1567 if sv_rm
is not None:
1568 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1570 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1571 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1573 # see if srcstep/dststep need skipping over masked-out predicate bits
1574 if (self
.is_svp64_mode
or ins_name
in ['setvl', 'svremap', 'svstate']):
1575 yield from self
.svstate_pre_inc()
1576 if self
.is_svp64_mode
:
1577 pre
= yield from self
.update_new_svstate_steps()
1579 self
.svp64_reset_loop()
1581 self
.update_pc_next()
1583 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1584 pred_dst_zero
= self
.pred_dst_zero
1585 pred_src_zero
= self
.pred_src_zero
1586 vl
= self
.svstate
.vl
1587 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1589 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1590 if self
.is_svp64_mode
and vl
== 0:
1591 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1592 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1593 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1596 # for when SVREMAP is active, using pre-arranged schedule.
1597 # note: modifying PowerDecoder2 needs to "settle"
1598 remap_en
= self
.svstate
.SVme
1599 persist
= self
.svstate
.RMpst
1600 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1601 if self
.is_svp64_mode
:
1602 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1604 if persist
or self
.last_op_svshape
:
1605 remaps
= self
.get_remap_indices()
1606 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1607 yield from self
.remap_set_steps(remaps
)
1608 # after that, settle down (combinatorial) to let Vector reg numbers
1609 # work themselves out
1611 if self
.is_svp64_mode
:
1612 remap_active
= yield self
.dec2
.remap_active
1614 remap_active
= False
1615 log("remap active", bin(remap_active
))
1617 # main input registers (RT, RA ...)
1619 for name
in input_names
:
1621 regval
= (yield from self
.get_input(name
))
1622 log("regval", regval
)
1623 inputs
.append(regval
)
1625 # arrrrgh, awful hack, to get _RT into namespace
1626 if ins_name
in ['setvl', 'svstep']:
1628 RT
= yield self
.dec2
.dec
.RT
1629 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1631 self
.namespace
["RT"] = SelectableInt(0, 5)
1632 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1633 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1635 # in SVP64 mode for LD/ST work out immediate
1636 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1637 # use info.form to detect
1638 if self
.is_svp64_mode
:
1639 yield from self
.check_replace_d(info
, remap_active
)
1641 # "special" registers
1642 for special
in info
.special_regs
:
1643 if special
in special_sprs
:
1644 inputs
.append(self
.spr
[special
])
1646 inputs
.append(self
.namespace
[special
])
1648 # clear trap (trap) NIA
1649 self
.trap_nia
= None
1651 # check if this was an sv.bc* and create an indicator that
1652 # this is the last check to be made as a loop. combined with
1653 # the ALL/ANY mode we can early-exit
1654 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1655 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1656 # XXX TODO - pack/unpack here
1657 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1658 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1660 # execute actual instruction here (finally)
1661 log("inputs", inputs
)
1662 results
= info
.func(self
, *inputs
)
1663 log("results", results
)
1665 # "inject" decorator takes namespace from function locals: we need to
1666 # overwrite NIA being overwritten (sigh)
1667 if self
.trap_nia
is not None:
1668 self
.namespace
['NIA'] = self
.trap_nia
1670 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1672 # check if op was a LD/ST so that debugging can check the
1674 if int_op
in [MicrOp
.OP_STORE
.value
,
1676 self
.last_st_addr
= self
.mem
.last_st_addr
1677 if int_op
in [MicrOp
.OP_LOAD
.value
,
1679 self
.last_ld_addr
= self
.mem
.last_ld_addr
1680 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1681 self
.last_st_addr
, self
.last_ld_addr
)
1683 # detect if CA/CA32 already in outputs (sra*, basically)
1687 output_names
= create_args(info
.write_regs
)
1688 for name
in output_names
:
1694 log("carry already done?", bin(already_done
), output_names
)
1695 carry_en
= yield self
.dec2
.e
.do
.output_carry
1697 yield from self
.handle_carry_(inputs
, results
, already_done
)
1699 # check if one of the regs was named "overflow"
1702 for name
, output
in zip(output_names
, results
):
1703 if name
== 'overflow':
1706 # and one called CR0
1709 for name
, output
in zip(output_names
, results
):
1713 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1714 # detect if overflow was in return result
1715 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1716 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1717 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1719 yield from self
.handle_overflow(inputs
, results
, overflow
)
1721 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1723 if not self
.is_svp64_mode
or not pred_dst_zero
:
1724 if hasattr(self
.dec2
.e
.do
, "rc"):
1725 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1726 # don't do Rc=1 for svstep it is handled explicitly.
1727 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1728 # to write directly to CR0 instead of in ISACaller. hooyahh.
1729 if rc_en
and ins_name
not in ['svstep']:
1730 yield from self
.do_rc_ov(ins_name
, results
, overflow
, cr0
)
1733 rm_mode
= yield self
.dec2
.rm_dec
.mode
1734 ff_inv
= yield self
.dec2
.rm_dec
.inv
1735 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
1736 RC1
= yield self
.dec2
.rm_dec
.RC1
1737 vli
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
1738 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
1742 log(" cr_bit", cr_bit
)
1744 if rc_en
and rm_mode
== SVP64RMMode
.FFIRST
.value
:
1745 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1746 crtest
= self
.crl
[regnum
]
1747 ffirst_hit
= crtest
[cr_bit
] != ff_inv
1748 log("cr test", regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
1749 log("cr test?", ffirst_hit
)
1751 vli
= SelectableInt(int(vli
), 7)
1752 self
.svstate
.vl
= srcstep
+ vli
1753 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1754 yield Settle() # let decoder update
1756 # any modified return results?
1757 yield from self
.do_outregs_nia(asmop
, ins_name
, info
,
1758 output_names
, results
,
1759 carry_en
, rc_en
, ffirst_hit
)
1761 def do_rc_ov(self
, ins_name
, results
, overflow
, cr0
):
1762 if ins_name
.startswith("f"):
1763 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1766 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, rc_reg
)
1768 # hang on... for `setvl` actually you want to test SVSTATE.VL
1769 is_setvl
= ins_name
== 'setvl'
1772 cmps
= (SelectableInt(vl
, 64), overflow
,)
1774 overflow
= None # do not override overflow except in setvl
1776 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
1778 self
.handle_comparison(cmps
, regnum
, overflow
, no_so
=is_setvl
)
1780 # otherwise we just blat CR0 into the required regnum
1781 log("explicit rc0", cr0
)
1782 self
.crl
[regnum
].eq(cr0
)
1784 def do_outregs_nia(self
, asmop
, ins_name
, info
, output_names
, results
,
1785 carry_en
, rc_en
, ffirst_hit
):
1786 # write out any regs for this instruction
1788 for name
, output
in zip(output_names
, results
):
1789 yield from self
.check_write(info
, name
, output
, carry_en
)
1792 self
.svp64_reset_loop()
1795 # check advancement of src/dst/sub-steps and if PC needs updating
1796 nia_update
= (yield from self
.check_step_increment(results
, rc_en
,
1799 self
.update_pc_next()
1801 def check_replace_d(self
, info
, remap_active
):
1802 replace_d
= False # update / replace constant in pseudocode
1803 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1804 vl
= self
.svstate
.vl
1805 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1806 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1807 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1808 if info
.form
== 'DS':
1809 # DS-Form, multiply by 4 then knock 2 bits off after
1810 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1812 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1813 imm
= exts(imm
, 16) # sign-extend to integer
1814 # get the right step. LD is from srcstep, ST is dststep
1815 op
= yield self
.dec2
.e
.do
.insn_type
1817 if op
== MicrOp
.OP_LOAD
.value
:
1819 offsmul
= yield self
.dec2
.in1_step
1820 log("D-field REMAP src", imm
, offsmul
)
1822 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
1823 log("D-field src", imm
, offsmul
)
1824 elif op
== MicrOp
.OP_STORE
.value
:
1825 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1826 offsmul
= (dststep
* (subvl
+1)) + dsubstep
1827 log("D-field dst", imm
, offsmul
)
1828 # Unit-Strided LD/ST adds offset*width to immediate
1829 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1830 ldst_len
= yield self
.dec2
.e
.do
.data_len
1831 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1833 # Element-strided multiplies the immediate by element step
1834 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1835 imm
= SelectableInt(imm
* offsmul
, 32)
1838 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1839 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1840 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1841 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1842 # new replacement D... errr.. DS
1844 if info
.form
== 'DS':
1845 # TODO: assert 2 LSBs are zero?
1846 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1847 imm
.value
= imm
.value
>> 2
1848 self
.namespace
['DS'] = imm
1850 self
.namespace
['D'] = imm
1852 def get_input(self
, name
):
1853 # using PowerDecoder2, first, find the decoder index.
1854 # (mapping name RA RB RC RS to in1, in2, in3)
1855 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1857 # doing this is not part of svp64, it's because output
1858 # registers, to be modified, need to be in the namespace.
1859 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1861 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1863 # in case getting the register number is needed, _RA, _RB
1864 regname
= "_" + name
1865 self
.namespace
[regname
] = regnum
1866 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
1867 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1869 reg_val
= SelectableInt(self
.fpr(regnum
))
1870 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1871 elif name
is not None:
1872 reg_val
= SelectableInt(self
.gpr(regnum
))
1873 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1875 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1879 def remap_set_steps(self
, remaps
):
1880 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1881 they work in concert with PowerDecoder2 at the moment,
1882 there is no HDL implementation of REMAP. therefore this
1883 function, because ISACaller still uses PowerDecoder2,
1884 will *explicitly* write the dec2.XX_step values. this has
1887 # just some convenient debug info
1889 sname
= 'SVSHAPE%d' % i
1890 shape
= self
.spr
[sname
]
1891 log(sname
, bin(shape
.value
))
1892 log(" lims", shape
.lims
)
1893 log(" mode", shape
.mode
)
1894 log(" skip", shape
.skip
)
1896 # set up the list of steps to remap
1897 mi0
= self
.svstate
.mi0
1898 mi1
= self
.svstate
.mi1
1899 mi2
= self
.svstate
.mi2
1900 mo0
= self
.svstate
.mo0
1901 mo1
= self
.svstate
.mo1
1902 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1903 (self
.dec2
.in2_step
, mi1
), # RB
1904 (self
.dec2
.in3_step
, mi2
), # RC
1905 (self
.dec2
.o_step
, mo0
), # RT
1906 (self
.dec2
.o2_step
, mo1
), # EA
1908 remap_idxs
= self
.remap_idxs
1910 # now cross-index the required SHAPE for each of 3-in 2-out regs
1911 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1912 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1913 (shape
, remap
) = remaps
[shape_idx
]
1914 remap_idx
= remap_idxs
[shape_idx
]
1915 # zero is "disabled"
1916 if shape
.value
== 0x0:
1918 # now set the actual requested step to the current index
1919 yield dstep
.eq(remap_idx
)
1921 # debug printout info
1922 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
1924 log("shape remap", x
)
1926 def check_write(self
, info
, name
, output
, carry_en
):
1927 if name
== 'overflow': # ignore, done already (above)
1929 if name
== 'CR0': # ignore, done already (above)
1931 if isinstance(output
, int):
1932 output
= SelectableInt(output
, 256)
1934 if name
in ['CA', 'CA32']:
1936 log("writing %s to XER" % name
, output
)
1937 log("write XER %s 0x%x" % (name
, output
.value
))
1938 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1940 log("NOT writing %s to XER" % name
, output
)
1942 # write special SPRs
1943 if name
in info
.special_regs
:
1944 log('writing special %s' % name
, output
, special_sprs
)
1945 log("write reg %s 0x%x" % (name
, output
.value
))
1946 if name
in special_sprs
:
1947 self
.spr
[name
] = output
1949 self
.namespace
[name
].eq(output
)
1951 log('msr written', hex(self
.msr
.value
))
1953 # find out1/out2 PR/FPR
1954 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1956 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1958 # temporary hack for not having 2nd output
1959 regnum
= yield getattr(self
.decoder
, name
)
1961 # convenient debug prefix
1966 # check zeroing due to predicate bit being zero
1967 if self
.is_svp64_mode
and self
.pred_dst_zero
:
1968 log('zeroing reg %d %s' % (regnum
, str(output
)), is_vec
)
1969 output
= SelectableInt(0, 256)
1970 log("write reg %s%d 0x%x" % (reg_prefix
, regnum
, output
.value
),
1971 kind
=LogKind
.InstrInOuts
)
1972 # zero-extend tov64 bit begore storing (should use EXT oh well)
1973 if output
.bits
> 64:
1974 output
= SelectableInt(output
.value
, 64)
1976 self
.fpr
[regnum
] = output
1978 self
.gpr
[regnum
] = output
1980 def check_step_increment(self
, results
, rc_en
, asmop
, ins_name
):
1981 # check if it is the SVSTATE.src/dest step that needs incrementing
1982 # this is our Sub-Program-Counter loop from 0 to VL-1
1983 if not self
.allow_next_step_inc
:
1984 if self
.is_svp64_mode
:
1985 return (yield from self
.svstate_post_inc(ins_name
))
1987 # XXX only in non-SVP64 mode!
1988 # record state of whether the current operation was an svshape,
1990 # to be able to know if it should apply in the next instruction.
1991 # also (if going to use this instruction) should disable ability
1992 # to interrupt in between. sigh.
1993 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2000 log("SVSTATE_NEXT: inc requested, mode",
2001 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2002 yield from self
.svstate_pre_inc()
2003 pre
= yield from self
.update_new_svstate_steps()
2005 # reset at end of loop including exit Vertical Mode
2006 log("SVSTATE_NEXT: end of loop, reset")
2007 self
.svp64_reset_loop()
2008 self
.svstate
.vfirst
= 0
2012 results
= [SelectableInt(0, 64)]
2013 self
.handle_comparison(results
) # CR0
2015 if self
.allow_next_step_inc
== 2:
2016 log("SVSTATE_NEXT: read")
2017 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2019 log("SVSTATE_NEXT: post-inc")
2020 # use actual (cached) src/dst-step here to check end
2021 remaps
= self
.get_remap_indices()
2022 remap_idxs
= self
.remap_idxs
2023 vl
= self
.svstate
.vl
2024 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2025 if self
.allow_next_step_inc
!= 2:
2026 yield from self
.advance_svstate_steps()
2027 #self.namespace['SVSTATE'] = self.svstate.spr
2028 # set CR0 (if Rc=1) based on end
2029 endtest
= 1 if self
.at_loopend() else 0
2031 #results = [SelectableInt(endtest, 64)]
2032 # self.handle_comparison(results) # CR0
2034 # see if svstep was requested, if so, which SVSTATE
2036 if self
.svstate_next_mode
> 0:
2037 shape_idx
= self
.svstate_next_mode
.value
-1
2038 endings
= self
.remap_loopends
[shape_idx
]
2039 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2040 log("svstep Rc=1, CR0", cr_field
, endtest
)
2041 self
.crl
[0].eq(cr_field
) # CR0
2043 # reset at end of loop including exit Vertical Mode
2044 log("SVSTATE_NEXT: after increments, reset")
2045 self
.svp64_reset_loop()
2046 self
.svstate
.vfirst
= 0
2049 def SVSTATE_NEXT(self
, mode
, submode
):
2050 """explicitly moves srcstep/dststep on to next element, for
2051 "Vertical-First" mode. this function is called from
2052 setvl pseudo-code, as a pseudo-op "svstep"
2054 WARNING: this function uses information that was created EARLIER
2055 due to it being in the middle of a yield, but this function is
2056 *NOT* called from yield (it's called from compiled pseudocode).
2058 self
.allow_next_step_inc
= submode
.value
+ 1
2059 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2060 self
.svstate_next_mode
= mode
2061 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2062 shape_idx
= self
.svstate_next_mode
.value
-1
2063 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2064 if self
.svstate_next_mode
== 5:
2065 self
.svstate_next_mode
= 0
2066 return SelectableInt(self
.svstate
.srcstep
, 7)
2067 if self
.svstate_next_mode
== 6:
2068 self
.svstate_next_mode
= 0
2069 return SelectableInt(self
.svstate
.dststep
, 7)
2070 return SelectableInt(0, 7)
2072 def get_src_dststeps(self
):
2073 """gets srcstep, dststep, and ssubstep, dsubstep
2075 return (self
.new_srcstep
, self
.new_dststep
,
2076 self
.new_ssubstep
, self
.new_dsubstep
)
2078 def update_new_svstate_steps(self
):
2079 # note, do not get the bit-reversed srcstep here!
2080 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2081 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2083 # update SVSTATE with new srcstep
2084 self
.svstate
.srcstep
= srcstep
2085 self
.svstate
.dststep
= dststep
2086 self
.svstate
.ssubstep
= ssubstep
2087 self
.svstate
.dsubstep
= dsubstep
2088 self
.namespace
['SVSTATE'] = self
.svstate
2089 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2090 yield Settle() # let decoder update
2091 srcstep
= self
.svstate
.srcstep
2092 dststep
= self
.svstate
.dststep
2093 ssubstep
= self
.svstate
.ssubstep
2094 dsubstep
= self
.svstate
.dsubstep
2095 pack
= self
.svstate
.pack
2096 unpack
= self
.svstate
.unpack
2097 vl
= self
.svstate
.vl
2098 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2099 rm_mode
= yield self
.dec2
.rm_dec
.mode
2100 ff_inv
= yield self
.dec2
.rm_dec
.inv
2101 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2102 log(" srcstep", srcstep
)
2103 log(" dststep", dststep
)
2105 log(" unpack", unpack
)
2106 log(" ssubstep", ssubstep
)
2107 log(" dsubstep", dsubstep
)
2109 log(" subvl", subvl
)
2110 log(" rm_mode", rm_mode
)
2112 log(" cr_bit", cr_bit
)
2114 # check if end reached (we let srcstep overrun, above)
2115 # nothing needs doing (TODO zeroing): just do next instruction
2116 return ((ssubstep
== subvl
and srcstep
== vl
) or
2117 (dsubstep
== subvl
and dststep
== vl
))
2119 def svstate_post_inc(self
, insn_name
, vf
=0):
2120 # check if SV "Vertical First" mode is enabled
2121 vfirst
= self
.svstate
.vfirst
2122 log(" SV Vertical First", vf
, vfirst
)
2123 if not vf
and vfirst
== 1:
2127 # check if it is the SVSTATE.src/dest step that needs incrementing
2128 # this is our Sub-Program-Counter loop from 0 to VL-1
2129 # XXX twin predication TODO
2130 vl
= self
.svstate
.vl
2131 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2132 mvl
= self
.svstate
.maxvl
2133 srcstep
= self
.svstate
.srcstep
2134 dststep
= self
.svstate
.dststep
2135 ssubstep
= self
.svstate
.ssubstep
2136 dsubstep
= self
.svstate
.dsubstep
2137 pack
= self
.svstate
.pack
2138 unpack
= self
.svstate
.unpack
2139 rm_mode
= yield self
.dec2
.rm_dec
.mode
2140 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2141 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2142 out_vec
= not (yield self
.dec2
.no_out_vec
)
2143 in_vec
= not (yield self
.dec2
.no_in_vec
)
2144 log(" svstate.vl", vl
)
2145 log(" svstate.mvl", mvl
)
2146 log(" rm.subvl", subvl
)
2147 log(" svstate.srcstep", srcstep
)
2148 log(" svstate.dststep", dststep
)
2149 log(" svstate.ssubstep", ssubstep
)
2150 log(" svstate.dsubstep", dsubstep
)
2151 log(" svstate.pack", pack
)
2152 log(" svstate.unpack", unpack
)
2153 log(" mode", rm_mode
)
2154 log(" reverse", reverse_gear
)
2155 log(" out_vec", out_vec
)
2156 log(" in_vec", in_vec
)
2157 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2158 # check if this was an sv.bc* and if so did it succeed
2159 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2160 end_loop
= self
.namespace
['end_loop']
2161 log("branch %s end_loop" % insn_name
, end_loop
)
2163 self
.svp64_reset_loop()
2164 self
.update_pc_next()
2166 # check if srcstep needs incrementing by one, stop PC advancing
2167 # but for 2-pred both src/dest have to be checked.
2168 # XXX this might not be true! it may just be LD/ST
2169 if sv_ptype
== SVPtype
.P2
.value
:
2170 svp64_is_vector
= (out_vec
or in_vec
)
2172 svp64_is_vector
= out_vec
2173 # loops end at the first "hit" (source or dest)
2174 yield from self
.advance_svstate_steps()
2175 loopend
= self
.loopend
2176 log("loopend", svp64_is_vector
, loopend
)
2177 if not svp64_is_vector
or loopend
:
2178 # reset loop to zero and update NIA
2179 self
.svp64_reset_loop()
2184 # still looping, advance and update NIA
2185 self
.namespace
['SVSTATE'] = self
.svstate
2187 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2188 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2189 # this way we keep repeating the same instruction (with new steps)
2190 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2191 self
.namespace
['NIA'] = self
.pc
.NIA
2192 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2193 return False # DO NOT allow PC update whilst Sub-PC loop running
2195 def update_pc_next(self
):
2196 # UPDATE program counter
2197 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2198 #self.svstate.spr = self.namespace['SVSTATE']
2199 log("end of call", self
.namespace
['CIA'],
2200 self
.namespace
['NIA'],
2201 self
.namespace
['SVSTATE'])
2203 def svp64_reset_loop(self
):
2204 self
.svstate
.srcstep
= 0
2205 self
.svstate
.dststep
= 0
2206 self
.svstate
.ssubstep
= 0
2207 self
.svstate
.dsubstep
= 0
2208 self
.loopend
= False
2209 log(" svstate.srcstep loop end (PC to update)")
2210 self
.namespace
['SVSTATE'] = self
.svstate
2212 def update_nia(self
):
2213 self
.pc
.update_nia(self
.is_svp64_mode
)
2214 self
.namespace
['NIA'] = self
.pc
.NIA
2218 """Decorator factory.
2220 this decorator will "inject" variables into the function's namespace,
2221 from the *dictionary* in self.namespace. it therefore becomes possible
2222 to make it look like a whole stack of variables which would otherwise
2223 need "self." inserted in front of them (*and* for those variables to be
2224 added to the instance) "appear" in the function.
2226 "self.namespace['SI']" for example becomes accessible as just "SI" but
2227 *only* inside the function, when decorated.
2229 def variable_injector(func
):
2231 def decorator(*args
, **kwargs
):
2233 func_globals
= func
.__globals
__ # Python 2.6+
2234 except AttributeError:
2235 func_globals
= func
.func_globals
# Earlier versions.
2237 context
= args
[0].namespace
# variables to be injected
2238 saved_values
= func_globals
.copy() # Shallow copy of dict.
2239 log("globals before", context
.keys())
2240 func_globals
.update(context
)
2241 result
= func(*args
, **kwargs
)
2242 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2243 log("args[0]", args
[0].namespace
['CIA'],
2244 args
[0].namespace
['NIA'],
2245 args
[0].namespace
['SVSTATE'])
2246 if 'end_loop' in func_globals
:
2247 log("args[0] end_loop", func_globals
['end_loop'])
2248 args
[0].namespace
= func_globals
2249 #exec (func.__code__, func_globals)
2252 # func_globals = saved_values # Undo changes.
2258 return variable_injector