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
16 from nmigen
.back
.pysim
import Settle
17 from functools
import wraps
18 from copy
import copy
, deepcopy
19 from openpower
.decoder
.orderedset
import OrderedSet
20 from openpower
.decoder
.selectable_int
import (FieldSelectableInt
, SelectableInt
,
22 from openpower
.decoder
.power_enums
import (spr_dict
, spr_byname
, XER_bits
,
23 insns
, MicrOp
, In1Sel
, In2Sel
, In3Sel
,
24 OutSel
, CRInSel
, CROutSel
, LDSTMode
,
25 SVP64RMMode
, SVP64PredMode
,
26 SVP64PredInt
, SVP64PredCR
,
29 from openpower
.decoder
.power_enums
import SVPtype
31 from openpower
.decoder
.helpers
import (exts
, gtu
, ltu
, undefined
,
32 ISACallerHelper
, ISAFPHelpers
)
33 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
34 from openpower
.consts
import (SVP64MODE
,
37 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
39 from openpower
.decoder
.isa
.radixmmu
import RADIX
40 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
41 from openpower
.decoder
.isa
.svshape
import SVSHAPE
42 from openpower
.decoder
.isa
.svstate
import SVP64State
45 from openpower
.util
import log
47 from collections
import namedtuple
51 instruction_info
= namedtuple('instruction_info',
52 'func read_regs uninit_regs write_regs ' +
53 'special_regs op_fields form asmregs')
64 # TODO (lkcl): adjust other registers that should be in a particular order
65 # probably CA, CA32, and CR
91 "overflow": 7, # should definitely be last
94 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
97 def create_args(reglist
, extra
=None):
98 retval
= list(OrderedSet(reglist
))
99 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
100 if extra
is not None:
101 return [extra
] + retval
107 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
110 self
.isacaller
= isacaller
111 self
.svstate
= svstate
112 for i
in range(len(regfile
)):
113 self
[i
] = SelectableInt(regfile
[i
], 64)
115 def __call__(self
, ridx
):
116 if isinstance(ridx
, SelectableInt
):
120 def set_form(self
, form
):
123 def __setitem__(self
, rnum
, value
):
124 # rnum = rnum.value # only SelectableInt allowed
125 log("GPR setitem", rnum
, value
)
126 if isinstance(rnum
, SelectableInt
):
128 dict.__setitem
__(self
, rnum
, value
)
130 def getz(self
, rnum
):
131 # rnum = rnum.value # only SelectableInt allowed
132 log("GPR getzero?", rnum
)
134 return SelectableInt(0, 64)
137 def _get_regnum(self
, attr
):
138 getform
= self
.sd
.sigforms
[self
.form
]
139 rnum
= getattr(getform
, attr
)
142 def ___getitem__(self
, attr
):
143 """ XXX currently not used
145 rnum
= self
._get
_regnum
(attr
)
146 log("GPR getitem", attr
, rnum
)
147 return self
.regfile
[rnum
]
149 def dump(self
, printout
=True):
151 for i
in range(len(self
)):
152 res
.append(self
[i
].value
)
154 for i
in range(0, len(res
), 8):
157 s
.append("%08x" % res
[i
+j
])
159 print("reg", "%2d" % i
, s
)
164 def __init__(self
, dec2
, initial_sprs
={}):
167 for key
, v
in initial_sprs
.items():
168 if isinstance(key
, SelectableInt
):
170 key
= special_sprs
.get(key
, key
)
171 if isinstance(key
, int):
174 info
= spr_byname
[key
]
175 if not isinstance(v
, SelectableInt
):
176 v
= SelectableInt(v
, info
.length
)
179 def __getitem__(self
, key
):
181 log("dict", self
.items())
182 # if key in special_sprs get the special spr, otherwise return key
183 if isinstance(key
, SelectableInt
):
185 if isinstance(key
, int):
186 key
= spr_dict
[key
].SPR
187 key
= special_sprs
.get(key
, key
)
188 if key
== 'HSRR0': # HACK!
190 if key
== 'HSRR1': # HACK!
193 res
= dict.__getitem
__(self
, key
)
195 if isinstance(key
, int):
198 info
= spr_byname
[key
]
199 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
200 res
= dict.__getitem
__(self
, key
)
201 log("spr returning", key
, res
)
204 def __setitem__(self
, key
, value
):
205 if isinstance(key
, SelectableInt
):
207 if isinstance(key
, int):
208 key
= spr_dict
[key
].SPR
210 key
= special_sprs
.get(key
, key
)
211 if key
== 'HSRR0': # HACK!
212 self
.__setitem
__('SRR0', value
)
213 if key
== 'HSRR1': # HACK!
214 self
.__setitem
__('SRR1', value
)
215 log("setting spr", key
, value
)
216 dict.__setitem
__(self
, key
, value
)
218 def __call__(self
, ridx
):
221 def dump(self
, printout
=True):
223 keys
= list(self
.keys())
226 sprname
= spr_dict
.get(k
, None)
230 sprname
= sprname
.SPR
231 res
.append((sprname
, self
[k
].value
))
233 for sprname
, value
in res
:
234 print(" ", sprname
, hex(value
))
239 def __init__(self
, pc_init
=0):
240 self
.CIA
= SelectableInt(pc_init
, 64)
241 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
243 def update_nia(self
, is_svp64
):
244 increment
= 8 if is_svp64
else 4
245 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
247 def update(self
, namespace
, is_svp64
):
248 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
250 self
.CIA
= namespace
['NIA'].narrow(64)
251 self
.update_nia(is_svp64
)
252 namespace
['CIA'] = self
.CIA
253 namespace
['NIA'] = self
.NIA
258 def __init__(self
, init
=0):
259 self
.spr
= SelectableInt(init
, 24)
260 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
261 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
262 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
263 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
264 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
265 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
266 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
267 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
268 # these cover the same extra field, split into parts as EXTRA2
269 self
.extra2
= list(range(4))
270 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
271 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
272 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
273 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
274 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
275 # and here as well, but EXTRA3
276 self
.extra3
= list(range(3))
277 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
278 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
279 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
282 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
283 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
284 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
285 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
286 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
287 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
288 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
289 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
290 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
293 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
294 class SVP64PrefixFields
:
296 self
.insn
= SelectableInt(0, 32)
297 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
298 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
299 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
300 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
301 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
304 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
305 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
306 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
310 # See PowerISA Version 3.0 B Book 1
311 # Section 2.3.1 Condition Register pages 30 - 31
313 LT
= FL
= 0 # negative, less than, floating-point less than
314 GT
= FG
= 1 # positive, greater than, floating-point greater than
315 EQ
= FE
= 2 # equal, floating-point equal
316 SO
= FU
= 3 # summary overflow, floating-point unordered
318 def __init__(self
, init
=0):
319 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
320 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
321 self
.cr
= SelectableInt(init
, 64) # underlying reg
322 # field-selectable versions of Condition Register TODO check bitranges?
325 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
326 _cr
= FieldSelectableInt(self
.cr
, bits
)
329 # decode SVP64 predicate integer to reg number and invert
330 def get_predint(gpr
, mask
):
333 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
334 if mask
== SVP64PredInt
.ALWAYS
.value
:
335 return 0xffff_ffff_ffff_ffff
336 if mask
== SVP64PredInt
.R3_UNARY
.value
:
337 return 1 << (gpr(3).value
& 0b111111)
338 if mask
== SVP64PredInt
.R3
.value
:
340 if mask
== SVP64PredInt
.R3_N
.value
:
342 if mask
== SVP64PredInt
.R10
.value
:
344 if mask
== SVP64PredInt
.R10_N
.value
:
345 return ~
gpr(10).value
346 if mask
== SVP64PredInt
.R30
.value
:
348 if mask
== SVP64PredInt
.R30_N
.value
:
349 return ~
gpr(30).value
351 # decode SVP64 predicate CR to reg number and invert status
352 def _get_predcr(mask
):
353 if mask
== SVP64PredCR
.LT
.value
:
355 if mask
== SVP64PredCR
.GE
.value
:
357 if mask
== SVP64PredCR
.GT
.value
:
359 if mask
== SVP64PredCR
.LE
.value
:
361 if mask
== SVP64PredCR
.EQ
.value
:
363 if mask
== SVP64PredCR
.NE
.value
:
365 if mask
== SVP64PredCR
.SO
.value
:
367 if mask
== SVP64PredCR
.NS
.value
:
370 # read individual CR fields (0..VL-1), extract the required bit
371 # and construct the mask
372 def get_predcr(crl
, mask
, vl
):
373 idx
, noninv
= _get_predcr(mask
)
376 cr
= crl
[i
+SVP64CROffs
.CRPred
]
377 if cr
[idx
].value
== noninv
:
382 # TODO, really should just be using PowerDecoder2
383 def get_pdecode_idx_in(dec2
, name
):
385 in1_sel
= yield op
.in1_sel
386 in2_sel
= yield op
.in2_sel
387 in3_sel
= yield op
.in3_sel
388 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
389 in1
= yield dec2
.e
.read_reg1
.data
390 in2
= yield dec2
.e
.read_reg2
.data
391 in3
= yield dec2
.e
.read_reg3
.data
392 in1_isvec
= yield dec2
.in1_isvec
393 in2_isvec
= yield dec2
.in2_isvec
394 in3_isvec
= yield dec2
.in3_isvec
395 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
397 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
399 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
401 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
403 log ("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
405 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
407 # identify which regnames map to in1/2/3
409 if (in1_sel
== In1Sel
.RA
.value
or
410 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
411 return in1
, in1_isvec
412 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
413 return in1
, in1_isvec
415 if in2_sel
== In2Sel
.RB
.value
:
416 return in2
, in2_isvec
417 if in3_sel
== In3Sel
.RB
.value
:
418 return in3
, in3_isvec
419 # XXX TODO, RC doesn't exist yet!
421 assert False, "RC does not exist yet"
423 if in1_sel
== In1Sel
.RS
.value
:
424 return in1
, in1_isvec
425 if in2_sel
== In2Sel
.RS
.value
:
426 return in2
, in2_isvec
427 if in3_sel
== In3Sel
.RS
.value
:
428 return in3
, in3_isvec
430 if in1_sel
== In1Sel
.FRA
.value
:
431 return in1
, in1_isvec
433 if in2_sel
== In2Sel
.FRB
.value
:
434 return in2
, in2_isvec
436 if in3_sel
== In3Sel
.FRC
.value
:
437 return in3
, in3_isvec
439 if in1_sel
== In1Sel
.FRS
.value
:
440 return in1
, in1_isvec
441 if in3_sel
== In3Sel
.FRS
.value
:
442 return in3
, in3_isvec
446 # TODO, really should just be using PowerDecoder2
447 def get_pdecode_cr_in(dec2
, name
):
449 in_sel
= yield op
.cr_in
450 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
451 sv_cr_in
= yield op
.sv_cr_in
452 spec
= yield dec2
.crin_svdec
.spec
453 sv_override
= yield dec2
.dec_cr_in
.sv_override
454 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
455 in1
= yield dec2
.e
.read_cr1
.data
456 cr_isvec
= yield dec2
.cr_in_isvec
457 log ("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
458 log (" sv_cr_in", sv_cr_in
)
459 log (" cr_bf", in_bitfield
)
461 log (" override", sv_override
)
462 # identify which regnames map to in / o2
464 if in_sel
== CRInSel
.BI
.value
:
466 log ("get_pdecode_cr_in not found", name
)
470 # TODO, really should just be using PowerDecoder2
471 def get_pdecode_cr_out(dec2
, name
):
473 out_sel
= yield op
.cr_out
474 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
475 sv_cr_out
= yield op
.sv_cr_out
476 spec
= yield dec2
.crout_svdec
.spec
477 sv_override
= yield dec2
.dec_cr_out
.sv_override
478 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
479 out
= yield dec2
.e
.write_cr
.data
480 o_isvec
= yield dec2
.o_isvec
481 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
482 log (" sv_cr_out", sv_cr_out
)
483 log (" cr_bf", out_bitfield
)
485 log (" override", sv_override
)
486 # identify which regnames map to out / o2
488 if out_sel
== CROutSel
.CR0
.value
:
490 log ("get_pdecode_cr_out not found", name
)
494 # TODO, really should just be using PowerDecoder2
495 def get_pdecode_idx_out(dec2
, name
):
497 out_sel
= yield op
.out_sel
498 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
499 out
= yield dec2
.e
.write_reg
.data
500 o_isvec
= yield dec2
.o_isvec
501 # identify which regnames map to out / o2
503 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
504 if out_sel
== OutSel
.RA
.value
:
507 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
508 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
510 if out_sel
== OutSel
.RT
.value
:
512 elif name
== 'RT_OR_ZERO':
513 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
514 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
516 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
519 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
520 if out_sel
== OutSel
.FRA
.value
:
523 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
524 OutSel
.FRT
.value
, out
, o_isvec
)
525 if out_sel
== OutSel
.FRT
.value
:
527 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
531 # TODO, really should just be using PowerDecoder2
532 def get_pdecode_idx_out2(dec2
, name
):
533 # check first if register is activated for write
535 out_sel
= yield op
.out_sel
536 out
= yield dec2
.e
.write_ea
.data
537 o_isvec
= yield dec2
.o2_isvec
538 out_ok
= yield dec2
.e
.write_ea
.ok
539 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
544 if hasattr(op
, "upd"):
545 # update mode LD/ST uses read-reg A also as an output
547 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
548 out_sel
, OutSel
.RA
.value
,
550 if upd
== LDSTMode
.update
.value
:
553 int_op
= yield dec2
.dec
.op
.internal_op
554 fft_en
= yield dec2
.use_svp64_fft
555 #if int_op == MicrOp.OP_FP_MADD.value and fft_en:
557 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
563 class ISACaller(ISACallerHelper
, ISAFPHelpers
):
564 # decoder2 - an instance of power_decoder2
565 # regfile - a list of initial values for the registers
566 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
567 # respect_pc - tracks the program counter. requires initial_insns
568 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
569 initial_mem
=None, initial_msr
=0,
580 self
.bigendian
= bigendian
582 self
.is_svp64_mode
= False
583 self
.respect_pc
= respect_pc
584 if initial_sprs
is None:
586 if initial_mem
is None:
588 if fpregfile
is None:
590 if initial_insns
is None:
592 assert self
.respect_pc
== False, "instructions required to honor pc"
594 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
595 log("ISACaller initial_msr", initial_msr
)
597 # "fake program counter" mode (for unit testing)
601 if isinstance(initial_mem
, tuple):
602 self
.fake_pc
= initial_mem
[0]
603 disasm_start
= self
.fake_pc
605 disasm_start
= initial_pc
607 # disassembly: we need this for now (not given from the decoder)
608 self
.disassembly
= {}
610 for i
, code
in enumerate(disassembly
):
611 self
.disassembly
[i
*4 + disasm_start
] = code
613 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
614 self
.svp64rm
= SVP64RM()
615 if initial_svstate
is None:
617 if isinstance(initial_svstate
, int):
618 initial_svstate
= SVP64State(initial_svstate
)
619 # SVSTATE, MSR and PC
620 self
.svstate
= initial_svstate
621 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
623 # GPR FPR SPR registers
624 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
625 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
626 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
627 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
629 # set up 4 dummy SVSHAPEs if they aren't already set up
631 sname
= 'SVSHAPE%d' % i
632 if sname
not in self
.spr
:
633 self
.spr
[sname
] = SVSHAPE(0)
635 # make sure it's an SVSHAPE
636 val
= self
.spr
[sname
].value
637 self
.spr
[sname
] = SVSHAPE(val
)
638 self
.last_op_svshape
= False
641 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
642 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
643 # MMU mode, redirect underlying Mem through RADIX
645 self
.mem
= RADIX(self
.mem
, self
)
647 self
.imem
= RADIX(self
.imem
, self
)
650 # FPR (same as GPR except for FP nums)
651 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
652 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
653 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
654 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
656 # 2.3.2 LR (actually SPR #8) -- Done
657 # 2.3.3 CTR (actually SPR #9) -- Done
658 # 2.3.4 TAR (actually SPR #815)
659 # 3.2.2 p45 XER (actually SPR #1) -- Done
660 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
662 # create CR then allow portions of it to be "selectable" (below)
663 self
.cr_fields
= CRFields(initial_cr
)
664 self
.cr
= self
.cr_fields
.cr
666 # "undefined", just set to variable-bit-width int (use exts "max")
667 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
670 self
.namespace
.update(self
.spr
)
671 self
.namespace
.update({'GPR': self
.gpr
,
675 'memassign': self
.memassign
,
678 'SVSTATE': self
.svstate
,
679 'SVSHAPE0': self
.spr
['SVSHAPE0'],
680 'SVSHAPE1': self
.spr
['SVSHAPE1'],
681 'SVSHAPE2': self
.spr
['SVSHAPE2'],
682 'SVSHAPE3': self
.spr
['SVSHAPE3'],
685 'undefined': undefined
,
686 'mode_is_64bit': True,
687 'SO': XER_bits
['SO'],
688 'XLEN': 64 # elwidth overrides, later
691 # update pc to requested start point
692 self
.set_pc(initial_pc
)
694 # field-selectable versions of Condition Register
695 self
.crl
= self
.cr_fields
.crl
697 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
699 self
.decoder
= decoder2
.dec
702 super().__init
__(XLEN
=self
.namespace
["XLEN"])
706 return self
.namespace
["XLEN"]
708 def call_trap(self
, trap_addr
, trap_bit
):
709 """calls TRAP and sets up NIA to the new execution location.
710 next instruction will begin at trap_addr.
712 self
.TRAP(trap_addr
, trap_bit
)
713 self
.namespace
['NIA'] = self
.trap_nia
714 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
716 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
717 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
719 TRAP function is callable from inside the pseudocode itself,
720 hence the default arguments. when calling from inside ISACaller
721 it is best to use call_trap()
723 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
724 # store CIA(+4?) in SRR0, set NIA to 0x700
725 # store MSR in SRR1, set MSR to um errr something, have to check spec
726 # store SVSTATE (if enabled) in SVSRR0
727 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
728 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
729 if self
.is_svp64_mode
:
730 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
731 self
.trap_nia
= SelectableInt(trap_addr
, 64)
732 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
734 # set exception bits. TODO: this should, based on the address
735 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
736 # bits appropriately. however it turns out that *for now* in all
737 # cases (all trap_addrs) the exact same thing is needed.
738 self
.msr
[MSRb
.IR
] = 0
739 self
.msr
[MSRb
.DR
] = 0
740 self
.msr
[MSRb
.FE0
] = 0
741 self
.msr
[MSRb
.FE1
] = 0
742 self
.msr
[MSRb
.EE
] = 0
743 self
.msr
[MSRb
.RI
] = 0
744 self
.msr
[MSRb
.SF
] = 1
745 self
.msr
[MSRb
.TM
] = 0
746 self
.msr
[MSRb
.VEC
] = 0
747 self
.msr
[MSRb
.VSX
] = 0
748 self
.msr
[MSRb
.PR
] = 0
749 self
.msr
[MSRb
.FP
] = 0
750 self
.msr
[MSRb
.PMM
] = 0
751 self
.msr
[MSRb
.TEs
] = 0
752 self
.msr
[MSRb
.TEe
] = 0
753 self
.msr
[MSRb
.UND
] = 0
754 self
.msr
[MSRb
.LE
] = 1
756 def memassign(self
, ea
, sz
, val
):
757 self
.mem
.memassign(ea
, sz
, val
)
759 def prep_namespace(self
, insn_name
, formname
, op_fields
):
760 # TODO: get field names from form in decoder*1* (not decoder2)
761 # decoder2 is hand-created, and decoder1.sigform is auto-generated
763 # then "yield" fields only from op_fields rather than hard-coded
765 fields
= self
.decoder
.sigforms
[formname
]
766 log("prep_namespace", formname
, op_fields
)
767 for name
in op_fields
:
768 # CR immediates. deal with separately. needs modifying
770 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
771 # BI is a 5-bit, must reconstruct the value
772 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
773 sig
= getattr(fields
, name
)
775 # low 2 LSBs (CR field selector) remain same, CR num extended
776 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
777 val
= (val
& 0b11) |
(regnum
<<2)
780 sig
= getattr(fields
, name
.upper())
782 sig
= getattr(fields
, name
)
784 # these are all opcode fields involved in index-selection of CR,
785 # and need to do "standard" arithmetic. CR[BA+32] for example
786 # would, if using SelectableInt, only be 5-bit.
787 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
788 self
.namespace
[name
] = val
790 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
792 self
.namespace
['XER'] = self
.spr
['XER']
793 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
794 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
796 # add some SVSTATE convenience variables
798 srcstep
= self
.svstate
.srcstep
799 self
.namespace
['VL'] = vl
800 self
.namespace
['srcstep'] = srcstep
802 # sv.bc* need some extra fields
803 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
804 # blegh grab bits manually
805 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
806 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
807 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
808 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
809 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
810 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
811 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
812 sz
= yield self
.dec2
.rm_dec
.pred_sz
813 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
814 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
815 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
816 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
817 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
818 self
.namespace
['sz'] = SelectableInt(sz
, 1)
819 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
821 def handle_carry_(self
, inputs
, outputs
, already_done
):
822 inv_a
= yield self
.dec2
.e
.do
.invert_in
824 inputs
[0] = ~inputs
[0]
826 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
828 imm
= yield self
.dec2
.e
.do
.imm_data
.data
829 inputs
.append(SelectableInt(imm
, 64))
830 assert len(outputs
) >= 1
831 log("outputs", repr(outputs
))
832 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
838 log("gt input", x
, output
)
839 gt
= (gtu(x
, output
))
842 cy
= 1 if any(gts
) else 0
844 if not (1 & already_done
):
845 self
.spr
['XER'][XER_bits
['CA']] = cy
847 log("inputs", already_done
, inputs
)
849 # ARGH... different for OP_ADD... *sigh*...
850 op
= yield self
.dec2
.e
.do
.insn_type
851 if op
== MicrOp
.OP_ADD
.value
:
852 res32
= (output
.value
& (1 << 32)) != 0
853 a32
= (inputs
[0].value
& (1 << 32)) != 0
855 b32
= (inputs
[1].value
& (1 << 32)) != 0
858 cy32
= res32 ^ a32 ^ b32
859 log("CA32 ADD", cy32
)
863 log("input", x
, output
)
864 log(" x[32:64]", x
, x
[32:64])
865 log(" o[32:64]", output
, output
[32:64])
866 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
868 cy32
= 1 if any(gts
) else 0
869 log("CA32", cy32
, gts
)
870 if not (2 & already_done
):
871 self
.spr
['XER'][XER_bits
['CA32']] = cy32
873 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
874 if hasattr(self
.dec2
.e
.do
, "invert_in"):
875 inv_a
= yield self
.dec2
.e
.do
.invert_in
877 inputs
[0] = ~inputs
[0]
879 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
881 imm
= yield self
.dec2
.e
.do
.imm_data
.data
882 inputs
.append(SelectableInt(imm
, 64))
883 assert len(outputs
) >= 1
884 log("handle_overflow", inputs
, outputs
, div_overflow
)
885 if len(inputs
) < 2 and div_overflow
is None:
888 # div overflow is different: it's returned by the pseudo-code
889 # because it's more complex than can be done by analysing the output
890 if div_overflow
is not None:
891 ov
, ov32
= div_overflow
, div_overflow
892 # arithmetic overflow can be done by analysing the input and output
893 elif len(inputs
) >= 2:
897 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
898 output_sgn
= exts(output
.value
, output
.bits
) < 0
899 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
900 output_sgn
!= input_sgn
[0] else 0
903 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
904 output32_sgn
= exts(output
.value
, 32) < 0
905 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
906 output32_sgn
!= input32_sgn
[0] else 0
908 self
.spr
['XER'][XER_bits
['OV']] = ov
909 self
.spr
['XER'][XER_bits
['OV32']] = ov32
910 so
= self
.spr
['XER'][XER_bits
['SO']]
912 self
.spr
['XER'][XER_bits
['SO']] = so
914 def handle_comparison(self
, outputs
, cr_idx
=0):
916 assert isinstance(out
, SelectableInt
), \
917 "out zero not a SelectableInt %s" % repr(outputs
)
918 log("handle_comparison", out
.bits
, hex(out
.value
))
919 # TODO - XXX *processor* in 32-bit mode
920 # https://bugs.libre-soc.org/show_bug.cgi?id=424
922 # o32 = exts(out.value, 32)
923 # print ("handle_comparison exts 32 bit", hex(o32))
924 out
= exts(out
.value
, out
.bits
)
925 log("handle_comparison exts", hex(out
))
926 zero
= SelectableInt(out
== 0, 1)
927 positive
= SelectableInt(out
> 0, 1)
928 negative
= SelectableInt(out
< 0, 1)
929 SO
= self
.spr
['XER'][XER_bits
['SO']]
930 log("handle_comparison SO", SO
)
931 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
932 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
933 self
.crl
[cr_idx
].eq(cr_field
)
935 def set_pc(self
, pc_val
):
936 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
937 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
939 def get_next_insn(self
):
943 pc
= self
.pc
.CIA
.value
946 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
948 raise KeyError("no instruction at 0x%x" % pc
)
952 """set up one instruction
954 pc
, insn
= self
.get_next_insn()
955 yield from self
.setup_next_insn(pc
, insn
)
957 def setup_next_insn(self
, pc
, ins
):
958 """set up next instruction
961 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
962 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
964 yield self
.dec2
.sv_rm
.eq(0)
965 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
966 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
967 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
968 yield self
.dec2
.state
.pc
.eq(pc
)
969 if self
.svstate
is not None:
970 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
972 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
974 opcode
= yield self
.dec2
.dec
.opcode_in
975 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
976 pfx
.insn
.value
= opcode
977 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
978 log ("prefix test: opcode:", major
, bin(major
),
979 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
980 self
.is_svp64_mode
= ((major
== 0b000001) and
981 pfx
.insn
[7].value
== 0b1 and
982 pfx
.insn
[9].value
== 0b1)
983 self
.pc
.update_nia(self
.is_svp64_mode
)
984 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
985 self
.namespace
['NIA'] = self
.pc
.NIA
986 self
.namespace
['SVSTATE'] = self
.svstate
987 if not self
.is_svp64_mode
:
990 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
991 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
992 log (" svstate.vl", self
.svstate
.vl
)
993 log (" svstate.mvl", self
.svstate
.maxvl
)
994 sv_rm
= pfx
.rm
.asint(msb0
=True)
995 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
996 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
997 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
998 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
1001 def execute_one(self
):
1002 """execute one instruction
1004 # get the disassembly code for this instruction
1005 if self
.is_svp64_mode
:
1006 if not self
.disassembly
:
1007 code
= yield from self
.get_assembly_name()
1009 code
= self
.disassembly
[self
._pc
+4]
1010 log(" svp64 sim-execute", hex(self
._pc
), code
)
1012 if not self
.disassembly
:
1013 code
= yield from self
.get_assembly_name()
1015 code
= self
.disassembly
[self
._pc
]
1016 log("sim-execute", hex(self
._pc
), code
)
1017 opname
= code
.split(' ')[0]
1019 yield from self
.call(opname
) # execute the instruction
1020 except MemException
as e
: # check for memory errors
1021 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
1022 raise e
# ... re-raise
1023 # run a Trap but set DAR first
1024 print ("memory unaligned exception, DAR", e
.dar
)
1025 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1026 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1029 # don't use this except in special circumstances
1030 if not self
.respect_pc
:
1033 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1034 hex(self
.pc
.NIA
.value
))
1036 def get_assembly_name(self
):
1037 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1038 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1039 dec_insn
= yield self
.dec2
.e
.do
.insn
1040 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1041 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1042 int_op
= yield self
.dec2
.dec
.op
.internal_op
1043 log("get assembly name asmcode", asmcode
, int_op
,
1044 hex(dec_insn
), bin(insn_1_11
))
1045 asmop
= insns
.get(asmcode
, None)
1047 # sigh reconstruct the assembly instruction name
1048 if hasattr(self
.dec2
.e
.do
, "oe"):
1049 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1050 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1054 if hasattr(self
.dec2
.e
.do
, "rc"):
1055 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1056 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1060 # grrrr have to special-case MUL op (see DecodeOE)
1061 log("ov %d en %d rc %d en %d op %d" %
1062 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1063 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1068 if not asmop
.endswith("."): # don't add "." to "andis."
1071 if hasattr(self
.dec2
.e
.do
, "lk"):
1072 lk
= yield self
.dec2
.e
.do
.lk
1075 log("int_op", int_op
)
1076 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1077 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1081 spr_msb
= yield from self
.get_spr_msb()
1082 if int_op
== MicrOp
.OP_MFCR
.value
:
1087 # XXX TODO: for whatever weird reason this doesn't work
1088 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1089 if int_op
== MicrOp
.OP_MTCRF
.value
:
1096 def get_remap_indices(self
):
1097 """WARNING, this function stores remap_idxs and remap_loopends
1098 in the class for later use. this to avoid problems with yield
1100 # go through all iterators in lock-step, advance to next remap_idx
1101 srcstep
, dststep
= self
.get_src_dststeps()
1102 # get four SVSHAPEs. here we are hard-coding
1103 SVSHAPE0
= self
.spr
['SVSHAPE0']
1104 SVSHAPE1
= self
.spr
['SVSHAPE1']
1105 SVSHAPE2
= self
.spr
['SVSHAPE2']
1106 SVSHAPE3
= self
.spr
['SVSHAPE3']
1107 # set up the iterators
1108 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1109 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1110 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1111 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1114 self
.remap_loopends
= [0] * 4
1115 self
.remap_idxs
= [0, 1, 2, 3]
1117 for i
, (shape
, remap
) in enumerate(remaps
):
1118 # zero is "disabled"
1119 if shape
.value
== 0x0:
1120 self
.remap_idxs
[i
] = 0
1121 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1122 step
= dststep
if (i
in [3, 4]) else srcstep
1123 # this is terrible. O(N^2) looking for the match. but hey.
1124 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1127 self
.remap_idxs
[i
] = remap_idx
1128 self
.remap_loopends
[i
] = loopends
1129 dbg
.append((i
, step
, remap_idx
, loopends
))
1130 for (i
, step
, remap_idx
, loopends
) in dbg
:
1131 log ("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1134 def get_spr_msb(self
):
1135 dec_insn
= yield self
.dec2
.e
.do
.insn
1136 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1138 def call(self
, name
):
1139 """call(opcode) - the primary execution point for instructions
1141 self
.last_st_addr
= None # reset the last known store address
1142 self
.last_ld_addr
= None # etc.
1144 ins_name
= name
.strip() # remove spaces if not already done so
1146 log("halted - not executing", ins_name
)
1149 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1150 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1151 asmop
= yield from self
.get_assembly_name()
1152 log("call", ins_name
, asmop
)
1155 int_op
= yield self
.dec2
.dec
.op
.internal_op
1156 spr_msb
= yield from self
.get_spr_msb()
1158 instr_is_privileged
= False
1159 if int_op
in [MicrOp
.OP_ATTN
.value
,
1160 MicrOp
.OP_MFMSR
.value
,
1161 MicrOp
.OP_MTMSR
.value
,
1162 MicrOp
.OP_MTMSRD
.value
,
1164 MicrOp
.OP_RFID
.value
]:
1165 instr_is_privileged
= True
1166 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1167 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1168 instr_is_privileged
= True
1170 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1172 # check MSR priv bit and whether op is privileged: if so, throw trap
1173 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1174 self
.call_trap(0x700, PIb
.PRIV
)
1177 # check halted condition
1178 if ins_name
== 'attn':
1182 # check illegal instruction
1184 if ins_name
not in ['mtcrf', 'mtocrf']:
1185 illegal
= ins_name
!= asmop
1187 # sigh deal with setvl not being supported by binutils (.long)
1188 if asmop
.startswith('setvl'):
1192 # and svstep not being supported by binutils (.long)
1193 if asmop
.startswith('svstep'):
1197 # and svremap not being supported by binutils (.long)
1198 if asmop
.startswith('svremap'):
1200 ins_name
= 'svremap'
1202 # and svshape not being supported by binutils (.long)
1203 if asmop
.startswith('svshape'):
1205 ins_name
= 'svshape'
1208 if asmop
== 'fsins':
1211 if asmop
== 'fcoss':
1215 # sigh also deal with ffmadds not being supported by binutils (.long)
1216 if asmop
== 'ffmadds':
1218 ins_name
= 'ffmadds'
1220 # and fdmadds not being supported by binutils (.long)
1221 if asmop
== 'fdmadds':
1223 ins_name
= 'fdmadds'
1225 # and ffadds not being supported by binutils (.long)
1226 if asmop
== 'ffadds':
1230 # branch-conditional redirects to sv.bc
1231 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1232 ins_name
= 'sv.%s' % ins_name
1234 log(" post-processed name", ins_name
, asmop
)
1236 # illegal instructions call TRAP at 0x700
1238 print("illegal", ins_name
, asmop
)
1239 self
.call_trap(0x700, PIb
.ILLEG
)
1240 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1241 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1244 # this is for setvl "Vertical" mode: if set true,
1245 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1246 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1247 self
.allow_next_step_inc
= False
1248 self
.svstate_next_mode
= 0
1250 # nop has to be supported, we could let the actual op calculate
1251 # but PowerDecoder has a pattern for nop
1252 if ins_name
is 'nop':
1253 self
.update_pc_next()
1256 # look up instruction in ISA.instrs, prepare namespace
1257 info
= self
.instrs
[ins_name
]
1258 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1260 # preserve order of register names
1261 input_names
= create_args(list(info
.read_regs
) +
1262 list(info
.uninit_regs
))
1263 log("input names", input_names
)
1265 # get SVP64 entry for the current instruction
1266 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1267 if sv_rm
is not None:
1268 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1270 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1271 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1273 # see if srcstep/dststep need skipping over masked-out predicate bits
1274 if (self
.is_svp64_mode
or ins_name
== 'setvl' or
1275 ins_name
in ['svremap', 'svstate']):
1276 yield from self
.svstate_pre_inc()
1277 if self
.is_svp64_mode
:
1278 pre
= yield from self
.update_new_svstate_steps()
1280 self
.svp64_reset_loop()
1282 self
.update_pc_next()
1284 srcstep
, dststep
= self
.get_src_dststeps()
1285 pred_dst_zero
= self
.pred_dst_zero
1286 pred_src_zero
= self
.pred_src_zero
1287 vl
= self
.svstate
.vl
1289 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1290 if self
.is_svp64_mode
and vl
== 0:
1291 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1292 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1293 self
.namespace
['NIA'])
1296 # for when SVREMAP is active, using pre-arranged schedule.
1297 # note: modifying PowerDecoder2 needs to "settle"
1298 remap_en
= self
.svstate
.SVme
1299 persist
= self
.svstate
.RMpst
1300 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1301 if self
.is_svp64_mode
:
1302 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1304 if persist
or self
.last_op_svshape
:
1305 remaps
= self
.get_remap_indices()
1306 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1307 # just some convenient debug info
1309 sname
= 'SVSHAPE%d' % i
1310 shape
= self
.spr
[sname
]
1311 log (sname
, bin(shape
.value
))
1312 log (" lims", shape
.lims
)
1313 log (" mode", shape
.mode
)
1314 log (" skip", shape
.skip
)
1316 # set up the list of steps to remap
1317 mi0
= self
.svstate
.mi0
1318 mi1
= self
.svstate
.mi1
1319 mi2
= self
.svstate
.mi2
1320 mo0
= self
.svstate
.mo0
1321 mo1
= self
.svstate
.mo1
1322 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1323 (self
.dec2
.in2_step
, mi1
), # RB
1324 (self
.dec2
.in3_step
, mi2
), # RC
1325 (self
.dec2
.o_step
, mo0
), # RT
1326 (self
.dec2
.o2_step
, mo1
), # EA
1328 remap_idxs
= self
.remap_idxs
1330 # now cross-index the required SHAPE for each of 3-in 2-out regs
1331 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1332 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1333 (shape
, remap
) = remaps
[shape_idx
]
1334 remap_idx
= remap_idxs
[shape_idx
]
1335 # zero is "disabled"
1336 if shape
.value
== 0x0:
1338 # now set the actual requested step to the current index
1339 yield dstep
.eq(remap_idx
)
1341 # debug printout info
1342 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
,
1345 log ("shape remap", x
)
1346 # after that, settle down (combinatorial) to let Vector reg numbers
1347 # work themselves out
1349 if self
.is_svp64_mode
:
1350 remap_active
= yield self
.dec2
.remap_active
1352 remap_active
= False
1353 log ("remap active", bin(remap_active
))
1355 # main input registers (RT, RA ...)
1357 for name
in input_names
:
1358 # using PowerDecoder2, first, find the decoder index.
1359 # (mapping name RA RB RC RS to in1, in2, in3)
1360 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1362 # doing this is not part of svp64, it's because output
1363 # registers, to be modified, need to be in the namespace.
1364 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1366 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1369 # in case getting the register number is needed, _RA, _RB
1370 regname
= "_" + name
1371 self
.namespace
[regname
] = regnum
1372 if not self
.is_svp64_mode
or not pred_src_zero
:
1373 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1375 reg_val
= SelectableInt(self
.fpr(regnum
))
1376 elif name
is not None:
1377 reg_val
= SelectableInt(self
.gpr(regnum
))
1379 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1381 inputs
.append(reg_val
)
1382 # arrrrgh, awful hack, to get _RT into namespace
1383 if ins_name
in ['setvl', 'svstep']:
1385 RT
= yield self
.dec2
.dec
.RT
1386 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1388 self
.namespace
["RT"] = SelectableInt(0, 5)
1389 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1390 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1392 # in SVP64 mode for LD/ST work out immediate
1393 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1394 # use info.form to detect
1395 replace_d
= False # update / replace constant in pseudocode
1396 if self
.is_svp64_mode
:
1397 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1398 # shift mode reads SVD (or SVDS - TODO)
1399 # *BUT*... because this is "overloading" of LD operations,
1400 # it gets *STORED* into D (or DS, TODO)
1401 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1402 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1403 imm
= exts(imm
, 11) # sign-extend to integer
1404 log ("shift SVD", imm
)
1407 if info
.form
== 'DS':
1408 # DS-Form, multiply by 4 then knock 2 bits off after
1409 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1411 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1412 imm
= exts(imm
, 16) # sign-extend to integer
1413 # get the right step. LD is from srcstep, ST is dststep
1414 op
= yield self
.dec2
.e
.do
.insn_type
1416 if op
== MicrOp
.OP_LOAD
.value
:
1418 offsmul
= yield self
.dec2
.in1_step
1419 log("D-field REMAP src", imm
, offsmul
)
1422 log("D-field src", imm
, offsmul
)
1423 elif op
== MicrOp
.OP_STORE
.value
:
1424 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1426 log("D-field dst", imm
, offsmul
)
1427 # bit-reverse mode, rev already done through get_src_dst_steps()
1428 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1429 # manually look up RC, sigh
1430 RC
= yield self
.dec2
.dec
.RC
[0:5]
1432 log ("LD-SHIFT:", "VL", vl
,
1433 "RC", RC
.value
, "imm", imm
,
1434 "offs", bin(offsmul
),
1436 imm
= SelectableInt((imm
* offsmul
) << RC
.value
, 32)
1437 # Unit-Strided LD/ST adds offset*width to immediate
1438 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1439 ldst_len
= yield self
.dec2
.e
.do
.data_len
1440 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1442 # Element-strided multiplies the immediate by element step
1443 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1444 imm
= SelectableInt(imm
* offsmul
, 32)
1447 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1448 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1449 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1450 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1451 # new replacement D... errr.. DS
1453 if info
.form
== 'DS':
1454 # TODO: assert 2 LSBs are zero?
1455 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1456 imm
.value
= imm
.value
>> 2
1457 self
.namespace
['DS'] = imm
1459 self
.namespace
['D'] = imm
1461 # "special" registers
1462 for special
in info
.special_regs
:
1463 if special
in special_sprs
:
1464 inputs
.append(self
.spr
[special
])
1466 inputs
.append(self
.namespace
[special
])
1468 # clear trap (trap) NIA
1469 self
.trap_nia
= None
1471 # check if this was an sv.bc* and create an indicator that
1472 # this is the last check to be made as a loop. combined with
1473 # the ALL/ANY mode we can early-exit
1474 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1475 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1476 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1477 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1479 # execute actual instruction here (finally)
1480 log("inputs", inputs
)
1481 results
= info
.func(self
, *inputs
)
1482 log("results", results
)
1484 # "inject" decorator takes namespace from function locals: we need to
1485 # overwrite NIA being overwritten (sigh)
1486 if self
.trap_nia
is not None:
1487 self
.namespace
['NIA'] = self
.trap_nia
1489 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1491 # check if op was a LD/ST so that debugging can check the
1493 if int_op
in [MicrOp
.OP_STORE
.value
,
1495 self
.last_st_addr
= self
.mem
.last_st_addr
1496 if int_op
in [MicrOp
.OP_LOAD
.value
,
1498 self
.last_ld_addr
= self
.mem
.last_ld_addr
1499 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1500 self
.last_st_addr
, self
.last_ld_addr
)
1502 # detect if CA/CA32 already in outputs (sra*, basically)
1505 output_names
= create_args(info
.write_regs
)
1506 for name
in output_names
:
1512 log("carry already done?", bin(already_done
))
1513 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1514 carry_en
= yield self
.dec2
.e
.do
.output_carry
1518 yield from self
.handle_carry_(inputs
, results
, already_done
)
1520 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1521 # detect if overflow was in return result
1524 for name
, output
in zip(output_names
, results
):
1525 if name
== 'overflow':
1528 if hasattr(self
.dec2
.e
.do
, "oe"):
1529 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1530 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1534 log("internal overflow", overflow
, ov_en
, ov_ok
)
1536 yield from self
.handle_overflow(inputs
, results
, overflow
)
1538 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1540 if not self
.is_svp64_mode
or not pred_dst_zero
:
1541 if hasattr(self
.dec2
.e
.do
, "rc"):
1542 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1543 if rc_en
and ins_name
not in ['svstep']:
1544 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1545 self
.handle_comparison(results
, regnum
)
1547 # any modified return results?
1549 for name
, output
in zip(output_names
, results
):
1550 if name
== 'overflow': # ignore, done already (above)
1552 if isinstance(output
, int):
1553 output
= SelectableInt(output
, 256)
1554 if name
in ['CA', 'CA32']:
1556 log("writing %s to XER" % name
, output
)
1557 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1559 log("NOT writing %s to XER" % name
, output
)
1560 elif name
in info
.special_regs
:
1561 log('writing special %s' % name
, output
, special_sprs
)
1562 if name
in special_sprs
:
1563 self
.spr
[name
] = output
1565 self
.namespace
[name
].eq(output
)
1567 log('msr written', hex(self
.msr
.value
))
1569 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1572 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1575 # temporary hack for not having 2nd output
1576 regnum
= yield getattr(self
.decoder
, name
)
1578 if self
.is_svp64_mode
and pred_dst_zero
:
1579 log('zeroing reg %d %s' % (regnum
, str(output
)),
1581 output
= SelectableInt(0, 256)
1587 log('writing %s %s %s' % (ftype
, regnum
, str(output
)),
1589 if output
.bits
> 64:
1590 output
= SelectableInt(output
.value
, 64)
1592 self
.fpr
[regnum
] = output
1594 self
.gpr
[regnum
] = output
1596 # check if it is the SVSTATE.src/dest step that needs incrementing
1597 # this is our Sub-Program-Counter loop from 0 to VL-1
1601 if self
.allow_next_step_inc
:
1602 log("SVSTATE_NEXT: inc requested, mode",
1603 self
.svstate_next_mode
, self
.allow_next_step_inc
)
1604 yield from self
.svstate_pre_inc()
1605 pre
= yield from self
.update_new_svstate_steps()
1607 # reset at end of loop including exit Vertical Mode
1608 log ("SVSTATE_NEXT: end of loop, reset")
1609 self
.svp64_reset_loop()
1610 self
.svstate
.vfirst
= 0
1613 results
= [SelectableInt(0, 64)]
1614 self
.handle_comparison(results
) # CR0
1616 if self
.allow_next_step_inc
== 2:
1617 log ("SVSTATE_NEXT: read")
1618 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1620 log ("SVSTATE_NEXT: post-inc")
1621 # use actual src/dst-step here to check end, do NOT
1622 # use bit-reversed version
1623 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1624 remaps
= self
.get_remap_indices()
1625 remap_idxs
= self
.remap_idxs
1626 vl
= self
.svstate
.vl
1627 end_src
= srcstep
== vl
-1
1628 end_dst
= dststep
== vl
-1
1629 if self
.allow_next_step_inc
!= 2:
1631 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1633 self
.svstate
.dststep
+= SelectableInt(1, 7)
1634 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1635 # set CR0 (if Rc=1) based on end
1637 srcstep
= self
.svstate
.srcstep
1638 dststep
= self
.svstate
.srcstep
1639 endtest
= 1 if (end_src
or end_dst
) else 0
1640 #results = [SelectableInt(endtest, 64)]
1641 #self.handle_comparison(results) # CR0
1643 # see if svstep was requested, if so, which SVSTATE
1645 if self
.svstate_next_mode
> 0:
1646 shape_idx
= self
.svstate_next_mode
.value
-1
1647 endings
= self
.remap_loopends
[shape_idx
]
1648 cr_field
= SelectableInt((~endings
)<<1 | endtest
, 4)
1649 print ("svstep Rc=1, CR0", cr_field
)
1650 self
.crl
[0].eq(cr_field
) # CR0
1651 if end_src
or end_dst
:
1652 # reset at end of loop including exit Vertical Mode
1653 log ("SVSTATE_NEXT: after increments, reset")
1654 self
.svp64_reset_loop()
1655 self
.svstate
.vfirst
= 0
1657 elif self
.is_svp64_mode
:
1658 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1660 # XXX only in non-SVP64 mode!
1661 # record state of whether the current operation was an svshape,
1662 # to be able to know if it should apply in the next instruction.
1663 # also (if going to use this instruction) should disable ability
1664 # to interrupt in between. sigh.
1665 self
.last_op_svshape
= asmop
== 'svremap'
1668 self
.update_pc_next()
1670 def SVSTATE_NEXT(self
, mode
, submode
):
1671 """explicitly moves srcstep/dststep on to next element, for
1672 "Vertical-First" mode. this function is called from
1673 setvl pseudo-code, as a pseudo-op "svstep"
1675 WARNING: this function uses information that was created EARLIER
1676 due to it being in the middle of a yield, but this function is
1677 *NOT* called from yield (it's called from compiled pseudocode).
1679 self
.allow_next_step_inc
= submode
.value
+ 1
1680 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
1681 self
.svstate_next_mode
= mode
1682 if self
.svstate_next_mode
> 0:
1683 shape_idx
= self
.svstate_next_mode
.value
-1
1684 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1685 return SelectableInt(0, 7)
1687 def svstate_pre_inc(self
):
1688 """check if srcstep/dststep need to skip over masked-out predicate bits
1690 # get SVSTATE VL (oh and print out some debug stuff)
1691 vl
= self
.svstate
.vl
1692 srcstep
= self
.svstate
.srcstep
1693 dststep
= self
.svstate
.dststep
1694 sv_a_nz
= yield self
.dec2
.sv_a_nz
1695 fft_mode
= yield self
.dec2
.use_svp64_fft
1696 in1
= yield self
.dec2
.e
.read_reg1
.data
1697 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft, svp64",
1698 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
,
1701 # get predicate mask
1702 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1704 pmode
= yield self
.dec2
.rm_dec
.predmode
1705 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1706 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1707 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1708 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1709 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1710 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1711 if pmode
== SVP64PredMode
.INT
.value
:
1712 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1713 if sv_ptype
== SVPtype
.P2
.value
:
1714 srcmask
= get_predint(self
.gpr
, srcpred
)
1715 elif pmode
== SVP64PredMode
.CR
.value
:
1716 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1717 if sv_ptype
== SVPtype
.P2
.value
:
1718 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1719 log (" pmode", pmode
)
1720 log (" reverse", reverse_gear
)
1721 log (" ptype", sv_ptype
)
1722 log (" srcpred", bin(srcpred
))
1723 log (" dstpred", bin(dstpred
))
1724 log (" srcmask", bin(srcmask
))
1725 log (" dstmask", bin(dstmask
))
1726 log (" pred_sz", bin(pred_src_zero
))
1727 log (" pred_dz", bin(pred_dst_zero
))
1729 # okaaay, so here we simply advance srcstep (TODO dststep)
1730 # until the predicate mask has a "1" bit... or we run out of VL
1731 # let srcstep==VL be the indicator to move to next instruction
1732 if not pred_src_zero
:
1733 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1734 log (" skip", bin(1<<srcstep
))
1737 if not pred_dst_zero
:
1738 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1739 log (" skip", bin(1<<dststep
))
1742 # now work out if the relevant mask bits require zeroing
1744 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1746 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1748 # store new srcstep / dststep
1749 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1750 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1751 log (" new srcstep", srcstep
)
1752 log (" new dststep", dststep
)
1754 def get_src_dststeps(self
):
1755 """gets srcstep and dststep
1757 return self
.new_srcstep
, self
.new_dststep
1759 def update_new_svstate_steps(self
):
1760 # note, do not get the bit-reversed srcstep here!
1761 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1763 # update SVSTATE with new srcstep
1764 self
.svstate
.srcstep
= srcstep
1765 self
.svstate
.dststep
= dststep
1766 self
.namespace
['SVSTATE'] = self
.svstate
1767 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1768 yield Settle() # let decoder update
1769 srcstep
= self
.svstate
.srcstep
1770 dststep
= self
.svstate
.dststep
1771 vl
= self
.svstate
.vl
1772 log (" srcstep", srcstep
)
1773 log (" dststep", dststep
)
1776 # check if end reached (we let srcstep overrun, above)
1777 # nothing needs doing (TODO zeroing): just do next instruction
1778 return srcstep
== vl
or dststep
== vl
1780 def svstate_post_inc(self
, insn_name
, vf
=0):
1781 # check if SV "Vertical First" mode is enabled
1782 vfirst
= self
.svstate
.vfirst
1783 log (" SV Vertical First", vf
, vfirst
)
1784 if not vf
and vfirst
== 1:
1788 # check if it is the SVSTATE.src/dest step that needs incrementing
1789 # this is our Sub-Program-Counter loop from 0 to VL-1
1790 # XXX twin predication TODO
1791 vl
= self
.svstate
.vl
1792 mvl
= self
.svstate
.maxvl
1793 srcstep
= self
.svstate
.srcstep
1794 dststep
= self
.svstate
.dststep
1795 rm_mode
= yield self
.dec2
.rm_dec
.mode
1796 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1797 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1798 out_vec
= not (yield self
.dec2
.no_out_vec
)
1799 in_vec
= not (yield self
.dec2
.no_in_vec
)
1800 log (" svstate.vl", vl
)
1801 log (" svstate.mvl", mvl
)
1802 log (" svstate.srcstep", srcstep
)
1803 log (" svstate.dststep", dststep
)
1804 log (" mode", rm_mode
)
1805 log (" reverse", reverse_gear
)
1806 log (" out_vec", out_vec
)
1807 log (" in_vec", in_vec
)
1808 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1809 # check if srcstep needs incrementing by one, stop PC advancing
1810 # svp64 loop can end early if the dest is scalar for single-pred
1811 # but for 2-pred both src/dest have to be checked.
1812 # XXX this might not be true! it may just be LD/ST
1813 if sv_ptype
== SVPtype
.P2
.value
:
1814 svp64_is_vector
= (out_vec
or in_vec
)
1816 svp64_is_vector
= out_vec
1817 # check if this was an sv.bc* and if so did it succeed
1818 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1819 end_loop
= self
.namespace
['end_loop']
1820 log("branch %s end_loop" % insn_name
, end_loop
)
1822 self
.svp64_reset_loop()
1823 self
.update_pc_next()
1825 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1826 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1827 self
.svstate
.dststep
+= SelectableInt(1, 7)
1828 self
.namespace
['SVSTATE'] = self
.svstate
1829 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1830 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1831 # this way we keep repeating the same instruction (with new steps)
1832 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1833 self
.namespace
['NIA'] = self
.pc
.NIA
1834 log("end of sub-pc call", self
.namespace
['CIA'],
1835 self
.namespace
['NIA'])
1836 return False # DO NOT allow PC update whilst Sub-PC loop running
1838 # reset loop to zero and update NIA
1839 self
.svp64_reset_loop()
1844 def update_pc_next(self
):
1845 # UPDATE program counter
1846 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1847 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1848 log("end of call", self
.namespace
['CIA'],
1849 self
.namespace
['NIA'],
1850 self
.namespace
['SVSTATE'])
1852 def svp64_reset_loop(self
):
1853 self
.svstate
.srcstep
= 0
1854 self
.svstate
.dststep
= 0
1855 log (" svstate.srcstep loop end (PC to update)")
1856 self
.namespace
['SVSTATE'] = self
.svstate
1858 def update_nia(self
):
1859 self
.pc
.update_nia(self
.is_svp64_mode
)
1860 self
.namespace
['NIA'] = self
.pc
.NIA
1864 """Decorator factory.
1866 this decorator will "inject" variables into the function's namespace,
1867 from the *dictionary* in self.namespace. it therefore becomes possible
1868 to make it look like a whole stack of variables which would otherwise
1869 need "self." inserted in front of them (*and* for those variables to be
1870 added to the instance) "appear" in the function.
1872 "self.namespace['SI']" for example becomes accessible as just "SI" but
1873 *only* inside the function, when decorated.
1875 def variable_injector(func
):
1877 def decorator(*args
, **kwargs
):
1879 func_globals
= func
.__globals
__ # Python 2.6+
1880 except AttributeError:
1881 func_globals
= func
.func_globals
# Earlier versions.
1883 context
= args
[0].namespace
# variables to be injected
1884 saved_values
= func_globals
.copy() # Shallow copy of dict.
1885 log("globals before", context
.keys())
1886 func_globals
.update(context
)
1887 result
= func(*args
, **kwargs
)
1888 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1889 log("args[0]", args
[0].namespace
['CIA'],
1890 args
[0].namespace
['NIA'],
1891 args
[0].namespace
['SVSTATE'])
1892 if 'end_loop' in func_globals
:
1893 log("args[0] end_loop", func_globals
['end_loop'])
1894 args
[0].namespace
= func_globals
1895 #exec (func.__code__, func_globals)
1898 # func_globals = saved_values # Undo changes.
1904 return variable_injector