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
633 srcmask
= self
.srcmask
635 # pack advances subvl in *outer* loop
637 assert srcstep
<= vl
-1
638 end_src
= srcstep
== vl
-1
643 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
647 srcstep
+= 1 # advance srcstep
648 if not self
.srcstep_skip
:
650 if ((1 << srcstep
) & srcmask
) != 0:
653 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
655 # advance subvl in *inner* loop
658 assert srcstep
<= vl
-1
659 end_src
= srcstep
== vl
-1
660 if end_src
: # end-point
665 if not self
.srcstep_skip
:
667 if ((1 << srcstep
) & srcmask
) != 0:
670 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
671 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
674 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
676 self
.svstate
.srcstep
= SelectableInt(srcstep
, 7)
677 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
680 def dst_iterate(self
):
681 """dest step iterator
685 pack
= self
.svstate
.pack
686 unpack
= self
.svstate
.unpack
687 dsubstep
= self
.svstate
.dsubstep
688 end_dsub
= dsubstep
== subvl
689 dststep
= self
.svstate
.dststep
690 end_dst
= dststep
== vl
-1
691 dstmask
= self
.dstmask
692 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
697 # unpack advances subvl in *outer* loop
699 assert dststep
<= vl
-1
700 end_dst
= dststep
== vl
-1
705 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
709 dststep
+= 1 # advance dststep
710 if not self
.dststep_skip
:
712 if ((1 << dststep
) & dstmask
) != 0:
715 log(" dskip", bin(dstmask
), bin(1 << dststep
))
717 # advance subvl in *inner* loop
720 assert dststep
<= vl
-1
721 end_dst
= dststep
== vl
-1
722 if end_dst
: # end-point
727 if not self
.dststep_skip
:
729 if ((1 << dststep
) & dstmask
) != 0:
732 log(" dskip", bin(dstmask
), bin(1 << dststep
))
733 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
736 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
738 self
.svstate
.dststep
= SelectableInt(dststep
, 7)
739 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
742 def at_loopend(self
):
743 """tells if this is the last possible element. uses the cached values
744 for src/dst-step and sub-steps
748 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
749 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
750 end_ssub
= ssubstep
== subvl
751 end_dsub
= dsubstep
== subvl
752 if srcstep
== vl
-1 and end_ssub
:
754 if dststep
== vl
-1 and end_dsub
:
758 def advance_svstate_steps(self
):
759 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
760 TODO when Pack/Unpack is set, substep becomes the *outer* loop
762 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
763 if self
.loopend
: # huhn??
768 def read_src_mask(self
):
769 """read/update pred_sz and src mask
771 # get SVSTATE VL (oh and print out some debug stuff)
773 srcstep
= self
.svstate
.srcstep
774 ssubstep
= self
.svstate
.ssubstep
776 # get predicate mask (all 64 bits)
777 srcmask
= 0xffff_ffff_ffff_ffff
779 pmode
= yield self
.dec2
.rm_dec
.predmode
780 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
781 srcpred
= yield self
.dec2
.rm_dec
.srcpred
782 dstpred
= yield self
.dec2
.rm_dec
.dstpred
783 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
784 if pmode
== SVP64PredMode
.INT
.value
:
785 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
786 if sv_ptype
== SVPtype
.P2
.value
:
787 srcmask
= get_predint(self
.gpr
, srcpred
)
788 elif pmode
== SVP64PredMode
.CR
.value
:
789 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
790 if sv_ptype
== SVPtype
.P2
.value
:
791 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
792 # work out if the ssubsteps are completed
793 ssubstart
= ssubstep
== 0
795 log(" ptype", sv_ptype
)
796 log(" srcpred", bin(srcpred
))
797 log(" srcmask", bin(srcmask
))
798 log(" pred_sz", bin(pred_sz
))
799 log(" ssubstart", ssubstart
)
801 # store all that above
802 self
.srcstep_skip
= False
803 self
.srcmask
= srcmask
804 self
.pred_sz
= pred_sz
805 self
.new_ssubstep
= ssubstep
806 log(" new ssubstep", ssubstep
)
807 # until the predicate mask has a "1" bit... or we run out of VL
808 # let srcstep==VL be the indicator to move to next instruction
810 self
.srcstep_skip
= True
812 def read_dst_mask(self
):
813 """same as read_src_mask - check and record everything needed
815 # get SVSTATE VL (oh and print out some debug stuff)
816 # yield Delay(1e-10) # make changes visible
818 dststep
= self
.svstate
.dststep
819 dsubstep
= self
.svstate
.dsubstep
821 # get predicate mask (all 64 bits)
822 dstmask
= 0xffff_ffff_ffff_ffff
824 pmode
= yield self
.dec2
.rm_dec
.predmode
825 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
826 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
827 dstpred
= yield self
.dec2
.rm_dec
.dstpred
828 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
829 if pmode
== SVP64PredMode
.INT
.value
:
830 dstmask
= get_predint(self
.gpr
, dstpred
)
831 elif pmode
== SVP64PredMode
.CR
.value
:
832 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
833 # work out if the ssubsteps are completed
834 dsubstart
= dsubstep
== 0
836 log(" ptype", sv_ptype
)
837 log(" dstpred", bin(dstpred
))
838 log(" dstmask", bin(dstmask
))
839 log(" pred_dz", bin(pred_dz
))
840 log(" dsubstart", dsubstart
)
842 self
.dststep_skip
= False
843 self
.dstmask
= dstmask
844 self
.pred_dz
= pred_dz
845 self
.new_dsubstep
= dsubstep
846 log(" new dsubstep", dsubstep
)
848 self
.dststep_skip
= True
850 def svstate_pre_inc(self
):
851 """check if srcstep/dststep need to skip over masked-out predicate bits
852 note that this is not supposed to do anything to substep,
853 it is purely for skipping masked-out bits
856 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
857 yield from self
.read_src_mask()
858 yield from self
.read_dst_mask()
865 srcstep
= self
.svstate
.srcstep
866 srcmask
= self
.srcmask
867 pred_src_zero
= self
.pred_sz
869 # srcstep-skipping opportunity identified
870 if self
.srcstep_skip
:
871 # cannot do this with sv.bc - XXX TODO
874 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
875 log(" sskip", bin(1 << srcstep
))
878 # now work out if the relevant mask bits require zeroing
880 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
882 # store new srcstep / dststep
883 self
.new_srcstep
= srcstep
884 self
.pred_src_zero
= pred_src_zero
885 log(" new srcstep", srcstep
)
888 # dststep-skipping opportunity identified
889 dststep
= self
.svstate
.dststep
890 dstmask
= self
.dstmask
891 pred_dst_zero
= self
.pred_dz
893 if self
.dststep_skip
:
894 # cannot do this with sv.bc - XXX TODO
897 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
898 log(" dskip", bin(1 << dststep
))
901 # now work out if the relevant mask bits require zeroing
903 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
905 # store new srcstep / dststep
906 self
.new_dststep
= dststep
907 self
.pred_dst_zero
= pred_dst_zero
908 log(" new dststep", dststep
)
911 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
912 # decoder2 - an instance of power_decoder2
913 # regfile - a list of initial values for the registers
914 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
915 # respect_pc - tracks the program counter. requires initial_insns
916 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
917 initial_mem
=None, initial_msr
=0,
928 self
.bigendian
= bigendian
930 self
.is_svp64_mode
= False
931 self
.respect_pc
= respect_pc
932 if initial_sprs
is None:
934 if initial_mem
is None:
936 if fpregfile
is None:
938 if initial_insns
is None:
940 assert self
.respect_pc
== False, "instructions required to honor pc"
942 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
943 log("ISACaller initial_msr", initial_msr
)
945 # "fake program counter" mode (for unit testing)
949 if isinstance(initial_mem
, tuple):
950 self
.fake_pc
= initial_mem
[0]
951 disasm_start
= self
.fake_pc
953 disasm_start
= initial_pc
955 # disassembly: we need this for now (not given from the decoder)
956 self
.disassembly
= {}
958 for i
, code
in enumerate(disassembly
):
959 self
.disassembly
[i
*4 + disasm_start
] = code
961 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
962 self
.svp64rm
= SVP64RM()
963 if initial_svstate
is None:
965 if isinstance(initial_svstate
, int):
966 initial_svstate
= SVP64State(initial_svstate
)
967 # SVSTATE, MSR and PC
968 StepLoop
.__init
__(self
, initial_svstate
)
969 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
971 # GPR FPR SPR registers
972 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
973 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
974 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
975 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
977 # set up 4 dummy SVSHAPEs if they aren't already set up
979 sname
= 'SVSHAPE%d' % i
980 if sname
not in self
.spr
:
983 val
= self
.spr
[sname
].value
984 # make sure it's an SVSHAPE
985 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
986 self
.last_op_svshape
= False
989 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
990 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
991 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
992 # MMU mode, redirect underlying Mem through RADIX
994 self
.mem
= RADIX(self
.mem
, self
)
996 self
.imem
= RADIX(self
.imem
, self
)
999 # FPR (same as GPR except for FP nums)
1000 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1001 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1002 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1003 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1005 # 2.3.2 LR (actually SPR #8) -- Done
1006 # 2.3.3 CTR (actually SPR #9) -- Done
1007 # 2.3.4 TAR (actually SPR #815)
1008 # 3.2.2 p45 XER (actually SPR #1) -- Done
1009 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1011 # create CR then allow portions of it to be "selectable" (below)
1012 self
.cr_fields
= CRFields(initial_cr
)
1013 self
.cr
= self
.cr_fields
.cr
1015 # "undefined", just set to variable-bit-width int (use exts "max")
1016 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
1019 self
.namespace
.update(self
.spr
)
1020 self
.namespace
.update({'GPR': self
.gpr
,
1024 'memassign': self
.memassign
,
1027 'SVSTATE': self
.svstate
,
1028 'SVSHAPE0': self
.spr
['SVSHAPE0'],
1029 'SVSHAPE1': self
.spr
['SVSHAPE1'],
1030 'SVSHAPE2': self
.spr
['SVSHAPE2'],
1031 'SVSHAPE3': self
.spr
['SVSHAPE3'],
1034 'undefined': undefined
,
1035 'mode_is_64bit': True,
1036 'SO': XER_bits
['SO'],
1037 'XLEN': 64 # elwidth overrides, later
1040 # update pc to requested start point
1041 self
.set_pc(initial_pc
)
1043 # field-selectable versions of Condition Register
1044 self
.crl
= self
.cr_fields
.crl
1046 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
1048 self
.decoder
= decoder2
.dec
1049 self
.dec2
= decoder2
1051 super().__init
__(XLEN
=self
.namespace
["XLEN"])
1055 return self
.namespace
["XLEN"]
1057 def call_trap(self
, trap_addr
, trap_bit
):
1058 """calls TRAP and sets up NIA to the new execution location.
1059 next instruction will begin at trap_addr.
1061 self
.TRAP(trap_addr
, trap_bit
)
1062 self
.namespace
['NIA'] = self
.trap_nia
1063 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1065 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1066 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1068 TRAP function is callable from inside the pseudocode itself,
1069 hence the default arguments. when calling from inside ISACaller
1070 it is best to use call_trap()
1072 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1073 kaivb
= self
.spr
['KAIVB'].value
1074 msr
= self
.namespace
['MSR'].value
1075 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1076 # store CIA(+4?) in SRR0, set NIA to 0x700
1077 # store MSR in SRR1, set MSR to um errr something, have to check spec
1078 # store SVSTATE (if enabled) in SVSRR0
1079 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1080 self
.spr
['SRR1'].value
= msr
1081 if self
.is_svp64_mode
:
1082 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1083 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1084 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1086 # set exception bits. TODO: this should, based on the address
1087 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1088 # bits appropriately. however it turns out that *for now* in all
1089 # cases (all trap_addrs) the exact same thing is needed.
1090 self
.msr
[MSRb
.IR
] = 0
1091 self
.msr
[MSRb
.DR
] = 0
1092 self
.msr
[MSRb
.FE0
] = 0
1093 self
.msr
[MSRb
.FE1
] = 0
1094 self
.msr
[MSRb
.EE
] = 0
1095 self
.msr
[MSRb
.RI
] = 0
1096 self
.msr
[MSRb
.SF
] = 1
1097 self
.msr
[MSRb
.TM
] = 0
1098 self
.msr
[MSRb
.VEC
] = 0
1099 self
.msr
[MSRb
.VSX
] = 0
1100 self
.msr
[MSRb
.PR
] = 0
1101 self
.msr
[MSRb
.FP
] = 0
1102 self
.msr
[MSRb
.PMM
] = 0
1103 self
.msr
[MSRb
.TEs
] = 0
1104 self
.msr
[MSRb
.TEe
] = 0
1105 self
.msr
[MSRb
.UND
] = 0
1106 self
.msr
[MSRb
.LE
] = 1
1108 def memassign(self
, ea
, sz
, val
):
1109 self
.mem
.memassign(ea
, sz
, val
)
1111 def prep_namespace(self
, insn_name
, formname
, op_fields
):
1112 # TODO: get field names from form in decoder*1* (not decoder2)
1113 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1115 # then "yield" fields only from op_fields rather than hard-coded
1117 fields
= self
.decoder
.sigforms
[formname
]
1118 log("prep_namespace", formname
, op_fields
, insn_name
)
1119 for name
in op_fields
:
1120 # CR immediates. deal with separately. needs modifying
1122 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1123 # BI is a 5-bit, must reconstruct the value
1124 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
1125 sig
= getattr(fields
, name
)
1127 # low 2 LSBs (CR field selector) remain same, CR num extended
1128 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1129 val
= (val
& 0b11) |
(regnum
<< 2)
1131 sig
= getattr(fields
, name
)
1133 # these are all opcode fields involved in index-selection of CR,
1134 # and need to do "standard" arithmetic. CR[BA+32] for example
1135 # would, if using SelectableInt, only be 5-bit.
1136 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1137 self
.namespace
[name
] = val
1139 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1141 self
.namespace
['XER'] = self
.spr
['XER']
1142 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1143 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1145 # add some SVSTATE convenience variables
1146 vl
= self
.svstate
.vl
1147 srcstep
= self
.svstate
.srcstep
1148 self
.namespace
['VL'] = vl
1149 self
.namespace
['srcstep'] = srcstep
1151 # sv.bc* need some extra fields
1152 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1153 # blegh grab bits manually
1154 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1155 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
1156 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
1157 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
1158 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1159 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1160 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1161 sz
= yield self
.dec2
.rm_dec
.pred_sz
1162 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1163 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1164 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1165 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1166 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1167 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1168 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1170 def handle_carry_(self
, inputs
, outputs
, already_done
):
1171 inv_a
= yield self
.dec2
.e
.do
.invert_in
1173 inputs
[0] = ~inputs
[0]
1175 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1177 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1178 inputs
.append(SelectableInt(imm
, 64))
1179 assert len(outputs
) >= 1
1180 log("outputs", repr(outputs
))
1181 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
1187 log("gt input", x
, output
)
1188 gt
= (gtu(x
, output
))
1191 cy
= 1 if any(gts
) else 0
1193 if not (1 & already_done
):
1194 self
.spr
['XER'][XER_bits
['CA']] = cy
1196 log("inputs", already_done
, inputs
)
1198 # ARGH... different for OP_ADD... *sigh*...
1199 op
= yield self
.dec2
.e
.do
.insn_type
1200 if op
== MicrOp
.OP_ADD
.value
:
1201 res32
= (output
.value
& (1 << 32)) != 0
1202 a32
= (inputs
[0].value
& (1 << 32)) != 0
1203 if len(inputs
) >= 2:
1204 b32
= (inputs
[1].value
& (1 << 32)) != 0
1207 cy32
= res32 ^ a32 ^ b32
1208 log("CA32 ADD", cy32
)
1212 log("input", x
, output
)
1213 log(" x[32:64]", x
, x
[32:64])
1214 log(" o[32:64]", output
, output
[32:64])
1215 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1217 cy32
= 1 if any(gts
) else 0
1218 log("CA32", cy32
, gts
)
1219 if not (2 & already_done
):
1220 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1222 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
1223 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1224 inv_a
= yield self
.dec2
.e
.do
.invert_in
1226 inputs
[0] = ~inputs
[0]
1228 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1230 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1231 inputs
.append(SelectableInt(imm
, 64))
1232 assert len(outputs
) >= 1
1233 log("handle_overflow", inputs
, outputs
, div_overflow
)
1234 if len(inputs
) < 2 and div_overflow
is None:
1237 # div overflow is different: it's returned by the pseudo-code
1238 # because it's more complex than can be done by analysing the output
1239 if div_overflow
is not None:
1240 ov
, ov32
= div_overflow
, div_overflow
1241 # arithmetic overflow can be done by analysing the input and output
1242 elif len(inputs
) >= 2:
1246 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1247 output_sgn
= exts(output
.value
, output
.bits
) < 0
1248 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1249 output_sgn
!= input_sgn
[0] else 0
1252 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1253 output32_sgn
= exts(output
.value
, 32) < 0
1254 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1255 output32_sgn
!= input32_sgn
[0] else 0
1257 # now update XER OV/OV32/SO
1258 so
= self
.spr
['XER'][XER_bits
['SO']]
1259 new_so
= so | ov
# sticky overflow ORs in old with new
1260 self
.spr
['XER'][XER_bits
['OV']] = ov
1261 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1262 self
.spr
['XER'][XER_bits
['SO']] = new_so
1263 log(" set overflow", ov
, ov32
, so
, new_so
)
1265 def handle_comparison(self
, outputs
, cr_idx
=0, overflow
=None, no_so
=False):
1267 assert isinstance(out
, SelectableInt
), \
1268 "out zero not a SelectableInt %s" % repr(outputs
)
1269 log("handle_comparison", out
.bits
, hex(out
.value
))
1270 # TODO - XXX *processor* in 32-bit mode
1271 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1273 # o32 = exts(out.value, 32)
1274 # print ("handle_comparison exts 32 bit", hex(o32))
1275 out
= exts(out
.value
, out
.bits
)
1276 log("handle_comparison exts", hex(out
))
1277 # create the three main CR flags, EQ GT LT
1278 zero
= SelectableInt(out
== 0, 1)
1279 positive
= SelectableInt(out
> 0, 1)
1280 negative
= SelectableInt(out
< 0, 1)
1281 # get (or not) XER.SO. for setvl this is important *not* to read SO
1283 SO
= SelectableInt(1, 0)
1285 SO
= self
.spr
['XER'][XER_bits
['SO']]
1286 log("handle_comparison SO overflow", SO
, overflow
)
1287 # alternative overflow checking (setvl mainly at the moment)
1288 if overflow
is not None and overflow
== 1:
1289 SO
= SelectableInt(1, 1)
1290 # create the four CR field values and set the required CR field
1291 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1292 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1293 self
.crl
[cr_idx
].eq(cr_field
)
1295 def set_pc(self
, pc_val
):
1296 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1297 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1299 def get_next_insn(self
):
1300 """check instruction
1303 pc
= self
.pc
.CIA
.value
1306 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1308 raise KeyError("no instruction at 0x%x" % pc
)
1311 def setup_one(self
):
1312 """set up one instruction
1314 pc
, insn
= self
.get_next_insn()
1315 yield from self
.setup_next_insn(pc
, insn
)
1317 def setup_next_insn(self
, pc
, ins
):
1318 """set up next instruction
1321 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1322 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1324 yield self
.dec2
.sv_rm
.eq(0)
1325 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1326 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1327 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1328 yield self
.dec2
.state
.pc
.eq(pc
)
1329 if self
.svstate
is not None:
1330 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1332 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1334 opcode
= yield self
.dec2
.dec
.opcode_in
1335 opcode
= SelectableInt(value
=opcode
, bits
=32)
1336 pfx
= SVP64Instruction
.Prefix(opcode
)
1337 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1338 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1339 self
.pc
.update_nia(self
.is_svp64_mode
)
1341 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1342 self
.namespace
['NIA'] = self
.pc
.NIA
1343 self
.namespace
['SVSTATE'] = self
.svstate
1344 if not self
.is_svp64_mode
:
1347 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1348 log("svp64.rm", bin(pfx
.rm
))
1349 log(" svstate.vl", self
.svstate
.vl
)
1350 log(" svstate.mvl", self
.svstate
.maxvl
)
1351 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1352 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1353 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1354 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1357 def execute_one(self
):
1358 """execute one instruction
1360 # get the disassembly code for this instruction
1361 if self
.is_svp64_mode
:
1362 if not self
.disassembly
:
1363 code
= yield from self
.get_assembly_name()
1365 code
= self
.disassembly
[self
._pc
+4]
1366 log(" svp64 sim-execute", hex(self
._pc
), code
)
1368 if not self
.disassembly
:
1369 code
= yield from self
.get_assembly_name()
1371 code
= self
.disassembly
[self
._pc
]
1372 log("sim-execute", hex(self
._pc
), code
)
1373 opname
= code
.split(' ')[0]
1375 yield from self
.call(opname
) # execute the instruction
1376 except MemException
as e
: # check for memory errors
1377 if e
.args
[0] == 'unaligned': # alignment error
1378 # run a Trap but set DAR first
1379 print("memory unaligned exception, DAR", e
.dar
)
1380 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1381 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1383 elif e
.args
[0] == 'invalid': # invalid
1384 # run a Trap but set DAR first
1385 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1386 if e
.mode
== 'EXECUTE':
1387 # XXX TODO: must set a few bits in SRR1,
1388 # see microwatt loadstore1.vhdl
1389 # if m_in.segerr = '0' then
1390 # v.srr1(47 - 33) := m_in.invalid;
1391 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1392 # v.srr1(47 - 44) := m_in.badtree;
1393 # v.srr1(47 - 45) := m_in.rc_error;
1394 # v.intr_vec := 16#400#;
1396 # v.intr_vec := 16#480#;
1397 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1399 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1401 # not supported yet:
1402 raise e
# ... re-raise
1404 # don't use this except in special circumstances
1405 if not self
.respect_pc
:
1408 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1409 hex(self
.pc
.NIA
.value
))
1411 def get_assembly_name(self
):
1412 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1413 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1414 dec_insn
= yield self
.dec2
.e
.do
.insn
1415 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1416 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1417 int_op
= yield self
.dec2
.dec
.op
.internal_op
1418 log("get assembly name asmcode", asmcode
, int_op
,
1419 hex(dec_insn
), bin(insn_1_11
))
1420 asmop
= insns
.get(asmcode
, None)
1422 # sigh reconstruct the assembly instruction name
1423 if hasattr(self
.dec2
.e
.do
, "oe"):
1424 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1425 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1429 if hasattr(self
.dec2
.e
.do
, "rc"):
1430 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1431 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1435 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1436 RC1
= yield self
.dec2
.rm_dec
.RC1
1440 # grrrr have to special-case MUL op (see DecodeOE)
1441 log("ov %d en %d rc %d en %d op %d" %
1442 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1443 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1448 if not asmop
.endswith("."): # don't add "." to "andis."
1451 if hasattr(self
.dec2
.e
.do
, "lk"):
1452 lk
= yield self
.dec2
.e
.do
.lk
1455 log("int_op", int_op
)
1456 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1457 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1461 spr_msb
= yield from self
.get_spr_msb()
1462 if int_op
== MicrOp
.OP_MFCR
.value
:
1467 # XXX TODO: for whatever weird reason this doesn't work
1468 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1469 if int_op
== MicrOp
.OP_MTCRF
.value
:
1476 def reset_remaps(self
):
1477 self
.remap_loopends
= [0] * 4
1478 self
.remap_idxs
= [0, 1, 2, 3]
1480 def get_remap_indices(self
):
1481 """WARNING, this function stores remap_idxs and remap_loopends
1482 in the class for later use. this to avoid problems with yield
1484 # go through all iterators in lock-step, advance to next remap_idx
1485 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1486 # get four SVSHAPEs. here we are hard-coding
1488 SVSHAPE0
= self
.spr
['SVSHAPE0']
1489 SVSHAPE1
= self
.spr
['SVSHAPE1']
1490 SVSHAPE2
= self
.spr
['SVSHAPE2']
1491 SVSHAPE3
= self
.spr
['SVSHAPE3']
1492 # set up the iterators
1493 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1494 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1495 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1496 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1500 for i
, (shape
, remap
) in enumerate(remaps
):
1501 # zero is "disabled"
1502 if shape
.value
== 0x0:
1503 self
.remap_idxs
[i
] = 0
1504 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1505 step
= dststep
if (i
in [3, 4]) else srcstep
1506 # this is terrible. O(N^2) looking for the match. but hey.
1507 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1510 self
.remap_idxs
[i
] = remap_idx
1511 self
.remap_loopends
[i
] = loopends
1512 dbg
.append((i
, step
, remap_idx
, loopends
))
1513 for (i
, step
, remap_idx
, loopends
) in dbg
:
1514 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1517 def get_spr_msb(self
):
1518 dec_insn
= yield self
.dec2
.e
.do
.insn
1519 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1521 def call(self
, name
):
1522 """call(opcode) - the primary execution point for instructions
1524 self
.last_st_addr
= None # reset the last known store address
1525 self
.last_ld_addr
= None # etc.
1527 ins_name
= name
.strip() # remove spaces if not already done so
1529 log("halted - not executing", ins_name
)
1532 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1533 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1534 asmop
= yield from self
.get_assembly_name()
1535 log("call", ins_name
, asmop
)
1537 # sv.setvl is *not* a loop-function. sigh
1538 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1541 int_op
= yield self
.dec2
.dec
.op
.internal_op
1542 spr_msb
= yield from self
.get_spr_msb()
1544 instr_is_privileged
= False
1545 if int_op
in [MicrOp
.OP_ATTN
.value
,
1546 MicrOp
.OP_MFMSR
.value
,
1547 MicrOp
.OP_MTMSR
.value
,
1548 MicrOp
.OP_MTMSRD
.value
,
1550 MicrOp
.OP_RFID
.value
]:
1551 instr_is_privileged
= True
1552 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1553 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1554 instr_is_privileged
= True
1556 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1558 # check MSR priv bit and whether op is privileged: if so, throw trap
1559 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1560 self
.call_trap(0x700, PIb
.PRIV
)
1563 # check halted condition
1564 if ins_name
== 'attn':
1568 # check illegal instruction
1570 if ins_name
not in ['mtcrf', 'mtocrf']:
1571 illegal
= ins_name
!= asmop
1573 # list of instructions not being supported by binutils (.long)
1574 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1575 if dotstrp
in [*FPTRANS_INSNS
,
1576 'ffmadds', 'fdmadds', 'ffadds',
1577 'mins', 'maxs', 'minu', 'maxu',
1578 'setvl', 'svindex', 'svremap', 'svstep',
1579 'svshape', 'svshape2',
1580 'grev', 'ternlogi', 'bmask', 'cprop',
1581 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1582 'fmvis', 'fishmv', 'pcdec'
1587 # branch-conditional redirects to sv.bc
1588 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1589 ins_name
= 'sv.%s' % ins_name
1591 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1593 # illegal instructions call TRAP at 0x700
1595 print("illegal", ins_name
, asmop
)
1596 self
.call_trap(0x700, PIb
.ILLEG
)
1597 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1598 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1601 # this is for setvl "Vertical" mode: if set true,
1602 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1603 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1604 self
.allow_next_step_inc
= False
1605 self
.svstate_next_mode
= 0
1607 # nop has to be supported, we could let the actual op calculate
1608 # but PowerDecoder has a pattern for nop
1609 if ins_name
== 'nop':
1610 self
.update_pc_next()
1613 # look up instruction in ISA.instrs, prepare namespace
1614 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1615 info
= self
.instrs
[ins_name
+"."]
1617 info
= self
.instrs
[ins_name
]
1618 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1620 # preserve order of register names
1621 input_names
= create_args(list(info
.read_regs
) +
1622 list(info
.uninit_regs
))
1623 log("input names", input_names
)
1625 # get SVP64 entry for the current instruction
1626 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1627 if sv_rm
is not None:
1628 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1630 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1631 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1633 # see if srcstep/dststep need skipping over masked-out predicate bits
1635 if (self
.is_svp64_mode
or ins_name
in ['setvl', 'svremap', 'svstate']):
1636 yield from self
.svstate_pre_inc()
1637 if self
.is_svp64_mode
:
1638 pre
= yield from self
.update_new_svstate_steps()
1640 self
.svp64_reset_loop()
1642 self
.update_pc_next()
1644 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1645 pred_dst_zero
= self
.pred_dst_zero
1646 pred_src_zero
= self
.pred_src_zero
1647 vl
= self
.svstate
.vl
1648 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1650 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1651 if self
.is_svp64_mode
and vl
== 0:
1652 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1653 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1654 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1657 # for when SVREMAP is active, using pre-arranged schedule.
1658 # note: modifying PowerDecoder2 needs to "settle"
1659 remap_en
= self
.svstate
.SVme
1660 persist
= self
.svstate
.RMpst
1661 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1662 if self
.is_svp64_mode
:
1663 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1665 if persist
or self
.last_op_svshape
:
1666 remaps
= self
.get_remap_indices()
1667 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1668 yield from self
.remap_set_steps(remaps
)
1669 # after that, settle down (combinatorial) to let Vector reg numbers
1670 # work themselves out
1672 if self
.is_svp64_mode
:
1673 remap_active
= yield self
.dec2
.remap_active
1675 remap_active
= False
1676 log("remap active", bin(remap_active
))
1678 # main input registers (RT, RA ...)
1680 for name
in input_names
:
1682 regval
= (yield from self
.get_input(name
))
1683 log("regval", regval
)
1684 inputs
.append(regval
)
1686 # arrrrgh, awful hack, to get _RT into namespace
1687 if ins_name
in ['setvl', 'svstep']:
1689 RT
= yield self
.dec2
.dec
.RT
1690 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1692 self
.namespace
["RT"] = SelectableInt(0, 5)
1693 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1694 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1696 # in SVP64 mode for LD/ST work out immediate
1697 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1698 # use info.form to detect
1699 if self
.is_svp64_mode
:
1700 yield from self
.check_replace_d(info
, remap_active
)
1702 # "special" registers
1703 for special
in info
.special_regs
:
1704 if special
in special_sprs
:
1705 inputs
.append(self
.spr
[special
])
1707 inputs
.append(self
.namespace
[special
])
1709 # clear trap (trap) NIA
1710 self
.trap_nia
= None
1712 # check if this was an sv.bc* and create an indicator that
1713 # this is the last check to be made as a loop. combined with
1714 # the ALL/ANY mode we can early-exit
1715 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1716 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1717 # XXX TODO - pack/unpack here
1718 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1719 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1721 # execute actual instruction here (finally)
1722 log("inputs", inputs
)
1723 results
= info
.func(self
, *inputs
)
1724 log("results", results
)
1726 # "inject" decorator takes namespace from function locals: we need to
1727 # overwrite NIA being overwritten (sigh)
1728 if self
.trap_nia
is not None:
1729 self
.namespace
['NIA'] = self
.trap_nia
1731 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1733 # check if op was a LD/ST so that debugging can check the
1735 if int_op
in [MicrOp
.OP_STORE
.value
,
1737 self
.last_st_addr
= self
.mem
.last_st_addr
1738 if int_op
in [MicrOp
.OP_LOAD
.value
,
1740 self
.last_ld_addr
= self
.mem
.last_ld_addr
1741 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1742 self
.last_st_addr
, self
.last_ld_addr
)
1744 # detect if CA/CA32 already in outputs (sra*, basically)
1748 output_names
= create_args(info
.write_regs
)
1749 for name
in output_names
:
1755 log("carry already done?", bin(already_done
), output_names
)
1756 carry_en
= yield self
.dec2
.e
.do
.output_carry
1758 yield from self
.handle_carry_(inputs
, results
, already_done
)
1760 # check if one of the regs was named "overflow"
1763 for name
, output
in zip(output_names
, results
):
1764 if name
== 'overflow':
1767 # and one called CR0
1770 for name
, output
in zip(output_names
, results
):
1774 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1775 # detect if overflow was in return result
1776 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1777 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1778 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1780 yield from self
.handle_overflow(inputs
, results
, overflow
)
1782 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1784 if not self
.is_svp64_mode
or not pred_dst_zero
:
1785 if hasattr(self
.dec2
.e
.do
, "rc"):
1786 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1787 # don't do Rc=1 for svstep it is handled explicitly.
1788 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1789 # to write directly to CR0 instead of in ISACaller. hooyahh.
1790 if rc_en
and ins_name
not in ['svstep']:
1791 yield from self
.do_rc_ov(ins_name
, results
, overflow
, cr0
)
1794 ffirst_hit
= (yield from self
.check_ffirst(rc_en
, srcstep
))
1796 # any modified return results?
1797 yield from self
.do_outregs_nia(asmop
, ins_name
, info
,
1798 output_names
, results
,
1799 carry_en
, rc_en
, ffirst_hit
)
1801 def check_ffirst(self
, rc_en
, srcstep
):
1802 rm_mode
= yield self
.dec2
.rm_dec
.mode
1803 ff_inv
= yield self
.dec2
.rm_dec
.inv
1804 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
1805 RC1
= yield self
.dec2
.rm_dec
.RC1
1806 vli
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
1807 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
1811 log(" cr_bit", cr_bit
)
1812 if not rc_en
or rm_mode
!= SVP64RMMode
.FFIRST
.value
:
1814 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1815 crtest
= self
.crl
[regnum
]
1816 ffirst_hit
= crtest
[cr_bit
] != ff_inv
1817 log("cr test", regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
1818 log("cr test?", ffirst_hit
)
1821 vli
= SelectableInt(int(vli
), 7)
1822 self
.svstate
.vl
= srcstep
+ vli
1823 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1824 yield Settle() # let decoder update
1827 def do_rc_ov(self
, ins_name
, results
, overflow
, cr0
):
1828 if ins_name
.startswith("f"):
1829 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1832 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, rc_reg
)
1834 # hang on... for `setvl` actually you want to test SVSTATE.VL
1835 is_setvl
= ins_name
== 'setvl'
1838 cmps
= (SelectableInt(vl
, 64), overflow
,)
1840 overflow
= None # do not override overflow except in setvl
1842 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
1844 self
.handle_comparison(cmps
, regnum
, overflow
, no_so
=is_setvl
)
1846 # otherwise we just blat CR0 into the required regnum
1847 log("explicit rc0", cr0
)
1848 self
.crl
[regnum
].eq(cr0
)
1850 def do_outregs_nia(self
, asmop
, ins_name
, info
, output_names
, results
,
1851 carry_en
, rc_en
, ffirst_hit
):
1852 # write out any regs for this instruction
1854 for name
, output
in zip(output_names
, results
):
1855 yield from self
.check_write(info
, name
, output
, carry_en
)
1858 self
.svp64_reset_loop()
1861 # check advancement of src/dst/sub-steps and if PC needs updating
1862 nia_update
= (yield from self
.check_step_increment(results
, rc_en
,
1865 self
.update_pc_next()
1867 def check_replace_d(self
, info
, remap_active
):
1868 replace_d
= False # update / replace constant in pseudocode
1869 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1870 vl
= self
.svstate
.vl
1871 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1872 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1873 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1874 if info
.form
== 'DS':
1875 # DS-Form, multiply by 4 then knock 2 bits off after
1876 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1878 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1879 imm
= exts(imm
, 16) # sign-extend to integer
1880 # get the right step. LD is from srcstep, ST is dststep
1881 op
= yield self
.dec2
.e
.do
.insn_type
1883 if op
== MicrOp
.OP_LOAD
.value
:
1885 offsmul
= yield self
.dec2
.in1_step
1886 log("D-field REMAP src", imm
, offsmul
)
1888 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
1889 log("D-field src", imm
, offsmul
)
1890 elif op
== MicrOp
.OP_STORE
.value
:
1891 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1892 offsmul
= (dststep
* (subvl
+1)) + dsubstep
1893 log("D-field dst", imm
, offsmul
)
1894 # Unit-Strided LD/ST adds offset*width to immediate
1895 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1896 ldst_len
= yield self
.dec2
.e
.do
.data_len
1897 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1899 # Element-strided multiplies the immediate by element step
1900 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1901 imm
= SelectableInt(imm
* offsmul
, 32)
1904 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1905 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1906 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1907 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1908 # new replacement D... errr.. DS
1910 if info
.form
== 'DS':
1911 # TODO: assert 2 LSBs are zero?
1912 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1913 imm
.value
= imm
.value
>> 2
1914 self
.namespace
['DS'] = imm
1916 self
.namespace
['D'] = imm
1918 def get_input(self
, name
):
1919 # using PowerDecoder2, first, find the decoder index.
1920 # (mapping name RA RB RC RS to in1, in2, in3)
1921 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1923 # doing this is not part of svp64, it's because output
1924 # registers, to be modified, need to be in the namespace.
1925 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1927 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1929 # in case getting the register number is needed, _RA, _RB
1930 regname
= "_" + name
1931 self
.namespace
[regname
] = regnum
1932 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
1933 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1935 reg_val
= SelectableInt(self
.fpr(regnum
))
1936 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1937 elif name
is not None:
1938 reg_val
= SelectableInt(self
.gpr(regnum
))
1939 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1941 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1945 def remap_set_steps(self
, remaps
):
1946 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1947 they work in concert with PowerDecoder2 at the moment,
1948 there is no HDL implementation of REMAP. therefore this
1949 function, because ISACaller still uses PowerDecoder2,
1950 will *explicitly* write the dec2.XX_step values. this has
1953 # just some convenient debug info
1955 sname
= 'SVSHAPE%d' % i
1956 shape
= self
.spr
[sname
]
1957 log(sname
, bin(shape
.value
))
1958 log(" lims", shape
.lims
)
1959 log(" mode", shape
.mode
)
1960 log(" skip", shape
.skip
)
1962 # set up the list of steps to remap
1963 mi0
= self
.svstate
.mi0
1964 mi1
= self
.svstate
.mi1
1965 mi2
= self
.svstate
.mi2
1966 mo0
= self
.svstate
.mo0
1967 mo1
= self
.svstate
.mo1
1968 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1969 (self
.dec2
.in2_step
, mi1
), # RB
1970 (self
.dec2
.in3_step
, mi2
), # RC
1971 (self
.dec2
.o_step
, mo0
), # RT
1972 (self
.dec2
.o2_step
, mo1
), # EA
1974 remap_idxs
= self
.remap_idxs
1976 # now cross-index the required SHAPE for each of 3-in 2-out regs
1977 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1978 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1979 (shape
, remap
) = remaps
[shape_idx
]
1980 remap_idx
= remap_idxs
[shape_idx
]
1981 # zero is "disabled"
1982 if shape
.value
== 0x0:
1984 # now set the actual requested step to the current index
1985 yield dstep
.eq(remap_idx
)
1987 # debug printout info
1988 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
1990 log("shape remap", x
)
1992 def check_write(self
, info
, name
, output
, carry_en
):
1993 if name
== 'overflow': # ignore, done already (above)
1995 if name
== 'CR0': # ignore, done already (above)
1997 if isinstance(output
, int):
1998 output
= SelectableInt(output
, 256)
2000 if name
in ['CA', 'CA32']:
2002 log("writing %s to XER" % name
, output
)
2003 log("write XER %s 0x%x" % (name
, output
.value
))
2004 self
.spr
['XER'][XER_bits
[name
]] = output
.value
2006 log("NOT writing %s to XER" % name
, output
)
2008 # write special SPRs
2009 if name
in info
.special_regs
:
2010 log('writing special %s' % name
, output
, special_sprs
)
2011 log("write reg %s 0x%x" % (name
, output
.value
))
2012 if name
in special_sprs
:
2013 self
.spr
[name
] = output
2015 self
.namespace
[name
].eq(output
)
2017 log('msr written', hex(self
.msr
.value
))
2019 # find out1/out2 PR/FPR
2020 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
2022 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
2024 # temporary hack for not having 2nd output
2025 regnum
= yield getattr(self
.decoder
, name
)
2027 # convenient debug prefix
2032 # check zeroing due to predicate bit being zero
2033 if self
.is_svp64_mode
and self
.pred_dst_zero
:
2034 log('zeroing reg %d %s' % (regnum
, str(output
)), is_vec
)
2035 output
= SelectableInt(0, 256)
2036 log("write reg %s%d 0x%x" % (reg_prefix
, regnum
, output
.value
),
2037 kind
=LogKind
.InstrInOuts
)
2038 # zero-extend tov64 bit begore storing (should use EXT oh well)
2039 if output
.bits
> 64:
2040 output
= SelectableInt(output
.value
, 64)
2042 self
.fpr
[regnum
] = output
2044 self
.gpr
[regnum
] = output
2046 def check_step_increment(self
, results
, rc_en
, asmop
, ins_name
):
2047 # check if it is the SVSTATE.src/dest step that needs incrementing
2048 # this is our Sub-Program-Counter loop from 0 to VL-1
2049 if not self
.allow_next_step_inc
:
2050 if self
.is_svp64_mode
:
2051 return (yield from self
.svstate_post_inc(ins_name
))
2053 # XXX only in non-SVP64 mode!
2054 # record state of whether the current operation was an svshape,
2056 # to be able to know if it should apply in the next instruction.
2057 # also (if going to use this instruction) should disable ability
2058 # to interrupt in between. sigh.
2059 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2066 log("SVSTATE_NEXT: inc requested, mode",
2067 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2068 yield from self
.svstate_pre_inc()
2069 pre
= yield from self
.update_new_svstate_steps()
2071 # reset at end of loop including exit Vertical Mode
2072 log("SVSTATE_NEXT: end of loop, reset")
2073 self
.svp64_reset_loop()
2074 self
.svstate
.vfirst
= 0
2078 results
= [SelectableInt(0, 64)]
2079 self
.handle_comparison(results
) # CR0
2081 if self
.allow_next_step_inc
== 2:
2082 log("SVSTATE_NEXT: read")
2083 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2085 log("SVSTATE_NEXT: post-inc")
2086 # use actual (cached) src/dst-step here to check end
2087 remaps
= self
.get_remap_indices()
2088 remap_idxs
= self
.remap_idxs
2089 vl
= self
.svstate
.vl
2090 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2091 if self
.allow_next_step_inc
!= 2:
2092 yield from self
.advance_svstate_steps()
2093 #self.namespace['SVSTATE'] = self.svstate.spr
2094 # set CR0 (if Rc=1) based on end
2095 endtest
= 1 if self
.at_loopend() else 0
2097 #results = [SelectableInt(endtest, 64)]
2098 # self.handle_comparison(results) # CR0
2100 # see if svstep was requested, if so, which SVSTATE
2102 if self
.svstate_next_mode
> 0:
2103 shape_idx
= self
.svstate_next_mode
.value
-1
2104 endings
= self
.remap_loopends
[shape_idx
]
2105 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2106 log("svstep Rc=1, CR0", cr_field
, endtest
)
2107 self
.crl
[0].eq(cr_field
) # CR0
2109 # reset at end of loop including exit Vertical Mode
2110 log("SVSTATE_NEXT: after increments, reset")
2111 self
.svp64_reset_loop()
2112 self
.svstate
.vfirst
= 0
2115 def SVSTATE_NEXT(self
, mode
, submode
):
2116 """explicitly moves srcstep/dststep on to next element, for
2117 "Vertical-First" mode. this function is called from
2118 setvl pseudo-code, as a pseudo-op "svstep"
2120 WARNING: this function uses information that was created EARLIER
2121 due to it being in the middle of a yield, but this function is
2122 *NOT* called from yield (it's called from compiled pseudocode).
2124 self
.allow_next_step_inc
= submode
.value
+ 1
2125 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2126 self
.svstate_next_mode
= mode
2127 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2128 shape_idx
= self
.svstate_next_mode
.value
-1
2129 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2130 if self
.svstate_next_mode
== 5:
2131 self
.svstate_next_mode
= 0
2132 return SelectableInt(self
.svstate
.srcstep
, 7)
2133 if self
.svstate_next_mode
== 6:
2134 self
.svstate_next_mode
= 0
2135 return SelectableInt(self
.svstate
.dststep
, 7)
2136 if self
.svstate_next_mode
== 7:
2137 self
.svstate_next_mode
= 0
2138 return SelectableInt(self
.svstate
.ssubstep
, 7)
2139 if self
.svstate_next_mode
== 8:
2140 self
.svstate_next_mode
= 0
2141 return SelectableInt(self
.svstate
.dsubstep
, 7)
2142 return SelectableInt(0, 7)
2144 def get_src_dststeps(self
):
2145 """gets srcstep, dststep, and ssubstep, dsubstep
2147 return (self
.new_srcstep
, self
.new_dststep
,
2148 self
.new_ssubstep
, self
.new_dsubstep
)
2150 def update_new_svstate_steps(self
):
2151 # note, do not get the bit-reversed srcstep here!
2152 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2153 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2155 # update SVSTATE with new srcstep
2156 self
.svstate
.srcstep
= srcstep
2157 self
.svstate
.dststep
= dststep
2158 self
.svstate
.ssubstep
= ssubstep
2159 self
.svstate
.dsubstep
= dsubstep
2160 self
.namespace
['SVSTATE'] = self
.svstate
2161 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2162 yield Settle() # let decoder update
2163 srcstep
= self
.svstate
.srcstep
2164 dststep
= self
.svstate
.dststep
2165 ssubstep
= self
.svstate
.ssubstep
2166 dsubstep
= self
.svstate
.dsubstep
2167 pack
= self
.svstate
.pack
2168 unpack
= self
.svstate
.unpack
2169 vl
= self
.svstate
.vl
2170 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2171 rm_mode
= yield self
.dec2
.rm_dec
.mode
2172 ff_inv
= yield self
.dec2
.rm_dec
.inv
2173 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2174 log(" srcstep", srcstep
)
2175 log(" dststep", dststep
)
2177 log(" unpack", unpack
)
2178 log(" ssubstep", ssubstep
)
2179 log(" dsubstep", dsubstep
)
2181 log(" subvl", subvl
)
2182 log(" rm_mode", rm_mode
)
2184 log(" cr_bit", cr_bit
)
2186 # check if end reached (we let srcstep overrun, above)
2187 # nothing needs doing (TODO zeroing): just do next instruction
2190 return ((ssubstep
== subvl
and srcstep
== vl
) or
2191 (dsubstep
== subvl
and dststep
== vl
))
2193 def svstate_post_inc(self
, insn_name
, vf
=0):
2194 # check if SV "Vertical First" mode is enabled
2195 vfirst
= self
.svstate
.vfirst
2196 log(" SV Vertical First", vf
, vfirst
)
2197 if not vf
and vfirst
== 1:
2201 # check if it is the SVSTATE.src/dest step that needs incrementing
2202 # this is our Sub-Program-Counter loop from 0 to VL-1
2203 # XXX twin predication TODO
2204 vl
= self
.svstate
.vl
2205 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2206 mvl
= self
.svstate
.maxvl
2207 srcstep
= self
.svstate
.srcstep
2208 dststep
= self
.svstate
.dststep
2209 ssubstep
= self
.svstate
.ssubstep
2210 dsubstep
= self
.svstate
.dsubstep
2211 pack
= self
.svstate
.pack
2212 unpack
= self
.svstate
.unpack
2213 rm_mode
= yield self
.dec2
.rm_dec
.mode
2214 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2215 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2216 out_vec
= not (yield self
.dec2
.no_out_vec
)
2217 in_vec
= not (yield self
.dec2
.no_in_vec
)
2218 log(" svstate.vl", vl
)
2219 log(" svstate.mvl", mvl
)
2220 log(" rm.subvl", subvl
)
2221 log(" svstate.srcstep", srcstep
)
2222 log(" svstate.dststep", dststep
)
2223 log(" svstate.ssubstep", ssubstep
)
2224 log(" svstate.dsubstep", dsubstep
)
2225 log(" svstate.pack", pack
)
2226 log(" svstate.unpack", unpack
)
2227 log(" mode", rm_mode
)
2228 log(" reverse", reverse_gear
)
2229 log(" out_vec", out_vec
)
2230 log(" in_vec", in_vec
)
2231 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2232 # check if this was an sv.bc* and if so did it succeed
2233 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2234 end_loop
= self
.namespace
['end_loop']
2235 log("branch %s end_loop" % insn_name
, end_loop
)
2237 self
.svp64_reset_loop()
2238 self
.update_pc_next()
2240 # check if srcstep needs incrementing by one, stop PC advancing
2241 # but for 2-pred both src/dest have to be checked.
2242 # XXX this might not be true! it may just be LD/ST
2243 if sv_ptype
== SVPtype
.P2
.value
:
2244 svp64_is_vector
= (out_vec
or in_vec
)
2246 svp64_is_vector
= out_vec
2247 # loops end at the first "hit" (source or dest)
2248 yield from self
.advance_svstate_steps()
2249 loopend
= self
.loopend
2250 log("loopend", svp64_is_vector
, loopend
)
2251 if not svp64_is_vector
or loopend
:
2252 # reset loop to zero and update NIA
2253 self
.svp64_reset_loop()
2258 # still looping, advance and update NIA
2259 self
.namespace
['SVSTATE'] = self
.svstate
2261 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2262 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2263 # this way we keep repeating the same instruction (with new steps)
2264 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2265 self
.namespace
['NIA'] = self
.pc
.NIA
2266 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2267 return False # DO NOT allow PC update whilst Sub-PC loop running
2269 def update_pc_next(self
):
2270 # UPDATE program counter
2271 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2272 #self.svstate.spr = self.namespace['SVSTATE']
2273 log("end of call", self
.namespace
['CIA'],
2274 self
.namespace
['NIA'],
2275 self
.namespace
['SVSTATE'])
2277 def svp64_reset_loop(self
):
2278 self
.svstate
.srcstep
= 0
2279 self
.svstate
.dststep
= 0
2280 self
.svstate
.ssubstep
= 0
2281 self
.svstate
.dsubstep
= 0
2282 self
.loopend
= False
2283 log(" svstate.srcstep loop end (PC to update)")
2284 self
.namespace
['SVSTATE'] = self
.svstate
2286 def update_nia(self
):
2287 self
.pc
.update_nia(self
.is_svp64_mode
)
2288 self
.namespace
['NIA'] = self
.pc
.NIA
2292 """Decorator factory.
2294 this decorator will "inject" variables into the function's namespace,
2295 from the *dictionary* in self.namespace. it therefore becomes possible
2296 to make it look like a whole stack of variables which would otherwise
2297 need "self." inserted in front of them (*and* for those variables to be
2298 added to the instance) "appear" in the function.
2300 "self.namespace['SI']" for example becomes accessible as just "SI" but
2301 *only* inside the function, when decorated.
2303 def variable_injector(func
):
2305 def decorator(*args
, **kwargs
):
2307 func_globals
= func
.__globals
__ # Python 2.6+
2308 except AttributeError:
2309 func_globals
= func
.func_globals
# Earlier versions.
2311 context
= args
[0].namespace
# variables to be injected
2312 saved_values
= func_globals
.copy() # Shallow copy of dict.
2313 log("globals before", context
.keys())
2314 func_globals
.update(context
)
2315 result
= func(*args
, **kwargs
)
2316 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2317 log("args[0]", args
[0].namespace
['CIA'],
2318 args
[0].namespace
['NIA'],
2319 args
[0].namespace
['SVSTATE'])
2320 if 'end_loop' in func_globals
:
2321 log("args[0] end_loop", func_globals
['end_loop'])
2322 args
[0].namespace
= func_globals
2323 #exec (func.__code__, func_globals)
2326 # func_globals = saved_values # Undo changes.
2332 return variable_injector