757527c4c91cc6312cd45450b0927519e8c91255
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
,
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
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 assert False, "RC does not exist yet"
381 if in1_sel
== In1Sel
.RS
.value
:
382 return in1
, in1_isvec
383 if in2_sel
== In2Sel
.RS
.value
:
384 return in2
, in2_isvec
385 if in3_sel
== In3Sel
.RS
.value
:
386 return in3
, in3_isvec
388 if in1_sel
== In1Sel
.FRA
.value
:
389 return in1
, in1_isvec
391 if in2_sel
== In2Sel
.FRB
.value
:
392 return in2
, in2_isvec
394 if in3_sel
== In3Sel
.FRC
.value
:
395 return in3
, in3_isvec
397 if in1_sel
== In1Sel
.FRS
.value
:
398 return in1
, in1_isvec
399 if in3_sel
== In3Sel
.FRS
.value
:
400 return in3
, in3_isvec
404 # TODO, really should just be using PowerDecoder2
405 def get_pdecode_cr_in(dec2
, name
):
407 in_sel
= yield op
.cr_in
408 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
409 sv_cr_in
= yield op
.sv_cr_in
410 spec
= yield dec2
.crin_svdec
.spec
411 sv_override
= yield dec2
.dec_cr_in
.sv_override
412 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
413 in1
= yield dec2
.e
.read_cr1
.data
414 cr_isvec
= yield dec2
.cr_in_isvec
415 log("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
416 log(" sv_cr_in", sv_cr_in
)
417 log(" cr_bf", in_bitfield
)
419 log(" override", sv_override
)
420 # identify which regnames map to in / o2
422 if in_sel
== CRInSel
.BI
.value
:
424 log("get_pdecode_cr_in not found", name
)
428 # TODO, really should just be using PowerDecoder2
429 def get_pdecode_cr_out(dec2
, name
):
431 out_sel
= yield op
.cr_out
432 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
433 sv_cr_out
= yield op
.sv_cr_out
434 spec
= yield dec2
.crout_svdec
.spec
435 sv_override
= yield dec2
.dec_cr_out
.sv_override
436 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
437 out
= yield dec2
.e
.write_cr
.data
438 o_isvec
= yield dec2
.o_isvec
439 log("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
440 log(" sv_cr_out", sv_cr_out
)
441 log(" cr_bf", out_bitfield
)
443 log(" override", sv_override
)
444 # identify which regnames map to out / o2
446 if out_sel
== CROutSel
.CR0
.value
:
448 if name
== 'CR1': # these are not actually calculated correctly
449 if out_sel
== CROutSel
.CR1
.value
:
451 log("get_pdecode_cr_out not found", name
)
455 # TODO, really should just be using PowerDecoder2
456 def get_pdecode_idx_out(dec2
, name
):
458 out_sel
= yield op
.out_sel
459 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
460 out
= yield dec2
.e
.write_reg
.data
461 o_isvec
= yield dec2
.o_isvec
462 # identify which regnames map to out / o2
464 log("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
465 if out_sel
== OutSel
.RA
.value
:
468 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
469 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
471 if out_sel
== OutSel
.RT
.value
:
473 elif name
== 'RT_OR_ZERO':
474 log("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
475 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
477 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
480 log("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
481 if out_sel
== OutSel
.FRA
.value
:
484 log("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
485 OutSel
.FRT
.value
, out
, o_isvec
)
486 if out_sel
== OutSel
.FRT
.value
:
488 log("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
492 # TODO, really should just be using PowerDecoder2
493 def get_pdecode_idx_out2(dec2
, name
):
494 # check first if register is activated for write
496 out_sel
= yield op
.out_sel
497 out
= yield dec2
.e
.write_ea
.data
498 o_isvec
= yield dec2
.o2_isvec
499 out_ok
= yield dec2
.e
.write_ea
.ok
500 log("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
505 if hasattr(op
, "upd"):
506 # update mode LD/ST uses read-reg A also as an output
508 log("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
509 out_sel
, OutSel
.RA
.value
,
511 if upd
== LDSTMode
.update
.value
:
514 int_op
= yield dec2
.dec
.op
.internal_op
515 fft_en
= yield dec2
.use_svp64_fft
516 # if int_op == MicrOp.OP_FP_MADD.value and fft_en:
518 log("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
524 class ISACaller(ISACallerHelper
, ISAFPHelpers
):
525 # decoder2 - an instance of power_decoder2
526 # regfile - a list of initial values for the registers
527 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
528 # respect_pc - tracks the program counter. requires initial_insns
529 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
530 initial_mem
=None, initial_msr
=0,
541 self
.bigendian
= bigendian
543 self
.is_svp64_mode
= False
544 self
.respect_pc
= respect_pc
545 if initial_sprs
is None:
547 if initial_mem
is None:
549 if fpregfile
is None:
551 if initial_insns
is None:
553 assert self
.respect_pc
== False, "instructions required to honor pc"
555 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
556 log("ISACaller initial_msr", initial_msr
)
558 # "fake program counter" mode (for unit testing)
562 if isinstance(initial_mem
, tuple):
563 self
.fake_pc
= initial_mem
[0]
564 disasm_start
= self
.fake_pc
566 disasm_start
= initial_pc
568 # disassembly: we need this for now (not given from the decoder)
569 self
.disassembly
= {}
571 for i
, code
in enumerate(disassembly
):
572 self
.disassembly
[i
*4 + disasm_start
] = code
574 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
575 self
.svp64rm
= SVP64RM()
576 if initial_svstate
is None:
578 if isinstance(initial_svstate
, int):
579 initial_svstate
= SVP64State(initial_svstate
)
580 # SVSTATE, MSR and PC
581 self
.svstate
= initial_svstate
582 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
584 # GPR FPR SPR registers
585 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
586 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
587 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
588 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
590 # set up 4 dummy SVSHAPEs if they aren't already set up
592 sname
= 'SVSHAPE%d' % i
593 if sname
not in self
.spr
:
596 val
= self
.spr
[sname
].value
597 # make sure it's an SVSHAPE
598 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
599 self
.last_op_svshape
= False
602 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
603 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
604 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
605 # MMU mode, redirect underlying Mem through RADIX
607 self
.mem
= RADIX(self
.mem
, self
)
609 self
.imem
= RADIX(self
.imem
, self
)
612 # FPR (same as GPR except for FP nums)
613 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
614 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
615 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
616 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
618 # 2.3.2 LR (actually SPR #8) -- Done
619 # 2.3.3 CTR (actually SPR #9) -- Done
620 # 2.3.4 TAR (actually SPR #815)
621 # 3.2.2 p45 XER (actually SPR #1) -- Done
622 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
624 # create CR then allow portions of it to be "selectable" (below)
625 self
.cr_fields
= CRFields(initial_cr
)
626 self
.cr
= self
.cr_fields
.cr
628 # "undefined", just set to variable-bit-width int (use exts "max")
629 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
632 self
.namespace
.update(self
.spr
)
633 self
.namespace
.update({'GPR': self
.gpr
,
637 'memassign': self
.memassign
,
640 'SVSTATE': self
.svstate
,
641 'SVSHAPE0': self
.spr
['SVSHAPE0'],
642 'SVSHAPE1': self
.spr
['SVSHAPE1'],
643 'SVSHAPE2': self
.spr
['SVSHAPE2'],
644 'SVSHAPE3': self
.spr
['SVSHAPE3'],
647 'undefined': undefined
,
648 'mode_is_64bit': True,
649 'SO': XER_bits
['SO'],
650 'XLEN': 64 # elwidth overrides, later
653 # update pc to requested start point
654 self
.set_pc(initial_pc
)
656 # field-selectable versions of Condition Register
657 self
.crl
= self
.cr_fields
.crl
659 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
661 self
.decoder
= decoder2
.dec
664 super().__init
__(XLEN
=self
.namespace
["XLEN"])
668 return self
.namespace
["XLEN"]
670 def call_trap(self
, trap_addr
, trap_bit
):
671 """calls TRAP and sets up NIA to the new execution location.
672 next instruction will begin at trap_addr.
674 self
.TRAP(trap_addr
, trap_bit
)
675 self
.namespace
['NIA'] = self
.trap_nia
676 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
678 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
679 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
681 TRAP function is callable from inside the pseudocode itself,
682 hence the default arguments. when calling from inside ISACaller
683 it is best to use call_trap()
685 # https://bugs.libre-soc.org/show_bug.cgi?id=859
686 kaivb
= self
.spr
['KAIVB'].value
687 msr
= self
.namespace
['MSR'].value
688 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
689 # store CIA(+4?) in SRR0, set NIA to 0x700
690 # store MSR in SRR1, set MSR to um errr something, have to check spec
691 # store SVSTATE (if enabled) in SVSRR0
692 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
693 self
.spr
['SRR1'].value
= msr
694 if self
.is_svp64_mode
:
695 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
696 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
&~
0x1fff), 64)
697 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
699 # set exception bits. TODO: this should, based on the address
700 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
701 # bits appropriately. however it turns out that *for now* in all
702 # cases (all trap_addrs) the exact same thing is needed.
703 self
.msr
[MSRb
.IR
] = 0
704 self
.msr
[MSRb
.DR
] = 0
705 self
.msr
[MSRb
.FE0
] = 0
706 self
.msr
[MSRb
.FE1
] = 0
707 self
.msr
[MSRb
.EE
] = 0
708 self
.msr
[MSRb
.RI
] = 0
709 self
.msr
[MSRb
.SF
] = 1
710 self
.msr
[MSRb
.TM
] = 0
711 self
.msr
[MSRb
.VEC
] = 0
712 self
.msr
[MSRb
.VSX
] = 0
713 self
.msr
[MSRb
.PR
] = 0
714 self
.msr
[MSRb
.FP
] = 0
715 self
.msr
[MSRb
.PMM
] = 0
716 self
.msr
[MSRb
.TEs
] = 0
717 self
.msr
[MSRb
.TEe
] = 0
718 self
.msr
[MSRb
.UND
] = 0
719 self
.msr
[MSRb
.LE
] = 1
721 def memassign(self
, ea
, sz
, val
):
722 self
.mem
.memassign(ea
, sz
, val
)
724 def prep_namespace(self
, insn_name
, formname
, op_fields
):
725 # TODO: get field names from form in decoder*1* (not decoder2)
726 # decoder2 is hand-created, and decoder1.sigform is auto-generated
728 # then "yield" fields only from op_fields rather than hard-coded
730 fields
= self
.decoder
.sigforms
[formname
]
731 log("prep_namespace", formname
, op_fields
)
732 for name
in op_fields
:
733 # CR immediates. deal with separately. needs modifying
735 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
736 # BI is a 5-bit, must reconstruct the value
737 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
738 sig
= getattr(fields
, name
)
740 # low 2 LSBs (CR field selector) remain same, CR num extended
741 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
742 val
= (val
& 0b11) |
(regnum
<< 2)
745 sig
= getattr(fields
, name
.upper())
747 sig
= getattr(fields
, name
)
749 # these are all opcode fields involved in index-selection of CR,
750 # and need to do "standard" arithmetic. CR[BA+32] for example
751 # would, if using SelectableInt, only be 5-bit.
752 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
753 self
.namespace
[name
] = val
755 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
757 self
.namespace
['XER'] = self
.spr
['XER']
758 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
759 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
761 # add some SVSTATE convenience variables
763 srcstep
= self
.svstate
.srcstep
764 self
.namespace
['VL'] = vl
765 self
.namespace
['srcstep'] = srcstep
767 # sv.bc* need some extra fields
768 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
769 # blegh grab bits manually
770 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
771 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
772 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
773 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
774 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
775 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
776 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
777 sz
= yield self
.dec2
.rm_dec
.pred_sz
778 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
779 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
780 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
781 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
782 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
783 self
.namespace
['sz'] = SelectableInt(sz
, 1)
784 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
786 def handle_carry_(self
, inputs
, outputs
, already_done
):
787 inv_a
= yield self
.dec2
.e
.do
.invert_in
789 inputs
[0] = ~inputs
[0]
791 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
793 imm
= yield self
.dec2
.e
.do
.imm_data
.data
794 inputs
.append(SelectableInt(imm
, 64))
795 assert len(outputs
) >= 1
796 log("outputs", repr(outputs
))
797 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
803 log("gt input", x
, output
)
804 gt
= (gtu(x
, output
))
807 cy
= 1 if any(gts
) else 0
809 if not (1 & already_done
):
810 self
.spr
['XER'][XER_bits
['CA']] = cy
812 log("inputs", already_done
, inputs
)
814 # ARGH... different for OP_ADD... *sigh*...
815 op
= yield self
.dec2
.e
.do
.insn_type
816 if op
== MicrOp
.OP_ADD
.value
:
817 res32
= (output
.value
& (1 << 32)) != 0
818 a32
= (inputs
[0].value
& (1 << 32)) != 0
820 b32
= (inputs
[1].value
& (1 << 32)) != 0
823 cy32
= res32 ^ a32 ^ b32
824 log("CA32 ADD", cy32
)
828 log("input", x
, output
)
829 log(" x[32:64]", x
, x
[32:64])
830 log(" o[32:64]", output
, output
[32:64])
831 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
833 cy32
= 1 if any(gts
) else 0
834 log("CA32", cy32
, gts
)
835 if not (2 & already_done
):
836 self
.spr
['XER'][XER_bits
['CA32']] = cy32
838 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
839 if hasattr(self
.dec2
.e
.do
, "invert_in"):
840 inv_a
= yield self
.dec2
.e
.do
.invert_in
842 inputs
[0] = ~inputs
[0]
844 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
846 imm
= yield self
.dec2
.e
.do
.imm_data
.data
847 inputs
.append(SelectableInt(imm
, 64))
848 assert len(outputs
) >= 1
849 log("handle_overflow", inputs
, outputs
, div_overflow
)
850 if len(inputs
) < 2 and div_overflow
is None:
853 # div overflow is different: it's returned by the pseudo-code
854 # because it's more complex than can be done by analysing the output
855 if div_overflow
is not None:
856 ov
, ov32
= div_overflow
, div_overflow
857 # arithmetic overflow can be done by analysing the input and output
858 elif len(inputs
) >= 2:
862 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
863 output_sgn
= exts(output
.value
, output
.bits
) < 0
864 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
865 output_sgn
!= input_sgn
[0] else 0
868 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
869 output32_sgn
= exts(output
.value
, 32) < 0
870 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
871 output32_sgn
!= input32_sgn
[0] else 0
873 # now update XER OV/OV32/SO
874 so
= self
.spr
['XER'][XER_bits
['SO']]
875 new_so
= so | ov
# sticky overflow ORs in old with new
876 self
.spr
['XER'][XER_bits
['OV']] = ov
877 self
.spr
['XER'][XER_bits
['OV32']] = ov32
878 self
.spr
['XER'][XER_bits
['SO']] = new_so
879 log(" set overflow", ov
, ov32
, so
, new_so
)
881 def handle_comparison(self
, outputs
, cr_idx
=0, overflow
=None, no_so
=False):
883 assert isinstance(out
, SelectableInt
), \
884 "out zero not a SelectableInt %s" % repr(outputs
)
885 log("handle_comparison", out
.bits
, hex(out
.value
))
886 # TODO - XXX *processor* in 32-bit mode
887 # https://bugs.libre-soc.org/show_bug.cgi?id=424
889 # o32 = exts(out.value, 32)
890 # print ("handle_comparison exts 32 bit", hex(o32))
891 out
= exts(out
.value
, out
.bits
)
892 log("handle_comparison exts", hex(out
))
893 # create the three main CR flags, EQ GT LT
894 zero
= SelectableInt(out
== 0, 1)
895 positive
= SelectableInt(out
> 0, 1)
896 negative
= SelectableInt(out
< 0, 1)
897 # get (or not) XER.SO. for setvl this is important *not* to read SO
899 SO
= SelectableInt(1, 0)
901 SO
= self
.spr
['XER'][XER_bits
['SO']]
902 log("handle_comparison SO overflow", SO
, overflow
)
903 # alternative overflow checking (setvl mainly at the moment)
904 if overflow
is not None and overflow
== 1:
905 SO
= SelectableInt(1, 1)
906 # create the four CR field values and set the required CR field
907 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
908 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
909 self
.crl
[cr_idx
].eq(cr_field
)
911 def set_pc(self
, pc_val
):
912 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
913 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
915 def get_next_insn(self
):
919 pc
= self
.pc
.CIA
.value
922 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
924 raise KeyError("no instruction at 0x%x" % pc
)
928 """set up one instruction
930 pc
, insn
= self
.get_next_insn()
931 yield from self
.setup_next_insn(pc
, insn
)
933 def setup_next_insn(self
, pc
, ins
):
934 """set up next instruction
937 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
938 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
940 yield self
.dec2
.sv_rm
.eq(0)
941 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
942 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
943 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
944 yield self
.dec2
.state
.pc
.eq(pc
)
945 if self
.svstate
is not None:
946 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
948 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
950 opcode
= yield self
.dec2
.dec
.opcode_in
951 opcode
= SelectableInt(value
=opcode
, bits
=32)
952 pfx
= SVP64Instruction
.Prefix(opcode
)
953 log("prefix test: opcode:", pfx
.po
, bin(pfx
.po
), pfx
.id)
954 self
.is_svp64_mode
= bool((pfx
.po
== 0b000001) and (pfx
.id == 0b11))
955 self
.pc
.update_nia(self
.is_svp64_mode
)
957 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
958 self
.namespace
['NIA'] = self
.pc
.NIA
959 self
.namespace
['SVSTATE'] = self
.svstate
960 if not self
.is_svp64_mode
:
963 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
964 log("svp64.rm", bin(pfx
.rm
))
965 log(" svstate.vl", self
.svstate
.vl
)
966 log(" svstate.mvl", self
.svstate
.maxvl
)
967 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
968 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
969 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
970 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
973 def execute_one(self
):
974 """execute one instruction
976 # get the disassembly code for this instruction
977 if self
.is_svp64_mode
:
978 if not self
.disassembly
:
979 code
= yield from self
.get_assembly_name()
981 code
= self
.disassembly
[self
._pc
+4]
982 log(" svp64 sim-execute", hex(self
._pc
), code
)
984 if not self
.disassembly
:
985 code
= yield from self
.get_assembly_name()
987 code
= self
.disassembly
[self
._pc
]
988 log("sim-execute", hex(self
._pc
), code
)
989 opname
= code
.split(' ')[0]
991 yield from self
.call(opname
) # execute the instruction
992 except MemException
as e
: # check for memory errors
993 if e
.args
[0] == 'unaligned': # alignment error
994 # run a Trap but set DAR first
995 print("memory unaligned exception, DAR", e
.dar
)
996 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
997 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
999 elif e
.args
[0] == 'invalid': # invalid
1000 # run a Trap but set DAR first
1001 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1002 if e
.mode
== 'EXECUTE':
1003 # XXX TODO: must set a few bits in SRR1,
1004 # see microwatt loadstore1.vhdl
1005 # if m_in.segerr = '0' then
1006 # v.srr1(47 - 33) := m_in.invalid;
1007 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1008 # v.srr1(47 - 44) := m_in.badtree;
1009 # v.srr1(47 - 45) := m_in.rc_error;
1010 # v.intr_vec := 16#400#;
1012 # v.intr_vec := 16#480#;
1013 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1015 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1017 # not supported yet:
1018 raise e
# ... re-raise
1020 # don't use this except in special circumstances
1021 if not self
.respect_pc
:
1024 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1025 hex(self
.pc
.NIA
.value
))
1027 def get_assembly_name(self
):
1028 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1029 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1030 dec_insn
= yield self
.dec2
.e
.do
.insn
1031 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1032 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1033 int_op
= yield self
.dec2
.dec
.op
.internal_op
1034 log("get assembly name asmcode", asmcode
, int_op
,
1035 hex(dec_insn
), bin(insn_1_11
))
1036 asmop
= insns
.get(asmcode
, None)
1038 # sigh reconstruct the assembly instruction name
1039 if hasattr(self
.dec2
.e
.do
, "oe"):
1040 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1041 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1045 if hasattr(self
.dec2
.e
.do
, "rc"):
1046 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1047 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1051 # grrrr have to special-case MUL op (see DecodeOE)
1052 log("ov %d en %d rc %d en %d op %d" %
1053 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1054 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1059 if not asmop
.endswith("."): # don't add "." to "andis."
1062 if hasattr(self
.dec2
.e
.do
, "lk"):
1063 lk
= yield self
.dec2
.e
.do
.lk
1066 log("int_op", int_op
)
1067 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1068 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1072 spr_msb
= yield from self
.get_spr_msb()
1073 if int_op
== MicrOp
.OP_MFCR
.value
:
1078 # XXX TODO: for whatever weird reason this doesn't work
1079 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1080 if int_op
== MicrOp
.OP_MTCRF
.value
:
1087 def get_remap_indices(self
):
1088 """WARNING, this function stores remap_idxs and remap_loopends
1089 in the class for later use. this to avoid problems with yield
1091 # go through all iterators in lock-step, advance to next remap_idx
1092 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1093 # get four SVSHAPEs. here we are hard-coding
1094 SVSHAPE0
= self
.spr
['SVSHAPE0']
1095 SVSHAPE1
= self
.spr
['SVSHAPE1']
1096 SVSHAPE2
= self
.spr
['SVSHAPE2']
1097 SVSHAPE3
= self
.spr
['SVSHAPE3']
1098 # set up the iterators
1099 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1100 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1101 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1102 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1105 self
.remap_loopends
= [0] * 4
1106 self
.remap_idxs
= [0, 1, 2, 3]
1108 for i
, (shape
, remap
) in enumerate(remaps
):
1109 # zero is "disabled"
1110 if shape
.value
== 0x0:
1111 self
.remap_idxs
[i
] = 0
1112 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1113 step
= dststep
if (i
in [3, 4]) else srcstep
1114 # this is terrible. O(N^2) looking for the match. but hey.
1115 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1118 self
.remap_idxs
[i
] = remap_idx
1119 self
.remap_loopends
[i
] = loopends
1120 dbg
.append((i
, step
, remap_idx
, loopends
))
1121 for (i
, step
, remap_idx
, loopends
) in dbg
:
1122 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1125 def get_spr_msb(self
):
1126 dec_insn
= yield self
.dec2
.e
.do
.insn
1127 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1129 def call(self
, name
):
1130 """call(opcode) - the primary execution point for instructions
1132 self
.last_st_addr
= None # reset the last known store address
1133 self
.last_ld_addr
= None # etc.
1135 ins_name
= name
.strip() # remove spaces if not already done so
1137 log("halted - not executing", ins_name
)
1140 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1141 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1142 asmop
= yield from self
.get_assembly_name()
1143 log("call", ins_name
, asmop
)
1146 int_op
= yield self
.dec2
.dec
.op
.internal_op
1147 spr_msb
= yield from self
.get_spr_msb()
1149 instr_is_privileged
= False
1150 if int_op
in [MicrOp
.OP_ATTN
.value
,
1151 MicrOp
.OP_MFMSR
.value
,
1152 MicrOp
.OP_MTMSR
.value
,
1153 MicrOp
.OP_MTMSRD
.value
,
1155 MicrOp
.OP_RFID
.value
]:
1156 instr_is_privileged
= True
1157 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1158 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1159 instr_is_privileged
= True
1161 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1163 # check MSR priv bit and whether op is privileged: if so, throw trap
1164 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1165 self
.call_trap(0x700, PIb
.PRIV
)
1168 # check halted condition
1169 if ins_name
== 'attn':
1173 # check illegal instruction
1175 if ins_name
not in ['mtcrf', 'mtocrf']:
1176 illegal
= ins_name
!= asmop
1178 # list of instructions not being supported by binutils (.long)
1179 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1180 if dotstrp
in [ 'fsins', 'fcoss',
1181 'ffmadds', 'fdmadds', 'ffadds',
1182 'mins', 'maxs', 'minu', 'maxu',
1183 'setvl', 'svindex', 'svremap', 'svstep',
1184 'svshape', 'svshape2',
1185 'grev', 'ternlogi', 'bmask', 'cprop',
1186 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1192 # branch-conditional redirects to sv.bc
1193 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1194 ins_name
= 'sv.%s' % ins_name
1196 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1198 # illegal instructions call TRAP at 0x700
1200 print("illegal", ins_name
, asmop
)
1201 self
.call_trap(0x700, PIb
.ILLEG
)
1202 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1203 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1206 # this is for setvl "Vertical" mode: if set true,
1207 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1208 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1209 self
.allow_next_step_inc
= False
1210 self
.svstate_next_mode
= 0
1212 # nop has to be supported, we could let the actual op calculate
1213 # but PowerDecoder has a pattern for nop
1214 if ins_name
== 'nop':
1215 self
.update_pc_next()
1218 # look up instruction in ISA.instrs, prepare namespace
1219 info
= self
.instrs
[ins_name
]
1220 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1222 # preserve order of register names
1223 input_names
= create_args(list(info
.read_regs
) +
1224 list(info
.uninit_regs
))
1225 log("input names", input_names
)
1227 # get SVP64 entry for the current instruction
1228 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1229 if sv_rm
is not None:
1230 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1232 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1233 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1235 # see if srcstep/dststep need skipping over masked-out predicate bits
1236 if (self
.is_svp64_mode
or ins_name
== 'setvl' or
1237 ins_name
in ['svremap', 'svstate']):
1238 yield from self
.svstate_pre_inc()
1239 if self
.is_svp64_mode
:
1240 pre
= yield from self
.update_new_svstate_steps()
1242 self
.svp64_reset_loop()
1244 self
.update_pc_next()
1246 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1247 pred_dst_zero
= self
.pred_dst_zero
1248 pred_src_zero
= self
.pred_src_zero
1249 vl
= self
.svstate
.vl
1250 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1252 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1253 if self
.is_svp64_mode
and vl
== 0:
1254 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1255 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1256 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
1259 # for when SVREMAP is active, using pre-arranged schedule.
1260 # note: modifying PowerDecoder2 needs to "settle"
1261 remap_en
= self
.svstate
.SVme
1262 persist
= self
.svstate
.RMpst
1263 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1264 if self
.is_svp64_mode
:
1265 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1267 if persist
or self
.last_op_svshape
:
1268 remaps
= self
.get_remap_indices()
1269 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1270 yield from self
.remap_set_steps(remaps
)
1271 # after that, settle down (combinatorial) to let Vector reg numbers
1272 # work themselves out
1274 if self
.is_svp64_mode
:
1275 remap_active
= yield self
.dec2
.remap_active
1277 remap_active
= False
1278 log("remap active", bin(remap_active
))
1280 # main input registers (RT, RA ...)
1282 for name
in input_names
:
1284 regval
= (yield from self
.get_input(name
))
1285 log("regval", regval
)
1286 inputs
.append(regval
)
1288 # arrrrgh, awful hack, to get _RT into namespace
1289 if ins_name
in ['setvl', 'svstep']:
1291 RT
= yield self
.dec2
.dec
.RT
1292 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1294 self
.namespace
["RT"] = SelectableInt(0, 5)
1295 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1296 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1298 # in SVP64 mode for LD/ST work out immediate
1299 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1300 # use info.form to detect
1301 if self
.is_svp64_mode
:
1302 yield from self
.check_replace_d(info
, remap_active
)
1304 # "special" registers
1305 for special
in info
.special_regs
:
1306 if special
in special_sprs
:
1307 inputs
.append(self
.spr
[special
])
1309 inputs
.append(self
.namespace
[special
])
1311 # clear trap (trap) NIA
1312 self
.trap_nia
= None
1314 # check if this was an sv.bc* and create an indicator that
1315 # this is the last check to be made as a loop. combined with
1316 # the ALL/ANY mode we can early-exit
1317 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1318 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1319 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1320 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1322 # execute actual instruction here (finally)
1323 log("inputs", inputs
)
1324 results
= info
.func(self
, *inputs
)
1325 log("results", results
)
1327 # "inject" decorator takes namespace from function locals: we need to
1328 # overwrite NIA being overwritten (sigh)
1329 if self
.trap_nia
is not None:
1330 self
.namespace
['NIA'] = self
.trap_nia
1332 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1334 # check if op was a LD/ST so that debugging can check the
1336 if int_op
in [MicrOp
.OP_STORE
.value
,
1338 self
.last_st_addr
= self
.mem
.last_st_addr
1339 if int_op
in [MicrOp
.OP_LOAD
.value
,
1341 self
.last_ld_addr
= self
.mem
.last_ld_addr
1342 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1343 self
.last_st_addr
, self
.last_ld_addr
)
1345 # detect if CA/CA32 already in outputs (sra*, basically)
1348 output_names
= create_args(info
.write_regs
)
1349 for name
in output_names
:
1355 log("carry already done?", bin(already_done
))
1356 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1357 carry_en
= yield self
.dec2
.e
.do
.output_carry
1361 yield from self
.handle_carry_(inputs
, results
, already_done
)
1363 # check if one of the regs was named "overflow"
1366 for name
, output
in zip(output_names
, results
):
1367 if name
== 'overflow':
1370 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1371 # detect if overflow was in return result
1372 if hasattr(self
.dec2
.e
.do
, "oe"):
1373 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1374 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1378 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
1380 yield from self
.handle_overflow(inputs
, results
, overflow
)
1382 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1384 if not self
.is_svp64_mode
or not pred_dst_zero
:
1385 if hasattr(self
.dec2
.e
.do
, "rc"):
1386 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1387 if rc_en
and ins_name
not in ['svstep']:
1388 if ins_name
.startswith("f"):
1389 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
1392 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, rc_reg
)
1394 # hang on... for `setvl` actually you want to test SVSTATE.VL
1395 is_setvl
= ins_name
== 'setvl'
1398 cmps
= (SelectableInt(vl
, 64), overflow
,)
1400 overflow
= None # do not override overflow except in setvl
1401 self
.handle_comparison(cmps
, regnum
, overflow
, no_so
=is_setvl
)
1403 # any modified return results?
1405 for name
, output
in zip(output_names
, results
):
1406 yield from self
.check_write(info
, name
, output
, carry_en
)
1408 nia_update
= (yield from self
.check_step_increment(results
, rc_en
,
1411 self
.update_pc_next()
1413 def check_replace_d(self
, info
, remap_active
):
1414 replace_d
= False # update / replace constant in pseudocode
1415 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1416 vl
= self
.svstate
.vl
1417 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1418 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1419 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1420 if info
.form
== 'DS':
1421 # DS-Form, multiply by 4 then knock 2 bits off after
1422 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1424 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1425 imm
= exts(imm
, 16) # sign-extend to integer
1426 # get the right step. LD is from srcstep, ST is dststep
1427 op
= yield self
.dec2
.e
.do
.insn_type
1429 if op
== MicrOp
.OP_LOAD
.value
:
1431 offsmul
= yield self
.dec2
.in1_step
1432 log("D-field REMAP src", imm
, offsmul
)
1434 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
1435 log("D-field src", imm
, offsmul
)
1436 elif op
== MicrOp
.OP_STORE
.value
:
1437 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1438 offsmul
= (dststep
* (subvl
+1)) + dsubstep
1439 log("D-field dst", imm
, offsmul
)
1440 # Unit-Strided LD/ST adds offset*width to immediate
1441 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1442 ldst_len
= yield self
.dec2
.e
.do
.data_len
1443 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1445 # Element-strided multiplies the immediate by element step
1446 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1447 imm
= SelectableInt(imm
* offsmul
, 32)
1450 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1451 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1452 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1453 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1454 # new replacement D... errr.. DS
1456 if info
.form
== 'DS':
1457 # TODO: assert 2 LSBs are zero?
1458 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1459 imm
.value
= imm
.value
>> 2
1460 self
.namespace
['DS'] = imm
1462 self
.namespace
['D'] = imm
1464 def get_input(self
, name
):
1465 # using PowerDecoder2, first, find the decoder index.
1466 # (mapping name RA RB RC RS to in1, in2, in3)
1467 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1469 # doing this is not part of svp64, it's because output
1470 # registers, to be modified, need to be in the namespace.
1471 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1473 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
, name
)
1475 # in case getting the register number is needed, _RA, _RB
1476 regname
= "_" + name
1477 self
.namespace
[regname
] = regnum
1478 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
1479 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1481 reg_val
= SelectableInt(self
.fpr(regnum
))
1482 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1483 elif name
is not None:
1484 reg_val
= SelectableInt(self
.gpr(regnum
))
1485 log("read reg %d: 0x%x" % (regnum
, reg_val
.value
))
1487 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1491 def remap_set_steps(self
, remaps
):
1492 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1493 they work in concert with PowerDecoder2 at the moment,
1494 there is no HDL implementation of REMAP. therefore this
1495 function, because ISACaller still uses PowerDecoder2,
1496 will *explicitly* write the dec2.XX_step values. this has
1499 # just some convenient debug info
1501 sname
= 'SVSHAPE%d' % i
1502 shape
= self
.spr
[sname
]
1503 log(sname
, bin(shape
.value
))
1504 log(" lims", shape
.lims
)
1505 log(" mode", shape
.mode
)
1506 log(" skip", shape
.skip
)
1508 # set up the list of steps to remap
1509 mi0
= self
.svstate
.mi0
1510 mi1
= self
.svstate
.mi1
1511 mi2
= self
.svstate
.mi2
1512 mo0
= self
.svstate
.mo0
1513 mo1
= self
.svstate
.mo1
1514 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1515 (self
.dec2
.in2_step
, mi1
), # RB
1516 (self
.dec2
.in3_step
, mi2
), # RC
1517 (self
.dec2
.o_step
, mo0
), # RT
1518 (self
.dec2
.o2_step
, mo1
), # EA
1520 remap_idxs
= self
.remap_idxs
1522 # now cross-index the required SHAPE for each of 3-in 2-out regs
1523 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1524 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1525 (shape
, remap
) = remaps
[shape_idx
]
1526 remap_idx
= remap_idxs
[shape_idx
]
1527 # zero is "disabled"
1528 if shape
.value
== 0x0:
1530 # now set the actual requested step to the current index
1531 yield dstep
.eq(remap_idx
)
1533 # debug printout info
1534 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
, remap_idx
))
1536 log("shape remap", x
)
1538 def check_write(self
, info
, name
, output
, carry_en
):
1539 if name
== 'overflow': # ignore, done already (above)
1541 if isinstance(output
, int):
1542 output
= SelectableInt(output
, 256)
1543 if name
in ['CA', 'CA32']:
1545 log("writing %s to XER" % name
, output
)
1546 log("write XER %s 0x%x" % (name
, output
.value
))
1547 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1549 log("NOT writing %s to XER" % name
, output
)
1550 elif name
in info
.special_regs
:
1551 log('writing special %s' % name
, output
, special_sprs
)
1552 log("write reg %s 0x%x" % (name
, output
.value
))
1553 if name
in special_sprs
:
1554 self
.spr
[name
] = output
1556 self
.namespace
[name
].eq(output
)
1558 log('msr written', hex(self
.msr
.value
))
1560 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1562 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1565 # temporary hack for not having 2nd output
1566 regnum
= yield getattr(self
.decoder
, name
)
1568 if self
.is_svp64_mode
and self
.pred_dst_zero
:
1569 log('zeroing reg %d %s' % (regnum
, str(output
)),
1571 output
= SelectableInt(0, 256)
1577 log("write reg %s%d %0xx" % (reg_prefix
, regnum
, output
.value
))
1578 if output
.bits
> 64:
1579 output
= SelectableInt(output
.value
, 64)
1581 self
.fpr
[regnum
] = output
1583 self
.gpr
[regnum
] = output
1585 def check_step_increment(self
, results
, rc_en
, asmop
, ins_name
):
1586 # check if it is the SVSTATE.src/dest step that needs incrementing
1587 # this is our Sub-Program-Counter loop from 0 to VL-1
1591 if self
.allow_next_step_inc
:
1592 log("SVSTATE_NEXT: inc requested, mode",
1593 self
.svstate_next_mode
, self
.allow_next_step_inc
)
1594 yield from self
.svstate_pre_inc()
1595 pre
= yield from self
.update_new_svstate_steps()
1597 # reset at end of loop including exit Vertical Mode
1598 log("SVSTATE_NEXT: end of loop, reset")
1599 self
.svp64_reset_loop()
1600 self
.svstate
.vfirst
= 0
1604 results
= [SelectableInt(0, 64)]
1605 self
.handle_comparison(results
) # CR0
1607 if self
.allow_next_step_inc
== 2:
1608 log("SVSTATE_NEXT: read")
1609 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1611 log("SVSTATE_NEXT: post-inc")
1612 # use actual src/dst-step here to check end, do NOT
1613 # use bit-reversed version
1614 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1615 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1616 remaps
= self
.get_remap_indices()
1617 remap_idxs
= self
.remap_idxs
1618 vl
= self
.svstate
.vl
1619 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1620 end_src
= srcstep
== vl
-1
1621 end_dst
= dststep
== vl
-1
1622 if self
.allow_next_step_inc
!= 2:
1623 yield from self
.advance_svstate_steps(end_src
, end_dst
)
1624 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1625 # set CR0 (if Rc=1) based on end
1627 endtest
= 1 if (end_src
or end_dst
) else 0
1628 #results = [SelectableInt(endtest, 64)]
1629 # self.handle_comparison(results) # CR0
1631 # see if svstep was requested, if so, which SVSTATE
1633 if self
.svstate_next_mode
> 0:
1634 shape_idx
= self
.svstate_next_mode
.value
-1
1635 endings
= self
.remap_loopends
[shape_idx
]
1636 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
1637 log("svstep Rc=1, CR0", cr_field
)
1638 self
.crl
[0].eq(cr_field
) # CR0
1639 if end_src
or end_dst
:
1640 # reset at end of loop including exit Vertical Mode
1641 log("SVSTATE_NEXT: after increments, reset")
1642 self
.svp64_reset_loop()
1643 self
.svstate
.vfirst
= 0
1646 if self
.is_svp64_mode
:
1647 return (yield from self
.svstate_post_inc(ins_name
))
1649 # XXX only in non-SVP64 mode!
1650 # record state of whether the current operation was an svshape,
1652 # to be able to know if it should apply in the next instruction.
1653 # also (if going to use this instruction) should disable ability
1654 # to interrupt in between. sigh.
1655 self
.last_op_svshape
= asmop
in ['svremap', 'svindex', 'svshape2']
1659 def SVSTATE_NEXT(self
, mode
, submode
):
1660 """explicitly moves srcstep/dststep on to next element, for
1661 "Vertical-First" mode. this function is called from
1662 setvl pseudo-code, as a pseudo-op "svstep"
1664 WARNING: this function uses information that was created EARLIER
1665 due to it being in the middle of a yield, but this function is
1666 *NOT* called from yield (it's called from compiled pseudocode).
1668 self
.allow_next_step_inc
= submode
.value
+ 1
1669 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
1670 self
.svstate_next_mode
= mode
1671 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
1672 shape_idx
= self
.svstate_next_mode
.value
-1
1673 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1674 if self
.svstate_next_mode
== 5:
1675 self
.svstate_next_mode
= 0
1676 return SelectableInt(self
.svstate
.srcstep
, 7)
1677 if self
.svstate_next_mode
== 6:
1678 self
.svstate_next_mode
= 0
1679 return SelectableInt(self
.svstate
.dststep
, 7)
1680 return SelectableInt(0, 7)
1682 def svstate_pre_inc(self
):
1683 """check if srcstep/dststep need to skip over masked-out predicate bits
1684 note that this is not supposed to do anything to substep,
1685 it is purely for skipping masked-out bits
1687 # get SVSTATE VL (oh and print out some debug stuff)
1688 # yield Delay(1e-10) # make changes visible
1689 vl
= self
.svstate
.vl
1690 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1691 srcstep
= self
.svstate
.srcstep
1692 dststep
= self
.svstate
.dststep
1693 ssubstep
= self
.svstate
.ssubstep
1694 dsubstep
= self
.svstate
.dsubstep
1695 sv_a_nz
= yield self
.dec2
.sv_a_nz
1696 fft_mode
= yield self
.dec2
.use_svp64_fft
1697 in1
= yield self
.dec2
.e
.read_reg1
.data
1698 log("SVP64: VL, subvl, srcstep, dststep, ssubstep, dsybstep, sv_a_nz, "
1700 vl
, subvl
, srcstep
, dststep
, ssubstep
, dsubstep
,
1701 sv_a_nz
, in1
, fft_mode
,
1704 # get predicate mask (all 64 bits)
1705 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1707 pmode
= yield self
.dec2
.rm_dec
.predmode
1708 pack
= yield self
.dec2
.rm_dec
.pack
1709 unpack
= yield self
.dec2
.rm_dec
.unpack
1710 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1711 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1712 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1713 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1714 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1715 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1716 if pmode
== SVP64PredMode
.INT
.value
:
1717 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1718 if sv_ptype
== SVPtype
.P2
.value
:
1719 srcmask
= get_predint(self
.gpr
, srcpred
)
1720 elif pmode
== SVP64PredMode
.CR
.value
:
1721 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1722 if sv_ptype
== SVPtype
.P2
.value
:
1723 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1724 # work out if the ssubsteps are completed
1725 ssubstart
= ssubstep
== 0
1726 dsubstart
= dsubstep
== 0
1727 log(" pmode", pmode
)
1728 log(" pack/unpack", pack
, unpack
)
1729 log(" reverse", reverse_gear
)
1730 log(" ptype", sv_ptype
)
1731 log(" srcpred", bin(srcpred
))
1732 log(" dstpred", bin(dstpred
))
1733 log(" srcmask", bin(srcmask
))
1734 log(" dstmask", bin(dstmask
))
1735 log(" pred_sz", bin(pred_src_zero
))
1736 log(" pred_dz", bin(pred_dst_zero
))
1737 log(" ssubstart", ssubstart
)
1738 log(" dsubstart", dsubstart
)
1740 # okaaay, so here we simply advance srcstep (TODO dststep)
1741 # this can ONLY be done at the beginning of the "for" loop
1742 # (this is all actually a FSM so it's hell to keep track sigh)
1744 # until the predicate mask has a "1" bit... or we run out of VL
1745 # let srcstep==VL be the indicator to move to next instruction
1746 if not pred_src_zero
:
1747 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1748 log(" sskip", bin(1 << srcstep
))
1752 if not pred_dst_zero
:
1753 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1754 log(" dskip", bin(1 << dststep
))
1757 # now work out if the relevant mask bits require zeroing
1759 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
1761 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
1763 # store new srcstep / dststep
1764 self
.new_srcstep
, self
.new_dststep
= (srcstep
, dststep
)
1765 self
.new_ssubstep
, self
.new_dsubstep
= (ssubstep
, dsubstep
)
1766 self
.pred_dst_zero
, self
.pred_src_zero
= (pred_dst_zero
, pred_src_zero
)
1767 log(" new srcstep", srcstep
)
1768 log(" new dststep", dststep
)
1769 log(" new ssubstep", ssubstep
)
1770 log(" new dsubstep", dsubstep
)
1772 def get_src_dststeps(self
):
1773 """gets srcstep, dststep, and ssubstep, dsubstep
1775 return (self
.new_srcstep
, self
.new_dststep
,
1776 self
.new_ssubstep
, self
.new_dsubstep
)
1778 def update_new_svstate_steps(self
):
1779 # note, do not get the bit-reversed srcstep here!
1780 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1781 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
1783 # update SVSTATE with new srcstep
1784 self
.svstate
.srcstep
= srcstep
1785 self
.svstate
.dststep
= dststep
1786 self
.svstate
.ssubstep
= ssubstep
1787 self
.svstate
.dsubstep
= dsubstep
1788 self
.namespace
['SVSTATE'] = self
.svstate
1789 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1790 yield Settle() # let decoder update
1791 srcstep
= self
.svstate
.srcstep
1792 dststep
= self
.svstate
.dststep
1793 ssubstep
= self
.svstate
.ssubstep
1794 dsubstep
= self
.svstate
.dsubstep
1795 vl
= self
.svstate
.vl
1796 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1797 log(" srcstep", srcstep
)
1798 log(" dststep", dststep
)
1799 log(" ssubstep", ssubstep
)
1800 log(" dsubstep", dsubstep
)
1802 log(" subvl", subvl
)
1804 # check if end reached (we let srcstep overrun, above)
1805 # nothing needs doing (TODO zeroing): just do next instruction
1806 return srcstep
== vl
or dststep
== vl
1808 def svstate_post_inc(self
, insn_name
, vf
=0):
1809 # check if SV "Vertical First" mode is enabled
1810 vfirst
= self
.svstate
.vfirst
1811 log(" SV Vertical First", vf
, vfirst
)
1812 if not vf
and vfirst
== 1:
1816 # check if it is the SVSTATE.src/dest step that needs incrementing
1817 # this is our Sub-Program-Counter loop from 0 to VL-1
1818 # XXX twin predication TODO
1819 vl
= self
.svstate
.vl
1820 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1821 mvl
= self
.svstate
.maxvl
1822 srcstep
= self
.svstate
.srcstep
1823 dststep
= self
.svstate
.dststep
1824 ssubstep
= self
.svstate
.ssubstep
1825 dsubstep
= self
.svstate
.dsubstep
1826 rm_mode
= yield self
.dec2
.rm_dec
.mode
1827 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1828 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1829 out_vec
= not (yield self
.dec2
.no_out_vec
)
1830 in_vec
= not (yield self
.dec2
.no_in_vec
)
1831 log(" svstate.vl", vl
)
1832 log(" svstate.mvl", mvl
)
1833 log(" rm.subvl", subvl
)
1834 log(" svstate.srcstep", srcstep
)
1835 log(" svstate.dststep", dststep
)
1836 log(" svstate.ssubstep", ssubstep
)
1837 log(" svstate.dsubstep", dsubstep
)
1838 log(" mode", rm_mode
)
1839 log(" reverse", reverse_gear
)
1840 log(" out_vec", out_vec
)
1841 log(" in_vec", in_vec
)
1842 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1843 # check if this was an sv.bc* and if so did it succeed
1844 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1845 end_loop
= self
.namespace
['end_loop']
1846 log("branch %s end_loop" % insn_name
, end_loop
)
1848 self
.svp64_reset_loop()
1849 self
.update_pc_next()
1851 # check if srcstep needs incrementing by one, stop PC advancing
1852 # but for 2-pred both src/dest have to be checked.
1853 # XXX this might not be true! it may just be LD/ST
1854 if sv_ptype
== SVPtype
.P2
.value
:
1855 svp64_is_vector
= (out_vec
or in_vec
)
1857 svp64_is_vector
= out_vec
1858 # loops end at the first "hit" (source or dest)
1859 loopend
= ((srcstep
== vl
-1 and ssubstep
== subvl
) or
1860 (dststep
== vl
-1 and dsubstep
== subvl
))
1861 if not svp64_is_vector
or loopend
:
1862 # reset loop to zero and update NIA
1863 self
.svp64_reset_loop()
1868 # still looping, advance and update NIA
1869 yield from self
.advance_svstate_steps()
1870 self
.namespace
['SVSTATE'] = self
.svstate
1871 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1872 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1873 # this way we keep repeating the same instruction (with new steps)
1874 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1875 self
.namespace
['NIA'] = self
.pc
.NIA
1876 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
1877 return False # DO NOT allow PC update whilst Sub-PC loop running
1879 def advance_svstate_steps(self
, end_src
=False, end_dst
=False):
1880 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
1881 TODO when Pack/Unpack is set, substep becomes the *outer* loop
1883 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1885 ssubstep
= self
.svstate
.ssubstep
1886 end_sub
= ssubstep
== subvl
1889 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1890 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
1892 self
.svstate
.ssubstep
+= SelectableInt(1, 2) # advance ssubstep
1894 dsubstep
= self
.svstate
.dsubstep
1895 end_sub
= dsubstep
== subvl
1898 self
.svstate
.dststep
+= SelectableInt(1, 7)
1899 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
1901 self
.svstate
.dsubstep
+= SelectableInt(1, 2) # advance ssubstep
1903 def update_pc_next(self
):
1904 # UPDATE program counter
1905 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1906 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1907 log("end of call", self
.namespace
['CIA'],
1908 self
.namespace
['NIA'],
1909 self
.namespace
['SVSTATE'])
1911 def svp64_reset_loop(self
):
1912 self
.svstate
.srcstep
= 0
1913 self
.svstate
.dststep
= 0
1914 self
.svstate
.ssubstep
= 0
1915 self
.svstate
.dsubstep
= 0
1916 log(" svstate.srcstep loop end (PC to update)")
1917 self
.namespace
['SVSTATE'] = self
.svstate
1919 def update_nia(self
):
1920 self
.pc
.update_nia(self
.is_svp64_mode
)
1921 self
.namespace
['NIA'] = self
.pc
.NIA
1925 """Decorator factory.
1927 this decorator will "inject" variables into the function's namespace,
1928 from the *dictionary* in self.namespace. it therefore becomes possible
1929 to make it look like a whole stack of variables which would otherwise
1930 need "self." inserted in front of them (*and* for those variables to be
1931 added to the instance) "appear" in the function.
1933 "self.namespace['SI']" for example becomes accessible as just "SI" but
1934 *only* inside the function, when decorated.
1936 def variable_injector(func
):
1938 def decorator(*args
, **kwargs
):
1940 func_globals
= func
.__globals
__ # Python 2.6+
1941 except AttributeError:
1942 func_globals
= func
.func_globals
# Earlier versions.
1944 context
= args
[0].namespace
# variables to be injected
1945 saved_values
= func_globals
.copy() # Shallow copy of dict.
1946 log("globals before", context
.keys())
1947 func_globals
.update(context
)
1948 result
= func(*args
, **kwargs
)
1949 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1950 log("args[0]", args
[0].namespace
['CIA'],
1951 args
[0].namespace
['NIA'],
1952 args
[0].namespace
['SVSTATE'])
1953 if 'end_loop' in func_globals
:
1954 log("args[0] end_loop", func_globals
['end_loop'])
1955 args
[0].namespace
= func_globals
1956 #exec (func.__code__, func_globals)
1959 # func_globals = saved_values # Undo changes.
1965 return variable_injector