15a4ad9fe3a35580944800d3e699ea465dbeff33
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
540 def get_iterators(self
):
541 self
.src_it
= self
.src_iterator()
542 self
.dst_it
= self
.dst_iterator()
544 def src_iterator(self
):
545 """source-stepping iterator
547 pack
= self
.svstate
.pack
551 # pack advances subvl in *outer* loop
554 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
555 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
557 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
559 # these cannot be done as for-loops because SVSTATE may change
560 # (srcstep/substep may be modified, interrupted, subvl/vl change)
561 # but they *can* be done as while-loops as long as every SVSTATE
562 # "thing" is re-read every single time a yield gives indices
563 while True: # outer vl loop
564 while True: # inner subvl loop
566 srcmask
= self
.srcmask
567 srcstep
= self
.svstate
.srcstep
568 if self
.pred_sz
or ((1 << srcstep
) & srcmask
) != 0:
569 log(" advance src", srcstep
, self
.svstate
.vl
,
570 self
.svstate
.ssubstep
, subvl
)
571 # yield actual substep/srcstep
572 yield (self
.svstate
.ssubstep
, srcstep
)
573 if self
.svstate
.ssubstep
== subvl
: # end-point
574 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
576 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
578 if srcstep
== vl
-1: # end-point
579 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
580 break # trigger StopIteration
581 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
583 def dst_iterator(self
):
584 """dest-stepping iterator
586 unpack
= self
.svstate
.unpack
590 # pack advances subvl in *outer* loop
593 # these cannot be done as for-loops because SVSTATE may change
594 # (dststep/substep may be modified, interrupted, subvl/vl change)
595 # but they *can* be done as while-loops as long as every SVSTATE
596 # "thing" is re-read every single time a yield gives indices
597 while True: # outer vl loop
598 while True: # inner subvl loop
600 dstmask
= self
.dstmask
601 dststep
= self
.svstate
.dststep
602 if self
.pred_dz
or ((1 << dststep
) & dstmask
) != 0:
603 log(" advance dst", dststep
, self
.svstate
.vl
,
604 self
.svstate
.dsubstep
, subvl
)
605 # yield actual substep/dststep
606 yield (self
.svstate
.dsubstep
, dststep
)
607 if self
.svstate
.dsubstep
== subvl
: # end-point
608 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
610 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
612 if dststep
== vl
-1: # end-point
613 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
614 break # trigger StopIteration
615 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
617 def src_iterate(self
):
618 """source-stepping iterator
620 end_src
= self
.end_src
622 pack
= self
.svstate
.pack
623 unpack
= self
.svstate
.unpack
624 ssubstep
= self
.svstate
.ssubstep
625 end_ssub
= ssubstep
== subvl
626 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
630 srcstep
= self
.svstate
.srcstep
632 # pack advances subvl in *outer* loop
635 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
636 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
638 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
640 # advance subvl in *inner* loop
643 self
.svstate
.srcstep
+= SelectableInt(1, 7)
644 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
647 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
649 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
)
651 def dst_iterate(self
):
652 """dest step iterator
654 end_dst
= self
.end_dst
656 pack
= self
.svstate
.pack
657 unpack
= self
.svstate
.unpack
658 dsubstep
= self
.svstate
.dsubstep
659 end_dsub
= dsubstep
== subvl
660 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
665 # unpack advances subvl in *outer* loop
668 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
669 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
671 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
673 # advance subvl in *inner* loop
676 self
.svstate
.dststep
+= SelectableInt(1, 7)
677 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
680 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
681 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
)
683 def advance_svstate_steps(self
, end_src
=False, end_dst
=False):
684 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
685 TODO when Pack/Unpack is set, substep becomes the *outer* loop
687 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
688 self
.end_src
= end_src
689 self
.end_dst
= end_dst
693 def read_src_mask(self
):
694 """read/update pred_sz and src mask
696 # get SVSTATE VL (oh and print out some debug stuff)
698 srcstep
= self
.svstate
.srcstep
699 ssubstep
= self
.svstate
.ssubstep
701 # get predicate mask (all 64 bits)
702 srcmask
= 0xffff_ffff_ffff_ffff
704 pmode
= yield self
.dec2
.rm_dec
.predmode
705 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
706 srcpred
= yield self
.dec2
.rm_dec
.srcpred
707 dstpred
= yield self
.dec2
.rm_dec
.dstpred
708 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
709 if pmode
== SVP64PredMode
.INT
.value
:
710 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
711 if sv_ptype
== SVPtype
.P2
.value
:
712 srcmask
= get_predint(self
.gpr
, srcpred
)
713 elif pmode
== SVP64PredMode
.CR
.value
:
714 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
715 if sv_ptype
== SVPtype
.P2
.value
:
716 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
717 # work out if the ssubsteps are completed
718 ssubstart
= ssubstep
== 0
720 log(" ptype", sv_ptype
)
721 log(" srcpred", bin(srcpred
))
722 log(" srcmask", bin(srcmask
))
723 log(" pred_sz", bin(pred_sz
))
724 log(" ssubstart", ssubstart
)
726 # store all that above
727 self
.srcstep_skip
= False
728 self
.srcmask
= srcmask
729 self
.pred_sz
= pred_sz
730 self
.new_ssubstep
= ssubstep
731 log(" new ssubstep", ssubstep
)
733 # until the predicate mask has a "1" bit... or we run out of VL
734 # let srcstep==VL be the indicator to move to next instruction
736 self
.srcstep_skip
= True
738 def read_dst_mask(self
):
739 """same as read_src_mask - check and record everything needed
741 # get SVSTATE VL (oh and print out some debug stuff)
742 # yield Delay(1e-10) # make changes visible
744 dststep
= self
.svstate
.dststep
745 dsubstep
= self
.svstate
.dsubstep
747 # get predicate mask (all 64 bits)
748 dstmask
= 0xffff_ffff_ffff_ffff
750 pmode
= yield self
.dec2
.rm_dec
.predmode
751 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
752 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
753 dstpred
= yield self
.dec2
.rm_dec
.dstpred
754 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
755 if pmode
== SVP64PredMode
.INT
.value
:
756 dstmask
= get_predint(self
.gpr
, dstpred
)
757 elif pmode
== SVP64PredMode
.CR
.value
:
758 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
759 # work out if the ssubsteps are completed
760 dsubstart
= dsubstep
== 0
762 log(" ptype", sv_ptype
)
763 log(" dstpred", bin(dstpred
))
764 log(" dstmask", bin(dstmask
))
765 log(" pred_dz", bin(pred_dz
))
766 log(" dsubstart", dsubstart
)
768 self
.dststep_skip
= False
769 self
.dstmask
= dstmask
770 self
.pred_dz
= pred_dz
771 self
.new_dsubstep
= dsubstep
772 log(" new dsubstep", dsubstep
)
775 self
.dststep_skip
= True
777 def svstate_pre_inc(self
):
778 """check if srcstep/dststep need to skip over masked-out predicate bits
779 note that this is not supposed to do anything to substep,
780 it is purely for skipping masked-out bits
783 yield from self
.read_src_mask()
784 yield from self
.read_dst_mask()
791 srcstep
= self
.svstate
.srcstep
792 srcmask
= self
.srcmask
793 pred_src_zero
= self
.pred_sz
795 # srcstep-skipping opportunity identified
796 if self
.srcstep_skip
:
797 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
798 log(" sskip", bin(1 << srcstep
))
801 # now work out if the relevant mask bits require zeroing
803 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
805 # store new srcstep / dststep
806 self
.new_srcstep
= srcstep
807 self
.pred_src_zero
= pred_src_zero
808 log(" new srcstep", srcstep
)
811 # dststep-skipping opportunity identified
812 dststep
= self
.svstate
.dststep
813 dstmask
= self
.dstmask
814 pred_dst_zero
= self
.pred_dz
816 if self
.dststep_skip
:
817 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
818 log(" dskip", bin(1 << dststep
))
821 # now work out if the relevant mask bits require zeroing
823 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
825 # store new srcstep / dststep
826 self
.new_dststep
= dststep
827 self
.pred_dst_zero
= pred_dst_zero
828 log(" new dststep", dststep
)
831 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
832 # decoder2 - an instance of power_decoder2
833 # regfile - a list of initial values for the registers
834 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
835 # respect_pc - tracks the program counter. requires initial_insns
836 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
837 initial_mem
=None, initial_msr
=0,
848 self
.bigendian
= bigendian
850 self
.is_svp64_mode
= False
851 self
.respect_pc
= respect_pc
852 if initial_sprs
is None:
854 if initial_mem
is None:
856 if fpregfile
is None:
858 if initial_insns
is None:
860 assert self
.respect_pc
== False, "instructions required to honor pc"
862 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
863 log("ISACaller initial_msr", initial_msr
)
865 # "fake program counter" mode (for unit testing)
869 if isinstance(initial_mem
, tuple):
870 self
.fake_pc
= initial_mem
[0]
871 disasm_start
= self
.fake_pc
873 disasm_start
= initial_pc
875 # disassembly: we need this for now (not given from the decoder)
876 self
.disassembly
= {}
878 for i
, code
in enumerate(disassembly
):
879 self
.disassembly
[i
*4 + disasm_start
] = code
881 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
882 self
.svp64rm
= SVP64RM()
883 if initial_svstate
is None:
885 if isinstance(initial_svstate
, int):
886 initial_svstate
= SVP64State(initial_svstate
)
887 # SVSTATE, MSR and PC
888 StepLoop
.__init
__(self
, initial_svstate
)
889 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
891 # GPR FPR SPR registers
892 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
893 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
894 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
895 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
897 # set up 4 dummy SVSHAPEs if they aren't already set up
899 sname
= 'SVSHAPE%d' % i
900 if sname
not in self
.spr
:
903 val
= self
.spr
[sname
].value
904 # make sure it's an SVSHAPE
905 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
906 self
.last_op_svshape
= False
909 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
910 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
911 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
912 # MMU mode, redirect underlying Mem through RADIX
914 self
.mem
= RADIX(self
.mem
, self
)
916 self
.imem
= RADIX(self
.imem
, self
)
919 # FPR (same as GPR except for FP nums)
920 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
921 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
922 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
923 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
925 # 2.3.2 LR (actually SPR #8) -- Done
926 # 2.3.3 CTR (actually SPR #9) -- Done
927 # 2.3.4 TAR (actually SPR #815)
928 # 3.2.2 p45 XER (actually SPR #1) -- Done
929 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
931 # create CR then allow portions of it to be "selectable" (below)
932 self
.cr_fields
= CRFields(initial_cr
)
933 self
.cr
= self
.cr_fields
.cr
935 # "undefined", just set to variable-bit-width int (use exts "max")
936 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
939 self
.namespace
.update(self
.spr
)
940 self
.namespace
.update({'GPR': self
.gpr
,
944 'memassign': self
.memassign
,
947 'SVSTATE': self
.svstate
,
948 'SVSHAPE0': self
.spr
['SVSHAPE0'],
949 'SVSHAPE1': self
.spr
['SVSHAPE1'],
950 'SVSHAPE2': self
.spr
['SVSHAPE2'],
951 'SVSHAPE3': self
.spr
['SVSHAPE3'],
954 'undefined': undefined
,
955 'mode_is_64bit': True,
956 'SO': XER_bits
['SO'],
957 'XLEN': 64 # elwidth overrides, later
960 # update pc to requested start point
961 self
.set_pc(initial_pc
)
963 # field-selectable versions of Condition Register
964 self
.crl
= self
.cr_fields
.crl
966 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
968 self
.decoder
= decoder2
.dec
971 super().__init
__(XLEN
=self
.namespace
["XLEN"])
975 return self
.namespace
["XLEN"]
977 def call_trap(self
, trap_addr
, trap_bit
):
978 """calls TRAP and sets up NIA to the new execution location.
979 next instruction will begin at trap_addr.
981 self
.TRAP(trap_addr
, trap_bit
)
982 self
.namespace
['NIA'] = self
.trap_nia
983 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
985 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
986 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
988 TRAP function is callable from inside the pseudocode itself,
989 hence the default arguments. when calling from inside ISACaller
990 it is best to use call_trap()
992 # https://bugs.libre-soc.org/show_bug.cgi?id=859
993 kaivb
= self
.spr
['KAIVB'].value
994 msr
= self
.namespace
['MSR'].value
995 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
996 # store CIA(+4?) in SRR0, set NIA to 0x700
997 # store MSR in SRR1, set MSR to um errr something, have to check spec
998 # store SVSTATE (if enabled) in SVSRR0
999 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1000 self
.spr
['SRR1'].value
= msr
1001 if self
.is_svp64_mode
:
1002 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1003 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1004 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1006 # set exception bits. TODO: this should, based on the address
1007 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1008 # bits appropriately. however it turns out that *for now* in all
1009 # cases (all trap_addrs) the exact same thing is needed.
1010 self
.msr
[MSRb
.IR
] = 0
1011 self
.msr
[MSRb
.DR
] = 0
1012 self
.msr
[MSRb
.FE0
] = 0
1013 self
.msr
[MSRb
.FE1
] = 0
1014 self
.msr
[MSRb
.EE
] = 0
1015 self
.msr
[MSRb
.RI
] = 0
1016 self
.msr
[MSRb
.SF
] = 1
1017 self
.msr
[MSRb
.TM
] = 0
1018 self
.msr
[MSRb
.VEC
] = 0
1019 self
.msr
[MSRb
.VSX
] = 0
1020 self
.msr
[MSRb
.PR
] = 0
1021 self
.msr
[MSRb
.FP
] = 0
1022 self
.msr
[MSRb
.PMM
] = 0
1023 self
.msr
[MSRb
.TEs
] = 0
1024 self
.msr
[MSRb
.TEe
] = 0
1025 self
.msr
[MSRb
.UND
] = 0
1026 self
.msr
[MSRb
.LE
] = 1
1028 def memassign(self
, ea
, sz
, val
):
1029 self
.mem
.memassign(ea
, sz
, val
)
1031 def prep_namespace(self
, insn_name
, formname
, op_fields
):
1032 # TODO: get field names from form in decoder*1* (not decoder2)
1033 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1035 # then "yield" fields only from op_fields rather than hard-coded
1037 fields
= self
.decoder
.sigforms
[formname
]
1038 log("prep_namespace", formname
, op_fields
, insn_name
)
1039 for name
in op_fields
:
1040 # CR immediates. deal with separately. needs modifying
1042 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1043 # BI is a 5-bit, must reconstruct the value
1044 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
1045 sig
= getattr(fields
, name
)
1047 # low 2 LSBs (CR field selector) remain same, CR num extended
1048 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1049 val
= (val
& 0b11) |
(regnum
<< 2)
1051 sig
= getattr(fields
, name
)
1053 # these are all opcode fields involved in index-selection of CR,
1054 # and need to do "standard" arithmetic. CR[BA+32] for example
1055 # would, if using SelectableInt, only be 5-bit.
1056 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1057 self
.namespace
[name
] = val
1059 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1061 self
.namespace
['XER'] = self
.spr
['XER']
1062 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1063 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1065 # add some SVSTATE convenience variables
1066 vl
= self
.svstate
.vl
1067 srcstep
= self
.svstate
.srcstep
1068 self
.namespace
['VL'] = vl
1069 self
.namespace
['srcstep'] = srcstep
1071 # sv.bc* need some extra fields
1072 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1073 # blegh grab bits manually
1074 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1075 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
1076 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
1077 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
1078 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1079 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1080 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1081 sz
= yield self
.dec2
.rm_dec
.pred_sz
1082 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1083 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1084 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1085 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1086 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1087 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1088 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1090 def handle_carry_(self
, inputs
, outputs
, already_done
):
1091 inv_a
= yield self
.dec2
.e
.do
.invert_in
1093 inputs
[0] = ~inputs
[0]
1095 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1097 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1098 inputs
.append(SelectableInt(imm
, 64))
1099 assert len(outputs
) >= 1
1100 log("outputs", repr(outputs
))
1101 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
1107 log("gt input", x
, output
)
1108 gt
= (gtu(x
, output
))
1111 cy
= 1 if any(gts
) else 0
1113 if not (1 & already_done
):
1114 self
.spr
['XER'][XER_bits
['CA']] = cy
1116 log("inputs", already_done
, inputs
)
1118 # ARGH... different for OP_ADD... *sigh*...
1119 op
= yield self
.dec2
.e
.do
.insn_type
1120 if op
== MicrOp
.OP_ADD
.value
:
1121 res32
= (output
.value
& (1 << 32)) != 0
1122 a32
= (inputs
[0].value
& (1 << 32)) != 0
1123 if len(inputs
) >= 2:
1124 b32
= (inputs
[1].value
& (1 << 32)) != 0
1127 cy32
= res32 ^ a32 ^ b32
1128 log("CA32 ADD", cy32
)
1132 log("input", x
, output
)
1133 log(" x[32:64]", x
, x
[32:64])
1134 log(" o[32:64]", output
, output
[32:64])
1135 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1137 cy32
= 1 if any(gts
) else 0
1138 log("CA32", cy32
, gts
)
1139 if not (2 & already_done
):
1140 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1142 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
1143 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1144 inv_a
= yield self
.dec2
.e
.do
.invert_in
1146 inputs
[0] = ~inputs
[0]
1148 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1150 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1151 inputs
.append(SelectableInt(imm
, 64))
1152 assert len(outputs
) >= 1
1153 log("handle_overflow", inputs
, outputs
, div_overflow
)
1154 if len(inputs
) < 2 and div_overflow
is None:
1157 # div overflow is different: it's returned by the pseudo-code
1158 # because it's more complex than can be done by analysing the output
1159 if div_overflow
is not None:
1160 ov
, ov32
= div_overflow
, div_overflow
1161 # arithmetic overflow can be done by analysing the input and output
1162 elif len(inputs
) >= 2:
1166 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1167 output_sgn
= exts(output
.value
, output
.bits
) < 0
1168 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1169 output_sgn
!= input_sgn
[0] else 0
1172 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1173 output32_sgn
= exts(output
.value
, 32) < 0
1174 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1175 output32_sgn
!= input32_sgn
[0] else 0
1177 # now update XER OV/OV32/SO
1178 so
= self
.spr
['XER'][XER_bits
['SO']]
1179 new_so
= so | ov
# sticky overflow ORs in old with new
1180 self
.spr
['XER'][XER_bits
['OV']] = ov
1181 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1182 self
.spr
['XER'][XER_bits
['SO']] = new_so
1183 log(" set overflow", ov
, ov32
, so
, new_so
)
1185 def handle_comparison(self
, outputs
, cr_idx
=0, overflow
=None, no_so
=False):
1187 assert isinstance(out
, SelectableInt
), \
1188 "out zero not a SelectableInt %s" % repr(outputs
)
1189 log("handle_comparison", out
.bits
, hex(out
.value
))
1190 # TODO - XXX *processor* in 32-bit mode
1191 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1193 # o32 = exts(out.value, 32)
1194 # print ("handle_comparison exts 32 bit", hex(o32))
1195 out
= exts(out
.value
, out
.bits
)
1196 log("handle_comparison exts", hex(out
))
1197 # create the three main CR flags, EQ GT LT
1198 zero
= SelectableInt(out
== 0, 1)
1199 positive
= SelectableInt(out
> 0, 1)
1200 negative
= SelectableInt(out
< 0, 1)
1201 # get (or not) XER.SO. for setvl this is important *not* to read SO
1203 SO
= SelectableInt(1, 0)
1205 SO
= self
.spr
['XER'][XER_bits
['SO']]
1206 log("handle_comparison SO overflow", SO
, overflow
)
1207 # alternative overflow checking (setvl mainly at the moment)
1208 if overflow
is not None and overflow
== 1:
1209 SO
= SelectableInt(1, 1)
1210 # create the four CR field values and set the required CR field
1211 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1212 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1213 self
.crl
[cr_idx
].eq(cr_field
)
1215 def set_pc(self
, pc_val
):
1216 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1217 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1219 def get_next_insn(self
):
1220 """check instruction
1223 pc
= self
.pc
.CIA
.value
1226 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1228 raise KeyError("no instruction at 0x%x" % pc
)
1231 def setup_one(self
):
1232 """set up one instruction
1234 pc
, insn
= self
.get_next_insn()
1235 yield from self
.setup_next_insn(pc
, insn
)
1237 def setup_next_insn(self
, pc
, ins
):
1238 """set up next instruction
1241 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1242 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1244 yield self
.dec2
.sv_rm
.eq(0)
1245 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1246 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1247 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1248 yield self
.dec2
.state
.pc
.eq(pc
)
1249 if self
.svstate
is not None:
1250 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1252 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1254 opcode
= yield self
.dec2
.dec
.opcode_in
1255 opcode
= SelectableInt(value
=opcode
, bits
=32)
1256 pfx
= SVP64Instruction
.Prefix(opcode
)
1257 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1258 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1259 self
.pc
.update_nia(self
.is_svp64_mode
)
1261 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1262 self
.namespace
['NIA'] = self
.pc
.NIA
1263 self
.namespace
['SVSTATE'] = self
.svstate
1264 if not self
.is_svp64_mode
:
1267 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1268 log("svp64.rm", bin(pfx
.rm
))
1269 log(" svstate.vl", self
.svstate
.vl
)
1270 log(" svstate.mvl", self
.svstate
.maxvl
)
1271 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1272 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1273 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1274 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1277 def execute_one(self
):
1278 """execute one instruction
1280 # get the disassembly code for this instruction
1281 if self
.is_svp64_mode
:
1282 if not self
.disassembly
:
1283 code
= yield from self
.get_assembly_name()
1285 code
= self
.disassembly
[self
._pc
+4]
1286 log(" svp64 sim-execute", hex(self
._pc
), code
)
1288 if not self
.disassembly
:
1289 code
= yield from self
.get_assembly_name()
1291 code
= self
.disassembly
[self
._pc
]
1292 log("sim-execute", hex(self
._pc
), code
)
1293 opname
= code
.split(' ')[0]
1295 yield from self
.call(opname
) # execute the instruction
1296 except MemException
as e
: # check for memory errors
1297 if e
.args
[0] == 'unaligned': # alignment error
1298 # run a Trap but set DAR first
1299 print("memory unaligned exception, DAR", e
.dar
)
1300 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1301 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1303 elif e
.args
[0] == 'invalid': # invalid
1304 # run a Trap but set DAR first
1305 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1306 if e
.mode
== 'EXECUTE':
1307 # XXX TODO: must set a few bits in SRR1,
1308 # see microwatt loadstore1.vhdl
1309 # if m_in.segerr = '0' then
1310 # v.srr1(47 - 33) := m_in.invalid;
1311 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1312 # v.srr1(47 - 44) := m_in.badtree;
1313 # v.srr1(47 - 45) := m_in.rc_error;
1314 # v.intr_vec := 16#400#;
1316 # v.intr_vec := 16#480#;
1317 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1319 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1321 # not supported yet:
1322 raise e
# ... re-raise
1324 # don't use this except in special circumstances
1325 if not self
.respect_pc
:
1328 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1329 hex(self
.pc
.NIA
.value
))
1331 def get_assembly_name(self
):
1332 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1333 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1334 dec_insn
= yield self
.dec2
.e
.do
.insn
1335 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1336 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1337 int_op
= yield self
.dec2
.dec
.op
.internal_op
1338 log("get assembly name asmcode", asmcode
, int_op
,
1339 hex(dec_insn
), bin(insn_1_11
))
1340 asmop
= insns
.get(asmcode
, None)
1342 # sigh reconstruct the assembly instruction name
1343 if hasattr(self
.dec2
.e
.do
, "oe"):
1344 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1345 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1349 if hasattr(self
.dec2
.e
.do
, "rc"):
1350 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1351 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1355 # grrrr have to special-case MUL op (see DecodeOE)
1356 log("ov %d en %d rc %d en %d op %d" %
1357 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1358 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1363 if not asmop
.endswith("."): # don't add "." to "andis."
1366 if hasattr(self
.dec2
.e
.do
, "lk"):
1367 lk
= yield self
.dec2
.e
.do
.lk
1370 log("int_op", int_op
)
1371 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1372 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1376 spr_msb
= yield from self
.get_spr_msb()
1377 if int_op
== MicrOp
.OP_MFCR
.value
:
1382 # XXX TODO: for whatever weird reason this doesn't work
1383 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1384 if int_op
== MicrOp
.OP_MTCRF
.value
:
1391 def get_remap_indices(self
):
1392 """WARNING, this function stores remap_idxs and remap_loopends
1393 in the class for later use. this to avoid problems with yield
1395 # go through all iterators in lock-step, advance to next remap_idx
1396 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1397 # get four SVSHAPEs. here we are hard-coding
1398 SVSHAPE0
= self
.spr
['SVSHAPE0']
1399 SVSHAPE1
= self
.spr
['SVSHAPE1']
1400 SVSHAPE2
= self
.spr
['SVSHAPE2']
1401 SVSHAPE3
= self
.spr
['SVSHAPE3']
1402 # set up the iterators
1403 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1404 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1405 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1406 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1409 self
.remap_loopends
= [0] * 4
1410 self
.remap_idxs
= [0, 1, 2, 3]
1412 for i
, (shape
, remap
) in enumerate(remaps
):
1413 # zero is "disabled"
1414 if shape
.value
== 0x0:
1415 self
.remap_idxs
[i
] = 0
1416 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1417 step
= dststep
if (i
in [3, 4]) else srcstep
1418 # this is terrible. O(N^2) looking for the match. but hey.
1419 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1422 self
.remap_idxs
[i
] = remap_idx
1423 self
.remap_loopends
[i
] = loopends
1424 dbg
.append((i
, step
, remap_idx
, loopends
))
1425 for (i
, step
, remap_idx
, loopends
) in dbg
:
1426 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1429 def get_spr_msb(self
):
1430 dec_insn
= yield self
.dec2
.e
.do
.insn
1431 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1433 def call(self
, name
):
1434 """call(opcode) - the primary execution point for instructions
1436 self
.last_st_addr
= None # reset the last known store address
1437 self
.last_ld_addr
= None # etc.
1439 ins_name
= name
.strip() # remove spaces if not already done so
1441 log("halted - not executing", ins_name
)
1444 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1445 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1446 asmop
= yield from self
.get_assembly_name()
1447 log("call", ins_name
, asmop
)
1449 # sv.setvl is *not* a loop-function. sigh
1450 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1453 int_op
= yield self
.dec2
.dec
.op
.internal_op
1454 spr_msb
= yield from self
.get_spr_msb()
1456 instr_is_privileged
= False
1457 if int_op
in [MicrOp
.OP_ATTN
.value
,
1458 MicrOp
.OP_MFMSR
.value
,
1459 MicrOp
.OP_MTMSR
.value
,
1460 MicrOp
.OP_MTMSRD
.value
,
1462 MicrOp
.OP_RFID
.value
]:
1463 instr_is_privileged
= True
1464 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1465 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1466 instr_is_privileged
= True
1468 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1470 # check MSR priv bit and whether op is privileged: if so, throw trap
1471 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1472 self
.call_trap(0x700, PIb
.PRIV
)
1475 # check halted condition
1476 if ins_name
== 'attn':
1480 # check illegal instruction
1482 if ins_name
not in ['mtcrf', 'mtocrf']:
1483 illegal
= ins_name
!= asmop
1485 # list of instructions not being supported by binutils (.long)
1486 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1487 if dotstrp
in [*FPTRANS_INSNS
,
1488 'ffmadds', 'fdmadds', 'ffadds',
1489 'mins', 'maxs', 'minu', 'maxu',
1490 'setvl', 'svindex', 'svremap', 'svstep',
1491 'svshape', 'svshape2',
1492 'grev', 'ternlogi', 'bmask', 'cprop',
1493 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1494 'fmvis', 'fishmv', 'pcdec'
1499 # branch-conditional redirects to sv.bc
1500 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1501 ins_name
= 'sv.%s' % ins_name
1503 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1505 # illegal instructions call TRAP at 0x700
1507 print("illegal", ins_name
, asmop
)
1508 self
.call_trap(0x700, PIb
.ILLEG
)
1509 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1510 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1513 # this is for setvl "Vertical" mode: if set true,
1514 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1515 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1516 self
.allow_next_step_inc
= False
1517 self
.svstate_next_mode
= 0
1519 # nop has to be supported, we could let the actual op calculate
1520 # but PowerDecoder has a pattern for nop
1521 if ins_name
== 'nop':
1522 self
.update_pc_next()
1525 # look up instruction in ISA.instrs, prepare namespace
1526 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1527 info
= self
.instrs
[ins_name
+"."]
1529 info
= self
.instrs
[ins_name
]
1530 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1532 # preserve order of register names
1533 input_names
= create_args(list(info
.read_regs
) +
1534 list(info
.uninit_regs
))
1535 log("input names", input_names
)
1537 # get SVP64 entry for the current instruction
1538 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1539 if sv_rm
is not None:
1540 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1542 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1543 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1545 # see if srcstep/dststep need skipping over masked-out predicate bits
1546 if (self
.is_svp64_mode
or ins_name
in ['setvl', 'svremap', 'svstate']):
1547 yield from self
.svstate_pre_inc()
1548 if self
.is_svp64_mode
:
1549 pre
= yield from self
.update_new_svstate_steps()
1551 self
.svp64_reset_loop()
1553 self
.update_pc_next()
1555 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1556 pred_dst_zero
= self
.pred_dst_zero
1557 pred_src_zero
= self
.pred_src_zero
1558 vl
= self
.svstate
.vl
1559 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1561 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1562 if self
.is_svp64_mode
and vl
== 0:
1563 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1564 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1565 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1568 # for when SVREMAP is active, using pre-arranged schedule.
1569 # note: modifying PowerDecoder2 needs to "settle"
1570 remap_en
= self
.svstate
.SVme
1571 persist
= self
.svstate
.RMpst
1572 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1573 if self
.is_svp64_mode
:
1574 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1576 if persist
or self
.last_op_svshape
:
1577 remaps
= self
.get_remap_indices()
1578 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1579 yield from self
.remap_set_steps(remaps
)
1580 # after that, settle down (combinatorial) to let Vector reg numbers
1581 # work themselves out
1583 if self
.is_svp64_mode
:
1584 remap_active
= yield self
.dec2
.remap_active
1586 remap_active
= False
1587 log("remap active", bin(remap_active
))
1589 # main input registers (RT, RA ...)
1591 for name
in input_names
:
1593 regval
= (yield from self
.get_input(name
))
1594 log("regval", regval
)
1595 inputs
.append(regval
)
1597 # arrrrgh, awful hack, to get _RT into namespace
1598 if ins_name
in ['setvl', 'svstep']:
1600 RT
= yield self
.dec2
.dec
.RT
1601 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1603 self
.namespace
["RT"] = SelectableInt(0, 5)
1604 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1605 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1607 # in SVP64 mode for LD/ST work out immediate
1608 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1609 # use info.form to detect
1610 if self
.is_svp64_mode
:
1611 yield from self
.check_replace_d(info
, remap_active
)
1613 # "special" registers
1614 for special
in info
.special_regs
:
1615 if special
in special_sprs
:
1616 inputs
.append(self
.spr
[special
])
1618 inputs
.append(self
.namespace
[special
])
1620 # clear trap (trap) NIA
1621 self
.trap_nia
= None
1623 # check if this was an sv.bc* and create an indicator that
1624 # this is the last check to be made as a loop. combined with
1625 # the ALL/ANY mode we can early-exit
1626 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1627 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1628 # XXX TODO - pack/unpack here
1629 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1630 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1632 # execute actual instruction here (finally)
1633 log("inputs", inputs
)
1634 results
= info
.func(self
, *inputs
)
1635 log("results", results
)
1637 # "inject" decorator takes namespace from function locals: we need to
1638 # overwrite NIA being overwritten (sigh)
1639 if self
.trap_nia
is not None:
1640 self
.namespace
['NIA'] = self
.trap_nia
1642 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1644 # check if op was a LD/ST so that debugging can check the
1646 if int_op
in [MicrOp
.OP_STORE
.value
,
1648 self
.last_st_addr
= self
.mem
.last_st_addr
1649 if int_op
in [MicrOp
.OP_LOAD
.value
,
1651 self
.last_ld_addr
= self
.mem
.last_ld_addr
1652 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1653 self
.last_st_addr
, self
.last_ld_addr
)
1655 # detect if CA/CA32 already in outputs (sra*, basically)
1659 output_names
= create_args(info
.write_regs
)
1660 for name
in output_names
:
1666 log("carry already done?", bin(already_done
), output_names
)
1667 carry_en
= yield self
.dec2
.e
.do
.output_carry
1669 yield from self
.handle_carry_(inputs
, results
, already_done
)
1671 # check if one of the regs was named "overflow"
1674 for name
, output
in zip(output_names
, results
):
1675 if name
== 'overflow':
1678 # and one called CR0
1681 for name
, output
in zip(output_names
, results
):
1685 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1686 # detect if overflow was in return result
1687 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1688 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1689 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1691 yield from self
.handle_overflow(inputs
, results
, overflow
)
1693 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1695 if not self
.is_svp64_mode
or not pred_dst_zero
:
1696 if hasattr(self
.dec2
.e
.do
, "rc"):
1697 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1698 # argh - these are *always* Rc=1 (but not really, they do write to CR0)
1699 if ins_name
== 'pcdec': # TODO add stbcx etc. when supported
1700 log ("hack-enable Rc=1 for %s - CR0" % ins_name
, cr0
)
1702 # don't do Rc=1 for svstep it is handled explicitly.
1703 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1704 # to write directly to CR0 instead of in ISACaller. hooyahh.
1705 if rc_en
and ins_name
not in ['svstep']:
1706 yield from self
.do_rc_ov(ins_name
, results
, overflow
, cr0
)
1708 # any modified return results?
1709 yield from self
.do_outregs_nia(asmop
, ins_name
, info
,
1710 output_names
, results
,
1713 def do_rc_ov(self
, ins_name
, results
, overflow
, cr0
):
1714 if ins_name
.startswith("f"):
1715 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1718 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, rc_reg
)
1720 # hang on... for `setvl` actually you want to test SVSTATE.VL
1721 is_setvl
= ins_name
== 'setvl'
1724 cmps
= (SelectableInt(vl
, 64), overflow
,)
1726 overflow
= None # do not override overflow except in setvl
1728 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
1730 self
.handle_comparison(cmps
, regnum
, overflow
, no_so
=is_setvl
)
1732 # otherwise we just blat CR0 into the required regnum
1733 log("explicit rc0", cr0
)
1734 self
.crl
[regnum
].eq(cr0
)
1736 def do_outregs_nia(self
, asmop
, ins_name
, info
, output_names
, results
,
1738 # write out any regs for this instruction
1740 for name
, output
in zip(output_names
, results
):
1741 yield from self
.check_write(info
, name
, output
, carry_en
)
1743 # check advancement of src/dst/sub-steps and if PC needs updating
1744 nia_update
= (yield from self
.check_step_increment(results
, rc_en
,
1747 self
.update_pc_next()
1749 def check_replace_d(self
, info
, remap_active
):
1750 replace_d
= False # update / replace constant in pseudocode
1751 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1752 vl
= self
.svstate
.vl
1753 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1754 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1755 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1756 if info
.form
== 'DS':
1757 # DS-Form, multiply by 4 then knock 2 bits off after
1758 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1760 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1761 imm
= exts(imm
, 16) # sign-extend to integer
1762 # get the right step. LD is from srcstep, ST is dststep
1763 op
= yield self
.dec2
.e
.do
.insn_type
1765 if op
== MicrOp
.OP_LOAD
.value
:
1767 offsmul
= yield self
.dec2
.in1_step
1768 log("D-field REMAP src", imm
, offsmul
)
1770 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
1771 log("D-field src", imm
, offsmul
)
1772 elif op
== MicrOp
.OP_STORE
.value
:
1773 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1774 offsmul
= (dststep
* (subvl
+1)) + dsubstep
1775 log("D-field dst", imm
, offsmul
)
1776 # Unit-Strided LD/ST adds offset*width to immediate
1777 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1778 ldst_len
= yield self
.dec2
.e
.do
.data_len
1779 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1781 # Element-strided multiplies the immediate by element step
1782 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1783 imm
= SelectableInt(imm
* offsmul
, 32)
1786 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1787 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1788 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1789 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1790 # new replacement D... errr.. DS
1792 if info
.form
== 'DS':
1793 # TODO: assert 2 LSBs are zero?
1794 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1795 imm
.value
= imm
.value
>> 2
1796 self
.namespace
['DS'] = imm
1798 self
.namespace
['D'] = imm
1800 def get_input(self
, name
):
1801 # using PowerDecoder2, first, find the decoder index.
1802 # (mapping name RA RB RC RS to in1, in2, in3)
1803 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1805 # doing this is not part of svp64, it's because output
1806 # registers, to be modified, need to be in the namespace.
1807 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1809 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1811 # in case getting the register number is needed, _RA, _RB
1812 regname
= "_" + name
1813 self
.namespace
[regname
] = regnum
1814 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
1815 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1817 reg_val
= SelectableInt(self
.fpr(regnum
))
1818 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1819 elif name
is not None:
1820 reg_val
= SelectableInt(self
.gpr(regnum
))
1821 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1823 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1827 def remap_set_steps(self
, remaps
):
1828 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1829 they work in concert with PowerDecoder2 at the moment,
1830 there is no HDL implementation of REMAP. therefore this
1831 function, because ISACaller still uses PowerDecoder2,
1832 will *explicitly* write the dec2.XX_step values. this has
1835 # just some convenient debug info
1837 sname
= 'SVSHAPE%d' % i
1838 shape
= self
.spr
[sname
]
1839 log(sname
, bin(shape
.value
))
1840 log(" lims", shape
.lims
)
1841 log(" mode", shape
.mode
)
1842 log(" skip", shape
.skip
)
1844 # set up the list of steps to remap
1845 mi0
= self
.svstate
.mi0
1846 mi1
= self
.svstate
.mi1
1847 mi2
= self
.svstate
.mi2
1848 mo0
= self
.svstate
.mo0
1849 mo1
= self
.svstate
.mo1
1850 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1851 (self
.dec2
.in2_step
, mi1
), # RB
1852 (self
.dec2
.in3_step
, mi2
), # RC
1853 (self
.dec2
.o_step
, mo0
), # RT
1854 (self
.dec2
.o2_step
, mo1
), # EA
1856 remap_idxs
= self
.remap_idxs
1858 # now cross-index the required SHAPE for each of 3-in 2-out regs
1859 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1860 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1861 (shape
, remap
) = remaps
[shape_idx
]
1862 remap_idx
= remap_idxs
[shape_idx
]
1863 # zero is "disabled"
1864 if shape
.value
== 0x0:
1866 # now set the actual requested step to the current index
1867 yield dstep
.eq(remap_idx
)
1869 # debug printout info
1870 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
1872 log("shape remap", x
)
1874 def check_write(self
, info
, name
, output
, carry_en
):
1875 if name
== 'overflow': # ignore, done already (above)
1877 if name
== 'CR0': # ignore, done already (above)
1879 if isinstance(output
, int):
1880 output
= SelectableInt(output
, 256)
1882 if name
in ['CA', 'CA32']:
1884 log("writing %s to XER" % name
, output
)
1885 log("write XER %s 0x%x" % (name
, output
.value
))
1886 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1888 log("NOT writing %s to XER" % name
, output
)
1890 # write special SPRs
1891 if name
in info
.special_regs
:
1892 log('writing special %s' % name
, output
, special_sprs
)
1893 log("write reg %s 0x%x" % (name
, output
.value
))
1894 if name
in special_sprs
:
1895 self
.spr
[name
] = output
1897 self
.namespace
[name
].eq(output
)
1899 log('msr written', hex(self
.msr
.value
))
1901 # find out1/out2 PR/FPR
1902 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1904 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1906 # temporary hack for not having 2nd output
1907 regnum
= yield getattr(self
.decoder
, name
)
1909 # convenient debug prefix
1914 # check zeroing due to predicate bit being zero
1915 if self
.is_svp64_mode
and self
.pred_dst_zero
:
1916 log('zeroing reg %d %s' % (regnum
, str(output
)), is_vec
)
1917 output
= SelectableInt(0, 256)
1918 log("write reg %s%d 0x%x" % (reg_prefix
, regnum
, output
.value
),
1919 kind
=LogKind
.InstrInOuts
)
1920 # zero-extend tov64 bit begore storing (should use EXT oh well)
1921 if output
.bits
> 64:
1922 output
= SelectableInt(output
.value
, 64)
1924 self
.fpr
[regnum
] = output
1926 self
.gpr
[regnum
] = output
1928 def check_step_increment(self
, results
, rc_en
, asmop
, ins_name
):
1929 # check if it is the SVSTATE.src/dest step that needs incrementing
1930 # this is our Sub-Program-Counter loop from 0 to VL-1
1931 if not self
.allow_next_step_inc
:
1932 if self
.is_svp64_mode
:
1933 return (yield from self
.svstate_post_inc(ins_name
))
1935 # XXX only in non-SVP64 mode!
1936 # record state of whether the current operation was an svshape,
1938 # to be able to know if it should apply in the next instruction.
1939 # also (if going to use this instruction) should disable ability
1940 # to interrupt in between. sigh.
1941 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
1948 log("SVSTATE_NEXT: inc requested, mode",
1949 self
.svstate_next_mode
, self
.allow_next_step_inc
)
1950 yield from self
.svstate_pre_inc()
1951 pre
= yield from self
.update_new_svstate_steps()
1953 # reset at end of loop including exit Vertical Mode
1954 log("SVSTATE_NEXT: end of loop, reset")
1955 self
.svp64_reset_loop()
1956 self
.svstate
.vfirst
= 0
1960 results
= [SelectableInt(0, 64)]
1961 self
.handle_comparison(results
) # CR0
1963 if self
.allow_next_step_inc
== 2:
1964 log("SVSTATE_NEXT: read")
1965 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1967 log("SVSTATE_NEXT: post-inc")
1968 # use actual src/dst-step here to check end, do NOT
1969 # use bit-reversed version
1970 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1971 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1972 remaps
= self
.get_remap_indices()
1973 remap_idxs
= self
.remap_idxs
1974 vl
= self
.svstate
.vl
1975 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1976 end_src
= srcstep
== vl
-1
1977 end_dst
= dststep
== vl
-1
1978 if self
.allow_next_step_inc
!= 2:
1979 yield from self
.advance_svstate_steps(end_src
, end_dst
)
1980 #self.namespace['SVSTATE'] = self.svstate.spr
1981 # set CR0 (if Rc=1) based on end
1983 endtest
= 1 if (end_src
or end_dst
) else 0
1984 #results = [SelectableInt(endtest, 64)]
1985 # self.handle_comparison(results) # CR0
1987 # see if svstep was requested, if so, which SVSTATE
1989 if self
.svstate_next_mode
> 0:
1990 shape_idx
= self
.svstate_next_mode
.value
-1
1991 endings
= self
.remap_loopends
[shape_idx
]
1992 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
1993 log("svstep Rc=1, CR0", cr_field
)
1994 self
.crl
[0].eq(cr_field
) # CR0
1995 if end_src
or end_dst
:
1996 # reset at end of loop including exit Vertical Mode
1997 log("SVSTATE_NEXT: after increments, reset")
1998 self
.svp64_reset_loop()
1999 self
.svstate
.vfirst
= 0
2002 def SVSTATE_NEXT(self
, mode
, submode
):
2003 """explicitly moves srcstep/dststep on to next element, for
2004 "Vertical-First" mode. this function is called from
2005 setvl pseudo-code, as a pseudo-op "svstep"
2007 WARNING: this function uses information that was created EARLIER
2008 due to it being in the middle of a yield, but this function is
2009 *NOT* called from yield (it's called from compiled pseudocode).
2011 self
.allow_next_step_inc
= submode
.value
+ 1
2012 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2013 self
.svstate_next_mode
= mode
2014 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2015 shape_idx
= self
.svstate_next_mode
.value
-1
2016 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2017 if self
.svstate_next_mode
== 5:
2018 self
.svstate_next_mode
= 0
2019 return SelectableInt(self
.svstate
.srcstep
, 7)
2020 if self
.svstate_next_mode
== 6:
2021 self
.svstate_next_mode
= 0
2022 return SelectableInt(self
.svstate
.dststep
, 7)
2023 return SelectableInt(0, 7)
2025 def get_src_dststeps(self
):
2026 """gets srcstep, dststep, and ssubstep, dsubstep
2028 return (self
.new_srcstep
, self
.new_dststep
,
2029 self
.new_ssubstep
, self
.new_dsubstep
)
2031 def update_new_svstate_steps(self
):
2032 # note, do not get the bit-reversed srcstep here!
2033 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2034 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2036 # update SVSTATE with new srcstep
2037 self
.svstate
.srcstep
= srcstep
2038 self
.svstate
.dststep
= dststep
2039 self
.svstate
.ssubstep
= ssubstep
2040 self
.svstate
.dsubstep
= dsubstep
2041 self
.namespace
['SVSTATE'] = self
.svstate
2042 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2043 yield Settle() # let decoder update
2044 srcstep
= self
.svstate
.srcstep
2045 dststep
= self
.svstate
.dststep
2046 ssubstep
= self
.svstate
.ssubstep
2047 dsubstep
= self
.svstate
.dsubstep
2048 pack
= self
.svstate
.pack
2049 unpack
= self
.svstate
.unpack
2050 vl
= self
.svstate
.vl
2051 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2052 log(" srcstep", srcstep
)
2053 log(" dststep", dststep
)
2055 log(" unpack", unpack
)
2056 log(" ssubstep", ssubstep
)
2057 log(" dsubstep", dsubstep
)
2059 log(" subvl", subvl
)
2061 # check if end reached (we let srcstep overrun, above)
2062 # nothing needs doing (TODO zeroing): just do next instruction
2063 return ((ssubstep
== subvl
and srcstep
== vl
) or
2064 (dsubstep
== subvl
and dststep
== vl
))
2066 def svstate_post_inc(self
, insn_name
, vf
=0):
2067 # check if SV "Vertical First" mode is enabled
2068 vfirst
= self
.svstate
.vfirst
2069 log(" SV Vertical First", vf
, vfirst
)
2070 if not vf
and vfirst
== 1:
2074 # check if it is the SVSTATE.src/dest step that needs incrementing
2075 # this is our Sub-Program-Counter loop from 0 to VL-1
2076 # XXX twin predication TODO
2077 vl
= self
.svstate
.vl
2078 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2079 mvl
= self
.svstate
.maxvl
2080 srcstep
= self
.svstate
.srcstep
2081 dststep
= self
.svstate
.dststep
2082 ssubstep
= self
.svstate
.ssubstep
2083 dsubstep
= self
.svstate
.dsubstep
2084 pack
= self
.svstate
.pack
2085 unpack
= self
.svstate
.unpack
2086 rm_mode
= yield self
.dec2
.rm_dec
.mode
2087 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2088 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2089 out_vec
= not (yield self
.dec2
.no_out_vec
)
2090 in_vec
= not (yield self
.dec2
.no_in_vec
)
2091 log(" svstate.vl", vl
)
2092 log(" svstate.mvl", mvl
)
2093 log(" rm.subvl", subvl
)
2094 log(" svstate.srcstep", srcstep
)
2095 log(" svstate.dststep", dststep
)
2096 log(" svstate.ssubstep", ssubstep
)
2097 log(" svstate.dsubstep", dsubstep
)
2098 log(" svstate.pack", pack
)
2099 log(" svstate.unpack", unpack
)
2100 log(" mode", rm_mode
)
2101 log(" reverse", reverse_gear
)
2102 log(" out_vec", out_vec
)
2103 log(" in_vec", in_vec
)
2104 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2105 # check if this was an sv.bc* and if so did it succeed
2106 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2107 end_loop
= self
.namespace
['end_loop']
2108 log("branch %s end_loop" % insn_name
, end_loop
)
2110 self
.svp64_reset_loop()
2111 self
.update_pc_next()
2113 # check if srcstep needs incrementing by one, stop PC advancing
2114 # but for 2-pred both src/dest have to be checked.
2115 # XXX this might not be true! it may just be LD/ST
2116 if sv_ptype
== SVPtype
.P2
.value
:
2117 svp64_is_vector
= (out_vec
or in_vec
)
2119 svp64_is_vector
= out_vec
2120 # loops end at the first "hit" (source or dest)
2121 end_src
= srcstep
== vl
-1
2122 end_dst
= dststep
== vl
-1
2123 loopend
= ((end_src
and ssubstep
== subvl
) or
2124 (end_dst
and dsubstep
== subvl
))
2125 log("loopend", svp64_is_vector
, loopend
, end_src
, end_dst
,
2126 ssubstep
== subvl
, dsubstep
== subvl
)
2127 if not svp64_is_vector
or loopend
:
2128 # reset loop to zero and update NIA
2129 self
.svp64_reset_loop()
2134 # still looping, advance and update NIA
2135 yield from self
.advance_svstate_steps(end_src
, end_dst
)
2136 self
.namespace
['SVSTATE'] = self
.svstate
2138 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2139 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2140 # this way we keep repeating the same instruction (with new steps)
2141 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2142 self
.namespace
['NIA'] = self
.pc
.NIA
2143 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2144 return False # DO NOT allow PC update whilst Sub-PC loop running
2146 def update_pc_next(self
):
2147 # UPDATE program counter
2148 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2149 #self.svstate.spr = self.namespace['SVSTATE']
2150 log("end of call", self
.namespace
['CIA'],
2151 self
.namespace
['NIA'],
2152 self
.namespace
['SVSTATE'])
2154 def svp64_reset_loop(self
):
2155 self
.svstate
.srcstep
= 0
2156 self
.svstate
.dststep
= 0
2157 self
.svstate
.ssubstep
= 0
2158 self
.svstate
.dsubstep
= 0
2159 log(" svstate.srcstep loop end (PC to update)")
2160 self
.namespace
['SVSTATE'] = self
.svstate
2162 def update_nia(self
):
2163 self
.pc
.update_nia(self
.is_svp64_mode
)
2164 self
.namespace
['NIA'] = self
.pc
.NIA
2168 """Decorator factory.
2170 this decorator will "inject" variables into the function's namespace,
2171 from the *dictionary* in self.namespace. it therefore becomes possible
2172 to make it look like a whole stack of variables which would otherwise
2173 need "self." inserted in front of them (*and* for those variables to be
2174 added to the instance) "appear" in the function.
2176 "self.namespace['SI']" for example becomes accessible as just "SI" but
2177 *only* inside the function, when decorated.
2179 def variable_injector(func
):
2181 def decorator(*args
, **kwargs
):
2183 func_globals
= func
.__globals
__ # Python 2.6+
2184 except AttributeError:
2185 func_globals
= func
.func_globals
# Earlier versions.
2187 context
= args
[0].namespace
# variables to be injected
2188 saved_values
= func_globals
.copy() # Shallow copy of dict.
2189 log("globals before", context
.keys())
2190 func_globals
.update(context
)
2191 result
= func(*args
, **kwargs
)
2192 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2193 log("args[0]", args
[0].namespace
['CIA'],
2194 args
[0].namespace
['NIA'],
2195 args
[0].namespace
['SVSTATE'])
2196 if 'end_loop' in func_globals
:
2197 log("args[0] end_loop", func_globals
['end_loop'])
2198 args
[0].namespace
= func_globals
2199 #exec (func.__code__, func_globals)
2202 # func_globals = saved_values # Undo changes.
2208 return variable_injector