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')
69 # rrright. this is here basically because the compiler pywriter returns
70 # results in a specific priority order. to make sure regs match up they
71 # need partial sorting. sigh.
73 # TODO (lkcl): adjust other registers that should be in a particular order
74 # probably CA, CA32, and CR
100 "overflow": 7, # should definitely be last
104 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
107 def create_args(reglist
, extra
=None):
108 retval
= list(OrderedSet(reglist
))
109 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
110 if extra
is not None:
111 return [extra
] + retval
116 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
119 self
.isacaller
= isacaller
120 self
.svstate
= svstate
121 for i
in range(len(regfile
)):
122 self
[i
] = SelectableInt(regfile
[i
], 64)
124 def __call__(self
, ridx
):
125 if isinstance(ridx
, SelectableInt
):
129 def set_form(self
, form
):
132 def __setitem__(self
, rnum
, value
):
133 # rnum = rnum.value # only SelectableInt allowed
134 log("GPR setitem", rnum
, value
)
135 if isinstance(rnum
, SelectableInt
):
137 dict.__setitem
__(self
, rnum
, value
)
139 def getz(self
, rnum
):
140 # rnum = rnum.value # only SelectableInt allowed
141 log("GPR getzero?", rnum
)
143 return SelectableInt(0, 64)
146 def _get_regnum(self
, attr
):
147 getform
= self
.sd
.sigforms
[self
.form
]
148 rnum
= getattr(getform
, attr
)
151 def ___getitem__(self
, attr
):
152 """ XXX currently not used
154 rnum
= self
._get
_regnum
(attr
)
155 log("GPR getitem", attr
, rnum
)
156 return self
.regfile
[rnum
]
158 def dump(self
, printout
=True):
160 for i
in range(len(self
)):
161 res
.append(self
[i
].value
)
163 for i
in range(0, len(res
), 8):
166 s
.append("%08x" % res
[i
+j
])
168 print("reg", "%2d" % i
, s
)
173 def __init__(self
, dec2
, initial_sprs
={}):
176 for key
, v
in initial_sprs
.items():
177 if isinstance(key
, SelectableInt
):
179 key
= special_sprs
.get(key
, key
)
180 if isinstance(key
, int):
183 info
= spr_byname
[key
]
184 if not isinstance(v
, SelectableInt
):
185 v
= SelectableInt(v
, info
.length
)
188 def __getitem__(self
, key
):
190 log("dict", self
.items())
191 # if key in special_sprs get the special spr, otherwise return key
192 if isinstance(key
, SelectableInt
):
194 if isinstance(key
, int):
195 key
= spr_dict
[key
].SPR
196 key
= special_sprs
.get(key
, key
)
197 if key
== 'HSRR0': # HACK!
199 if key
== 'HSRR1': # HACK!
202 res
= dict.__getitem
__(self
, key
)
204 if isinstance(key
, int):
207 info
= spr_byname
[key
]
208 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
209 res
= dict.__getitem
__(self
, key
)
210 log("spr returning", key
, res
)
213 def __setitem__(self
, key
, value
):
214 if isinstance(key
, SelectableInt
):
216 if isinstance(key
, int):
217 key
= spr_dict
[key
].SPR
219 key
= special_sprs
.get(key
, key
)
220 if key
== 'HSRR0': # HACK!
221 self
.__setitem
__('SRR0', value
)
222 if key
== 'HSRR1': # HACK!
223 self
.__setitem
__('SRR1', value
)
224 log("setting spr", key
, value
)
225 dict.__setitem
__(self
, key
, value
)
227 def __call__(self
, ridx
):
230 def dump(self
, printout
=True):
232 keys
= list(self
.keys())
235 sprname
= spr_dict
.get(k
, None)
239 sprname
= sprname
.SPR
240 res
.append((sprname
, self
[k
].value
))
242 for sprname
, value
in res
:
243 print(" ", sprname
, hex(value
))
248 def __init__(self
, pc_init
=0):
249 self
.CIA
= SelectableInt(pc_init
, 64)
250 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
252 def update_nia(self
, is_svp64
):
253 increment
= 8 if is_svp64
else 4
254 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
256 def update(self
, namespace
, is_svp64
):
257 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
259 self
.CIA
= namespace
['NIA'].narrow(64)
260 self
.update_nia(is_svp64
)
261 namespace
['CIA'] = self
.CIA
262 namespace
['NIA'] = self
.NIA
266 # See PowerISA Version 3.0 B Book 1
267 # Section 2.3.1 Condition Register pages 30 - 31
269 LT
= FL
= 0 # negative, less than, floating-point less than
270 GT
= FG
= 1 # positive, greater than, floating-point greater than
271 EQ
= FE
= 2 # equal, floating-point equal
272 SO
= FU
= 3 # summary overflow, floating-point unordered
274 def __init__(self
, init
=0):
275 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
276 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
277 self
.cr
= SelectableInt(init
, 64) # underlying reg
278 # field-selectable versions of Condition Register TODO check bitranges?
281 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
282 _cr
= FieldSelectableInt(self
.cr
, bits
)
285 # decode SVP64 predicate integer to reg number and invert
288 def get_predint(gpr
, mask
):
291 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
292 if mask
== SVP64PredInt
.ALWAYS
.value
:
293 return 0xffff_ffff_ffff_ffff # 64 bits of 1
294 if mask
== SVP64PredInt
.R3_UNARY
.value
:
295 return 1 << (gpr(3).value
& 0b111111)
296 if mask
== SVP64PredInt
.R3
.value
:
298 if mask
== SVP64PredInt
.R3_N
.value
:
300 if mask
== SVP64PredInt
.R10
.value
:
302 if mask
== SVP64PredInt
.R10_N
.value
:
303 return ~
gpr(10).value
304 if mask
== SVP64PredInt
.R30
.value
:
306 if mask
== SVP64PredInt
.R30_N
.value
:
307 return ~
gpr(30).value
309 # decode SVP64 predicate CR to reg number and invert status
312 def _get_predcr(mask
):
313 if mask
== SVP64PredCR
.LT
.value
:
315 if mask
== SVP64PredCR
.GE
.value
:
317 if mask
== SVP64PredCR
.GT
.value
:
319 if mask
== SVP64PredCR
.LE
.value
:
321 if mask
== SVP64PredCR
.EQ
.value
:
323 if mask
== SVP64PredCR
.NE
.value
:
325 if mask
== SVP64PredCR
.SO
.value
:
327 if mask
== SVP64PredCR
.NS
.value
:
330 # read individual CR fields (0..VL-1), extract the required bit
331 # and construct the mask
334 def get_predcr(crl
, mask
, vl
):
335 idx
, noninv
= _get_predcr(mask
)
338 cr
= crl
[i
+SVP64CROffs
.CRPred
]
339 if cr
[idx
].value
== noninv
:
344 # TODO, really should just be using PowerDecoder2
345 def get_pdecode_idx_in(dec2
, name
):
347 in1_sel
= yield op
.in1_sel
348 in2_sel
= yield op
.in2_sel
349 in3_sel
= yield op
.in3_sel
350 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
351 in1
= yield dec2
.e
.read_reg1
.data
352 in2
= yield dec2
.e
.read_reg2
.data
353 in3
= yield dec2
.e
.read_reg3
.data
354 in1_isvec
= yield dec2
.in1_isvec
355 in2_isvec
= yield dec2
.in2_isvec
356 in3_isvec
= yield dec2
.in3_isvec
357 log("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
359 log("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
361 log("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
363 log("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
365 log("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
367 log("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
369 # identify which regnames map to in1/2/3
370 if name
== 'RA' or name
== 'RA_OR_ZERO':
371 if (in1_sel
== In1Sel
.RA
.value
or
372 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
373 return in1
, in1_isvec
374 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
375 return in1
, in1_isvec
377 if in2_sel
== In2Sel
.RB
.value
:
378 return in2
, in2_isvec
379 if in3_sel
== In3Sel
.RB
.value
:
380 return in3
, in3_isvec
381 # XXX TODO, RC doesn't exist yet!
383 if in3_sel
== In3Sel
.RC
.value
:
384 return in3
, in3_isvec
385 assert False, "RC does not exist yet"
387 if in1_sel
== In1Sel
.RS
.value
:
388 return in1
, in1_isvec
389 if in2_sel
== In2Sel
.RS
.value
:
390 return in2
, in2_isvec
391 if in3_sel
== In3Sel
.RS
.value
:
392 return in3
, in3_isvec
394 if in1_sel
== In1Sel
.FRA
.value
:
395 return in1
, in1_isvec
397 if in2_sel
== In2Sel
.FRB
.value
:
398 return in2
, in2_isvec
400 if in3_sel
== In3Sel
.FRC
.value
:
401 return in3
, in3_isvec
403 if in1_sel
== In1Sel
.FRS
.value
:
404 return in1
, in1_isvec
405 if in3_sel
== In3Sel
.FRS
.value
:
406 return in3
, in3_isvec
410 # TODO, really should just be using PowerDecoder2
411 def get_pdecode_cr_in(dec2
, name
):
413 in_sel
= yield op
.cr_in
414 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
415 sv_cr_in
= yield op
.sv_cr_in
416 spec
= yield dec2
.crin_svdec
.spec
417 sv_override
= yield dec2
.dec_cr_in
.sv_override
418 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
419 in1
= yield dec2
.e
.read_cr1
.data
420 cr_isvec
= yield dec2
.cr_in_isvec
421 log("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
422 log(" sv_cr_in", sv_cr_in
)
423 log(" cr_bf", in_bitfield
)
425 log(" override", sv_override
)
426 # identify which regnames map to in / o2
428 if in_sel
== CRInSel
.BI
.value
:
430 log("get_pdecode_cr_in not found", name
)
434 # TODO, really should just be using PowerDecoder2
435 def get_pdecode_cr_out(dec2
, name
):
437 out_sel
= yield op
.cr_out
438 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
439 sv_cr_out
= yield op
.sv_cr_out
440 spec
= yield dec2
.crout_svdec
.spec
441 sv_override
= yield dec2
.dec_cr_out
.sv_override
442 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
443 out
= yield dec2
.e
.write_cr
.data
444 o_isvec
= yield dec2
.o_isvec
445 log("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
446 log(" sv_cr_out", sv_cr_out
)
447 log(" cr_bf", out_bitfield
)
449 log(" override", sv_override
)
450 # identify which regnames map to out / o2
452 if out_sel
== CROutSel
.CR0
.value
:
454 if name
== 'CR1': # these are not actually calculated correctly
455 if out_sel
== CROutSel
.CR1
.value
:
457 log("get_pdecode_cr_out not found", name
)
461 # TODO, really should just be using PowerDecoder2
462 def get_pdecode_idx_out(dec2
, name
):
464 out_sel
= yield op
.out_sel
465 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
466 out
= yield dec2
.e
.write_reg
.data
467 o_isvec
= yield dec2
.o_isvec
468 # identify which regnames map to out / o2
470 log("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
471 if out_sel
== OutSel
.RA
.value
:
474 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
475 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
477 if out_sel
== OutSel
.RT
.value
:
479 if out_sel
== OutSel
.RT_OR_ZERO
.value
and out
!= 0:
481 elif name
== 'RT_OR_ZERO':
482 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
483 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
485 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
488 log("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
489 if out_sel
== OutSel
.FRA
.value
:
492 log("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
493 OutSel
.FRT
.value
, out
, o_isvec
)
494 if out_sel
== OutSel
.FRT
.value
:
496 log("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
500 # TODO, really should just be using PowerDecoder2
501 def get_pdecode_idx_out2(dec2
, name
):
502 # check first if register is activated for write
504 out_sel
= yield op
.out_sel
505 out
= yield dec2
.e
.write_ea
.data
506 o_isvec
= yield dec2
.o2_isvec
507 out_ok
= yield dec2
.e
.write_ea
.ok
508 log("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
513 if hasattr(op
, "upd"):
514 # update mode LD/ST uses read-reg A also as an output
516 log("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
517 out_sel
, OutSel
.RA
.value
,
519 if upd
== LDSTMode
.update
.value
:
522 fft_en
= yield dec2
.implicit_rs
524 log("get_pdecode_idx_out2", out_sel
, OutSel
.RS
.value
,
528 fft_en
= yield dec2
.implicit_rs
530 log("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
537 """deals with svstate looping.
540 def __init__(self
, svstate
):
541 self
.svstate
= svstate
544 def new_iterators(self
):
545 self
.src_it
= self
.src_iterator()
546 self
.dst_it
= self
.dst_iterator()
550 self
.new_ssubstep
= 0
551 self
.new_dsubstep
= 0
552 self
.pred_dst_zero
= 0
553 self
.pred_src_zero
= 0
555 def src_iterator(self
):
556 """source-stepping iterator
558 pack
= self
.svstate
.pack
562 # pack advances subvl in *outer* loop
563 while True: # outer subvl loop
564 while True: # inner vl loop
566 srcmask
= self
.srcmask
567 srcstep
= self
.svstate
.srcstep
568 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
569 if self
.pred_sz
or pred_src_zero
:
570 self
.pred_src_zero
= not pred_src_zero
571 log(" advance src", srcstep
, self
.svstate
.vl
,
572 self
.svstate
.ssubstep
, subvl
)
573 # yield actual substep/srcstep
574 yield (self
.svstate
.ssubstep
, srcstep
)
577 srcstep
= self
.svstate
.srcstep
578 log(" advance src check", srcstep
, vl
,
579 self
.svstate
.ssubstep
, subvl
, srcstep
== vl
-1,
580 self
.svstate
.ssubstep
== subvl
)
581 if srcstep
== vl
-1: # end-point
582 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
583 if self
.svstate
.ssubstep
== subvl
: # end-point
584 log(" advance pack stop")
586 break # exit inner loop
587 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance ss
589 if self
.svstate
.ssubstep
== subvl
: # end-point
590 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
591 log(" advance pack stop")
593 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
596 # these cannot be done as for-loops because SVSTATE may change
597 # (srcstep/substep may be modified, interrupted, subvl/vl change)
598 # but they *can* be done as while-loops as long as every SVSTATE
599 # "thing" is re-read every single time a yield gives indices
600 while True: # outer vl loop
601 while True: # inner subvl loop
603 srcmask
= self
.srcmask
604 srcstep
= self
.svstate
.srcstep
605 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
606 if self
.pred_sz
or pred_src_zero
:
607 self
.pred_src_zero
= not pred_src_zero
608 log(" advance src", srcstep
, self
.svstate
.vl
,
609 self
.svstate
.ssubstep
, subvl
)
610 # yield actual substep/srcstep
611 yield (self
.svstate
.ssubstep
, srcstep
)
612 if self
.svstate
.ssubstep
== subvl
: # end-point
613 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
614 break # exit inner loop
615 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
617 if srcstep
== vl
-1: # end-point
618 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
621 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
623 def dst_iterator(self
):
624 """dest-stepping iterator
626 unpack
= self
.svstate
.unpack
630 # pack advances subvl in *outer* loop
631 while True: # outer subvl loop
632 while True: # inner vl loop
634 dstmask
= self
.dstmask
635 dststep
= self
.svstate
.dststep
636 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
637 if self
.pred_dz
or pred_dst_zero
:
638 self
.pred_dst_zero
= not pred_dst_zero
639 log(" advance dst", dststep
, self
.svstate
.vl
,
640 self
.svstate
.dsubstep
, subvl
)
641 # yield actual substep/dststep
642 yield (self
.svstate
.dsubstep
, dststep
)
644 dststep
= self
.svstate
.dststep
645 log(" advance dst check", dststep
, self
.svstate
.vl
,
646 self
.svstate
.ssubstep
, subvl
)
647 if dststep
== vl
-1: # end-point
648 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
649 if self
.svstate
.dsubstep
== subvl
: # end-point
650 log(" advance unpack stop")
653 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance ds
655 if self
.svstate
.dsubstep
== subvl
: # end-point
656 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
657 log(" advance unpack stop")
659 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
661 # these cannot be done as for-loops because SVSTATE may change
662 # (dststep/substep may be modified, interrupted, subvl/vl change)
663 # but they *can* be done as while-loops as long as every SVSTATE
664 # "thing" is re-read every single time a yield gives indices
665 while True: # outer vl loop
666 while True: # inner subvl loop
668 dstmask
= self
.dstmask
669 dststep
= self
.svstate
.dststep
670 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
671 if self
.pred_dz
or pred_dst_zero
:
672 self
.pred_dst_zero
= not pred_dst_zero
673 log(" advance dst", dststep
, self
.svstate
.vl
,
674 self
.svstate
.dsubstep
, subvl
)
675 # yield actual substep/dststep
676 yield (self
.svstate
.dsubstep
, dststep
)
677 if self
.svstate
.dsubstep
== subvl
: # end-point
678 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
680 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
683 if dststep
== vl
-1: # end-point
684 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
686 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
688 def src_iterate(self
):
689 """source-stepping iterator
693 pack
= self
.svstate
.pack
694 unpack
= self
.svstate
.unpack
695 ssubstep
= self
.svstate
.ssubstep
696 end_ssub
= ssubstep
== subvl
697 end_src
= self
.svstate
.srcstep
== vl
-1
698 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
702 srcstep
= self
.svstate
.srcstep
703 srcmask
= self
.srcmask
705 # pack advances subvl in *outer* loop
707 assert srcstep
<= vl
-1
708 end_src
= srcstep
== vl
-1
713 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
717 srcstep
+= 1 # advance srcstep
718 if not self
.srcstep_skip
:
720 if ((1 << srcstep
) & srcmask
) != 0:
723 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
725 # advance subvl in *inner* loop
728 assert srcstep
<= vl
-1
729 end_src
= srcstep
== vl
-1
730 if end_src
: # end-point
735 if not self
.srcstep_skip
:
737 if ((1 << srcstep
) & srcmask
) != 0:
740 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
741 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
744 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
746 self
.svstate
.srcstep
= SelectableInt(srcstep
, 7)
747 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
750 def dst_iterate(self
):
751 """dest step iterator
755 pack
= self
.svstate
.pack
756 unpack
= self
.svstate
.unpack
757 dsubstep
= self
.svstate
.dsubstep
758 end_dsub
= dsubstep
== subvl
759 dststep
= self
.svstate
.dststep
760 end_dst
= dststep
== vl
-1
761 dstmask
= self
.dstmask
762 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
767 # unpack advances subvl in *outer* loop
769 assert dststep
<= vl
-1
770 end_dst
= dststep
== vl
-1
775 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
779 dststep
+= 1 # advance dststep
780 if not self
.dststep_skip
:
782 if ((1 << dststep
) & dstmask
) != 0:
785 log(" dskip", bin(dstmask
), bin(1 << dststep
))
787 # advance subvl in *inner* loop
790 assert dststep
<= vl
-1
791 end_dst
= dststep
== vl
-1
792 if end_dst
: # end-point
797 if not self
.dststep_skip
:
799 if ((1 << dststep
) & dstmask
) != 0:
802 log(" dskip", bin(dstmask
), bin(1 << dststep
))
803 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
806 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
808 self
.svstate
.dststep
= SelectableInt(dststep
, 7)
809 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
812 def at_loopend(self
):
813 """tells if this is the last possible element. uses the cached values
814 for src/dst-step and sub-steps
818 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
819 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
820 end_ssub
= ssubstep
== subvl
821 end_dsub
= dsubstep
== subvl
822 if srcstep
== vl
-1 and end_ssub
:
824 if dststep
== vl
-1 and end_dsub
:
828 def advance_svstate_steps(self
):
829 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
830 TODO when Pack/Unpack is set, substep becomes the *outer* loop
832 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
833 if self
.loopend
: # huhn??
838 def read_src_mask(self
):
839 """read/update pred_sz and src mask
841 # get SVSTATE VL (oh and print out some debug stuff)
843 srcstep
= self
.svstate
.srcstep
844 ssubstep
= self
.svstate
.ssubstep
846 # get predicate mask (all 64 bits)
847 srcmask
= 0xffff_ffff_ffff_ffff
849 pmode
= yield self
.dec2
.rm_dec
.predmode
850 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
851 srcpred
= yield self
.dec2
.rm_dec
.srcpred
852 dstpred
= yield self
.dec2
.rm_dec
.dstpred
853 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
854 if pmode
== SVP64PredMode
.INT
.value
:
855 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
856 if sv_ptype
== SVPtype
.P2
.value
:
857 srcmask
= get_predint(self
.gpr
, srcpred
)
858 elif pmode
== SVP64PredMode
.CR
.value
:
859 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
860 if sv_ptype
== SVPtype
.P2
.value
:
861 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
862 # work out if the ssubsteps are completed
863 ssubstart
= ssubstep
== 0
865 log(" ptype", sv_ptype
)
866 log(" srcpred", bin(srcpred
))
867 log(" srcmask", bin(srcmask
))
868 log(" pred_sz", bin(pred_sz
))
869 log(" ssubstart", ssubstart
)
871 # store all that above
872 self
.srcstep_skip
= False
873 self
.srcmask
= srcmask
874 self
.pred_sz
= pred_sz
875 self
.new_ssubstep
= ssubstep
876 log(" new ssubstep", ssubstep
)
877 # until the predicate mask has a "1" bit... or we run out of VL
878 # let srcstep==VL be the indicator to move to next instruction
880 self
.srcstep_skip
= True
882 def read_dst_mask(self
):
883 """same as read_src_mask - check and record everything needed
885 # get SVSTATE VL (oh and print out some debug stuff)
886 # yield Delay(1e-10) # make changes visible
888 dststep
= self
.svstate
.dststep
889 dsubstep
= self
.svstate
.dsubstep
891 # get predicate mask (all 64 bits)
892 dstmask
= 0xffff_ffff_ffff_ffff
894 pmode
= yield self
.dec2
.rm_dec
.predmode
895 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
896 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
897 dstpred
= yield self
.dec2
.rm_dec
.dstpred
898 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
899 if pmode
== SVP64PredMode
.INT
.value
:
900 dstmask
= get_predint(self
.gpr
, dstpred
)
901 elif pmode
== SVP64PredMode
.CR
.value
:
902 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
903 # work out if the ssubsteps are completed
904 dsubstart
= dsubstep
== 0
906 log(" ptype", sv_ptype
)
907 log(" dstpred", bin(dstpred
))
908 log(" dstmask", bin(dstmask
))
909 log(" pred_dz", bin(pred_dz
))
910 log(" dsubstart", dsubstart
)
912 self
.dststep_skip
= False
913 self
.dstmask
= dstmask
914 self
.pred_dz
= pred_dz
915 self
.new_dsubstep
= dsubstep
916 log(" new dsubstep", dsubstep
)
918 self
.dststep_skip
= True
920 def svstate_pre_inc(self
):
921 """check if srcstep/dststep need to skip over masked-out predicate bits
922 note that this is not supposed to do anything to substep,
923 it is purely for skipping masked-out bits
926 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
927 yield from self
.read_src_mask()
928 yield from self
.read_dst_mask()
935 srcstep
= self
.svstate
.srcstep
936 srcmask
= self
.srcmask
937 pred_src_zero
= self
.pred_sz
939 # srcstep-skipping opportunity identified
940 if self
.srcstep_skip
:
941 # cannot do this with sv.bc - XXX TODO
944 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
945 log(" sskip", bin(1 << srcstep
))
948 # now work out if the relevant mask bits require zeroing
950 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
952 # store new srcstep / dststep
953 self
.new_srcstep
= srcstep
954 self
.pred_src_zero
= pred_src_zero
955 log(" new srcstep", srcstep
)
958 # dststep-skipping opportunity identified
959 dststep
= self
.svstate
.dststep
960 dstmask
= self
.dstmask
961 pred_dst_zero
= self
.pred_dz
963 if self
.dststep_skip
:
964 # cannot do this with sv.bc - XXX TODO
967 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
968 log(" dskip", bin(1 << dststep
))
971 # now work out if the relevant mask bits require zeroing
973 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
975 # store new srcstep / dststep
976 self
.new_dststep
= dststep
977 self
.pred_dst_zero
= pred_dst_zero
978 log(" new dststep", dststep
)
981 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
982 # decoder2 - an instance of power_decoder2
983 # regfile - a list of initial values for the registers
984 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
985 # respect_pc - tracks the program counter. requires initial_insns
986 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
987 initial_mem
=None, initial_msr
=0,
998 self
.bigendian
= bigendian
1000 self
.is_svp64_mode
= False
1001 self
.respect_pc
= respect_pc
1002 if initial_sprs
is None:
1004 if initial_mem
is None:
1006 if fpregfile
is None:
1007 fpregfile
= [0] * 32
1008 if initial_insns
is None:
1010 assert self
.respect_pc
== False, "instructions required to honor pc"
1012 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
1013 log("ISACaller initial_msr", initial_msr
)
1015 # "fake program counter" mode (for unit testing)
1019 if isinstance(initial_mem
, tuple):
1020 self
.fake_pc
= initial_mem
[0]
1021 disasm_start
= self
.fake_pc
1023 disasm_start
= initial_pc
1025 # disassembly: we need this for now (not given from the decoder)
1026 self
.disassembly
= {}
1028 for i
, code
in enumerate(disassembly
):
1029 self
.disassembly
[i
*4 + disasm_start
] = code
1031 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
1032 self
.svp64rm
= SVP64RM()
1033 if initial_svstate
is None:
1035 if isinstance(initial_svstate
, int):
1036 initial_svstate
= SVP64State(initial_svstate
)
1037 # SVSTATE, MSR and PC
1038 StepLoop
.__init
__(self
, initial_svstate
)
1039 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
1041 # GPR FPR SPR registers
1042 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
1043 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
1044 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
1045 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
1047 # set up 4 dummy SVSHAPEs if they aren't already set up
1049 sname
= 'SVSHAPE%d' % i
1050 if sname
not in self
.spr
:
1053 val
= self
.spr
[sname
].value
1054 # make sure it's an SVSHAPE
1055 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
1056 self
.last_op_svshape
= False
1059 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
1060 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
1061 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
1062 # MMU mode, redirect underlying Mem through RADIX
1064 self
.mem
= RADIX(self
.mem
, self
)
1066 self
.imem
= RADIX(self
.imem
, self
)
1068 # TODO, needed here:
1069 # FPR (same as GPR except for FP nums)
1070 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1071 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1072 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1073 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1075 # 2.3.2 LR (actually SPR #8) -- Done
1076 # 2.3.3 CTR (actually SPR #9) -- Done
1077 # 2.3.4 TAR (actually SPR #815)
1078 # 3.2.2 p45 XER (actually SPR #1) -- Done
1079 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1081 # create CR then allow portions of it to be "selectable" (below)
1082 self
.cr_fields
= CRFields(initial_cr
)
1083 self
.cr
= self
.cr_fields
.cr
1085 # "undefined", just set to variable-bit-width int (use exts "max")
1086 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
1089 self
.namespace
.update(self
.spr
)
1090 self
.namespace
.update({'GPR': self
.gpr
,
1094 'memassign': self
.memassign
,
1097 'SVSTATE': self
.svstate
,
1098 'SVSHAPE0': self
.spr
['SVSHAPE0'],
1099 'SVSHAPE1': self
.spr
['SVSHAPE1'],
1100 'SVSHAPE2': self
.spr
['SVSHAPE2'],
1101 'SVSHAPE3': self
.spr
['SVSHAPE3'],
1104 'undefined': undefined
,
1105 'mode_is_64bit': True,
1106 'SO': XER_bits
['SO'],
1107 'XLEN': 64 # elwidth overrides, later
1110 # update pc to requested start point
1111 self
.set_pc(initial_pc
)
1113 # field-selectable versions of Condition Register
1114 self
.crl
= self
.cr_fields
.crl
1116 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
1118 self
.decoder
= decoder2
.dec
1119 self
.dec2
= decoder2
1121 super().__init
__(XLEN
=self
.namespace
["XLEN"])
1125 return self
.namespace
["XLEN"]
1127 def call_trap(self
, trap_addr
, trap_bit
):
1128 """calls TRAP and sets up NIA to the new execution location.
1129 next instruction will begin at trap_addr.
1131 self
.TRAP(trap_addr
, trap_bit
)
1132 self
.namespace
['NIA'] = self
.trap_nia
1133 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1135 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1136 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1138 TRAP function is callable from inside the pseudocode itself,
1139 hence the default arguments. when calling from inside ISACaller
1140 it is best to use call_trap()
1142 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1143 kaivb
= self
.spr
['KAIVB'].value
1144 msr
= self
.namespace
['MSR'].value
1145 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1146 # store CIA(+4?) in SRR0, set NIA to 0x700
1147 # store MSR in SRR1, set MSR to um errr something, have to check spec
1148 # store SVSTATE (if enabled) in SVSRR0
1149 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1150 self
.spr
['SRR1'].value
= msr
1151 if self
.is_svp64_mode
:
1152 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1153 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1154 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1156 # set exception bits. TODO: this should, based on the address
1157 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1158 # bits appropriately. however it turns out that *for now* in all
1159 # cases (all trap_addrs) the exact same thing is needed.
1160 self
.msr
[MSRb
.IR
] = 0
1161 self
.msr
[MSRb
.DR
] = 0
1162 self
.msr
[MSRb
.FE0
] = 0
1163 self
.msr
[MSRb
.FE1
] = 0
1164 self
.msr
[MSRb
.EE
] = 0
1165 self
.msr
[MSRb
.RI
] = 0
1166 self
.msr
[MSRb
.SF
] = 1
1167 self
.msr
[MSRb
.TM
] = 0
1168 self
.msr
[MSRb
.VEC
] = 0
1169 self
.msr
[MSRb
.VSX
] = 0
1170 self
.msr
[MSRb
.PR
] = 0
1171 self
.msr
[MSRb
.FP
] = 0
1172 self
.msr
[MSRb
.PMM
] = 0
1173 self
.msr
[MSRb
.TEs
] = 0
1174 self
.msr
[MSRb
.TEe
] = 0
1175 self
.msr
[MSRb
.UND
] = 0
1176 self
.msr
[MSRb
.LE
] = 1
1178 def memassign(self
, ea
, sz
, val
):
1179 self
.mem
.memassign(ea
, sz
, val
)
1181 def prep_namespace(self
, insn_name
, formname
, op_fields
):
1182 # TODO: get field names from form in decoder*1* (not decoder2)
1183 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1185 # then "yield" fields only from op_fields rather than hard-coded
1187 fields
= self
.decoder
.sigforms
[formname
]
1188 log("prep_namespace", formname
, op_fields
, insn_name
)
1189 for name
in op_fields
:
1190 # CR immediates. deal with separately. needs modifying
1192 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1193 # BI is a 5-bit, must reconstruct the value
1194 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
1195 sig
= getattr(fields
, name
)
1197 # low 2 LSBs (CR field selector) remain same, CR num extended
1198 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1199 val
= (val
& 0b11) |
(regnum
<< 2)
1201 sig
= getattr(fields
, name
)
1203 # these are all opcode fields involved in index-selection of CR,
1204 # and need to do "standard" arithmetic. CR[BA+32] for example
1205 # would, if using SelectableInt, only be 5-bit.
1206 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1207 self
.namespace
[name
] = val
1209 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1211 self
.namespace
['XER'] = self
.spr
['XER']
1212 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1213 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1215 # add some SVSTATE convenience variables
1216 vl
= self
.svstate
.vl
1217 srcstep
= self
.svstate
.srcstep
1218 self
.namespace
['VL'] = vl
1219 self
.namespace
['srcstep'] = srcstep
1221 # sv.bc* need some extra fields
1222 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1223 # blegh grab bits manually
1224 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1225 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
1226 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
1227 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
1228 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1229 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1230 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1231 sz
= yield self
.dec2
.rm_dec
.pred_sz
1232 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1233 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1234 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1235 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1236 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1237 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1238 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1240 def handle_carry_(self
, inputs
, outputs
, already_done
):
1241 inv_a
= yield self
.dec2
.e
.do
.invert_in
1243 inputs
[0] = ~inputs
[0]
1245 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1247 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1248 inputs
.append(SelectableInt(imm
, 64))
1249 assert len(outputs
) >= 1
1250 log("outputs", repr(outputs
))
1251 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
1257 log("gt input", x
, output
)
1258 gt
= (gtu(x
, output
))
1261 cy
= 1 if any(gts
) else 0
1263 if not (1 & already_done
):
1264 self
.spr
['XER'][XER_bits
['CA']] = cy
1266 log("inputs", already_done
, inputs
)
1268 # ARGH... different for OP_ADD... *sigh*...
1269 op
= yield self
.dec2
.e
.do
.insn_type
1270 if op
== MicrOp
.OP_ADD
.value
:
1271 res32
= (output
.value
& (1 << 32)) != 0
1272 a32
= (inputs
[0].value
& (1 << 32)) != 0
1273 if len(inputs
) >= 2:
1274 b32
= (inputs
[1].value
& (1 << 32)) != 0
1277 cy32
= res32 ^ a32 ^ b32
1278 log("CA32 ADD", cy32
)
1282 log("input", x
, output
)
1283 log(" x[32:64]", x
, x
[32:64])
1284 log(" o[32:64]", output
, output
[32:64])
1285 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1287 cy32
= 1 if any(gts
) else 0
1288 log("CA32", cy32
, gts
)
1289 if not (2 & already_done
):
1290 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1292 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
1293 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1294 inv_a
= yield self
.dec2
.e
.do
.invert_in
1296 inputs
[0] = ~inputs
[0]
1298 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1300 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1301 inputs
.append(SelectableInt(imm
, 64))
1302 assert len(outputs
) >= 1
1303 log("handle_overflow", inputs
, outputs
, div_overflow
)
1304 if len(inputs
) < 2 and div_overflow
is None:
1307 # div overflow is different: it's returned by the pseudo-code
1308 # because it's more complex than can be done by analysing the output
1309 if div_overflow
is not None:
1310 ov
, ov32
= div_overflow
, div_overflow
1311 # arithmetic overflow can be done by analysing the input and output
1312 elif len(inputs
) >= 2:
1316 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1317 output_sgn
= exts(output
.value
, output
.bits
) < 0
1318 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1319 output_sgn
!= input_sgn
[0] else 0
1322 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1323 output32_sgn
= exts(output
.value
, 32) < 0
1324 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1325 output32_sgn
!= input32_sgn
[0] else 0
1327 # now update XER OV/OV32/SO
1328 so
= self
.spr
['XER'][XER_bits
['SO']]
1329 new_so
= so | ov
# sticky overflow ORs in old with new
1330 self
.spr
['XER'][XER_bits
['OV']] = ov
1331 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1332 self
.spr
['XER'][XER_bits
['SO']] = new_so
1333 log(" set overflow", ov
, ov32
, so
, new_so
)
1335 def handle_comparison(self
, outputs
, cr_idx
=0, overflow
=None, no_so
=False):
1337 assert isinstance(out
, SelectableInt
), \
1338 "out zero not a SelectableInt %s" % repr(outputs
)
1339 log("handle_comparison", out
.bits
, hex(out
.value
))
1340 # TODO - XXX *processor* in 32-bit mode
1341 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1343 # o32 = exts(out.value, 32)
1344 # print ("handle_comparison exts 32 bit", hex(o32))
1345 out
= exts(out
.value
, out
.bits
)
1346 log("handle_comparison exts", hex(out
))
1347 # create the three main CR flags, EQ GT LT
1348 zero
= SelectableInt(out
== 0, 1)
1349 positive
= SelectableInt(out
> 0, 1)
1350 negative
= SelectableInt(out
< 0, 1)
1351 # get (or not) XER.SO. for setvl this is important *not* to read SO
1353 SO
= SelectableInt(1, 0)
1355 SO
= self
.spr
['XER'][XER_bits
['SO']]
1356 log("handle_comparison SO overflow", SO
, overflow
)
1357 # alternative overflow checking (setvl mainly at the moment)
1358 if overflow
is not None and overflow
== 1:
1359 SO
= SelectableInt(1, 1)
1360 # create the four CR field values and set the required CR field
1361 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1362 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1363 self
.crl
[cr_idx
].eq(cr_field
)
1365 def set_pc(self
, pc_val
):
1366 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1367 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1369 def get_next_insn(self
):
1370 """check instruction
1373 pc
= self
.pc
.CIA
.value
1376 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1378 raise KeyError("no instruction at 0x%x" % pc
)
1381 def setup_one(self
):
1382 """set up one instruction
1384 pc
, insn
= self
.get_next_insn()
1385 yield from self
.setup_next_insn(pc
, insn
)
1387 def setup_next_insn(self
, pc
, ins
):
1388 """set up next instruction
1391 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1392 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1394 yield self
.dec2
.sv_rm
.eq(0)
1395 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1396 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1397 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1398 yield self
.dec2
.state
.pc
.eq(pc
)
1399 if self
.svstate
is not None:
1400 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1402 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1404 opcode
= yield self
.dec2
.dec
.opcode_in
1405 opcode
= SelectableInt(value
=opcode
, bits
=32)
1406 pfx
= SVP64Instruction
.Prefix(opcode
)
1407 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1408 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1409 self
.pc
.update_nia(self
.is_svp64_mode
)
1411 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1412 self
.namespace
['NIA'] = self
.pc
.NIA
1413 self
.namespace
['SVSTATE'] = self
.svstate
1414 if not self
.is_svp64_mode
:
1417 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1418 log("svp64.rm", bin(pfx
.rm
))
1419 log(" svstate.vl", self
.svstate
.vl
)
1420 log(" svstate.mvl", self
.svstate
.maxvl
)
1421 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1422 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1423 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1424 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1427 def execute_one(self
):
1428 """execute one instruction
1430 # get the disassembly code for this instruction
1431 if self
.is_svp64_mode
:
1432 if not self
.disassembly
:
1433 code
= yield from self
.get_assembly_name()
1435 code
= self
.disassembly
[self
._pc
+4]
1436 log(" svp64 sim-execute", hex(self
._pc
), code
)
1438 if not self
.disassembly
:
1439 code
= yield from self
.get_assembly_name()
1441 code
= self
.disassembly
[self
._pc
]
1442 log("sim-execute", hex(self
._pc
), code
)
1443 opname
= code
.split(' ')[0]
1445 yield from self
.call(opname
) # execute the instruction
1446 except MemException
as e
: # check for memory errors
1447 if e
.args
[0] == 'unaligned': # alignment error
1448 # run a Trap but set DAR first
1449 print("memory unaligned exception, DAR", e
.dar
)
1450 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1451 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1453 elif e
.args
[0] == 'invalid': # invalid
1454 # run a Trap but set DAR first
1455 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1456 if e
.mode
== 'EXECUTE':
1457 # XXX TODO: must set a few bits in SRR1,
1458 # see microwatt loadstore1.vhdl
1459 # if m_in.segerr = '0' then
1460 # v.srr1(47 - 33) := m_in.invalid;
1461 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1462 # v.srr1(47 - 44) := m_in.badtree;
1463 # v.srr1(47 - 45) := m_in.rc_error;
1464 # v.intr_vec := 16#400#;
1466 # v.intr_vec := 16#480#;
1467 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1469 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1471 # not supported yet:
1472 raise e
# ... re-raise
1474 # don't use this except in special circumstances
1475 if not self
.respect_pc
:
1478 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1479 hex(self
.pc
.NIA
.value
))
1481 def get_assembly_name(self
):
1482 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1483 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1484 dec_insn
= yield self
.dec2
.e
.do
.insn
1485 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1486 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1487 int_op
= yield self
.dec2
.dec
.op
.internal_op
1488 log("get assembly name asmcode", asmcode
, int_op
,
1489 hex(dec_insn
), bin(insn_1_11
))
1490 asmop
= insns
.get(asmcode
, None)
1492 # sigh reconstruct the assembly instruction name
1493 if hasattr(self
.dec2
.e
.do
, "oe"):
1494 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1495 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1499 if hasattr(self
.dec2
.e
.do
, "rc"):
1500 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1501 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1505 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1506 RC1
= yield self
.dec2
.rm_dec
.RC1
1510 # grrrr have to special-case MUL op (see DecodeOE)
1511 log("ov %d en %d rc %d en %d op %d" %
1512 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1513 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1518 if not asmop
.endswith("."): # don't add "." to "andis."
1521 if hasattr(self
.dec2
.e
.do
, "lk"):
1522 lk
= yield self
.dec2
.e
.do
.lk
1525 log("int_op", int_op
)
1526 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1527 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1531 spr_msb
= yield from self
.get_spr_msb()
1532 if int_op
== MicrOp
.OP_MFCR
.value
:
1537 # XXX TODO: for whatever weird reason this doesn't work
1538 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1539 if int_op
== MicrOp
.OP_MTCRF
.value
:
1546 def reset_remaps(self
):
1547 self
.remap_loopends
= [0] * 4
1548 self
.remap_idxs
= [0, 1, 2, 3]
1550 def get_remap_indices(self
):
1551 """WARNING, this function stores remap_idxs and remap_loopends
1552 in the class for later use. this to avoid problems with yield
1554 # go through all iterators in lock-step, advance to next remap_idx
1555 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1556 # get four SVSHAPEs. here we are hard-coding
1558 SVSHAPE0
= self
.spr
['SVSHAPE0']
1559 SVSHAPE1
= self
.spr
['SVSHAPE1']
1560 SVSHAPE2
= self
.spr
['SVSHAPE2']
1561 SVSHAPE3
= self
.spr
['SVSHAPE3']
1562 # set up the iterators
1563 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1564 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1565 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1566 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1570 for i
, (shape
, remap
) in enumerate(remaps
):
1571 # zero is "disabled"
1572 if shape
.value
== 0x0:
1573 self
.remap_idxs
[i
] = 0
1574 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1575 step
= dststep
if (i
in [3, 4]) else srcstep
1576 # this is terrible. O(N^2) looking for the match. but hey.
1577 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1580 self
.remap_idxs
[i
] = remap_idx
1581 self
.remap_loopends
[i
] = loopends
1582 dbg
.append((i
, step
, remap_idx
, loopends
))
1583 for (i
, step
, remap_idx
, loopends
) in dbg
:
1584 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1587 def get_spr_msb(self
):
1588 dec_insn
= yield self
.dec2
.e
.do
.insn
1589 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1591 def call(self
, name
):
1592 """call(opcode) - the primary execution point for instructions
1594 self
.last_st_addr
= None # reset the last known store address
1595 self
.last_ld_addr
= None # etc.
1597 ins_name
= name
.strip() # remove spaces if not already done so
1599 log("halted - not executing", ins_name
)
1602 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1603 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1604 asmop
= yield from self
.get_assembly_name()
1605 log("call", ins_name
, asmop
)
1607 # sv.setvl is *not* a loop-function. sigh
1608 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1611 int_op
= yield self
.dec2
.dec
.op
.internal_op
1612 spr_msb
= yield from self
.get_spr_msb()
1614 instr_is_privileged
= False
1615 if int_op
in [MicrOp
.OP_ATTN
.value
,
1616 MicrOp
.OP_MFMSR
.value
,
1617 MicrOp
.OP_MTMSR
.value
,
1618 MicrOp
.OP_MTMSRD
.value
,
1620 MicrOp
.OP_RFID
.value
]:
1621 instr_is_privileged
= True
1622 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1623 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1624 instr_is_privileged
= True
1626 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1628 # check MSR priv bit and whether op is privileged: if so, throw trap
1629 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1630 self
.call_trap(0x700, PIb
.PRIV
)
1633 # check halted condition
1634 if ins_name
== 'attn':
1638 # check illegal instruction
1640 if ins_name
not in ['mtcrf', 'mtocrf']:
1641 illegal
= ins_name
!= asmop
1643 # list of instructions not being supported by binutils (.long)
1644 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1645 if dotstrp
in [*FPTRANS_INSNS
,
1646 'ffmadds', 'fdmadds', 'ffadds',
1647 'mins', 'maxs', 'minu', 'maxu',
1648 'setvl', 'svindex', 'svremap', 'svstep',
1649 'svshape', 'svshape2',
1650 'grev', 'ternlogi', 'bmask', 'cprop',
1651 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1652 'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
1658 # branch-conditional redirects to sv.bc
1659 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1660 ins_name
= 'sv.%s' % ins_name
1662 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1664 # illegal instructions call TRAP at 0x700
1666 print("illegal", ins_name
, asmop
)
1667 self
.call_trap(0x700, PIb
.ILLEG
)
1668 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1669 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1672 # this is for setvl "Vertical" mode: if set true,
1673 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1674 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1675 self
.allow_next_step_inc
= False
1676 self
.svstate_next_mode
= 0
1678 # nop has to be supported, we could let the actual op calculate
1679 # but PowerDecoder has a pattern for nop
1680 if ins_name
== 'nop':
1681 self
.update_pc_next()
1684 # look up instruction in ISA.instrs, prepare namespace
1685 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1686 info
= self
.instrs
[ins_name
+"."]
1688 info
= self
.instrs
[ins_name
]
1689 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1691 # preserve order of register names
1692 input_names
= create_args(list(info
.read_regs
) +
1693 list(info
.uninit_regs
))
1694 log("input names", input_names
)
1696 # get SVP64 entry for the current instruction
1697 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1698 if sv_rm
is not None:
1699 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1701 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1702 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1704 # see if srcstep/dststep need skipping over masked-out predicate bits
1706 if (self
.is_svp64_mode
or ins_name
in ['setvl', 'svremap', 'svstate']):
1707 yield from self
.svstate_pre_inc()
1708 if self
.is_svp64_mode
:
1709 pre
= yield from self
.update_new_svstate_steps()
1711 self
.svp64_reset_loop()
1713 self
.update_pc_next()
1715 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1716 pred_dst_zero
= self
.pred_dst_zero
1717 pred_src_zero
= self
.pred_src_zero
1718 vl
= self
.svstate
.vl
1719 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1721 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1722 if self
.is_svp64_mode
and vl
== 0:
1723 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1724 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1725 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1728 # for when SVREMAP is active, using pre-arranged schedule.
1729 # note: modifying PowerDecoder2 needs to "settle"
1730 remap_en
= self
.svstate
.SVme
1731 persist
= self
.svstate
.RMpst
1732 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1733 if self
.is_svp64_mode
:
1734 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1736 if persist
or self
.last_op_svshape
:
1737 remaps
= self
.get_remap_indices()
1738 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1739 yield from self
.remap_set_steps(remaps
)
1740 # after that, settle down (combinatorial) to let Vector reg numbers
1741 # work themselves out
1743 if self
.is_svp64_mode
:
1744 remap_active
= yield self
.dec2
.remap_active
1746 remap_active
= False
1747 log("remap active", bin(remap_active
))
1749 # main input registers (RT, RA ...)
1751 for name
in input_names
:
1753 regval
= (yield from self
.get_input(name
))
1754 log("regval", regval
)
1755 inputs
.append(regval
)
1757 # arrrrgh, awful hack, to get _RT into namespace
1758 if ins_name
in ['setvl', 'svstep']:
1760 RT
= yield self
.dec2
.dec
.RT
1761 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1763 self
.namespace
["RT"] = SelectableInt(0, 5)
1764 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1765 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1767 # in SVP64 mode for LD/ST work out immediate
1768 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1769 # use info.form to detect
1770 if self
.is_svp64_mode
:
1771 yield from self
.check_replace_d(info
, remap_active
)
1773 # "special" registers
1774 for special
in info
.special_regs
:
1775 if special
in special_sprs
:
1776 inputs
.append(self
.spr
[special
])
1778 inputs
.append(self
.namespace
[special
])
1780 # clear trap (trap) NIA
1781 self
.trap_nia
= None
1783 # check if this was an sv.bc* and create an indicator that
1784 # this is the last check to be made as a loop. combined with
1785 # the ALL/ANY mode we can early-exit
1786 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1787 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1788 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1789 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1791 # execute actual instruction here (finally)
1792 log("inputs", inputs
)
1793 results
= info
.func(self
, *inputs
)
1794 log("results", results
)
1796 # "inject" decorator takes namespace from function locals: we need to
1797 # overwrite NIA being overwritten (sigh)
1798 if self
.trap_nia
is not None:
1799 self
.namespace
['NIA'] = self
.trap_nia
1801 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1803 # check if op was a LD/ST so that debugging can check the
1805 if int_op
in [MicrOp
.OP_STORE
.value
,
1807 self
.last_st_addr
= self
.mem
.last_st_addr
1808 if int_op
in [MicrOp
.OP_LOAD
.value
,
1810 self
.last_ld_addr
= self
.mem
.last_ld_addr
1811 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1812 self
.last_st_addr
, self
.last_ld_addr
)
1814 # detect if CA/CA32 already in outputs (sra*, basically)
1818 output_names
= create_args(info
.write_regs
)
1819 for name
in output_names
:
1825 log("carry already done?", bin(already_done
), output_names
)
1826 carry_en
= yield self
.dec2
.e
.do
.output_carry
1828 yield from self
.handle_carry_(inputs
, results
, already_done
)
1830 # check if one of the regs was named "overflow"
1833 for name
, output
in zip(output_names
, results
):
1834 if name
== 'overflow':
1837 # and one called CR0
1840 for name
, output
in zip(output_names
, results
):
1844 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1845 # detect if overflow was in return result
1846 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1847 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1848 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1850 yield from self
.handle_overflow(inputs
, results
, overflow
)
1852 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1854 if not self
.is_svp64_mode
or not pred_dst_zero
:
1855 if hasattr(self
.dec2
.e
.do
, "rc"):
1856 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1857 # don't do Rc=1 for svstep it is handled explicitly.
1858 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1859 # to write directly to CR0 instead of in ISACaller. hooyahh.
1860 if rc_en
and ins_name
not in ['svstep']:
1861 yield from self
.do_rc_ov(ins_name
, results
, overflow
, cr0
)
1865 if self
.is_svp64_mode
:
1866 ffirst_hit
= (yield from self
.check_ffirst(rc_en
, srcstep
))
1868 # any modified return results?
1869 yield from self
.do_outregs_nia(asmop
, ins_name
, info
,
1870 output_names
, results
,
1871 carry_en
, rc_en
, ffirst_hit
)
1873 def check_ffirst(self
, rc_en
, srcstep
):
1874 rm_mode
= yield self
.dec2
.rm_dec
.mode
1875 ff_inv
= yield self
.dec2
.rm_dec
.inv
1876 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
1877 RC1
= yield self
.dec2
.rm_dec
.RC1
1878 vli
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
1879 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
1883 log(" cr_bit", cr_bit
)
1884 if not rc_en
or rm_mode
!= SVP64RMMode
.FFIRST
.value
:
1886 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1887 crtest
= self
.crl
[regnum
]
1888 ffirst_hit
= crtest
[cr_bit
] != ff_inv
1889 log("cr test", regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
1890 log("cr test?", ffirst_hit
)
1893 vli
= SelectableInt(int(vli
), 7)
1894 self
.svstate
.vl
= srcstep
+ vli
1895 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1896 yield Settle() # let decoder update
1899 def do_rc_ov(self
, ins_name
, results
, overflow
, cr0
):
1900 if ins_name
.startswith("f"):
1901 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1904 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, rc_reg
)
1906 # hang on... for `setvl` actually you want to test SVSTATE.VL
1907 is_setvl
= ins_name
== 'setvl'
1910 cmps
= (SelectableInt(vl
, 64), overflow
,)
1912 overflow
= None # do not override overflow except in setvl
1914 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
1916 self
.handle_comparison(cmps
, regnum
, overflow
, no_so
=is_setvl
)
1918 # otherwise we just blat CR0 into the required regnum
1919 log("explicit rc0", cr0
)
1920 self
.crl
[regnum
].eq(cr0
)
1922 def do_outregs_nia(self
, asmop
, ins_name
, info
, output_names
, results
,
1923 carry_en
, rc_en
, ffirst_hit
):
1924 # write out any regs for this instruction
1926 for name
, output
in zip(output_names
, results
):
1927 yield from self
.check_write(info
, name
, output
, carry_en
)
1930 self
.svp64_reset_loop()
1933 # check advancement of src/dst/sub-steps and if PC needs updating
1934 nia_update
= (yield from self
.check_step_increment(results
, rc_en
,
1937 self
.update_pc_next()
1939 def check_replace_d(self
, info
, remap_active
):
1940 replace_d
= False # update / replace constant in pseudocode
1941 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1942 vl
= self
.svstate
.vl
1943 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1944 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1945 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1946 if info
.form
== 'DS':
1947 # DS-Form, multiply by 4 then knock 2 bits off after
1948 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1950 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1951 imm
= exts(imm
, 16) # sign-extend to integer
1952 # get the right step. LD is from srcstep, ST is dststep
1953 op
= yield self
.dec2
.e
.do
.insn_type
1955 if op
== MicrOp
.OP_LOAD
.value
:
1957 offsmul
= yield self
.dec2
.in1_step
1958 log("D-field REMAP src", imm
, offsmul
)
1960 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
1961 log("D-field src", imm
, offsmul
)
1962 elif op
== MicrOp
.OP_STORE
.value
:
1963 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1964 offsmul
= (dststep
* (subvl
+1)) + dsubstep
1965 log("D-field dst", imm
, offsmul
)
1966 # Unit-Strided LD/ST adds offset*width to immediate
1967 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1968 ldst_len
= yield self
.dec2
.e
.do
.data_len
1969 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1971 # Element-strided multiplies the immediate by element step
1972 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1973 imm
= SelectableInt(imm
* offsmul
, 32)
1976 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1977 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1978 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1979 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1980 # new replacement D... errr.. DS
1982 if info
.form
== 'DS':
1983 # TODO: assert 2 LSBs are zero?
1984 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1985 imm
.value
= imm
.value
>> 2
1986 self
.namespace
['DS'] = imm
1988 self
.namespace
['D'] = imm
1990 def get_input(self
, name
):
1991 # using PowerDecoder2, first, find the decoder index.
1992 # (mapping name RA RB RC RS to in1, in2, in3)
1993 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1995 # doing this is not part of svp64, it's because output
1996 # registers, to be modified, need to be in the namespace.
1997 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1999 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
2001 # in case getting the register number is needed, _RA, _RB
2002 regname
= "_" + name
2003 self
.namespace
[regname
] = regnum
2004 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
2005 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
2007 reg_val
= SelectableInt(self
.fpr(regnum
))
2008 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
2009 elif name
is not None:
2010 reg_val
= SelectableInt(self
.gpr(regnum
))
2011 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
2013 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
2017 def remap_set_steps(self
, remaps
):
2018 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
2019 they work in concert with PowerDecoder2 at the moment,
2020 there is no HDL implementation of REMAP. therefore this
2021 function, because ISACaller still uses PowerDecoder2,
2022 will *explicitly* write the dec2.XX_step values. this has
2025 # just some convenient debug info
2027 sname
= 'SVSHAPE%d' % i
2028 shape
= self
.spr
[sname
]
2029 log(sname
, bin(shape
.value
))
2030 log(" lims", shape
.lims
)
2031 log(" mode", shape
.mode
)
2032 log(" skip", shape
.skip
)
2034 # set up the list of steps to remap
2035 mi0
= self
.svstate
.mi0
2036 mi1
= self
.svstate
.mi1
2037 mi2
= self
.svstate
.mi2
2038 mo0
= self
.svstate
.mo0
2039 mo1
= self
.svstate
.mo1
2040 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
2041 (self
.dec2
.in2_step
, mi1
), # RB
2042 (self
.dec2
.in3_step
, mi2
), # RC
2043 (self
.dec2
.o_step
, mo0
), # RT
2044 (self
.dec2
.o2_step
, mo1
), # EA
2046 remap_idxs
= self
.remap_idxs
2048 # now cross-index the required SHAPE for each of 3-in 2-out regs
2049 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
2050 for i
, (dstep
, shape_idx
) in enumerate(steps
):
2051 (shape
, remap
) = remaps
[shape_idx
]
2052 remap_idx
= remap_idxs
[shape_idx
]
2053 # zero is "disabled"
2054 if shape
.value
== 0x0:
2056 # now set the actual requested step to the current index
2057 yield dstep
.eq(remap_idx
)
2059 # debug printout info
2060 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
2062 log("shape remap", x
)
2064 def check_write(self
, info
, name
, output
, carry_en
):
2065 if name
== 'overflow': # ignore, done already (above)
2067 if name
== 'CR0': # ignore, done already (above)
2069 if isinstance(output
, int):
2070 output
= SelectableInt(output
, 256)
2072 if name
in ['CA', 'CA32']:
2074 log("writing %s to XER" % name
, output
)
2075 log("write XER %s 0x%x" % (name
, output
.value
))
2076 self
.spr
['XER'][XER_bits
[name
]] = output
.value
2078 log("NOT writing %s to XER" % name
, output
)
2080 # write special SPRs
2081 if name
in info
.special_regs
:
2082 log('writing special %s' % name
, output
, special_sprs
)
2083 log("write reg %s 0x%x" % (name
, output
.value
))
2084 if name
in special_sprs
:
2085 self
.spr
[name
] = output
2087 self
.namespace
[name
].eq(output
)
2089 log('msr written', hex(self
.msr
.value
))
2091 # find out1/out2 PR/FPR
2092 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
2094 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
2096 # temporary hack for not having 2nd output
2097 regnum
= yield getattr(self
.decoder
, name
)
2099 # convenient debug prefix
2104 # check zeroing due to predicate bit being zero
2105 if self
.is_svp64_mode
and self
.pred_dst_zero
:
2106 log('zeroing reg %d %s' % (regnum
, str(output
)), is_vec
)
2107 output
= SelectableInt(0, 256)
2108 log("write reg %s%d 0x%x" % (reg_prefix
, regnum
, output
.value
),
2109 kind
=LogKind
.InstrInOuts
)
2110 # zero-extend tov64 bit begore storing (should use EXT oh well)
2111 if output
.bits
> 64:
2112 output
= SelectableInt(output
.value
, 64)
2114 self
.fpr
[regnum
] = output
2116 self
.gpr
[regnum
] = output
2118 def check_step_increment(self
, results
, rc_en
, asmop
, ins_name
):
2119 # check if it is the SVSTATE.src/dest step that needs incrementing
2120 # this is our Sub-Program-Counter loop from 0 to VL-1
2121 if not self
.allow_next_step_inc
:
2122 if self
.is_svp64_mode
:
2123 return (yield from self
.svstate_post_inc(ins_name
))
2125 # XXX only in non-SVP64 mode!
2126 # record state of whether the current operation was an svshape,
2128 # to be able to know if it should apply in the next instruction.
2129 # also (if going to use this instruction) should disable ability
2130 # to interrupt in between. sigh.
2131 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2138 log("SVSTATE_NEXT: inc requested, mode",
2139 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2140 yield from self
.svstate_pre_inc()
2141 pre
= yield from self
.update_new_svstate_steps()
2143 # reset at end of loop including exit Vertical Mode
2144 log("SVSTATE_NEXT: end of loop, reset")
2145 self
.svp64_reset_loop()
2146 self
.svstate
.vfirst
= 0
2150 results
= [SelectableInt(0, 64)]
2151 self
.handle_comparison(results
) # CR0
2153 if self
.allow_next_step_inc
== 2:
2154 log("SVSTATE_NEXT: read")
2155 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2157 log("SVSTATE_NEXT: post-inc")
2158 # use actual (cached) src/dst-step here to check end
2159 remaps
= self
.get_remap_indices()
2160 remap_idxs
= self
.remap_idxs
2161 vl
= self
.svstate
.vl
2162 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2163 if self
.allow_next_step_inc
!= 2:
2164 yield from self
.advance_svstate_steps()
2165 #self.namespace['SVSTATE'] = self.svstate.spr
2166 # set CR0 (if Rc=1) based on end
2167 endtest
= 1 if self
.at_loopend() else 0
2169 #results = [SelectableInt(endtest, 64)]
2170 # self.handle_comparison(results) # CR0
2172 # see if svstep was requested, if so, which SVSTATE
2174 if self
.svstate_next_mode
> 0:
2175 shape_idx
= self
.svstate_next_mode
.value
-1
2176 endings
= self
.remap_loopends
[shape_idx
]
2177 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2178 log("svstep Rc=1, CR0", cr_field
, endtest
)
2179 self
.crl
[0].eq(cr_field
) # CR0
2181 # reset at end of loop including exit Vertical Mode
2182 log("SVSTATE_NEXT: after increments, reset")
2183 self
.svp64_reset_loop()
2184 self
.svstate
.vfirst
= 0
2187 def SVSTATE_NEXT(self
, mode
, submode
):
2188 """explicitly moves srcstep/dststep on to next element, for
2189 "Vertical-First" mode. this function is called from
2190 setvl pseudo-code, as a pseudo-op "svstep"
2192 WARNING: this function uses information that was created EARLIER
2193 due to it being in the middle of a yield, but this function is
2194 *NOT* called from yield (it's called from compiled pseudocode).
2196 self
.allow_next_step_inc
= submode
.value
+ 1
2197 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2198 self
.svstate_next_mode
= mode
2199 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2200 shape_idx
= self
.svstate_next_mode
.value
-1
2201 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2202 if self
.svstate_next_mode
== 5:
2203 self
.svstate_next_mode
= 0
2204 return SelectableInt(self
.svstate
.srcstep
, 7)
2205 if self
.svstate_next_mode
== 6:
2206 self
.svstate_next_mode
= 0
2207 return SelectableInt(self
.svstate
.dststep
, 7)
2208 if self
.svstate_next_mode
== 7:
2209 self
.svstate_next_mode
= 0
2210 return SelectableInt(self
.svstate
.ssubstep
, 7)
2211 if self
.svstate_next_mode
== 8:
2212 self
.svstate_next_mode
= 0
2213 return SelectableInt(self
.svstate
.dsubstep
, 7)
2214 return SelectableInt(0, 7)
2216 def get_src_dststeps(self
):
2217 """gets srcstep, dststep, and ssubstep, dsubstep
2219 return (self
.new_srcstep
, self
.new_dststep
,
2220 self
.new_ssubstep
, self
.new_dsubstep
)
2222 def update_svstate_namespace(self
, overwrite_svstate
=True):
2223 if overwrite_svstate
:
2224 # note, do not get the bit-reversed srcstep here!
2225 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2226 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2228 # update SVSTATE with new srcstep
2229 self
.svstate
.srcstep
= srcstep
2230 self
.svstate
.dststep
= dststep
2231 self
.svstate
.ssubstep
= ssubstep
2232 self
.svstate
.dsubstep
= dsubstep
2233 self
.namespace
['SVSTATE'] = self
.svstate
2234 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2235 yield Settle() # let decoder update
2237 def update_new_svstate_steps(self
, overwrite_svstate
=True):
2238 yield from self
.update_svstate_namespace(overwrite_svstate
)
2239 srcstep
= self
.svstate
.srcstep
2240 dststep
= self
.svstate
.dststep
2241 ssubstep
= self
.svstate
.ssubstep
2242 dsubstep
= self
.svstate
.dsubstep
2243 pack
= self
.svstate
.pack
2244 unpack
= self
.svstate
.unpack
2245 vl
= self
.svstate
.vl
2246 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2247 rm_mode
= yield self
.dec2
.rm_dec
.mode
2248 ff_inv
= yield self
.dec2
.rm_dec
.inv
2249 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2250 log(" srcstep", srcstep
)
2251 log(" dststep", dststep
)
2253 log(" unpack", unpack
)
2254 log(" ssubstep", ssubstep
)
2255 log(" dsubstep", dsubstep
)
2257 log(" subvl", subvl
)
2258 log(" rm_mode", rm_mode
)
2260 log(" cr_bit", cr_bit
)
2262 # check if end reached (we let srcstep overrun, above)
2263 # nothing needs doing (TODO zeroing): just do next instruction
2266 return ((ssubstep
== subvl
and srcstep
== vl
) or
2267 (dsubstep
== subvl
and dststep
== vl
))
2269 def svstate_post_inc(self
, insn_name
, vf
=0):
2270 # check if SV "Vertical First" mode is enabled
2271 vfirst
= self
.svstate
.vfirst
2272 log(" SV Vertical First", vf
, vfirst
)
2273 if not vf
and vfirst
== 1:
2277 # check if it is the SVSTATE.src/dest step that needs incrementing
2278 # this is our Sub-Program-Counter loop from 0 to VL-1
2279 # XXX twin predication TODO
2280 vl
= self
.svstate
.vl
2281 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2282 mvl
= self
.svstate
.maxvl
2283 srcstep
= self
.svstate
.srcstep
2284 dststep
= self
.svstate
.dststep
2285 ssubstep
= self
.svstate
.ssubstep
2286 dsubstep
= self
.svstate
.dsubstep
2287 pack
= self
.svstate
.pack
2288 unpack
= self
.svstate
.unpack
2289 rm_mode
= yield self
.dec2
.rm_dec
.mode
2290 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2291 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2292 out_vec
= not (yield self
.dec2
.no_out_vec
)
2293 in_vec
= not (yield self
.dec2
.no_in_vec
)
2294 log(" svstate.vl", vl
)
2295 log(" svstate.mvl", mvl
)
2296 log(" rm.subvl", subvl
)
2297 log(" svstate.srcstep", srcstep
)
2298 log(" svstate.dststep", dststep
)
2299 log(" svstate.ssubstep", ssubstep
)
2300 log(" svstate.dsubstep", dsubstep
)
2301 log(" svstate.pack", pack
)
2302 log(" svstate.unpack", unpack
)
2303 log(" mode", rm_mode
)
2304 log(" reverse", reverse_gear
)
2305 log(" out_vec", out_vec
)
2306 log(" in_vec", in_vec
)
2307 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2308 # check if this was an sv.bc* and if so did it succeed
2309 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2310 end_loop
= self
.namespace
['end_loop']
2311 log("branch %s end_loop" % insn_name
, end_loop
)
2313 self
.svp64_reset_loop()
2314 self
.update_pc_next()
2316 # check if srcstep needs incrementing by one, stop PC advancing
2317 # but for 2-pred both src/dest have to be checked.
2318 # XXX this might not be true! it may just be LD/ST
2319 if sv_ptype
== SVPtype
.P2
.value
:
2320 svp64_is_vector
= (out_vec
or in_vec
)
2322 svp64_is_vector
= out_vec
2323 # loops end at the first "hit" (source or dest)
2324 yield from self
.advance_svstate_steps()
2325 loopend
= self
.loopend
2326 log("loopend", svp64_is_vector
, loopend
)
2327 if not svp64_is_vector
or loopend
:
2328 # reset loop to zero and update NIA
2329 self
.svp64_reset_loop()
2334 # still looping, advance and update NIA
2335 self
.namespace
['SVSTATE'] = self
.svstate
2337 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2338 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2339 # this way we keep repeating the same instruction (with new steps)
2340 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2341 self
.namespace
['NIA'] = self
.pc
.NIA
2342 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2343 return False # DO NOT allow PC update whilst Sub-PC loop running
2345 def update_pc_next(self
):
2346 # UPDATE program counter
2347 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2348 #self.svstate.spr = self.namespace['SVSTATE']
2349 log("end of call", self
.namespace
['CIA'],
2350 self
.namespace
['NIA'],
2351 self
.namespace
['SVSTATE'])
2353 def svp64_reset_loop(self
):
2354 self
.svstate
.srcstep
= 0
2355 self
.svstate
.dststep
= 0
2356 self
.svstate
.ssubstep
= 0
2357 self
.svstate
.dsubstep
= 0
2358 self
.loopend
= False
2359 log(" svstate.srcstep loop end (PC to update)")
2360 self
.namespace
['SVSTATE'] = self
.svstate
2362 def update_nia(self
):
2363 self
.pc
.update_nia(self
.is_svp64_mode
)
2364 self
.namespace
['NIA'] = self
.pc
.NIA
2368 """Decorator factory.
2370 this decorator will "inject" variables into the function's namespace,
2371 from the *dictionary* in self.namespace. it therefore becomes possible
2372 to make it look like a whole stack of variables which would otherwise
2373 need "self." inserted in front of them (*and* for those variables to be
2374 added to the instance) "appear" in the function.
2376 "self.namespace['SI']" for example becomes accessible as just "SI" but
2377 *only* inside the function, when decorated.
2379 def variable_injector(func
):
2381 def decorator(*args
, **kwargs
):
2383 func_globals
= func
.__globals
__ # Python 2.6+
2384 except AttributeError:
2385 func_globals
= func
.func_globals
# Earlier versions.
2387 context
= args
[0].namespace
# variables to be injected
2388 saved_values
= func_globals
.copy() # Shallow copy of dict.
2389 log("globals before", context
.keys())
2390 func_globals
.update(context
)
2391 result
= func(*args
, **kwargs
)
2392 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2393 log("args[0]", args
[0].namespace
['CIA'],
2394 args
[0].namespace
['NIA'],
2395 args
[0].namespace
['SVSTATE'])
2396 if 'end_loop' in func_globals
:
2397 log("args[0] end_loop", func_globals
['end_loop'])
2398 args
[0].namespace
= func_globals
2399 #exec (func.__code__, func_globals)
2402 # func_globals = saved_values # Undo changes.
2408 return variable_injector