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
.back
.pysim
import Settle
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 (
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
,
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 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 class SVP64RMFields(SelectableIntMapping
, bits
=24, fields
={
264 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
267 "elwidth": range(4, 6),
268 "ewsrc": range(6, 8),
269 "subvl": range(8, 10),
270 "extra": range(10, 19),
271 "mode": range(19, 24),
272 # these cover the same extra field, split into parts as EXTRA2
273 "extra2": dict(enumerate([
279 "smask": range(16, 19),
280 # and here as well, but EXTRA3
281 "extra3": dict(enumerate([
288 def __init__(self
, value
=0):
289 super().__init
__(value
=value
)
293 SVP64RM_MMODE_SIZE
= len(SVP64RMFields
.mmode
)
294 SVP64RM_MASK_SIZE
= len(SVP64RMFields
.mask
)
295 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields
.elwidth
)
296 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields
.ewsrc
)
297 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields
.subvl
)
298 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields
.extra2
[0])
299 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields
.extra3
[0])
300 SVP64RM_SMASK_SIZE
= len(SVP64RMFields
.smask
)
301 SVP64RM_MODE_SIZE
= len(SVP64RMFields
.mode
)
304 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
305 class SVP64PrefixFields(SelectableIntMapping
, bits
=32, fields
={
307 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
308 "major": range(0, 6),
310 # SVP64 24-bit RM (ReMap)
311 "rm": ((6, 8) + tuple(range(10, 32))),
314 def __init__(self
, value
=0):
315 super().__init
__(value
=value
)
319 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields
.major
)
320 SV64P_PID_SIZE
= len(SVP64PrefixFields
.pid
)
321 SV64P_RM_SIZE
= len(SVP64PrefixFields
.rm
)
325 # See PowerISA Version 3.0 B Book 1
326 # Section 2.3.1 Condition Register pages 30 - 31
328 LT
= FL
= 0 # negative, less than, floating-point less than
329 GT
= FG
= 1 # positive, greater than, floating-point greater than
330 EQ
= FE
= 2 # equal, floating-point equal
331 SO
= FU
= 3 # summary overflow, floating-point unordered
333 def __init__(self
, init
=0):
334 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
335 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
336 self
.cr
= SelectableInt(init
, 64) # underlying reg
337 # field-selectable versions of Condition Register TODO check bitranges?
340 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
341 _cr
= FieldSelectableInt(self
.cr
, bits
)
344 # decode SVP64 predicate integer to reg number and invert
347 def get_predint(gpr
, mask
):
350 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
351 if mask
== SVP64PredInt
.ALWAYS
.value
:
352 return 0xffff_ffff_ffff_ffff # 64 bits of 1
353 if mask
== SVP64PredInt
.R3_UNARY
.value
:
354 return 1 << (gpr(3).value
& 0b111111)
355 if mask
== SVP64PredInt
.R3
.value
:
357 if mask
== SVP64PredInt
.R3_N
.value
:
359 if mask
== SVP64PredInt
.R10
.value
:
361 if mask
== SVP64PredInt
.R10_N
.value
:
362 return ~
gpr(10).value
363 if mask
== SVP64PredInt
.R30
.value
:
365 if mask
== SVP64PredInt
.R30_N
.value
:
366 return ~
gpr(30).value
368 # decode SVP64 predicate CR to reg number and invert status
371 def _get_predcr(mask
):
372 if mask
== SVP64PredCR
.LT
.value
:
374 if mask
== SVP64PredCR
.GE
.value
:
376 if mask
== SVP64PredCR
.GT
.value
:
378 if mask
== SVP64PredCR
.LE
.value
:
380 if mask
== SVP64PredCR
.EQ
.value
:
382 if mask
== SVP64PredCR
.NE
.value
:
384 if mask
== SVP64PredCR
.SO
.value
:
386 if mask
== SVP64PredCR
.NS
.value
:
389 # read individual CR fields (0..VL-1), extract the required bit
390 # and construct the mask
393 def get_predcr(crl
, mask
, vl
):
394 idx
, noninv
= _get_predcr(mask
)
397 cr
= crl
[i
+SVP64CROffs
.CRPred
]
398 if cr
[idx
].value
== noninv
:
403 # TODO, really should just be using PowerDecoder2
404 def get_pdecode_idx_in(dec2
, name
):
406 in1_sel
= yield op
.in1_sel
407 in2_sel
= yield op
.in2_sel
408 in3_sel
= yield op
.in3_sel
409 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
410 in1
= yield dec2
.e
.read_reg1
.data
411 in2
= yield dec2
.e
.read_reg2
.data
412 in3
= yield dec2
.e
.read_reg3
.data
413 in1_isvec
= yield dec2
.in1_isvec
414 in2_isvec
= yield dec2
.in2_isvec
415 in3_isvec
= yield dec2
.in3_isvec
416 log("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
418 log("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
420 log("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
422 log("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
424 log("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
426 log("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
428 # identify which regnames map to in1/2/3
430 if (in1_sel
== In1Sel
.RA
.value
or
431 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
432 return in1
, in1_isvec
433 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
434 return in1
, in1_isvec
436 if in2_sel
== In2Sel
.RB
.value
:
437 return in2
, in2_isvec
438 if in3_sel
== In3Sel
.RB
.value
:
439 return in3
, in3_isvec
440 # XXX TODO, RC doesn't exist yet!
442 assert False, "RC does not exist yet"
444 if in1_sel
== In1Sel
.RS
.value
:
445 return in1
, in1_isvec
446 if in2_sel
== In2Sel
.RS
.value
:
447 return in2
, in2_isvec
448 if in3_sel
== In3Sel
.RS
.value
:
449 return in3
, in3_isvec
451 if in1_sel
== In1Sel
.FRA
.value
:
452 return in1
, in1_isvec
454 if in2_sel
== In2Sel
.FRB
.value
:
455 return in2
, in2_isvec
457 if in3_sel
== In3Sel
.FRC
.value
:
458 return in3
, in3_isvec
460 if in1_sel
== In1Sel
.FRS
.value
:
461 return in1
, in1_isvec
462 if in3_sel
== In3Sel
.FRS
.value
:
463 return in3
, in3_isvec
467 # TODO, really should just be using PowerDecoder2
468 def get_pdecode_cr_in(dec2
, name
):
470 in_sel
= yield op
.cr_in
471 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
472 sv_cr_in
= yield op
.sv_cr_in
473 spec
= yield dec2
.crin_svdec
.spec
474 sv_override
= yield dec2
.dec_cr_in
.sv_override
475 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
476 in1
= yield dec2
.e
.read_cr1
.data
477 cr_isvec
= yield dec2
.cr_in_isvec
478 log("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
479 log(" sv_cr_in", sv_cr_in
)
480 log(" cr_bf", in_bitfield
)
482 log(" override", sv_override
)
483 # identify which regnames map to in / o2
485 if in_sel
== CRInSel
.BI
.value
:
487 log("get_pdecode_cr_in not found", name
)
491 # TODO, really should just be using PowerDecoder2
492 def get_pdecode_cr_out(dec2
, name
):
494 out_sel
= yield op
.cr_out
495 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
496 sv_cr_out
= yield op
.sv_cr_out
497 spec
= yield dec2
.crout_svdec
.spec
498 sv_override
= yield dec2
.dec_cr_out
.sv_override
499 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
500 out
= yield dec2
.e
.write_cr
.data
501 o_isvec
= yield dec2
.o_isvec
502 log("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
503 log(" sv_cr_out", sv_cr_out
)
504 log(" cr_bf", out_bitfield
)
506 log(" override", sv_override
)
507 # identify which regnames map to out / o2
509 if out_sel
== CROutSel
.CR0
.value
:
511 log("get_pdecode_cr_out not found", name
)
515 # TODO, really should just be using PowerDecoder2
516 def get_pdecode_idx_out(dec2
, name
):
518 out_sel
= yield op
.out_sel
519 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
520 out
= yield dec2
.e
.write_reg
.data
521 o_isvec
= yield dec2
.o_isvec
522 # identify which regnames map to out / o2
524 log("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
525 if out_sel
== OutSel
.RA
.value
:
528 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
529 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
531 if out_sel
== OutSel
.RT
.value
:
533 elif name
== 'RT_OR_ZERO':
534 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
535 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
537 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
540 log("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
541 if out_sel
== OutSel
.FRA
.value
:
544 log("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
545 OutSel
.FRT
.value
, out
, o_isvec
)
546 if out_sel
== OutSel
.FRT
.value
:
548 log("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
552 # TODO, really should just be using PowerDecoder2
553 def get_pdecode_idx_out2(dec2
, name
):
554 # check first if register is activated for write
556 out_sel
= yield op
.out_sel
557 out
= yield dec2
.e
.write_ea
.data
558 o_isvec
= yield dec2
.o2_isvec
559 out_ok
= yield dec2
.e
.write_ea
.ok
560 log("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
565 if hasattr(op
, "upd"):
566 # update mode LD/ST uses read-reg A also as an output
568 log("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
569 out_sel
, OutSel
.RA
.value
,
571 if upd
== LDSTMode
.update
.value
:
574 int_op
= yield dec2
.dec
.op
.internal_op
575 fft_en
= yield dec2
.use_svp64_fft
576 # if int_op == MicrOp.OP_FP_MADD.value and fft_en:
578 log("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
584 class ISACaller(ISACallerHelper
, ISAFPHelpers
):
585 # decoder2 - an instance of power_decoder2
586 # regfile - a list of initial values for the registers
587 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
588 # respect_pc - tracks the program counter. requires initial_insns
589 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
590 initial_mem
=None, initial_msr
=0,
601 self
.bigendian
= bigendian
603 self
.is_svp64_mode
= False
604 self
.respect_pc
= respect_pc
605 if initial_sprs
is None:
607 if initial_mem
is None:
609 if fpregfile
is None:
611 if initial_insns
is None:
613 assert self
.respect_pc
== False, "instructions required to honor pc"
615 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
616 log("ISACaller initial_msr", initial_msr
)
618 # "fake program counter" mode (for unit testing)
622 if isinstance(initial_mem
, tuple):
623 self
.fake_pc
= initial_mem
[0]
624 disasm_start
= self
.fake_pc
626 disasm_start
= initial_pc
628 # disassembly: we need this for now (not given from the decoder)
629 self
.disassembly
= {}
631 for i
, code
in enumerate(disassembly
):
632 self
.disassembly
[i
*4 + disasm_start
] = code
634 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
635 self
.svp64rm
= SVP64RM()
636 if initial_svstate
is None:
638 if isinstance(initial_svstate
, int):
639 initial_svstate
= SVP64State(initial_svstate
)
640 # SVSTATE, MSR and PC
641 self
.svstate
= initial_svstate
642 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
644 # GPR FPR SPR registers
645 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
646 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
647 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
648 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
650 # set up 4 dummy SVSHAPEs if they aren't already set up
652 sname
= 'SVSHAPE%d' % i
653 if sname
not in self
.spr
:
654 self
.spr
[sname
] = SVSHAPE(0)
656 # make sure it's an SVSHAPE
657 val
= self
.spr
[sname
].value
658 self
.spr
[sname
] = SVSHAPE(val
)
659 self
.last_op_svshape
= False
662 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
663 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
664 # MMU mode, redirect underlying Mem through RADIX
666 self
.mem
= RADIX(self
.mem
, self
)
668 self
.imem
= RADIX(self
.imem
, self
)
671 # FPR (same as GPR except for FP nums)
672 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
673 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
674 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
675 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
677 # 2.3.2 LR (actually SPR #8) -- Done
678 # 2.3.3 CTR (actually SPR #9) -- Done
679 # 2.3.4 TAR (actually SPR #815)
680 # 3.2.2 p45 XER (actually SPR #1) -- Done
681 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
683 # create CR then allow portions of it to be "selectable" (below)
684 self
.cr_fields
= CRFields(initial_cr
)
685 self
.cr
= self
.cr_fields
.cr
687 # "undefined", just set to variable-bit-width int (use exts "max")
688 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
691 self
.namespace
.update(self
.spr
)
692 self
.namespace
.update({'GPR': self
.gpr
,
696 'memassign': self
.memassign
,
699 'SVSTATE': self
.svstate
,
700 'SVSHAPE0': self
.spr
['SVSHAPE0'],
701 'SVSHAPE1': self
.spr
['SVSHAPE1'],
702 'SVSHAPE2': self
.spr
['SVSHAPE2'],
703 'SVSHAPE3': self
.spr
['SVSHAPE3'],
706 'undefined': undefined
,
707 'mode_is_64bit': True,
708 'SO': XER_bits
['SO'],
709 'XLEN': 64 # elwidth overrides, later
712 # update pc to requested start point
713 self
.set_pc(initial_pc
)
715 # field-selectable versions of Condition Register
716 self
.crl
= self
.cr_fields
.crl
718 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
720 self
.decoder
= decoder2
.dec
723 super().__init
__(XLEN
=self
.namespace
["XLEN"])
727 return self
.namespace
["XLEN"]
729 def call_trap(self
, trap_addr
, trap_bit
):
730 """calls TRAP and sets up NIA to the new execution location.
731 next instruction will begin at trap_addr.
733 self
.TRAP(trap_addr
, trap_bit
)
734 self
.namespace
['NIA'] = self
.trap_nia
735 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
737 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
738 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
740 TRAP function is callable from inside the pseudocode itself,
741 hence the default arguments. when calling from inside ISACaller
742 it is best to use call_trap()
744 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
745 # store CIA(+4?) in SRR0, set NIA to 0x700
746 # store MSR in SRR1, set MSR to um errr something, have to check spec
747 # store SVSTATE (if enabled) in SVSRR0
748 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
749 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
750 if self
.is_svp64_mode
:
751 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
752 self
.trap_nia
= SelectableInt(trap_addr
, 64)
753 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
755 # set exception bits. TODO: this should, based on the address
756 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
757 # bits appropriately. however it turns out that *for now* in all
758 # cases (all trap_addrs) the exact same thing is needed.
759 self
.msr
[MSRb
.IR
] = 0
760 self
.msr
[MSRb
.DR
] = 0
761 self
.msr
[MSRb
.FE0
] = 0
762 self
.msr
[MSRb
.FE1
] = 0
763 self
.msr
[MSRb
.EE
] = 0
764 self
.msr
[MSRb
.RI
] = 0
765 self
.msr
[MSRb
.SF
] = 1
766 self
.msr
[MSRb
.TM
] = 0
767 self
.msr
[MSRb
.VEC
] = 0
768 self
.msr
[MSRb
.VSX
] = 0
769 self
.msr
[MSRb
.PR
] = 0
770 self
.msr
[MSRb
.FP
] = 0
771 self
.msr
[MSRb
.PMM
] = 0
772 self
.msr
[MSRb
.TEs
] = 0
773 self
.msr
[MSRb
.TEe
] = 0
774 self
.msr
[MSRb
.UND
] = 0
775 self
.msr
[MSRb
.LE
] = 1
777 def memassign(self
, ea
, sz
, val
):
778 self
.mem
.memassign(ea
, sz
, val
)
780 def prep_namespace(self
, insn_name
, formname
, op_fields
):
781 # TODO: get field names from form in decoder*1* (not decoder2)
782 # decoder2 is hand-created, and decoder1.sigform is auto-generated
784 # then "yield" fields only from op_fields rather than hard-coded
786 fields
= self
.decoder
.sigforms
[formname
]
787 log("prep_namespace", formname
, op_fields
)
788 for name
in op_fields
:
789 # CR immediates. deal with separately. needs modifying
791 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
792 # BI is a 5-bit, must reconstruct the value
793 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
794 sig
= getattr(fields
, name
)
796 # low 2 LSBs (CR field selector) remain same, CR num extended
797 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
798 val
= (val
& 0b11) |
(regnum
<< 2)
801 sig
= getattr(fields
, name
.upper())
803 sig
= getattr(fields
, name
)
805 # these are all opcode fields involved in index-selection of CR,
806 # and need to do "standard" arithmetic. CR[BA+32] for example
807 # would, if using SelectableInt, only be 5-bit.
808 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
809 self
.namespace
[name
] = val
811 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
813 self
.namespace
['XER'] = self
.spr
['XER']
814 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
815 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
817 # add some SVSTATE convenience variables
819 srcstep
= self
.svstate
.srcstep
820 self
.namespace
['VL'] = vl
821 self
.namespace
['srcstep'] = srcstep
823 # sv.bc* need some extra fields
824 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
825 # blegh grab bits manually
826 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
827 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
828 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
829 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
830 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
831 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
832 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
833 sz
= yield self
.dec2
.rm_dec
.pred_sz
834 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
835 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
836 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
837 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
838 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
839 self
.namespace
['sz'] = SelectableInt(sz
, 1)
840 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
842 def handle_carry_(self
, inputs
, outputs
, already_done
):
843 inv_a
= yield self
.dec2
.e
.do
.invert_in
845 inputs
[0] = ~inputs
[0]
847 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
849 imm
= yield self
.dec2
.e
.do
.imm_data
.data
850 inputs
.append(SelectableInt(imm
, 64))
851 assert len(outputs
) >= 1
852 log("outputs", repr(outputs
))
853 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
859 log("gt input", x
, output
)
860 gt
= (gtu(x
, output
))
863 cy
= 1 if any(gts
) else 0
865 if not (1 & already_done
):
866 self
.spr
['XER'][XER_bits
['CA']] = cy
868 log("inputs", already_done
, inputs
)
870 # ARGH... different for OP_ADD... *sigh*...
871 op
= yield self
.dec2
.e
.do
.insn_type
872 if op
== MicrOp
.OP_ADD
.value
:
873 res32
= (output
.value
& (1 << 32)) != 0
874 a32
= (inputs
[0].value
& (1 << 32)) != 0
876 b32
= (inputs
[1].value
& (1 << 32)) != 0
879 cy32
= res32 ^ a32 ^ b32
880 log("CA32 ADD", cy32
)
884 log("input", x
, output
)
885 log(" x[32:64]", x
, x
[32:64])
886 log(" o[32:64]", output
, output
[32:64])
887 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
889 cy32
= 1 if any(gts
) else 0
890 log("CA32", cy32
, gts
)
891 if not (2 & already_done
):
892 self
.spr
['XER'][XER_bits
['CA32']] = cy32
894 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
895 if hasattr(self
.dec2
.e
.do
, "invert_in"):
896 inv_a
= yield self
.dec2
.e
.do
.invert_in
898 inputs
[0] = ~inputs
[0]
900 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
902 imm
= yield self
.dec2
.e
.do
.imm_data
.data
903 inputs
.append(SelectableInt(imm
, 64))
904 assert len(outputs
) >= 1
905 log("handle_overflow", inputs
, outputs
, div_overflow
)
906 if len(inputs
) < 2 and div_overflow
is None:
909 # div overflow is different: it's returned by the pseudo-code
910 # because it's more complex than can be done by analysing the output
911 if div_overflow
is not None:
912 ov
, ov32
= div_overflow
, div_overflow
913 # arithmetic overflow can be done by analysing the input and output
914 elif len(inputs
) >= 2:
918 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
919 output_sgn
= exts(output
.value
, output
.bits
) < 0
920 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
921 output_sgn
!= input_sgn
[0] else 0
924 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
925 output32_sgn
= exts(output
.value
, 32) < 0
926 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
927 output32_sgn
!= input32_sgn
[0] else 0
929 self
.spr
['XER'][XER_bits
['OV']] = ov
930 self
.spr
['XER'][XER_bits
['OV32']] = ov32
931 so
= self
.spr
['XER'][XER_bits
['SO']]
933 self
.spr
['XER'][XER_bits
['SO']] = so
935 def handle_comparison(self
, outputs
, cr_idx
=0):
937 assert isinstance(out
, SelectableInt
), \
938 "out zero not a SelectableInt %s" % repr(outputs
)
939 log("handle_comparison", out
.bits
, hex(out
.value
))
940 # TODO - XXX *processor* in 32-bit mode
941 # https://bugs.libre-soc.org/show_bug.cgi?id=424
943 # o32 = exts(out.value, 32)
944 # print ("handle_comparison exts 32 bit", hex(o32))
945 out
= exts(out
.value
, out
.bits
)
946 log("handle_comparison exts", hex(out
))
947 zero
= SelectableInt(out
== 0, 1)
948 positive
= SelectableInt(out
> 0, 1)
949 negative
= SelectableInt(out
< 0, 1)
950 SO
= self
.spr
['XER'][XER_bits
['SO']]
951 log("handle_comparison SO", SO
)
952 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
953 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
954 self
.crl
[cr_idx
].eq(cr_field
)
956 def set_pc(self
, pc_val
):
957 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
958 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
960 def get_next_insn(self
):
964 pc
= self
.pc
.CIA
.value
967 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
969 raise KeyError("no instruction at 0x%x" % pc
)
973 """set up one instruction
975 pc
, insn
= self
.get_next_insn()
976 yield from self
.setup_next_insn(pc
, insn
)
978 def setup_next_insn(self
, pc
, ins
):
979 """set up next instruction
982 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
983 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
985 yield self
.dec2
.sv_rm
.eq(0)
986 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
987 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
988 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
989 yield self
.dec2
.state
.pc
.eq(pc
)
990 if self
.svstate
is not None:
991 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
993 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
995 opcode
= yield self
.dec2
.dec
.opcode_in
996 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
997 pfx
.insn
.value
= opcode
998 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
999 log("prefix test: opcode:", major
, bin(major
),
1000 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
1001 self
.is_svp64_mode
= ((major
== 0b000001) and
1002 pfx
.insn
[7].value
== 0b1 and
1003 pfx
.insn
[9].value
== 0b1)
1004 self
.pc
.update_nia(self
.is_svp64_mode
)
1006 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1007 self
.namespace
['NIA'] = self
.pc
.NIA
1008 self
.namespace
['SVSTATE'] = self
.svstate
1009 if not self
.is_svp64_mode
:
1012 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1013 log("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
1014 log(" svstate.vl", self
.svstate
.vl
)
1015 log(" svstate.mvl", self
.svstate
.maxvl
)
1016 sv_rm
= pfx
.rm
.asint(msb0
=True)
1017 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1018 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1019 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1020 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
1023 def execute_one(self
):
1024 """execute one instruction
1026 # get the disassembly code for this instruction
1027 if self
.is_svp64_mode
:
1028 if not self
.disassembly
:
1029 code
= yield from self
.get_assembly_name()
1031 code
= self
.disassembly
[self
._pc
+4]
1032 log(" svp64 sim-execute", hex(self
._pc
), code
)
1034 if not self
.disassembly
:
1035 code
= yield from self
.get_assembly_name()
1037 code
= self
.disassembly
[self
._pc
]
1038 log("sim-execute", hex(self
._pc
), code
)
1039 opname
= code
.split(' ')[0]
1041 yield from self
.call(opname
) # execute the instruction
1042 except MemException
as e
: # check for memory errors
1043 if e
.args
[0] == 'unaligned': # alignment error
1044 # run a Trap but set DAR first
1045 print("memory unaligned exception, DAR", e
.dar
)
1046 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1047 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1049 elif e
.args
[0] == 'invalid': # invalid
1050 # run a Trap but set DAR first
1051 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1052 if e
.mode
== 'EXECUTE':
1053 # XXX TODO: must set a few bits in SRR1,
1054 # see microwatt loadstore1.vhdl
1055 # if m_in.segerr = '0' then
1056 # v.srr1(47 - 33) := m_in.invalid;
1057 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1058 # v.srr1(47 - 44) := m_in.badtree;
1059 # v.srr1(47 - 45) := m_in.rc_error;
1060 # v.intr_vec := 16#400#;
1062 # v.intr_vec := 16#480#;
1063 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1065 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1067 # not supported yet:
1068 raise e
# ... re-raise
1070 # don't use this except in special circumstances
1071 if not self
.respect_pc
:
1074 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1075 hex(self
.pc
.NIA
.value
))
1077 def get_assembly_name(self
):
1078 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1079 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1080 dec_insn
= yield self
.dec2
.e
.do
.insn
1081 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1082 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1083 int_op
= yield self
.dec2
.dec
.op
.internal_op
1084 log("get assembly name asmcode", asmcode
, int_op
,
1085 hex(dec_insn
), bin(insn_1_11
))
1086 asmop
= insns
.get(asmcode
, None)
1088 # sigh reconstruct the assembly instruction name
1089 if hasattr(self
.dec2
.e
.do
, "oe"):
1090 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1091 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1095 if hasattr(self
.dec2
.e
.do
, "rc"):
1096 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1097 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1101 # grrrr have to special-case MUL op (see DecodeOE)
1102 log("ov %d en %d rc %d en %d op %d" %
1103 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1104 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1109 if not asmop
.endswith("."): # don't add "." to "andis."
1112 if hasattr(self
.dec2
.e
.do
, "lk"):
1113 lk
= yield self
.dec2
.e
.do
.lk
1116 log("int_op", int_op
)
1117 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1118 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1122 spr_msb
= yield from self
.get_spr_msb()
1123 if int_op
== MicrOp
.OP_MFCR
.value
:
1128 # XXX TODO: for whatever weird reason this doesn't work
1129 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1130 if int_op
== MicrOp
.OP_MTCRF
.value
:
1137 def get_remap_indices(self
):
1138 """WARNING, this function stores remap_idxs and remap_loopends
1139 in the class for later use. this to avoid problems with yield
1141 # go through all iterators in lock-step, advance to next remap_idx
1142 srcstep
, dststep
= self
.get_src_dststeps()
1143 # get four SVSHAPEs. here we are hard-coding
1144 SVSHAPE0
= self
.spr
['SVSHAPE0']
1145 SVSHAPE1
= self
.spr
['SVSHAPE1']
1146 SVSHAPE2
= self
.spr
['SVSHAPE2']
1147 SVSHAPE3
= self
.spr
['SVSHAPE3']
1148 # set up the iterators
1149 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1150 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1151 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1152 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1155 self
.remap_loopends
= [0] * 4
1156 self
.remap_idxs
= [0, 1, 2, 3]
1158 for i
, (shape
, remap
) in enumerate(remaps
):
1159 # zero is "disabled"
1160 if shape
.value
== 0x0:
1161 self
.remap_idxs
[i
] = 0
1162 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1163 step
= dststep
if (i
in [3, 4]) else srcstep
1164 # this is terrible. O(N^2) looking for the match. but hey.
1165 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1168 self
.remap_idxs
[i
] = remap_idx
1169 self
.remap_loopends
[i
] = loopends
1170 dbg
.append((i
, step
, remap_idx
, loopends
))
1171 for (i
, step
, remap_idx
, loopends
) in dbg
:
1172 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1175 def get_spr_msb(self
):
1176 dec_insn
= yield self
.dec2
.e
.do
.insn
1177 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1179 def call(self
, name
):
1180 """call(opcode) - the primary execution point for instructions
1182 self
.last_st_addr
= None # reset the last known store address
1183 self
.last_ld_addr
= None # etc.
1185 ins_name
= name
.strip() # remove spaces if not already done so
1187 log("halted - not executing", ins_name
)
1190 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1191 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1192 asmop
= yield from self
.get_assembly_name()
1193 log("call", ins_name
, asmop
)
1196 int_op
= yield self
.dec2
.dec
.op
.internal_op
1197 spr_msb
= yield from self
.get_spr_msb()
1199 instr_is_privileged
= False
1200 if int_op
in [MicrOp
.OP_ATTN
.value
,
1201 MicrOp
.OP_MFMSR
.value
,
1202 MicrOp
.OP_MTMSR
.value
,
1203 MicrOp
.OP_MTMSRD
.value
,
1205 MicrOp
.OP_RFID
.value
]:
1206 instr_is_privileged
= True
1207 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1208 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1209 instr_is_privileged
= True
1211 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1213 # check MSR priv bit and whether op is privileged: if so, throw trap
1214 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1215 self
.call_trap(0x700, PIb
.PRIV
)
1218 # check halted condition
1219 if ins_name
== 'attn':
1223 # check illegal instruction
1225 if ins_name
not in ['mtcrf', 'mtocrf']:
1226 illegal
= ins_name
!= asmop
1228 # sigh deal with setvl not being supported by binutils (.long)
1229 if asmop
.startswith('setvl'):
1233 # and svstep not being supported by binutils (.long)
1234 if asmop
.startswith('svstep'):
1238 # and svremap not being supported by binutils (.long)
1239 if asmop
.startswith('svremap'):
1241 ins_name
= 'svremap'
1243 # and svshape not being supported by binutils (.long)
1244 if asmop
.startswith('svshape'):
1246 ins_name
= 'svshape'
1249 if asmop
== 'fsins':
1252 if asmop
== 'fcoss':
1256 # sigh also deal with ffmadds not being supported by binutils (.long)
1257 if asmop
== 'ffmadds':
1259 ins_name
= 'ffmadds'
1261 # and fdmadds not being supported by binutils (.long)
1262 if asmop
== 'fdmadds':
1264 ins_name
= 'fdmadds'
1266 # and ffadds not being supported by binutils (.long)
1267 if asmop
== 'ffadds':
1272 if asmop
in ['mins', 'maxs', 'minu', 'maxu',
1273 'mins.', 'maxs.', 'minu.', 'maxu.']:
1277 # and anything avgadd
1278 if asmop
.startswith('avgadd'):
1282 # and anything absdu
1283 if asmop
.startswith('absdu'):
1287 # and anything absds
1288 if asmop
.startswith('absds'):
1292 # and anything absadd
1293 if asmop
.startswith('absdac'):
1297 # and anything cprop
1298 if asmop
.startswith('cprop'):
1302 # and anything bmask
1303 if asmop
.startswith('bmask'):
1307 # and anything ternlog
1308 if asmop
.startswith('ternlog'):
1313 if asmop
.startswith('grev'):
1317 # branch-conditional redirects to sv.bc
1318 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1319 ins_name
= 'sv.%s' % ins_name
1321 log(" post-processed name", ins_name
, asmop
)
1323 # illegal instructions call TRAP at 0x700
1325 print("illegal", ins_name
, asmop
)
1326 self
.call_trap(0x700, PIb
.ILLEG
)
1327 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1328 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1331 # this is for setvl "Vertical" mode: if set true,
1332 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1333 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1334 self
.allow_next_step_inc
= False
1335 self
.svstate_next_mode
= 0
1337 # nop has to be supported, we could let the actual op calculate
1338 # but PowerDecoder has a pattern for nop
1339 if ins_name
is 'nop':
1340 self
.update_pc_next()
1343 # look up instruction in ISA.instrs, prepare namespace
1344 info
= self
.instrs
[ins_name
]
1345 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1347 # preserve order of register names
1348 input_names
= create_args(list(info
.read_regs
) +
1349 list(info
.uninit_regs
))
1350 log("input names", input_names
)
1352 # get SVP64 entry for the current instruction
1353 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1354 if sv_rm
is not None:
1355 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1357 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1358 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1360 # see if srcstep/dststep need skipping over masked-out predicate bits
1361 if (self
.is_svp64_mode
or ins_name
== 'setvl' or
1362 ins_name
in ['svremap', 'svstate']):
1363 yield from self
.svstate_pre_inc()
1364 if self
.is_svp64_mode
:
1365 pre
= yield from self
.update_new_svstate_steps()
1367 self
.svp64_reset_loop()
1369 self
.update_pc_next()
1371 srcstep
, dststep
= self
.get_src_dststeps()
1372 pred_dst_zero
= self
.pred_dst_zero
1373 pred_src_zero
= self
.pred_src_zero
1374 vl
= self
.svstate
.vl
1376 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1377 if self
.is_svp64_mode
and vl
== 0:
1378 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1379 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1380 self
.namespace
['NIA'])
1383 # for when SVREMAP is active, using pre-arranged schedule.
1384 # note: modifying PowerDecoder2 needs to "settle"
1385 remap_en
= self
.svstate
.SVme
1386 persist
= self
.svstate
.RMpst
1387 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1388 if self
.is_svp64_mode
:
1389 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1391 if persist
or self
.last_op_svshape
:
1392 remaps
= self
.get_remap_indices()
1393 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1394 # just some convenient debug info
1396 sname
= 'SVSHAPE%d' % i
1397 shape
= self
.spr
[sname
]
1398 log(sname
, bin(shape
.value
))
1399 log(" lims", shape
.lims
)
1400 log(" mode", shape
.mode
)
1401 log(" skip", shape
.skip
)
1403 # set up the list of steps to remap
1404 mi0
= self
.svstate
.mi0
1405 mi1
= self
.svstate
.mi1
1406 mi2
= self
.svstate
.mi2
1407 mo0
= self
.svstate
.mo0
1408 mo1
= self
.svstate
.mo1
1409 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1410 (self
.dec2
.in2_step
, mi1
), # RB
1411 (self
.dec2
.in3_step
, mi2
), # RC
1412 (self
.dec2
.o_step
, mo0
), # RT
1413 (self
.dec2
.o2_step
, mo1
), # EA
1415 remap_idxs
= self
.remap_idxs
1417 # now cross-index the required SHAPE for each of 3-in 2-out regs
1418 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1419 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1420 (shape
, remap
) = remaps
[shape_idx
]
1421 remap_idx
= remap_idxs
[shape_idx
]
1422 # zero is "disabled"
1423 if shape
.value
== 0x0:
1425 # now set the actual requested step to the current index
1426 yield dstep
.eq(remap_idx
)
1428 # debug printout info
1429 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
,
1432 log("shape remap", x
)
1433 # after that, settle down (combinatorial) to let Vector reg numbers
1434 # work themselves out
1436 if self
.is_svp64_mode
:
1437 remap_active
= yield self
.dec2
.remap_active
1439 remap_active
= False
1440 log("remap active", bin(remap_active
))
1442 # main input registers (RT, RA ...)
1444 for name
in input_names
:
1445 # using PowerDecoder2, first, find the decoder index.
1446 # (mapping name RA RB RC RS to in1, in2, in3)
1447 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1449 # doing this is not part of svp64, it's because output
1450 # registers, to be modified, need to be in the namespace.
1451 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1453 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1456 # in case getting the register number is needed, _RA, _RB
1457 regname
= "_" + name
1458 self
.namespace
[regname
] = regnum
1459 if not self
.is_svp64_mode
or not pred_src_zero
:
1460 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1462 reg_val
= SelectableInt(self
.fpr(regnum
))
1463 elif name
is not None:
1464 reg_val
= SelectableInt(self
.gpr(regnum
))
1466 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1468 inputs
.append(reg_val
)
1469 # arrrrgh, awful hack, to get _RT into namespace
1470 if ins_name
in ['setvl', 'svstep']:
1472 RT
= yield self
.dec2
.dec
.RT
1473 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1475 self
.namespace
["RT"] = SelectableInt(0, 5)
1476 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1477 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1479 # in SVP64 mode for LD/ST work out immediate
1480 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1481 # use info.form to detect
1482 replace_d
= False # update / replace constant in pseudocode
1483 if self
.is_svp64_mode
:
1484 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1485 # shift mode reads SVD (or SVDS - TODO)
1486 # *BUT*... because this is "overloading" of LD operations,
1487 # it gets *STORED* into D (or DS, TODO)
1488 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1489 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1490 imm
= exts(imm
, 11) # sign-extend to integer
1491 log("shift SVD", imm
)
1494 if info
.form
== 'DS':
1495 # DS-Form, multiply by 4 then knock 2 bits off after
1496 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1498 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1499 imm
= exts(imm
, 16) # sign-extend to integer
1500 # get the right step. LD is from srcstep, ST is dststep
1501 op
= yield self
.dec2
.e
.do
.insn_type
1503 if op
== MicrOp
.OP_LOAD
.value
:
1505 offsmul
= yield self
.dec2
.in1_step
1506 log("D-field REMAP src", imm
, offsmul
)
1509 log("D-field src", imm
, offsmul
)
1510 elif op
== MicrOp
.OP_STORE
.value
:
1511 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1513 log("D-field dst", imm
, offsmul
)
1514 # bit-reverse mode, rev already done through get_src_dst_steps()
1515 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1516 # manually look up RC, sigh
1517 RC
= yield self
.dec2
.dec
.RC
[0:5]
1519 log("LD-SHIFT:", "VL", vl
,
1520 "RC", RC
.value
, "imm", imm
,
1521 "offs", bin(offsmul
),
1523 imm
= SelectableInt((imm
* offsmul
) << RC
.value
, 32)
1524 # Unit-Strided LD/ST adds offset*width to immediate
1525 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1526 ldst_len
= yield self
.dec2
.e
.do
.data_len
1527 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1529 # Element-strided multiplies the immediate by element step
1530 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1531 imm
= SelectableInt(imm
* offsmul
, 32)
1534 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1535 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1536 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1537 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1538 # new replacement D... errr.. DS
1540 if info
.form
== 'DS':
1541 # TODO: assert 2 LSBs are zero?
1542 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1543 imm
.value
= imm
.value
>> 2
1544 self
.namespace
['DS'] = imm
1546 self
.namespace
['D'] = imm
1548 # "special" registers
1549 for special
in info
.special_regs
:
1550 if special
in special_sprs
:
1551 inputs
.append(self
.spr
[special
])
1553 inputs
.append(self
.namespace
[special
])
1555 # clear trap (trap) NIA
1556 self
.trap_nia
= None
1558 # check if this was an sv.bc* and create an indicator that
1559 # this is the last check to be made as a loop. combined with
1560 # the ALL/ANY mode we can early-exit
1561 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1562 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1563 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1564 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1566 # execute actual instruction here (finally)
1567 log("inputs", inputs
)
1568 results
= info
.func(self
, *inputs
)
1569 log("results", results
)
1571 # "inject" decorator takes namespace from function locals: we need to
1572 # overwrite NIA being overwritten (sigh)
1573 if self
.trap_nia
is not None:
1574 self
.namespace
['NIA'] = self
.trap_nia
1576 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1578 # check if op was a LD/ST so that debugging can check the
1580 if int_op
in [MicrOp
.OP_STORE
.value
,
1582 self
.last_st_addr
= self
.mem
.last_st_addr
1583 if int_op
in [MicrOp
.OP_LOAD
.value
,
1585 self
.last_ld_addr
= self
.mem
.last_ld_addr
1586 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1587 self
.last_st_addr
, self
.last_ld_addr
)
1589 # detect if CA/CA32 already in outputs (sra*, basically)
1592 output_names
= create_args(info
.write_regs
)
1593 for name
in output_names
:
1599 log("carry already done?", bin(already_done
))
1600 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1601 carry_en
= yield self
.dec2
.e
.do
.output_carry
1605 yield from self
.handle_carry_(inputs
, results
, already_done
)
1607 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1608 # detect if overflow was in return result
1611 for name
, output
in zip(output_names
, results
):
1612 if name
== 'overflow':
1615 if hasattr(self
.dec2
.e
.do
, "oe"):
1616 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1617 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1621 log("internal overflow", overflow
, ov_en
, ov_ok
)
1623 yield from self
.handle_overflow(inputs
, results
, overflow
)
1625 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1627 if not self
.is_svp64_mode
or not pred_dst_zero
:
1628 if hasattr(self
.dec2
.e
.do
, "rc"):
1629 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1630 if rc_en
and ins_name
not in ['svstep']:
1631 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1632 self
.handle_comparison(results
, regnum
)
1634 # any modified return results?
1636 for name
, output
in zip(output_names
, results
):
1637 if name
== 'overflow': # ignore, done already (above)
1639 if isinstance(output
, int):
1640 output
= SelectableInt(output
, 256)
1641 if name
in ['CA', 'CA32']:
1643 log("writing %s to XER" % name
, output
)
1644 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1646 log("NOT writing %s to XER" % name
, output
)
1647 elif name
in info
.special_regs
:
1648 log('writing special %s' % name
, output
, special_sprs
)
1649 if name
in special_sprs
:
1650 self
.spr
[name
] = output
1652 self
.namespace
[name
].eq(output
)
1654 log('msr written', hex(self
.msr
.value
))
1656 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1659 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1662 # temporary hack for not having 2nd output
1663 regnum
= yield getattr(self
.decoder
, name
)
1665 if self
.is_svp64_mode
and pred_dst_zero
:
1666 log('zeroing reg %d %s' % (regnum
, str(output
)),
1668 output
= SelectableInt(0, 256)
1674 log('writing %s %s %s' % (ftype
, regnum
, str(output
)),
1676 if output
.bits
> 64:
1677 output
= SelectableInt(output
.value
, 64)
1679 self
.fpr
[regnum
] = output
1681 self
.gpr
[regnum
] = output
1683 # check if it is the SVSTATE.src/dest step that needs incrementing
1684 # this is our Sub-Program-Counter loop from 0 to VL-1
1688 if self
.allow_next_step_inc
:
1689 log("SVSTATE_NEXT: inc requested, mode",
1690 self
.svstate_next_mode
, self
.allow_next_step_inc
)
1691 yield from self
.svstate_pre_inc()
1692 pre
= yield from self
.update_new_svstate_steps()
1694 # reset at end of loop including exit Vertical Mode
1695 log("SVSTATE_NEXT: end of loop, reset")
1696 self
.svp64_reset_loop()
1697 self
.svstate
.vfirst
= 0
1700 results
= [SelectableInt(0, 64)]
1701 self
.handle_comparison(results
) # CR0
1703 if self
.allow_next_step_inc
== 2:
1704 log("SVSTATE_NEXT: read")
1705 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1707 log("SVSTATE_NEXT: post-inc")
1708 # use actual src/dst-step here to check end, do NOT
1709 # use bit-reversed version
1710 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1711 remaps
= self
.get_remap_indices()
1712 remap_idxs
= self
.remap_idxs
1713 vl
= self
.svstate
.vl
1714 end_src
= srcstep
== vl
-1
1715 end_dst
= dststep
== vl
-1
1716 if self
.allow_next_step_inc
!= 2:
1718 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1720 self
.svstate
.dststep
+= SelectableInt(1, 7)
1721 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1722 # set CR0 (if Rc=1) based on end
1724 srcstep
= self
.svstate
.srcstep
1725 dststep
= self
.svstate
.srcstep
1726 endtest
= 1 if (end_src
or end_dst
) else 0
1727 #results = [SelectableInt(endtest, 64)]
1728 # self.handle_comparison(results) # CR0
1730 # see if svstep was requested, if so, which SVSTATE
1732 if self
.svstate_next_mode
> 0:
1733 shape_idx
= self
.svstate_next_mode
.value
-1
1734 endings
= self
.remap_loopends
[shape_idx
]
1735 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
1736 print("svstep Rc=1, CR0", cr_field
)
1737 self
.crl
[0].eq(cr_field
) # CR0
1738 if end_src
or end_dst
:
1739 # reset at end of loop including exit Vertical Mode
1740 log("SVSTATE_NEXT: after increments, reset")
1741 self
.svp64_reset_loop()
1742 self
.svstate
.vfirst
= 0
1744 elif self
.is_svp64_mode
:
1745 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1747 # XXX only in non-SVP64 mode!
1748 # record state of whether the current operation was an svshape,
1749 # to be able to know if it should apply in the next instruction.
1750 # also (if going to use this instruction) should disable ability
1751 # to interrupt in between. sigh.
1752 self
.last_op_svshape
= asmop
== 'svremap'
1755 self
.update_pc_next()
1757 def SVSTATE_NEXT(self
, mode
, submode
):
1758 """explicitly moves srcstep/dststep on to next element, for
1759 "Vertical-First" mode. this function is called from
1760 setvl pseudo-code, as a pseudo-op "svstep"
1762 WARNING: this function uses information that was created EARLIER
1763 due to it being in the middle of a yield, but this function is
1764 *NOT* called from yield (it's called from compiled pseudocode).
1766 self
.allow_next_step_inc
= submode
.value
+ 1
1767 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
1768 self
.svstate_next_mode
= mode
1769 if self
.svstate_next_mode
> 0:
1770 shape_idx
= self
.svstate_next_mode
.value
-1
1771 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1772 return SelectableInt(0, 7)
1774 def svstate_pre_inc(self
):
1775 """check if srcstep/dststep need to skip over masked-out predicate bits
1777 # get SVSTATE VL (oh and print out some debug stuff)
1778 vl
= self
.svstate
.vl
1779 srcstep
= self
.svstate
.srcstep
1780 dststep
= self
.svstate
.dststep
1781 sv_a_nz
= yield self
.dec2
.sv_a_nz
1782 fft_mode
= yield self
.dec2
.use_svp64_fft
1783 in1
= yield self
.dec2
.e
.read_reg1
.data
1784 log("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft, svp64",
1785 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
,
1788 # get predicate mask (all 64 bits)
1789 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1791 pmode
= yield self
.dec2
.rm_dec
.predmode
1792 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1793 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1794 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1795 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1796 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1797 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1798 if pmode
== SVP64PredMode
.INT
.value
:
1799 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1800 if sv_ptype
== SVPtype
.P2
.value
:
1801 srcmask
= get_predint(self
.gpr
, srcpred
)
1802 elif pmode
== SVP64PredMode
.CR
.value
:
1803 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1804 if sv_ptype
== SVPtype
.P2
.value
:
1805 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1806 log(" pmode", pmode
)
1807 log(" reverse", reverse_gear
)
1808 log(" ptype", sv_ptype
)
1809 log(" srcpred", bin(srcpred
))
1810 log(" dstpred", bin(dstpred
))
1811 log(" srcmask", bin(srcmask
))
1812 log(" dstmask", bin(dstmask
))
1813 log(" pred_sz", bin(pred_src_zero
))
1814 log(" pred_dz", bin(pred_dst_zero
))
1816 # okaaay, so here we simply advance srcstep (TODO dststep)
1817 # until the predicate mask has a "1" bit... or we run out of VL
1818 # let srcstep==VL be the indicator to move to next instruction
1819 if not pred_src_zero
:
1820 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1821 log(" skip", bin(1 << srcstep
))
1824 if not pred_dst_zero
:
1825 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1826 log(" skip", bin(1 << dststep
))
1829 # now work out if the relevant mask bits require zeroing
1831 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
1833 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
1835 # store new srcstep / dststep
1836 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1837 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1838 log(" new srcstep", srcstep
)
1839 log(" new dststep", dststep
)
1841 def get_src_dststeps(self
):
1842 """gets srcstep and dststep
1844 return self
.new_srcstep
, self
.new_dststep
1846 def update_new_svstate_steps(self
):
1847 # note, do not get the bit-reversed srcstep here!
1848 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1850 # update SVSTATE with new srcstep
1851 self
.svstate
.srcstep
= srcstep
1852 self
.svstate
.dststep
= dststep
1853 self
.namespace
['SVSTATE'] = self
.svstate
1854 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1855 yield Settle() # let decoder update
1856 srcstep
= self
.svstate
.srcstep
1857 dststep
= self
.svstate
.dststep
1858 vl
= self
.svstate
.vl
1859 log(" srcstep", srcstep
)
1860 log(" dststep", dststep
)
1863 # check if end reached (we let srcstep overrun, above)
1864 # nothing needs doing (TODO zeroing): just do next instruction
1865 return srcstep
== vl
or dststep
== vl
1867 def svstate_post_inc(self
, insn_name
, vf
=0):
1868 # check if SV "Vertical First" mode is enabled
1869 vfirst
= self
.svstate
.vfirst
1870 log(" SV Vertical First", vf
, vfirst
)
1871 if not vf
and vfirst
== 1:
1875 # check if it is the SVSTATE.src/dest step that needs incrementing
1876 # this is our Sub-Program-Counter loop from 0 to VL-1
1877 # XXX twin predication TODO
1878 vl
= self
.svstate
.vl
1879 mvl
= self
.svstate
.maxvl
1880 srcstep
= self
.svstate
.srcstep
1881 dststep
= self
.svstate
.dststep
1882 rm_mode
= yield self
.dec2
.rm_dec
.mode
1883 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1884 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1885 out_vec
= not (yield self
.dec2
.no_out_vec
)
1886 in_vec
= not (yield self
.dec2
.no_in_vec
)
1887 log(" svstate.vl", vl
)
1888 log(" svstate.mvl", mvl
)
1889 log(" svstate.srcstep", srcstep
)
1890 log(" svstate.dststep", dststep
)
1891 log(" mode", rm_mode
)
1892 log(" reverse", reverse_gear
)
1893 log(" out_vec", out_vec
)
1894 log(" in_vec", in_vec
)
1895 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1896 # check if srcstep needs incrementing by one, stop PC advancing
1897 # svp64 loop can end early if the dest is scalar for single-pred
1898 # but for 2-pred both src/dest have to be checked.
1899 # XXX this might not be true! it may just be LD/ST
1900 if sv_ptype
== SVPtype
.P2
.value
:
1901 svp64_is_vector
= (out_vec
or in_vec
)
1903 svp64_is_vector
= out_vec
1904 # check if this was an sv.bc* and if so did it succeed
1905 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1906 end_loop
= self
.namespace
['end_loop']
1907 log("branch %s end_loop" % insn_name
, end_loop
)
1909 self
.svp64_reset_loop()
1910 self
.update_pc_next()
1912 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1913 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1914 self
.svstate
.dststep
+= SelectableInt(1, 7)
1915 self
.namespace
['SVSTATE'] = self
.svstate
1916 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1917 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1918 # this way we keep repeating the same instruction (with new steps)
1919 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1920 self
.namespace
['NIA'] = self
.pc
.NIA
1921 log("end of sub-pc call", self
.namespace
['CIA'],
1922 self
.namespace
['NIA'])
1923 return False # DO NOT allow PC update whilst Sub-PC loop running
1925 # reset loop to zero and update NIA
1926 self
.svp64_reset_loop()
1931 def update_pc_next(self
):
1932 # UPDATE program counter
1933 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1934 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1935 log("end of call", self
.namespace
['CIA'],
1936 self
.namespace
['NIA'],
1937 self
.namespace
['SVSTATE'])
1939 def svp64_reset_loop(self
):
1940 self
.svstate
.srcstep
= 0
1941 self
.svstate
.dststep
= 0
1942 log(" svstate.srcstep loop end (PC to update)")
1943 self
.namespace
['SVSTATE'] = self
.svstate
1945 def update_nia(self
):
1946 self
.pc
.update_nia(self
.is_svp64_mode
)
1947 self
.namespace
['NIA'] = self
.pc
.NIA
1951 """Decorator factory.
1953 this decorator will "inject" variables into the function's namespace,
1954 from the *dictionary* in self.namespace. it therefore becomes possible
1955 to make it look like a whole stack of variables which would otherwise
1956 need "self." inserted in front of them (*and* for those variables to be
1957 added to the instance) "appear" in the function.
1959 "self.namespace['SI']" for example becomes accessible as just "SI" but
1960 *only* inside the function, when decorated.
1962 def variable_injector(func
):
1964 def decorator(*args
, **kwargs
):
1966 func_globals
= func
.__globals
__ # Python 2.6+
1967 except AttributeError:
1968 func_globals
= func
.func_globals
# Earlier versions.
1970 context
= args
[0].namespace
# variables to be injected
1971 saved_values
= func_globals
.copy() # Shallow copy of dict.
1972 log("globals before", context
.keys())
1973 func_globals
.update(context
)
1974 result
= func(*args
, **kwargs
)
1975 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1976 log("args[0]", args
[0].namespace
['CIA'],
1977 args
[0].namespace
['NIA'],
1978 args
[0].namespace
['SVSTATE'])
1979 if 'end_loop' in func_globals
:
1980 log("args[0] end_loop", func_globals
['end_loop'])
1981 args
[0].namespace
= func_globals
1982 #exec (func.__code__, func_globals)
1985 # func_globals = saved_values # Undo changes.
1991 return variable_injector