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
100 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
103 def create_args(reglist
, extra
=None):
104 retval
= list(OrderedSet(reglist
))
105 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
106 if extra
is not None:
107 return [extra
] + retval
112 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
115 self
.isacaller
= isacaller
116 self
.svstate
= svstate
117 for i
in range(len(regfile
)):
118 self
[i
] = SelectableInt(regfile
[i
], 64)
120 def __call__(self
, ridx
):
121 if isinstance(ridx
, SelectableInt
):
125 def set_form(self
, form
):
128 def __setitem__(self
, rnum
, value
):
129 # rnum = rnum.value # only SelectableInt allowed
130 log("GPR setitem", rnum
, value
)
131 if isinstance(rnum
, SelectableInt
):
133 dict.__setitem
__(self
, rnum
, value
)
135 def getz(self
, rnum
):
136 # rnum = rnum.value # only SelectableInt allowed
137 log("GPR getzero?", rnum
)
139 return SelectableInt(0, 64)
142 def _get_regnum(self
, attr
):
143 getform
= self
.sd
.sigforms
[self
.form
]
144 rnum
= getattr(getform
, attr
)
147 def ___getitem__(self
, attr
):
148 """ XXX currently not used
150 rnum
= self
._get
_regnum
(attr
)
151 log("GPR getitem", attr
, rnum
)
152 return self
.regfile
[rnum
]
154 def dump(self
, printout
=True):
156 for i
in range(len(self
)):
157 res
.append(self
[i
].value
)
159 for i
in range(0, len(res
), 8):
162 s
.append("%08x" % res
[i
+j
])
164 print("reg", "%2d" % i
, s
)
169 def __init__(self
, dec2
, initial_sprs
={}):
172 for key
, v
in initial_sprs
.items():
173 if isinstance(key
, SelectableInt
):
175 key
= special_sprs
.get(key
, key
)
176 if isinstance(key
, int):
179 info
= spr_byname
[key
]
180 if not isinstance(v
, SelectableInt
):
181 v
= SelectableInt(v
, info
.length
)
184 def __getitem__(self
, key
):
186 log("dict", self
.items())
187 # if key in special_sprs get the special spr, otherwise return key
188 if isinstance(key
, SelectableInt
):
190 if isinstance(key
, int):
191 key
= spr_dict
[key
].SPR
192 key
= special_sprs
.get(key
, key
)
193 if key
== 'HSRR0': # HACK!
195 if key
== 'HSRR1': # HACK!
198 res
= dict.__getitem
__(self
, key
)
200 if isinstance(key
, int):
203 info
= spr_byname
[key
]
204 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
205 res
= dict.__getitem
__(self
, key
)
206 log("spr returning", key
, res
)
209 def __setitem__(self
, key
, value
):
210 if isinstance(key
, SelectableInt
):
212 if isinstance(key
, int):
213 key
= spr_dict
[key
].SPR
215 key
= special_sprs
.get(key
, key
)
216 if key
== 'HSRR0': # HACK!
217 self
.__setitem
__('SRR0', value
)
218 if key
== 'HSRR1': # HACK!
219 self
.__setitem
__('SRR1', value
)
220 log("setting spr", key
, value
)
221 dict.__setitem
__(self
, key
, value
)
223 def __call__(self
, ridx
):
226 def dump(self
, printout
=True):
228 keys
= list(self
.keys())
231 sprname
= spr_dict
.get(k
, None)
235 sprname
= sprname
.SPR
236 res
.append((sprname
, self
[k
].value
))
238 for sprname
, value
in res
:
239 print(" ", sprname
, hex(value
))
244 def __init__(self
, pc_init
=0):
245 self
.CIA
= SelectableInt(pc_init
, 64)
246 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
248 def update_nia(self
, is_svp64
):
249 increment
= 8 if is_svp64
else 4
250 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
252 def update(self
, namespace
, is_svp64
):
253 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
255 self
.CIA
= namespace
['NIA'].narrow(64)
256 self
.update_nia(is_svp64
)
257 namespace
['CIA'] = self
.CIA
258 namespace
['NIA'] = self
.NIA
262 # See PowerISA Version 3.0 B Book 1
263 # Section 2.3.1 Condition Register pages 30 - 31
265 LT
= FL
= 0 # negative, less than, floating-point less than
266 GT
= FG
= 1 # positive, greater than, floating-point greater than
267 EQ
= FE
= 2 # equal, floating-point equal
268 SO
= FU
= 3 # summary overflow, floating-point unordered
270 def __init__(self
, init
=0):
271 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
272 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
273 self
.cr
= SelectableInt(init
, 64) # underlying reg
274 # field-selectable versions of Condition Register TODO check bitranges?
277 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
278 _cr
= FieldSelectableInt(self
.cr
, bits
)
281 # decode SVP64 predicate integer to reg number and invert
284 def get_predint(gpr
, mask
):
287 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
288 if mask
== SVP64PredInt
.ALWAYS
.value
:
289 return 0xffff_ffff_ffff_ffff # 64 bits of 1
290 if mask
== SVP64PredInt
.R3_UNARY
.value
:
291 return 1 << (gpr(3).value
& 0b111111)
292 if mask
== SVP64PredInt
.R3
.value
:
294 if mask
== SVP64PredInt
.R3_N
.value
:
296 if mask
== SVP64PredInt
.R10
.value
:
298 if mask
== SVP64PredInt
.R10_N
.value
:
299 return ~
gpr(10).value
300 if mask
== SVP64PredInt
.R30
.value
:
302 if mask
== SVP64PredInt
.R30_N
.value
:
303 return ~
gpr(30).value
305 # decode SVP64 predicate CR to reg number and invert status
308 def _get_predcr(mask
):
309 if mask
== SVP64PredCR
.LT
.value
:
311 if mask
== SVP64PredCR
.GE
.value
:
313 if mask
== SVP64PredCR
.GT
.value
:
315 if mask
== SVP64PredCR
.LE
.value
:
317 if mask
== SVP64PredCR
.EQ
.value
:
319 if mask
== SVP64PredCR
.NE
.value
:
321 if mask
== SVP64PredCR
.SO
.value
:
323 if mask
== SVP64PredCR
.NS
.value
:
326 # read individual CR fields (0..VL-1), extract the required bit
327 # and construct the mask
330 def get_predcr(crl
, mask
, vl
):
331 idx
, noninv
= _get_predcr(mask
)
334 cr
= crl
[i
+SVP64CROffs
.CRPred
]
335 if cr
[idx
].value
== noninv
:
340 # TODO, really should just be using PowerDecoder2
341 def get_pdecode_idx_in(dec2
, name
):
343 in1_sel
= yield op
.in1_sel
344 in2_sel
= yield op
.in2_sel
345 in3_sel
= yield op
.in3_sel
346 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
347 in1
= yield dec2
.e
.read_reg1
.data
348 in2
= yield dec2
.e
.read_reg2
.data
349 in3
= yield dec2
.e
.read_reg3
.data
350 in1_isvec
= yield dec2
.in1_isvec
351 in2_isvec
= yield dec2
.in2_isvec
352 in3_isvec
= yield dec2
.in3_isvec
353 log("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
355 log("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
357 log("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
359 log("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
361 log("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
363 log("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
365 # identify which regnames map to in1/2/3
366 if name
== 'RA' or name
== 'RA_OR_ZERO':
367 if (in1_sel
== In1Sel
.RA
.value
or
368 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
369 return in1
, in1_isvec
370 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
371 return in1
, in1_isvec
373 if in2_sel
== In2Sel
.RB
.value
:
374 return in2
, in2_isvec
375 if in3_sel
== In3Sel
.RB
.value
:
376 return in3
, in3_isvec
377 # XXX TODO, RC doesn't exist yet!
379 if in3_sel
== In3Sel
.RC
.value
:
380 return in3
, in3_isvec
381 assert False, "RC does not exist yet"
383 if in1_sel
== In1Sel
.RS
.value
:
384 return in1
, in1_isvec
385 if in2_sel
== In2Sel
.RS
.value
:
386 return in2
, in2_isvec
387 if in3_sel
== In3Sel
.RS
.value
:
388 return in3
, in3_isvec
390 if in1_sel
== In1Sel
.FRA
.value
:
391 return in1
, in1_isvec
393 if in2_sel
== In2Sel
.FRB
.value
:
394 return in2
, in2_isvec
396 if in3_sel
== In3Sel
.FRC
.value
:
397 return in3
, in3_isvec
399 if in1_sel
== In1Sel
.FRS
.value
:
400 return in1
, in1_isvec
401 if in3_sel
== In3Sel
.FRS
.value
:
402 return in3
, in3_isvec
406 # TODO, really should just be using PowerDecoder2
407 def get_pdecode_cr_in(dec2
, name
):
409 in_sel
= yield op
.cr_in
410 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
411 sv_cr_in
= yield op
.sv_cr_in
412 spec
= yield dec2
.crin_svdec
.spec
413 sv_override
= yield dec2
.dec_cr_in
.sv_override
414 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
415 in1
= yield dec2
.e
.read_cr1
.data
416 cr_isvec
= yield dec2
.cr_in_isvec
417 log("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
418 log(" sv_cr_in", sv_cr_in
)
419 log(" cr_bf", in_bitfield
)
421 log(" override", sv_override
)
422 # identify which regnames map to in / o2
424 if in_sel
== CRInSel
.BI
.value
:
426 log("get_pdecode_cr_in not found", name
)
430 # TODO, really should just be using PowerDecoder2
431 def get_pdecode_cr_out(dec2
, name
):
433 out_sel
= yield op
.cr_out
434 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
435 sv_cr_out
= yield op
.sv_cr_out
436 spec
= yield dec2
.crout_svdec
.spec
437 sv_override
= yield dec2
.dec_cr_out
.sv_override
438 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
439 out
= yield dec2
.e
.write_cr
.data
440 o_isvec
= yield dec2
.o_isvec
441 log("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
442 log(" sv_cr_out", sv_cr_out
)
443 log(" cr_bf", out_bitfield
)
445 log(" override", sv_override
)
446 # identify which regnames map to out / o2
448 if out_sel
== CROutSel
.CR0
.value
:
450 if name
== 'CR1': # these are not actually calculated correctly
451 if out_sel
== CROutSel
.CR1
.value
:
453 log("get_pdecode_cr_out not found", name
)
457 # TODO, really should just be using PowerDecoder2
458 def get_pdecode_idx_out(dec2
, name
):
460 out_sel
= yield op
.out_sel
461 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
462 out
= yield dec2
.e
.write_reg
.data
463 o_isvec
= yield dec2
.o_isvec
464 # identify which regnames map to out / o2
466 log("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
467 if out_sel
== OutSel
.RA
.value
:
470 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
471 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
473 if out_sel
== OutSel
.RT
.value
:
475 if out_sel
== OutSel
.RT_OR_ZERO
.value
and out
!= 0:
477 elif name
== 'RT_OR_ZERO':
478 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
479 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
481 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
484 log("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
485 if out_sel
== OutSel
.FRA
.value
:
488 log("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
489 OutSel
.FRT
.value
, out
, o_isvec
)
490 if out_sel
== OutSel
.FRT
.value
:
492 log("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
496 # TODO, really should just be using PowerDecoder2
497 def get_pdecode_idx_out2(dec2
, name
):
498 # check first if register is activated for write
500 out_sel
= yield op
.out_sel
501 out
= yield dec2
.e
.write_ea
.data
502 o_isvec
= yield dec2
.o2_isvec
503 out_ok
= yield dec2
.e
.write_ea
.ok
504 log("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
509 if hasattr(op
, "upd"):
510 # update mode LD/ST uses read-reg A also as an output
512 log("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
513 out_sel
, OutSel
.RA
.value
,
515 if upd
== LDSTMode
.update
.value
:
518 int_op
= yield dec2
.dec
.op
.internal_op
519 fft_en
= yield dec2
.use_svp64_fft
520 # if int_op == MicrOp.OP_FP_MADD.value and fft_en:
522 log("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
529 """deals with svstate looping.
532 def __init__(self
, svstate
):
533 self
.svstate
= svstate
535 def get_iterators(self
):
536 self
.src_it
= self
.src_iterator()
537 self
.dst_it
= self
.dst_iterator()
539 def src_iterator(self
):
540 """source-stepping iterator
542 pack
= self
.svstate
.pack
546 # pack advances subvl in *outer* loop
549 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
550 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
552 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
554 # these cannot be done as for-loops because SVSTATE may change
555 # (srcstep/substep may be modified, interrupted, subvl/vl change)
556 # but they *can* be done as while-loops as long as every SVSTATE
557 # "thing" is re-read every single time a yield gives indices
558 while True: # outer vl loop
559 while True: # inner subvl loop
561 srcmask
= self
.srcmask
562 srcstep
= self
.svstate
.srcstep
563 if self
.pred_sz
or ((1 << srcstep
) & srcmask
) != 0:
564 log(" advance src", srcstep
, self
.svstate
.vl
,
565 self
.svstate
.ssubstep
, subvl
)
566 # yield actual substep/srcstep
567 yield (self
.svstate
.ssubstep
, srcstep
)
568 if self
.svstate
.ssubstep
== subvl
: # end-point
569 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
571 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
573 if srcstep
== vl
-1: # end-point
574 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
575 break # trigger StopIteration
576 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
578 def dst_iterator(self
):
579 """dest-stepping iterator
581 unpack
= self
.svstate
.unpack
585 # pack advances subvl in *outer* loop
588 # these cannot be done as for-loops because SVSTATE may change
589 # (dststep/substep may be modified, interrupted, subvl/vl change)
590 # but they *can* be done as while-loops as long as every SVSTATE
591 # "thing" is re-read every single time a yield gives indices
592 while True: # outer vl loop
593 while True: # inner subvl loop
595 dstmask
= self
.dstmask
596 dststep
= self
.svstate
.dststep
597 if self
.pred_dz
or ((1 << dststep
) & dstmask
) != 0:
598 log(" advance dst", dststep
, self
.svstate
.vl
,
599 self
.svstate
.dsubstep
, subvl
)
600 # yield actual substep/dststep
601 yield (self
.svstate
.dsubstep
, dststep
)
602 if self
.svstate
.dsubstep
== subvl
: # end-point
603 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
605 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
607 if dststep
== vl
-1: # end-point
608 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
609 break # trigger StopIteration
610 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
612 def src_iterate(self
):
613 """source-stepping iterator
615 end_src
= self
.end_src
617 pack
= self
.svstate
.pack
618 unpack
= self
.svstate
.unpack
619 ssubstep
= self
.svstate
.ssubstep
620 end_ssub
= ssubstep
== subvl
621 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
625 srcstep
= self
.svstate
.srcstep
627 # pack advances subvl in *outer* loop
630 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
631 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
633 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
635 # advance subvl in *inner* loop
638 self
.svstate
.srcstep
+= SelectableInt(1, 7)
639 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
642 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
644 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
)
646 def dst_iterate(self
):
647 """dest step iterator
649 end_dst
= self
.end_dst
651 pack
= self
.svstate
.pack
652 unpack
= self
.svstate
.unpack
653 dsubstep
= self
.svstate
.dsubstep
654 end_dsub
= dsubstep
== subvl
655 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
660 # unpack advances subvl in *outer* loop
663 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
664 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
666 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
668 # advance subvl in *inner* loop
671 self
.svstate
.dststep
+= SelectableInt(1, 7)
672 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
675 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
676 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
)
678 def advance_svstate_steps(self
, end_src
=False, end_dst
=False):
679 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
680 TODO when Pack/Unpack is set, substep becomes the *outer* loop
682 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
683 self
.end_src
= end_src
684 self
.end_dst
= end_dst
688 def read_src_mask(self
):
689 """read/update pred_sz and src mask
691 # get SVSTATE VL (oh and print out some debug stuff)
693 srcstep
= self
.svstate
.srcstep
694 ssubstep
= self
.svstate
.ssubstep
696 # get predicate mask (all 64 bits)
697 srcmask
= 0xffff_ffff_ffff_ffff
699 pmode
= yield self
.dec2
.rm_dec
.predmode
700 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
701 srcpred
= yield self
.dec2
.rm_dec
.srcpred
702 dstpred
= yield self
.dec2
.rm_dec
.dstpred
703 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
704 if pmode
== SVP64PredMode
.INT
.value
:
705 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
706 if sv_ptype
== SVPtype
.P2
.value
:
707 srcmask
= get_predint(self
.gpr
, srcpred
)
708 elif pmode
== SVP64PredMode
.CR
.value
:
709 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
710 if sv_ptype
== SVPtype
.P2
.value
:
711 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
712 # work out if the ssubsteps are completed
713 ssubstart
= ssubstep
== 0
715 log(" ptype", sv_ptype
)
716 log(" srcpred", bin(srcpred
))
717 log(" srcmask", bin(srcmask
))
718 log(" pred_sz", bin(pred_sz
))
719 log(" ssubstart", ssubstart
)
721 # store all that above
722 self
.srcstep_skip
= False
723 self
.srcmask
= srcmask
724 self
.pred_sz
= pred_sz
725 self
.new_ssubstep
= ssubstep
726 log(" new ssubstep", ssubstep
)
728 # until the predicate mask has a "1" bit... or we run out of VL
729 # let srcstep==VL be the indicator to move to next instruction
731 self
.srcstep_skip
= True
733 def read_dst_mask(self
):
734 """same as read_src_mask - check and record everything needed
736 # get SVSTATE VL (oh and print out some debug stuff)
737 # yield Delay(1e-10) # make changes visible
739 dststep
= self
.svstate
.dststep
740 dsubstep
= self
.svstate
.dsubstep
742 # get predicate mask (all 64 bits)
743 dstmask
= 0xffff_ffff_ffff_ffff
745 pmode
= yield self
.dec2
.rm_dec
.predmode
746 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
747 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
748 dstpred
= yield self
.dec2
.rm_dec
.dstpred
749 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
750 if pmode
== SVP64PredMode
.INT
.value
:
751 dstmask
= get_predint(self
.gpr
, dstpred
)
752 elif pmode
== SVP64PredMode
.CR
.value
:
753 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
754 # work out if the ssubsteps are completed
755 dsubstart
= dsubstep
== 0
757 log(" ptype", sv_ptype
)
758 log(" dstpred", bin(dstpred
))
759 log(" dstmask", bin(dstmask
))
760 log(" pred_dz", bin(pred_dz
))
761 log(" dsubstart", dsubstart
)
763 self
.dststep_skip
= False
764 self
.dstmask
= dstmask
765 self
.pred_dz
= pred_dz
766 self
.new_dsubstep
= dsubstep
767 log(" new dsubstep", dsubstep
)
770 self
.dststep_skip
= True
772 def svstate_pre_inc(self
):
773 """check if srcstep/dststep need to skip over masked-out predicate bits
774 note that this is not supposed to do anything to substep,
775 it is purely for skipping masked-out bits
778 yield from self
.read_src_mask()
779 yield from self
.read_dst_mask()
786 srcstep
= self
.svstate
.srcstep
787 srcmask
= self
.srcmask
788 pred_src_zero
= self
.pred_sz
790 # srcstep-skipping opportunity identified
791 if self
.srcstep_skip
:
792 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
793 log(" sskip", bin(1 << srcstep
))
796 # now work out if the relevant mask bits require zeroing
798 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
800 # store new srcstep / dststep
801 self
.new_srcstep
= srcstep
802 self
.pred_src_zero
= pred_src_zero
803 log(" new srcstep", srcstep
)
806 # dststep-skipping opportunity identified
807 dststep
= self
.svstate
.dststep
808 dstmask
= self
.dstmask
809 pred_dst_zero
= self
.pred_dz
811 if self
.dststep_skip
:
812 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
813 log(" dskip", bin(1 << dststep
))
816 # now work out if the relevant mask bits require zeroing
818 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
820 # store new srcstep / dststep
821 self
.new_dststep
= dststep
822 self
.pred_dst_zero
= pred_dst_zero
823 log(" new dststep", dststep
)
826 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
827 # decoder2 - an instance of power_decoder2
828 # regfile - a list of initial values for the registers
829 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
830 # respect_pc - tracks the program counter. requires initial_insns
831 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
832 initial_mem
=None, initial_msr
=0,
843 self
.bigendian
= bigendian
845 self
.is_svp64_mode
= False
846 self
.respect_pc
= respect_pc
847 if initial_sprs
is None:
849 if initial_mem
is None:
851 if fpregfile
is None:
853 if initial_insns
is None:
855 assert self
.respect_pc
== False, "instructions required to honor pc"
857 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
858 log("ISACaller initial_msr", initial_msr
)
860 # "fake program counter" mode (for unit testing)
864 if isinstance(initial_mem
, tuple):
865 self
.fake_pc
= initial_mem
[0]
866 disasm_start
= self
.fake_pc
868 disasm_start
= initial_pc
870 # disassembly: we need this for now (not given from the decoder)
871 self
.disassembly
= {}
873 for i
, code
in enumerate(disassembly
):
874 self
.disassembly
[i
*4 + disasm_start
] = code
876 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
877 self
.svp64rm
= SVP64RM()
878 if initial_svstate
is None:
880 if isinstance(initial_svstate
, int):
881 initial_svstate
= SVP64State(initial_svstate
)
882 # SVSTATE, MSR and PC
883 StepLoop
.__init
__(self
, initial_svstate
)
884 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
886 # GPR FPR SPR registers
887 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
888 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
889 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
890 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
892 # set up 4 dummy SVSHAPEs if they aren't already set up
894 sname
= 'SVSHAPE%d' % i
895 if sname
not in self
.spr
:
898 val
= self
.spr
[sname
].value
899 # make sure it's an SVSHAPE
900 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
901 self
.last_op_svshape
= False
904 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
905 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
906 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
907 # MMU mode, redirect underlying Mem through RADIX
909 self
.mem
= RADIX(self
.mem
, self
)
911 self
.imem
= RADIX(self
.imem
, self
)
914 # FPR (same as GPR except for FP nums)
915 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
916 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
917 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
918 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
920 # 2.3.2 LR (actually SPR #8) -- Done
921 # 2.3.3 CTR (actually SPR #9) -- Done
922 # 2.3.4 TAR (actually SPR #815)
923 # 3.2.2 p45 XER (actually SPR #1) -- Done
924 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
926 # create CR then allow portions of it to be "selectable" (below)
927 self
.cr_fields
= CRFields(initial_cr
)
928 self
.cr
= self
.cr_fields
.cr
930 # "undefined", just set to variable-bit-width int (use exts "max")
931 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
934 self
.namespace
.update(self
.spr
)
935 self
.namespace
.update({'GPR': self
.gpr
,
939 'memassign': self
.memassign
,
942 'SVSTATE': self
.svstate
,
943 'SVSHAPE0': self
.spr
['SVSHAPE0'],
944 'SVSHAPE1': self
.spr
['SVSHAPE1'],
945 'SVSHAPE2': self
.spr
['SVSHAPE2'],
946 'SVSHAPE3': self
.spr
['SVSHAPE3'],
949 'undefined': undefined
,
950 'mode_is_64bit': True,
951 'SO': XER_bits
['SO'],
952 'XLEN': 64 # elwidth overrides, later
955 # update pc to requested start point
956 self
.set_pc(initial_pc
)
958 # field-selectable versions of Condition Register
959 self
.crl
= self
.cr_fields
.crl
961 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
963 self
.decoder
= decoder2
.dec
966 super().__init
__(XLEN
=self
.namespace
["XLEN"])
970 return self
.namespace
["XLEN"]
972 def call_trap(self
, trap_addr
, trap_bit
):
973 """calls TRAP and sets up NIA to the new execution location.
974 next instruction will begin at trap_addr.
976 self
.TRAP(trap_addr
, trap_bit
)
977 self
.namespace
['NIA'] = self
.trap_nia
978 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
980 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
981 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
983 TRAP function is callable from inside the pseudocode itself,
984 hence the default arguments. when calling from inside ISACaller
985 it is best to use call_trap()
987 # https://bugs.libre-soc.org/show_bug.cgi?id=859
988 kaivb
= self
.spr
['KAIVB'].value
989 msr
= self
.namespace
['MSR'].value
990 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
991 # store CIA(+4?) in SRR0, set NIA to 0x700
992 # store MSR in SRR1, set MSR to um errr something, have to check spec
993 # store SVSTATE (if enabled) in SVSRR0
994 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
995 self
.spr
['SRR1'].value
= msr
996 if self
.is_svp64_mode
:
997 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
998 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
999 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1001 # set exception bits. TODO: this should, based on the address
1002 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1003 # bits appropriately. however it turns out that *for now* in all
1004 # cases (all trap_addrs) the exact same thing is needed.
1005 self
.msr
[MSRb
.IR
] = 0
1006 self
.msr
[MSRb
.DR
] = 0
1007 self
.msr
[MSRb
.FE0
] = 0
1008 self
.msr
[MSRb
.FE1
] = 0
1009 self
.msr
[MSRb
.EE
] = 0
1010 self
.msr
[MSRb
.RI
] = 0
1011 self
.msr
[MSRb
.SF
] = 1
1012 self
.msr
[MSRb
.TM
] = 0
1013 self
.msr
[MSRb
.VEC
] = 0
1014 self
.msr
[MSRb
.VSX
] = 0
1015 self
.msr
[MSRb
.PR
] = 0
1016 self
.msr
[MSRb
.FP
] = 0
1017 self
.msr
[MSRb
.PMM
] = 0
1018 self
.msr
[MSRb
.TEs
] = 0
1019 self
.msr
[MSRb
.TEe
] = 0
1020 self
.msr
[MSRb
.UND
] = 0
1021 self
.msr
[MSRb
.LE
] = 1
1023 def memassign(self
, ea
, sz
, val
):
1024 self
.mem
.memassign(ea
, sz
, val
)
1026 def prep_namespace(self
, insn_name
, formname
, op_fields
):
1027 # TODO: get field names from form in decoder*1* (not decoder2)
1028 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1030 # then "yield" fields only from op_fields rather than hard-coded
1032 fields
= self
.decoder
.sigforms
[formname
]
1033 log("prep_namespace", formname
, op_fields
, insn_name
)
1034 for name
in op_fields
:
1035 # CR immediates. deal with separately. needs modifying
1037 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1038 # BI is a 5-bit, must reconstruct the value
1039 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
1040 sig
= getattr(fields
, name
)
1042 # low 2 LSBs (CR field selector) remain same, CR num extended
1043 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1044 val
= (val
& 0b11) |
(regnum
<< 2)
1046 sig
= getattr(fields
, name
)
1048 # these are all opcode fields involved in index-selection of CR,
1049 # and need to do "standard" arithmetic. CR[BA+32] for example
1050 # would, if using SelectableInt, only be 5-bit.
1051 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1052 self
.namespace
[name
] = val
1054 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1056 self
.namespace
['XER'] = self
.spr
['XER']
1057 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1058 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1060 # add some SVSTATE convenience variables
1061 vl
= self
.svstate
.vl
1062 srcstep
= self
.svstate
.srcstep
1063 self
.namespace
['VL'] = vl
1064 self
.namespace
['srcstep'] = srcstep
1066 # sv.bc* need some extra fields
1067 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1068 # blegh grab bits manually
1069 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1070 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
1071 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
1072 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
1073 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1074 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1075 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1076 sz
= yield self
.dec2
.rm_dec
.pred_sz
1077 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1078 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1079 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1080 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1081 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1082 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1083 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1085 def handle_carry_(self
, inputs
, outputs
, already_done
):
1086 inv_a
= yield self
.dec2
.e
.do
.invert_in
1088 inputs
[0] = ~inputs
[0]
1090 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1092 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1093 inputs
.append(SelectableInt(imm
, 64))
1094 assert len(outputs
) >= 1
1095 log("outputs", repr(outputs
))
1096 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
1102 log("gt input", x
, output
)
1103 gt
= (gtu(x
, output
))
1106 cy
= 1 if any(gts
) else 0
1108 if not (1 & already_done
):
1109 self
.spr
['XER'][XER_bits
['CA']] = cy
1111 log("inputs", already_done
, inputs
)
1113 # ARGH... different for OP_ADD... *sigh*...
1114 op
= yield self
.dec2
.e
.do
.insn_type
1115 if op
== MicrOp
.OP_ADD
.value
:
1116 res32
= (output
.value
& (1 << 32)) != 0
1117 a32
= (inputs
[0].value
& (1 << 32)) != 0
1118 if len(inputs
) >= 2:
1119 b32
= (inputs
[1].value
& (1 << 32)) != 0
1122 cy32
= res32 ^ a32 ^ b32
1123 log("CA32 ADD", cy32
)
1127 log("input", x
, output
)
1128 log(" x[32:64]", x
, x
[32:64])
1129 log(" o[32:64]", output
, output
[32:64])
1130 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1132 cy32
= 1 if any(gts
) else 0
1133 log("CA32", cy32
, gts
)
1134 if not (2 & already_done
):
1135 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1137 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
1138 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1139 inv_a
= yield self
.dec2
.e
.do
.invert_in
1141 inputs
[0] = ~inputs
[0]
1143 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1145 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1146 inputs
.append(SelectableInt(imm
, 64))
1147 assert len(outputs
) >= 1
1148 log("handle_overflow", inputs
, outputs
, div_overflow
)
1149 if len(inputs
) < 2 and div_overflow
is None:
1152 # div overflow is different: it's returned by the pseudo-code
1153 # because it's more complex than can be done by analysing the output
1154 if div_overflow
is not None:
1155 ov
, ov32
= div_overflow
, div_overflow
1156 # arithmetic overflow can be done by analysing the input and output
1157 elif len(inputs
) >= 2:
1161 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1162 output_sgn
= exts(output
.value
, output
.bits
) < 0
1163 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1164 output_sgn
!= input_sgn
[0] else 0
1167 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1168 output32_sgn
= exts(output
.value
, 32) < 0
1169 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1170 output32_sgn
!= input32_sgn
[0] else 0
1172 # now update XER OV/OV32/SO
1173 so
= self
.spr
['XER'][XER_bits
['SO']]
1174 new_so
= so | ov
# sticky overflow ORs in old with new
1175 self
.spr
['XER'][XER_bits
['OV']] = ov
1176 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1177 self
.spr
['XER'][XER_bits
['SO']] = new_so
1178 log(" set overflow", ov
, ov32
, so
, new_so
)
1180 def handle_comparison(self
, outputs
, cr_idx
=0, overflow
=None, no_so
=False):
1182 assert isinstance(out
, SelectableInt
), \
1183 "out zero not a SelectableInt %s" % repr(outputs
)
1184 log("handle_comparison", out
.bits
, hex(out
.value
))
1185 # TODO - XXX *processor* in 32-bit mode
1186 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1188 # o32 = exts(out.value, 32)
1189 # print ("handle_comparison exts 32 bit", hex(o32))
1190 out
= exts(out
.value
, out
.bits
)
1191 log("handle_comparison exts", hex(out
))
1192 # create the three main CR flags, EQ GT LT
1193 zero
= SelectableInt(out
== 0, 1)
1194 positive
= SelectableInt(out
> 0, 1)
1195 negative
= SelectableInt(out
< 0, 1)
1196 # get (or not) XER.SO. for setvl this is important *not* to read SO
1198 SO
= SelectableInt(1, 0)
1200 SO
= self
.spr
['XER'][XER_bits
['SO']]
1201 log("handle_comparison SO overflow", SO
, overflow
)
1202 # alternative overflow checking (setvl mainly at the moment)
1203 if overflow
is not None and overflow
== 1:
1204 SO
= SelectableInt(1, 1)
1205 # create the four CR field values and set the required CR field
1206 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1207 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1208 self
.crl
[cr_idx
].eq(cr_field
)
1210 def set_pc(self
, pc_val
):
1211 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1212 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1214 def get_next_insn(self
):
1215 """check instruction
1218 pc
= self
.pc
.CIA
.value
1221 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1223 raise KeyError("no instruction at 0x%x" % pc
)
1226 def setup_one(self
):
1227 """set up one instruction
1229 pc
, insn
= self
.get_next_insn()
1230 yield from self
.setup_next_insn(pc
, insn
)
1232 def setup_next_insn(self
, pc
, ins
):
1233 """set up next instruction
1236 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1237 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1239 yield self
.dec2
.sv_rm
.eq(0)
1240 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1241 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1242 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1243 yield self
.dec2
.state
.pc
.eq(pc
)
1244 if self
.svstate
is not None:
1245 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1247 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1249 opcode
= yield self
.dec2
.dec
.opcode_in
1250 opcode
= SelectableInt(value
=opcode
, bits
=32)
1251 pfx
= SVP64Instruction
.Prefix(opcode
)
1252 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
1253 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
1254 self
.pc
.update_nia(self
.is_svp64_mode
)
1256 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1257 self
.namespace
['NIA'] = self
.pc
.NIA
1258 self
.namespace
['SVSTATE'] = self
.svstate
1259 if not self
.is_svp64_mode
:
1262 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1263 log("svp64.rm", bin(pfx
.rm
))
1264 log(" svstate.vl", self
.svstate
.vl
)
1265 log(" svstate.mvl", self
.svstate
.maxvl
)
1266 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1267 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1268 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1269 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1272 def execute_one(self
):
1273 """execute one instruction
1275 # get the disassembly code for this instruction
1276 if self
.is_svp64_mode
:
1277 if not self
.disassembly
:
1278 code
= yield from self
.get_assembly_name()
1280 code
= self
.disassembly
[self
._pc
+4]
1281 log(" svp64 sim-execute", hex(self
._pc
), code
)
1283 if not self
.disassembly
:
1284 code
= yield from self
.get_assembly_name()
1286 code
= self
.disassembly
[self
._pc
]
1287 log("sim-execute", hex(self
._pc
), code
)
1288 opname
= code
.split(' ')[0]
1290 yield from self
.call(opname
) # execute the instruction
1291 except MemException
as e
: # check for memory errors
1292 if e
.args
[0] == 'unaligned': # alignment error
1293 # run a Trap but set DAR first
1294 print("memory unaligned exception, DAR", e
.dar
)
1295 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1296 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1298 elif e
.args
[0] == 'invalid': # invalid
1299 # run a Trap but set DAR first
1300 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1301 if e
.mode
== 'EXECUTE':
1302 # XXX TODO: must set a few bits in SRR1,
1303 # see microwatt loadstore1.vhdl
1304 # if m_in.segerr = '0' then
1305 # v.srr1(47 - 33) := m_in.invalid;
1306 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1307 # v.srr1(47 - 44) := m_in.badtree;
1308 # v.srr1(47 - 45) := m_in.rc_error;
1309 # v.intr_vec := 16#400#;
1311 # v.intr_vec := 16#480#;
1312 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1314 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1316 # not supported yet:
1317 raise e
# ... re-raise
1319 # don't use this except in special circumstances
1320 if not self
.respect_pc
:
1323 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1324 hex(self
.pc
.NIA
.value
))
1326 def get_assembly_name(self
):
1327 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1328 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1329 dec_insn
= yield self
.dec2
.e
.do
.insn
1330 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1331 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1332 int_op
= yield self
.dec2
.dec
.op
.internal_op
1333 log("get assembly name asmcode", asmcode
, int_op
,
1334 hex(dec_insn
), bin(insn_1_11
))
1335 asmop
= insns
.get(asmcode
, None)
1337 # sigh reconstruct the assembly instruction name
1338 if hasattr(self
.dec2
.e
.do
, "oe"):
1339 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1340 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1344 if hasattr(self
.dec2
.e
.do
, "rc"):
1345 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1346 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1350 # grrrr have to special-case MUL op (see DecodeOE)
1351 log("ov %d en %d rc %d en %d op %d" %
1352 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1353 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1358 if not asmop
.endswith("."): # don't add "." to "andis."
1361 if hasattr(self
.dec2
.e
.do
, "lk"):
1362 lk
= yield self
.dec2
.e
.do
.lk
1365 log("int_op", int_op
)
1366 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1367 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1371 spr_msb
= yield from self
.get_spr_msb()
1372 if int_op
== MicrOp
.OP_MFCR
.value
:
1377 # XXX TODO: for whatever weird reason this doesn't work
1378 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1379 if int_op
== MicrOp
.OP_MTCRF
.value
:
1386 def get_remap_indices(self
):
1387 """WARNING, this function stores remap_idxs and remap_loopends
1388 in the class for later use. this to avoid problems with yield
1390 # go through all iterators in lock-step, advance to next remap_idx
1391 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1392 # get four SVSHAPEs. here we are hard-coding
1393 SVSHAPE0
= self
.spr
['SVSHAPE0']
1394 SVSHAPE1
= self
.spr
['SVSHAPE1']
1395 SVSHAPE2
= self
.spr
['SVSHAPE2']
1396 SVSHAPE3
= self
.spr
['SVSHAPE3']
1397 # set up the iterators
1398 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1399 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1400 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1401 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1404 self
.remap_loopends
= [0] * 4
1405 self
.remap_idxs
= [0, 1, 2, 3]
1407 for i
, (shape
, remap
) in enumerate(remaps
):
1408 # zero is "disabled"
1409 if shape
.value
== 0x0:
1410 self
.remap_idxs
[i
] = 0
1411 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1412 step
= dststep
if (i
in [3, 4]) else srcstep
1413 # this is terrible. O(N^2) looking for the match. but hey.
1414 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1417 self
.remap_idxs
[i
] = remap_idx
1418 self
.remap_loopends
[i
] = loopends
1419 dbg
.append((i
, step
, remap_idx
, loopends
))
1420 for (i
, step
, remap_idx
, loopends
) in dbg
:
1421 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1424 def get_spr_msb(self
):
1425 dec_insn
= yield self
.dec2
.e
.do
.insn
1426 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1428 def call(self
, name
):
1429 """call(opcode) - the primary execution point for instructions
1431 self
.last_st_addr
= None # reset the last known store address
1432 self
.last_ld_addr
= None # etc.
1434 ins_name
= name
.strip() # remove spaces if not already done so
1436 log("halted - not executing", ins_name
)
1439 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1440 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1441 asmop
= yield from self
.get_assembly_name()
1442 log("call", ins_name
, asmop
)
1444 # sv.setvl is *not* a loop-function. sigh
1445 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1448 int_op
= yield self
.dec2
.dec
.op
.internal_op
1449 spr_msb
= yield from self
.get_spr_msb()
1451 instr_is_privileged
= False
1452 if int_op
in [MicrOp
.OP_ATTN
.value
,
1453 MicrOp
.OP_MFMSR
.value
,
1454 MicrOp
.OP_MTMSR
.value
,
1455 MicrOp
.OP_MTMSRD
.value
,
1457 MicrOp
.OP_RFID
.value
]:
1458 instr_is_privileged
= True
1459 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1460 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1461 instr_is_privileged
= True
1463 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1465 # check MSR priv bit and whether op is privileged: if so, throw trap
1466 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1467 self
.call_trap(0x700, PIb
.PRIV
)
1470 # check halted condition
1471 if ins_name
== 'attn':
1475 # check illegal instruction
1477 if ins_name
not in ['mtcrf', 'mtocrf']:
1478 illegal
= ins_name
!= asmop
1480 # list of instructions not being supported by binutils (.long)
1481 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1482 if dotstrp
in [*FPTRANS_INSNS
,
1483 'ffmadds', 'fdmadds', 'ffadds',
1484 'mins', 'maxs', 'minu', 'maxu',
1485 'setvl', 'svindex', 'svremap', 'svstep',
1486 'svshape', 'svshape2',
1487 'grev', 'ternlogi', 'bmask', 'cprop',
1488 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1489 'fmvis', 'fishmv', 'pcdec'
1494 # branch-conditional redirects to sv.bc
1495 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1496 ins_name
= 'sv.%s' % ins_name
1498 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1500 # illegal instructions call TRAP at 0x700
1502 print("illegal", ins_name
, asmop
)
1503 self
.call_trap(0x700, PIb
.ILLEG
)
1504 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1505 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1508 # this is for setvl "Vertical" mode: if set true,
1509 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1510 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1511 self
.allow_next_step_inc
= False
1512 self
.svstate_next_mode
= 0
1514 # nop has to be supported, we could let the actual op calculate
1515 # but PowerDecoder has a pattern for nop
1516 if ins_name
== 'nop':
1517 self
.update_pc_next()
1520 # look up instruction in ISA.instrs, prepare namespace
1521 info
= self
.instrs
[ins_name
]
1522 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1524 # preserve order of register names
1525 input_names
= create_args(list(info
.read_regs
) +
1526 list(info
.uninit_regs
))
1527 log("input names", input_names
)
1529 # get SVP64 entry for the current instruction
1530 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1531 if sv_rm
is not None:
1532 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1534 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1535 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1537 # see if srcstep/dststep need skipping over masked-out predicate bits
1538 if (self
.is_svp64_mode
or ins_name
in ['setvl', 'svremap', 'svstate']):
1539 yield from self
.svstate_pre_inc()
1540 if self
.is_svp64_mode
:
1541 pre
= yield from self
.update_new_svstate_steps()
1543 self
.svp64_reset_loop()
1545 self
.update_pc_next()
1547 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1548 pred_dst_zero
= self
.pred_dst_zero
1549 pred_src_zero
= self
.pred_src_zero
1550 vl
= self
.svstate
.vl
1551 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1553 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1554 if self
.is_svp64_mode
and vl
== 0:
1555 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1556 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1557 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1560 # for when SVREMAP is active, using pre-arranged schedule.
1561 # note: modifying PowerDecoder2 needs to "settle"
1562 remap_en
= self
.svstate
.SVme
1563 persist
= self
.svstate
.RMpst
1564 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1565 if self
.is_svp64_mode
:
1566 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1568 if persist
or self
.last_op_svshape
:
1569 remaps
= self
.get_remap_indices()
1570 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1571 yield from self
.remap_set_steps(remaps
)
1572 # after that, settle down (combinatorial) to let Vector reg numbers
1573 # work themselves out
1575 if self
.is_svp64_mode
:
1576 remap_active
= yield self
.dec2
.remap_active
1578 remap_active
= False
1579 log("remap active", bin(remap_active
))
1581 # main input registers (RT, RA ...)
1583 for name
in input_names
:
1585 regval
= (yield from self
.get_input(name
))
1586 log("regval", regval
)
1587 inputs
.append(regval
)
1589 # arrrrgh, awful hack, to get _RT into namespace
1590 if ins_name
in ['setvl', 'svstep']:
1592 RT
= yield self
.dec2
.dec
.RT
1593 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1595 self
.namespace
["RT"] = SelectableInt(0, 5)
1596 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1597 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1599 # in SVP64 mode for LD/ST work out immediate
1600 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1601 # use info.form to detect
1602 if self
.is_svp64_mode
:
1603 yield from self
.check_replace_d(info
, remap_active
)
1605 # "special" registers
1606 for special
in info
.special_regs
:
1607 if special
in special_sprs
:
1608 inputs
.append(self
.spr
[special
])
1610 inputs
.append(self
.namespace
[special
])
1612 # clear trap (trap) NIA
1613 self
.trap_nia
= None
1615 # check if this was an sv.bc* and create an indicator that
1616 # this is the last check to be made as a loop. combined with
1617 # the ALL/ANY mode we can early-exit
1618 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1619 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1620 # XXX TODO - pack/unpack here
1621 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1622 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1624 # execute actual instruction here (finally)
1625 log("inputs", inputs
)
1626 results
= info
.func(self
, *inputs
)
1627 log("results", results
)
1629 # "inject" decorator takes namespace from function locals: we need to
1630 # overwrite NIA being overwritten (sigh)
1631 if self
.trap_nia
is not None:
1632 self
.namespace
['NIA'] = self
.trap_nia
1634 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1636 # check if op was a LD/ST so that debugging can check the
1638 if int_op
in [MicrOp
.OP_STORE
.value
,
1640 self
.last_st_addr
= self
.mem
.last_st_addr
1641 if int_op
in [MicrOp
.OP_LOAD
.value
,
1643 self
.last_ld_addr
= self
.mem
.last_ld_addr
1644 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1645 self
.last_st_addr
, self
.last_ld_addr
)
1647 # detect if CA/CA32 already in outputs (sra*, basically)
1651 output_names
= create_args(info
.write_regs
)
1652 for name
in output_names
:
1658 log("carry already done?", bin(already_done
))
1659 carry_en
= yield self
.dec2
.e
.do
.output_carry
1661 yield from self
.handle_carry_(inputs
, results
, already_done
)
1663 # check if one of the regs was named "overflow"
1666 for name
, output
in zip(output_names
, results
):
1667 if name
== 'overflow':
1670 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1671 # detect if overflow was in return result
1672 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1673 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1674 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1676 yield from self
.handle_overflow(inputs
, results
, overflow
)
1678 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1680 if not self
.is_svp64_mode
or not pred_dst_zero
:
1681 if hasattr(self
.dec2
.e
.do
, "rc"):
1682 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1683 if rc_en
and ins_name
not in ['svstep']:
1684 yield from self
.do_rc_ov(ins_name
, results
, overflow
)
1686 # any modified return results?
1687 yield from self
.do_outregs_nia(asmop
, ins_name
, info
,
1688 output_names
, results
,
1691 def do_rc_ov(self
, ins_name
, results
, overflow
):
1692 if ins_name
.startswith("f"):
1693 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1696 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, rc_reg
)
1698 # hang on... for `setvl` actually you want to test SVSTATE.VL
1699 is_setvl
= ins_name
== 'setvl'
1702 cmps
= (SelectableInt(vl
, 64), overflow
,)
1704 overflow
= None # do not override overflow except in setvl
1705 self
.handle_comparison(cmps
, regnum
, overflow
, no_so
=is_setvl
)
1707 def do_outregs_nia(self
, asmop
, ins_name
, info
, output_names
, results
,
1709 # write out any regs for this instruction
1711 for name
, output
in zip(output_names
, results
):
1712 yield from self
.check_write(info
, name
, output
, carry_en
)
1714 # check advancement of src/dst/sub-steps and if PC needs updating
1715 nia_update
= (yield from self
.check_step_increment(results
, rc_en
,
1718 self
.update_pc_next()
1720 def check_replace_d(self
, info
, remap_active
):
1721 replace_d
= False # update / replace constant in pseudocode
1722 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1723 vl
= self
.svstate
.vl
1724 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1725 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1726 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1727 if info
.form
== 'DS':
1728 # DS-Form, multiply by 4 then knock 2 bits off after
1729 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1731 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1732 imm
= exts(imm
, 16) # sign-extend to integer
1733 # get the right step. LD is from srcstep, ST is dststep
1734 op
= yield self
.dec2
.e
.do
.insn_type
1736 if op
== MicrOp
.OP_LOAD
.value
:
1738 offsmul
= yield self
.dec2
.in1_step
1739 log("D-field REMAP src", imm
, offsmul
)
1741 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
1742 log("D-field src", imm
, offsmul
)
1743 elif op
== MicrOp
.OP_STORE
.value
:
1744 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1745 offsmul
= (dststep
* (subvl
+1)) + dsubstep
1746 log("D-field dst", imm
, offsmul
)
1747 # Unit-Strided LD/ST adds offset*width to immediate
1748 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1749 ldst_len
= yield self
.dec2
.e
.do
.data_len
1750 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1752 # Element-strided multiplies the immediate by element step
1753 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1754 imm
= SelectableInt(imm
* offsmul
, 32)
1757 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1758 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1759 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1760 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1761 # new replacement D... errr.. DS
1763 if info
.form
== 'DS':
1764 # TODO: assert 2 LSBs are zero?
1765 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1766 imm
.value
= imm
.value
>> 2
1767 self
.namespace
['DS'] = imm
1769 self
.namespace
['D'] = imm
1771 def get_input(self
, name
):
1772 # using PowerDecoder2, first, find the decoder index.
1773 # (mapping name RA RB RC RS to in1, in2, in3)
1774 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1776 # doing this is not part of svp64, it's because output
1777 # registers, to be modified, need to be in the namespace.
1778 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1780 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1782 # in case getting the register number is needed, _RA, _RB
1783 regname
= "_" + name
1784 self
.namespace
[regname
] = regnum
1785 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
1786 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1788 reg_val
= SelectableInt(self
.fpr(regnum
))
1789 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1790 elif name
is not None:
1791 reg_val
= SelectableInt(self
.gpr(regnum
))
1792 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1794 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1798 def remap_set_steps(self
, remaps
):
1799 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1800 they work in concert with PowerDecoder2 at the moment,
1801 there is no HDL implementation of REMAP. therefore this
1802 function, because ISACaller still uses PowerDecoder2,
1803 will *explicitly* write the dec2.XX_step values. this has
1806 # just some convenient debug info
1808 sname
= 'SVSHAPE%d' % i
1809 shape
= self
.spr
[sname
]
1810 log(sname
, bin(shape
.value
))
1811 log(" lims", shape
.lims
)
1812 log(" mode", shape
.mode
)
1813 log(" skip", shape
.skip
)
1815 # set up the list of steps to remap
1816 mi0
= self
.svstate
.mi0
1817 mi1
= self
.svstate
.mi1
1818 mi2
= self
.svstate
.mi2
1819 mo0
= self
.svstate
.mo0
1820 mo1
= self
.svstate
.mo1
1821 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1822 (self
.dec2
.in2_step
, mi1
), # RB
1823 (self
.dec2
.in3_step
, mi2
), # RC
1824 (self
.dec2
.o_step
, mo0
), # RT
1825 (self
.dec2
.o2_step
, mo1
), # EA
1827 remap_idxs
= self
.remap_idxs
1829 # now cross-index the required SHAPE for each of 3-in 2-out regs
1830 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1831 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1832 (shape
, remap
) = remaps
[shape_idx
]
1833 remap_idx
= remap_idxs
[shape_idx
]
1834 # zero is "disabled"
1835 if shape
.value
== 0x0:
1837 # now set the actual requested step to the current index
1838 yield dstep
.eq(remap_idx
)
1840 # debug printout info
1841 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
1843 log("shape remap", x
)
1845 def check_write(self
, info
, name
, output
, carry_en
):
1846 if name
== 'overflow': # ignore, done already (above)
1848 if isinstance(output
, int):
1849 output
= SelectableInt(output
, 256)
1851 if name
in ['CA', 'CA32']:
1853 log("writing %s to XER" % name
, output
)
1854 log("write XER %s 0x%x" % (name
, output
.value
))
1855 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1857 log("NOT writing %s to XER" % name
, output
)
1859 # write special SPRs
1860 if name
in info
.special_regs
:
1861 log('writing special %s' % name
, output
, special_sprs
)
1862 log("write reg %s 0x%x" % (name
, output
.value
))
1863 if name
in special_sprs
:
1864 self
.spr
[name
] = output
1866 self
.namespace
[name
].eq(output
)
1868 log('msr written', hex(self
.msr
.value
))
1870 # find out1/out2 PR/FPR
1871 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1873 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1875 # temporary hack for not having 2nd output
1876 regnum
= yield getattr(self
.decoder
, name
)
1878 # convenient debug prefix
1883 # check zeroing due to predicate bit being zero
1884 if self
.is_svp64_mode
and self
.pred_dst_zero
:
1885 log('zeroing reg %d %s' % (regnum
, str(output
)), is_vec
)
1886 output
= SelectableInt(0, 256)
1887 log("write reg %s%d 0x%x" % (reg_prefix
, regnum
, output
.value
),
1888 kind
=LogKind
.InstrInOuts
)
1889 # zero-extend tov64 bit begore storing (should use EXT oh well)
1890 if output
.bits
> 64:
1891 output
= SelectableInt(output
.value
, 64)
1893 self
.fpr
[regnum
] = output
1895 self
.gpr
[regnum
] = output
1897 def check_step_increment(self
, results
, rc_en
, asmop
, ins_name
):
1898 # check if it is the SVSTATE.src/dest step that needs incrementing
1899 # this is our Sub-Program-Counter loop from 0 to VL-1
1900 if not self
.allow_next_step_inc
:
1901 if self
.is_svp64_mode
:
1902 return (yield from self
.svstate_post_inc(ins_name
))
1904 # XXX only in non-SVP64 mode!
1905 # record state of whether the current operation was an svshape,
1907 # to be able to know if it should apply in the next instruction.
1908 # also (if going to use this instruction) should disable ability
1909 # to interrupt in between. sigh.
1910 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
1917 log("SVSTATE_NEXT: inc requested, mode",
1918 self
.svstate_next_mode
, self
.allow_next_step_inc
)
1919 yield from self
.svstate_pre_inc()
1920 pre
= yield from self
.update_new_svstate_steps()
1922 # reset at end of loop including exit Vertical Mode
1923 log("SVSTATE_NEXT: end of loop, reset")
1924 self
.svp64_reset_loop()
1925 self
.svstate
.vfirst
= 0
1929 results
= [SelectableInt(0, 64)]
1930 self
.handle_comparison(results
) # CR0
1932 if self
.allow_next_step_inc
== 2:
1933 log("SVSTATE_NEXT: read")
1934 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1936 log("SVSTATE_NEXT: post-inc")
1937 # use actual src/dst-step here to check end, do NOT
1938 # use bit-reversed version
1939 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1940 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1941 remaps
= self
.get_remap_indices()
1942 remap_idxs
= self
.remap_idxs
1943 vl
= self
.svstate
.vl
1944 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1945 end_src
= srcstep
== vl
-1
1946 end_dst
= dststep
== vl
-1
1947 if self
.allow_next_step_inc
!= 2:
1948 yield from self
.advance_svstate_steps(end_src
, end_dst
)
1949 #self.namespace['SVSTATE'] = self.svstate.spr
1950 # set CR0 (if Rc=1) based on end
1952 endtest
= 1 if (end_src
or end_dst
) else 0
1953 #results = [SelectableInt(endtest, 64)]
1954 # self.handle_comparison(results) # CR0
1956 # see if svstep was requested, if so, which SVSTATE
1958 if self
.svstate_next_mode
> 0:
1959 shape_idx
= self
.svstate_next_mode
.value
-1
1960 endings
= self
.remap_loopends
[shape_idx
]
1961 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
1962 log("svstep Rc=1, CR0", cr_field
)
1963 self
.crl
[0].eq(cr_field
) # CR0
1964 if end_src
or end_dst
:
1965 # reset at end of loop including exit Vertical Mode
1966 log("SVSTATE_NEXT: after increments, reset")
1967 self
.svp64_reset_loop()
1968 self
.svstate
.vfirst
= 0
1971 def SVSTATE_NEXT(self
, mode
, submode
):
1972 """explicitly moves srcstep/dststep on to next element, for
1973 "Vertical-First" mode. this function is called from
1974 setvl pseudo-code, as a pseudo-op "svstep"
1976 WARNING: this function uses information that was created EARLIER
1977 due to it being in the middle of a yield, but this function is
1978 *NOT* called from yield (it's called from compiled pseudocode).
1980 self
.allow_next_step_inc
= submode
.value
+ 1
1981 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
1982 self
.svstate_next_mode
= mode
1983 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
1984 shape_idx
= self
.svstate_next_mode
.value
-1
1985 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1986 if self
.svstate_next_mode
== 5:
1987 self
.svstate_next_mode
= 0
1988 return SelectableInt(self
.svstate
.srcstep
, 7)
1989 if self
.svstate_next_mode
== 6:
1990 self
.svstate_next_mode
= 0
1991 return SelectableInt(self
.svstate
.dststep
, 7)
1992 return SelectableInt(0, 7)
1994 def get_src_dststeps(self
):
1995 """gets srcstep, dststep, and ssubstep, dsubstep
1997 return (self
.new_srcstep
, self
.new_dststep
,
1998 self
.new_ssubstep
, self
.new_dsubstep
)
2000 def update_new_svstate_steps(self
):
2001 # note, do not get the bit-reversed srcstep here!
2002 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2003 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2005 # update SVSTATE with new srcstep
2006 self
.svstate
.srcstep
= srcstep
2007 self
.svstate
.dststep
= dststep
2008 self
.svstate
.ssubstep
= ssubstep
2009 self
.svstate
.dsubstep
= dsubstep
2010 self
.namespace
['SVSTATE'] = self
.svstate
2011 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2012 yield Settle() # let decoder update
2013 srcstep
= self
.svstate
.srcstep
2014 dststep
= self
.svstate
.dststep
2015 ssubstep
= self
.svstate
.ssubstep
2016 dsubstep
= self
.svstate
.dsubstep
2017 pack
= self
.svstate
.pack
2018 unpack
= self
.svstate
.unpack
2019 vl
= self
.svstate
.vl
2020 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2021 log(" srcstep", srcstep
)
2022 log(" dststep", dststep
)
2024 log(" unpack", unpack
)
2025 log(" ssubstep", ssubstep
)
2026 log(" dsubstep", dsubstep
)
2028 log(" subvl", subvl
)
2030 # check if end reached (we let srcstep overrun, above)
2031 # nothing needs doing (TODO zeroing): just do next instruction
2032 return ((ssubstep
== subvl
and srcstep
== vl
) or
2033 (dsubstep
== subvl
and dststep
== vl
))
2035 def svstate_post_inc(self
, insn_name
, vf
=0):
2036 # check if SV "Vertical First" mode is enabled
2037 vfirst
= self
.svstate
.vfirst
2038 log(" SV Vertical First", vf
, vfirst
)
2039 if not vf
and vfirst
== 1:
2043 # check if it is the SVSTATE.src/dest step that needs incrementing
2044 # this is our Sub-Program-Counter loop from 0 to VL-1
2045 # XXX twin predication TODO
2046 vl
= self
.svstate
.vl
2047 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2048 mvl
= self
.svstate
.maxvl
2049 srcstep
= self
.svstate
.srcstep
2050 dststep
= self
.svstate
.dststep
2051 ssubstep
= self
.svstate
.ssubstep
2052 dsubstep
= self
.svstate
.dsubstep
2053 pack
= self
.svstate
.pack
2054 unpack
= self
.svstate
.unpack
2055 rm_mode
= yield self
.dec2
.rm_dec
.mode
2056 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2057 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2058 out_vec
= not (yield self
.dec2
.no_out_vec
)
2059 in_vec
= not (yield self
.dec2
.no_in_vec
)
2060 log(" svstate.vl", vl
)
2061 log(" svstate.mvl", mvl
)
2062 log(" rm.subvl", subvl
)
2063 log(" svstate.srcstep", srcstep
)
2064 log(" svstate.dststep", dststep
)
2065 log(" svstate.ssubstep", ssubstep
)
2066 log(" svstate.dsubstep", dsubstep
)
2067 log(" svstate.pack", pack
)
2068 log(" svstate.unpack", unpack
)
2069 log(" mode", rm_mode
)
2070 log(" reverse", reverse_gear
)
2071 log(" out_vec", out_vec
)
2072 log(" in_vec", in_vec
)
2073 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
2074 # check if this was an sv.bc* and if so did it succeed
2075 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2076 end_loop
= self
.namespace
['end_loop']
2077 log("branch %s end_loop" % insn_name
, end_loop
)
2079 self
.svp64_reset_loop()
2080 self
.update_pc_next()
2082 # check if srcstep needs incrementing by one, stop PC advancing
2083 # but for 2-pred both src/dest have to be checked.
2084 # XXX this might not be true! it may just be LD/ST
2085 if sv_ptype
== SVPtype
.P2
.value
:
2086 svp64_is_vector
= (out_vec
or in_vec
)
2088 svp64_is_vector
= out_vec
2089 # loops end at the first "hit" (source or dest)
2090 end_src
= srcstep
== vl
-1
2091 end_dst
= dststep
== vl
-1
2092 loopend
= ((end_src
and ssubstep
== subvl
) or
2093 (end_dst
and dsubstep
== subvl
))
2094 log("loopend", svp64_is_vector
, loopend
, end_src
, end_dst
,
2095 ssubstep
== subvl
, dsubstep
== subvl
)
2096 if not svp64_is_vector
or loopend
:
2097 # reset loop to zero and update NIA
2098 self
.svp64_reset_loop()
2103 # still looping, advance and update NIA
2104 yield from self
.advance_svstate_steps(end_src
, end_dst
)
2105 self
.namespace
['SVSTATE'] = self
.svstate
2107 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2108 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2109 # this way we keep repeating the same instruction (with new steps)
2110 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2111 self
.namespace
['NIA'] = self
.pc
.NIA
2112 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2113 return False # DO NOT allow PC update whilst Sub-PC loop running
2115 def update_pc_next(self
):
2116 # UPDATE program counter
2117 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2118 #self.svstate.spr = self.namespace['SVSTATE']
2119 log("end of call", self
.namespace
['CIA'],
2120 self
.namespace
['NIA'],
2121 self
.namespace
['SVSTATE'])
2123 def svp64_reset_loop(self
):
2124 self
.svstate
.srcstep
= 0
2125 self
.svstate
.dststep
= 0
2126 self
.svstate
.ssubstep
= 0
2127 self
.svstate
.dsubstep
= 0
2128 log(" svstate.srcstep loop end (PC to update)")
2129 self
.namespace
['SVSTATE'] = self
.svstate
2131 def update_nia(self
):
2132 self
.pc
.update_nia(self
.is_svp64_mode
)
2133 self
.namespace
['NIA'] = self
.pc
.NIA
2137 """Decorator factory.
2139 this decorator will "inject" variables into the function's namespace,
2140 from the *dictionary* in self.namespace. it therefore becomes possible
2141 to make it look like a whole stack of variables which would otherwise
2142 need "self." inserted in front of them (*and* for those variables to be
2143 added to the instance) "appear" in the function.
2145 "self.namespace['SI']" for example becomes accessible as just "SI" but
2146 *only* inside the function, when decorated.
2148 def variable_injector(func
):
2150 def decorator(*args
, **kwargs
):
2152 func_globals
= func
.__globals
__ # Python 2.6+
2153 except AttributeError:
2154 func_globals
= func
.func_globals
# Earlier versions.
2156 context
= args
[0].namespace
# variables to be injected
2157 saved_values
= func_globals
.copy() # Shallow copy of dict.
2158 log("globals before", context
.keys())
2159 func_globals
.update(context
)
2160 result
= func(*args
, **kwargs
)
2161 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2162 log("args[0]", args
[0].namespace
['CIA'],
2163 args
[0].namespace
['NIA'],
2164 args
[0].namespace
['SVSTATE'])
2165 if 'end_loop' in func_globals
:
2166 log("args[0] end_loop", func_globals
['end_loop'])
2167 args
[0].namespace
= func_globals
2168 #exec (func.__code__, func_globals)
2171 # func_globals = saved_values # Undo changes.
2177 return variable_injector