100b686c23c95e03cf39dc197a501928fad3c103
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
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
,
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
):
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
= copy(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 def call_trap(self
, trap_addr
, trap_bit
):
703 """calls TRAP and sets up NIA to the new execution location.
704 next instruction will begin at trap_addr.
706 self
.TRAP(trap_addr
, trap_bit
)
707 self
.namespace
['NIA'] = self
.trap_nia
708 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
710 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
711 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
713 TRAP function is callable from inside the pseudocode itself,
714 hence the default arguments. when calling from inside ISACaller
715 it is best to use call_trap()
717 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
718 # store CIA(+4?) in SRR0, set NIA to 0x700
719 # store MSR in SRR1, set MSR to um errr something, have to check spec
720 # store SVSTATE (if enabled) in SVSRR0
721 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
722 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
723 if self
.is_svp64_mode
:
724 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
725 self
.trap_nia
= SelectableInt(trap_addr
, 64)
726 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
728 # set exception bits. TODO: this should, based on the address
729 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
730 # bits appropriately. however it turns out that *for now* in all
731 # cases (all trap_addrs) the exact same thing is needed.
732 self
.msr
[MSRb
.IR
] = 0
733 self
.msr
[MSRb
.DR
] = 0
734 self
.msr
[MSRb
.FE0
] = 0
735 self
.msr
[MSRb
.FE1
] = 0
736 self
.msr
[MSRb
.EE
] = 0
737 self
.msr
[MSRb
.RI
] = 0
738 self
.msr
[MSRb
.SF
] = 1
739 self
.msr
[MSRb
.TM
] = 0
740 self
.msr
[MSRb
.VEC
] = 0
741 self
.msr
[MSRb
.VSX
] = 0
742 self
.msr
[MSRb
.PR
] = 0
743 self
.msr
[MSRb
.FP
] = 0
744 self
.msr
[MSRb
.PMM
] = 0
745 self
.msr
[MSRb
.TEs
] = 0
746 self
.msr
[MSRb
.TEe
] = 0
747 self
.msr
[MSRb
.UND
] = 0
748 self
.msr
[MSRb
.LE
] = 1
750 def memassign(self
, ea
, sz
, val
):
751 self
.mem
.memassign(ea
, sz
, val
)
753 def prep_namespace(self
, insn_name
, formname
, op_fields
):
754 # TODO: get field names from form in decoder*1* (not decoder2)
755 # decoder2 is hand-created, and decoder1.sigform is auto-generated
757 # then "yield" fields only from op_fields rather than hard-coded
759 fields
= self
.decoder
.sigforms
[formname
]
760 log("prep_namespace", formname
, op_fields
)
761 for name
in op_fields
:
762 # CR immediates. deal with separately. needs modifying
764 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
765 # BI is a 5-bit, must reconstruct the value
766 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
767 sig
= getattr(fields
, name
)
769 # low 2 LSBs (CR field selector) remain same, CR num extended
770 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
771 val
= (val
& 0b11) |
(regnum
<<2)
774 sig
= getattr(fields
, name
.upper())
776 sig
= getattr(fields
, name
)
778 # these are all opcode fields involved in index-selection of CR,
779 # and need to do "standard" arithmetic. CR[BA+32] for example
780 # would, if using SelectableInt, only be 5-bit.
781 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
782 self
.namespace
[name
] = val
784 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
786 self
.namespace
['XER'] = self
.spr
['XER']
787 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
788 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
790 # add some SVSTATE convenience variables
792 srcstep
= self
.svstate
.srcstep
793 self
.namespace
['VL'] = vl
794 self
.namespace
['srcstep'] = srcstep
796 # sv.bc* need some extra fields
797 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
798 # blegh grab bits manually
799 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
800 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
801 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
802 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
803 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
804 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
805 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
806 sz
= yield self
.dec2
.rm_dec
.pred_sz
807 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
808 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
809 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
810 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
811 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
812 self
.namespace
['sz'] = SelectableInt(sz
, 1)
813 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
815 def handle_carry_(self
, inputs
, outputs
, already_done
):
816 inv_a
= yield self
.dec2
.e
.do
.invert_in
818 inputs
[0] = ~inputs
[0]
820 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
822 imm
= yield self
.dec2
.e
.do
.imm_data
.data
823 inputs
.append(SelectableInt(imm
, 64))
824 assert len(outputs
) >= 1
825 log("outputs", repr(outputs
))
826 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
832 log("gt input", x
, output
)
833 gt
= (gtu(x
, output
))
836 cy
= 1 if any(gts
) else 0
838 if not (1 & already_done
):
839 self
.spr
['XER'][XER_bits
['CA']] = cy
841 log("inputs", already_done
, inputs
)
843 # ARGH... different for OP_ADD... *sigh*...
844 op
= yield self
.dec2
.e
.do
.insn_type
845 if op
== MicrOp
.OP_ADD
.value
:
846 res32
= (output
.value
& (1 << 32)) != 0
847 a32
= (inputs
[0].value
& (1 << 32)) != 0
849 b32
= (inputs
[1].value
& (1 << 32)) != 0
852 cy32
= res32 ^ a32 ^ b32
853 log("CA32 ADD", cy32
)
857 log("input", x
, output
)
858 log(" x[32:64]", x
, x
[32:64])
859 log(" o[32:64]", output
, output
[32:64])
860 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
862 cy32
= 1 if any(gts
) else 0
863 log("CA32", cy32
, gts
)
864 if not (2 & already_done
):
865 self
.spr
['XER'][XER_bits
['CA32']] = cy32
867 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
868 if hasattr(self
.dec2
.e
.do
, "invert_in"):
869 inv_a
= yield self
.dec2
.e
.do
.invert_in
871 inputs
[0] = ~inputs
[0]
873 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
875 imm
= yield self
.dec2
.e
.do
.imm_data
.data
876 inputs
.append(SelectableInt(imm
, 64))
877 assert len(outputs
) >= 1
878 log("handle_overflow", inputs
, outputs
, div_overflow
)
879 if len(inputs
) < 2 and div_overflow
is None:
882 # div overflow is different: it's returned by the pseudo-code
883 # because it's more complex than can be done by analysing the output
884 if div_overflow
is not None:
885 ov
, ov32
= div_overflow
, div_overflow
886 # arithmetic overflow can be done by analysing the input and output
887 elif len(inputs
) >= 2:
891 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
892 output_sgn
= exts(output
.value
, output
.bits
) < 0
893 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
894 output_sgn
!= input_sgn
[0] else 0
897 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
898 output32_sgn
= exts(output
.value
, 32) < 0
899 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
900 output32_sgn
!= input32_sgn
[0] else 0
902 self
.spr
['XER'][XER_bits
['OV']] = ov
903 self
.spr
['XER'][XER_bits
['OV32']] = ov32
904 so
= self
.spr
['XER'][XER_bits
['SO']]
906 self
.spr
['XER'][XER_bits
['SO']] = so
908 def handle_comparison(self
, outputs
, cr_idx
=0):
910 assert isinstance(out
, SelectableInt
), \
911 "out zero not a SelectableInt %s" % repr(outputs
)
912 log("handle_comparison", out
.bits
, hex(out
.value
))
913 # TODO - XXX *processor* in 32-bit mode
914 # https://bugs.libre-soc.org/show_bug.cgi?id=424
916 # o32 = exts(out.value, 32)
917 # print ("handle_comparison exts 32 bit", hex(o32))
918 out
= exts(out
.value
, out
.bits
)
919 log("handle_comparison exts", hex(out
))
920 zero
= SelectableInt(out
== 0, 1)
921 positive
= SelectableInt(out
> 0, 1)
922 negative
= SelectableInt(out
< 0, 1)
923 SO
= self
.spr
['XER'][XER_bits
['SO']]
924 log("handle_comparison SO", SO
)
925 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
926 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
927 self
.crl
[cr_idx
].eq(cr_field
)
929 def set_pc(self
, pc_val
):
930 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
931 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
933 def get_next_insn(self
):
937 pc
= self
.pc
.CIA
.value
940 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
942 raise KeyError("no instruction at 0x%x" % pc
)
946 """set up one instruction
948 pc
, insn
= self
.get_next_insn()
949 yield from self
.setup_next_insn(pc
, insn
)
951 def setup_next_insn(self
, pc
, ins
):
952 """set up next instruction
955 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
956 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
958 yield self
.dec2
.sv_rm
.eq(0)
959 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
960 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
961 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
962 yield self
.dec2
.state
.pc
.eq(pc
)
963 if self
.svstate
is not None:
964 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
966 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
968 opcode
= yield self
.dec2
.dec
.opcode_in
969 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
970 pfx
.insn
.value
= opcode
971 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
972 log ("prefix test: opcode:", major
, bin(major
),
973 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
974 self
.is_svp64_mode
= ((major
== 0b000001) and
975 pfx
.insn
[7].value
== 0b1 and
976 pfx
.insn
[9].value
== 0b1)
977 self
.pc
.update_nia(self
.is_svp64_mode
)
978 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
979 self
.namespace
['NIA'] = self
.pc
.NIA
980 self
.namespace
['SVSTATE'] = self
.svstate
981 if not self
.is_svp64_mode
:
984 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
985 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
986 log (" svstate.vl", self
.svstate
.vl
)
987 log (" svstate.mvl", self
.svstate
.maxvl
)
988 sv_rm
= pfx
.rm
.asint(msb0
=True)
989 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
990 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
991 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
992 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
995 def execute_one(self
):
996 """execute one instruction
998 # get the disassembly code for this instruction
999 if self
.is_svp64_mode
:
1000 if not self
.disassembly
:
1001 code
= yield from self
.get_assembly_name()
1003 code
= self
.disassembly
[self
._pc
+4]
1004 log(" svp64 sim-execute", hex(self
._pc
), code
)
1006 if not self
.disassembly
:
1007 code
= yield from self
.get_assembly_name()
1009 code
= self
.disassembly
[self
._pc
]
1010 log("sim-execute", hex(self
._pc
), code
)
1011 opname
= code
.split(' ')[0]
1013 yield from self
.call(opname
) # execute the instruction
1014 except MemException
as e
: # check for memory errors
1015 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
1016 raise e
# ... re-raise
1017 # run a Trap but set DAR first
1018 print ("memory unaligned exception, DAR", e
.dar
)
1019 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1020 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1023 # don't use this except in special circumstances
1024 if not self
.respect_pc
:
1027 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1028 hex(self
.pc
.NIA
.value
))
1030 def get_assembly_name(self
):
1031 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1032 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1033 dec_insn
= yield self
.dec2
.e
.do
.insn
1034 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1035 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1036 int_op
= yield self
.dec2
.dec
.op
.internal_op
1037 log("get assembly name asmcode", asmcode
, int_op
,
1038 hex(dec_insn
), bin(insn_1_11
))
1039 asmop
= insns
.get(asmcode
, None)
1041 # sigh reconstruct the assembly instruction name
1042 if hasattr(self
.dec2
.e
.do
, "oe"):
1043 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1044 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1048 if hasattr(self
.dec2
.e
.do
, "rc"):
1049 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1050 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1054 # grrrr have to special-case MUL op (see DecodeOE)
1055 log("ov %d en %d rc %d en %d op %d" %
1056 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1057 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1062 if not asmop
.endswith("."): # don't add "." to "andis."
1065 if hasattr(self
.dec2
.e
.do
, "lk"):
1066 lk
= yield self
.dec2
.e
.do
.lk
1069 log("int_op", int_op
)
1070 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1071 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1075 spr_msb
= yield from self
.get_spr_msb()
1076 if int_op
== MicrOp
.OP_MFCR
.value
:
1081 # XXX TODO: for whatever weird reason this doesn't work
1082 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1083 if int_op
== MicrOp
.OP_MTCRF
.value
:
1090 def get_remap_indices(self
):
1091 """WARNING, this function stores remap_idxs and remap_loopends
1092 in the class for later use. this to avoid problems with yield
1094 # go through all iterators in lock-step, advance to next remap_idx
1095 srcstep
, dststep
= self
.get_src_dststeps()
1096 # get four SVSHAPEs. here we are hard-coding
1097 SVSHAPE0
= self
.spr
['SVSHAPE0']
1098 SVSHAPE1
= self
.spr
['SVSHAPE1']
1099 SVSHAPE2
= self
.spr
['SVSHAPE2']
1100 SVSHAPE3
= self
.spr
['SVSHAPE3']
1101 # set up the iterators
1102 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1103 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1104 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1105 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1108 self
.remap_loopends
= [0] * 4
1109 self
.remap_idxs
= [0, 1, 2, 3]
1111 for i
, (shape
, remap
) in enumerate(remaps
):
1112 # zero is "disabled"
1113 if shape
.value
== 0x0:
1114 self
.remap_idxs
[i
] = 0
1115 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1116 step
= dststep
if (i
in [3, 4]) else srcstep
1117 # this is terrible. O(N^2) looking for the match. but hey.
1118 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1121 self
.remap_idxs
[i
] = remap_idx
1122 self
.remap_loopends
[i
] = loopends
1123 dbg
.append((i
, step
, remap_idx
, loopends
))
1124 for (i
, step
, remap_idx
, loopends
) in dbg
:
1125 log ("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1128 def get_spr_msb(self
):
1129 dec_insn
= yield self
.dec2
.e
.do
.insn
1130 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1132 def call(self
, name
):
1133 """call(opcode) - the primary execution point for instructions
1135 self
.last_st_addr
= None # reset the last known store address
1136 self
.last_ld_addr
= None # etc.
1138 ins_name
= name
.strip() # remove spaces if not already done so
1140 log("halted - not executing", ins_name
)
1143 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1144 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1145 asmop
= yield from self
.get_assembly_name()
1146 log("call", ins_name
, asmop
)
1149 int_op
= yield self
.dec2
.dec
.op
.internal_op
1150 spr_msb
= yield from self
.get_spr_msb()
1152 instr_is_privileged
= False
1153 if int_op
in [MicrOp
.OP_ATTN
.value
,
1154 MicrOp
.OP_MFMSR
.value
,
1155 MicrOp
.OP_MTMSR
.value
,
1156 MicrOp
.OP_MTMSRD
.value
,
1158 MicrOp
.OP_RFID
.value
]:
1159 instr_is_privileged
= True
1160 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1161 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1162 instr_is_privileged
= True
1164 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1166 # check MSR priv bit and whether op is privileged: if so, throw trap
1167 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1168 self
.call_trap(0x700, PIb
.PRIV
)
1171 # check halted condition
1172 if ins_name
== 'attn':
1176 # check illegal instruction
1178 if ins_name
not in ['mtcrf', 'mtocrf']:
1179 illegal
= ins_name
!= asmop
1181 # sigh deal with setvl not being supported by binutils (.long)
1182 if asmop
.startswith('setvl'):
1186 # and svstep not being supported by binutils (.long)
1187 if asmop
.startswith('svstep'):
1191 # and svremap not being supported by binutils (.long)
1192 if asmop
.startswith('svremap'):
1194 ins_name
= 'svremap'
1196 # and svshape not being supported by binutils (.long)
1197 if asmop
.startswith('svshape'):
1199 ins_name
= 'svshape'
1202 if asmop
== 'fsins':
1205 if asmop
== 'fcoss':
1209 # sigh also deal with ffmadds not being supported by binutils (.long)
1210 if asmop
== 'ffmadds':
1212 ins_name
= 'ffmadds'
1214 # and fdmadds not being supported by binutils (.long)
1215 if asmop
== 'fdmadds':
1217 ins_name
= 'fdmadds'
1219 # and ffadds not being supported by binutils (.long)
1220 if asmop
== 'ffadds':
1224 # branch-conditional redirects to sv.bc
1225 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1226 ins_name
= 'sv.%s' % ins_name
1228 log(" post-processed name", ins_name
, asmop
)
1230 # illegal instructions call TRAP at 0x700
1232 print("illegal", ins_name
, asmop
)
1233 self
.call_trap(0x700, PIb
.ILLEG
)
1234 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1235 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1238 # this is for setvl "Vertical" mode: if set true,
1239 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1240 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1241 self
.allow_next_step_inc
= False
1242 self
.svstate_next_mode
= 0
1244 # nop has to be supported, we could let the actual op calculate
1245 # but PowerDecoder has a pattern for nop
1246 if ins_name
is 'nop':
1247 self
.update_pc_next()
1250 # look up instruction in ISA.instrs, prepare namespace
1251 info
= self
.instrs
[ins_name
]
1252 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1254 # preserve order of register names
1255 input_names
= create_args(list(info
.read_regs
) +
1256 list(info
.uninit_regs
))
1257 log("input names", input_names
)
1259 # get SVP64 entry for the current instruction
1260 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1261 if sv_rm
is not None:
1262 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1264 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1265 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1267 # see if srcstep/dststep need skipping over masked-out predicate bits
1268 if (self
.is_svp64_mode
or ins_name
== 'setvl' or
1269 ins_name
in ['svremap', 'svstate']):
1270 yield from self
.svstate_pre_inc()
1271 if self
.is_svp64_mode
:
1272 pre
= yield from self
.update_new_svstate_steps()
1274 self
.svp64_reset_loop()
1276 self
.update_pc_next()
1278 srcstep
, dststep
= self
.get_src_dststeps()
1279 pred_dst_zero
= self
.pred_dst_zero
1280 pred_src_zero
= self
.pred_src_zero
1281 vl
= self
.svstate
.vl
1283 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1284 if self
.is_svp64_mode
and vl
== 0:
1285 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1286 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1287 self
.namespace
['NIA'])
1290 # for when SVREMAP is active, using pre-arranged schedule.
1291 # note: modifying PowerDecoder2 needs to "settle"
1292 remap_en
= self
.svstate
.SVme
1293 persist
= self
.svstate
.RMpst
1294 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1295 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1297 if persist
or self
.last_op_svshape
:
1298 remaps
= self
.get_remap_indices()
1299 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1300 # just some convenient debug info
1302 sname
= 'SVSHAPE%d' % i
1303 shape
= self
.spr
[sname
]
1304 log (sname
, bin(shape
.value
))
1305 log (" lims", shape
.lims
)
1306 log (" mode", shape
.mode
)
1307 log (" skip", shape
.skip
)
1309 # set up the list of steps to remap
1310 mi0
= self
.svstate
.mi0
1311 mi1
= self
.svstate
.mi1
1312 mi2
= self
.svstate
.mi2
1313 mo0
= self
.svstate
.mo0
1314 mo1
= self
.svstate
.mo1
1315 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1316 (self
.dec2
.in2_step
, mi1
), # RB
1317 (self
.dec2
.in3_step
, mi2
), # RC
1318 (self
.dec2
.o_step
, mo0
), # RT
1319 (self
.dec2
.o2_step
, mo1
), # EA
1321 remap_idxs
= self
.remap_idxs
1323 # now cross-index the required SHAPE for each of 3-in 2-out regs
1324 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1325 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1326 (shape
, remap
) = remaps
[shape_idx
]
1327 remap_idx
= remap_idxs
[shape_idx
]
1328 # zero is "disabled"
1329 if shape
.value
== 0x0:
1331 # now set the actual requested step to the current index
1332 yield dstep
.eq(remap_idx
)
1334 # debug printout info
1335 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
,
1338 log ("shape remap", x
)
1339 # after that, settle down (combinatorial) to let Vector reg numbers
1340 # work themselves out
1342 remap_active
= yield self
.dec2
.remap_active
1343 log ("remap active", bin(remap_active
))
1345 # main input registers (RT, RA ...)
1347 for name
in input_names
:
1348 # using PowerDecoder2, first, find the decoder index.
1349 # (mapping name RA RB RC RS to in1, in2, in3)
1350 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1352 # doing this is not part of svp64, it's because output
1353 # registers, to be modified, need to be in the namespace.
1354 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1356 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1359 # in case getting the register number is needed, _RA, _RB
1360 regname
= "_" + name
1361 self
.namespace
[regname
] = regnum
1362 if not self
.is_svp64_mode
or not pred_src_zero
:
1363 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1365 reg_val
= SelectableInt(self
.fpr(regnum
))
1366 elif name
is not None:
1367 reg_val
= SelectableInt(self
.gpr(regnum
))
1369 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1371 inputs
.append(reg_val
)
1372 # arrrrgh, awful hack, to get _RT into namespace
1373 if ins_name
in ['setvl', 'svstep']:
1375 RT
= yield self
.dec2
.dec
.RT
1376 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1378 self
.namespace
["RT"] = SelectableInt(0, 5)
1379 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1380 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1382 # in SVP64 mode for LD/ST work out immediate
1383 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1384 # use info.form to detect
1385 replace_d
= False # update / replace constant in pseudocode
1386 if self
.is_svp64_mode
:
1387 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1388 # shift mode reads SVD (or SVDS - TODO)
1389 # *BUT*... because this is "overloading" of LD operations,
1390 # it gets *STORED* into D (or DS, TODO)
1391 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1392 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1393 imm
= exts(imm
, 11) # sign-extend to integer
1394 log ("shift SVD", imm
)
1397 if info
.form
== 'DS':
1398 # DS-Form, multiply by 4 then knock 2 bits off after
1399 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1401 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1402 imm
= exts(imm
, 16) # sign-extend to integer
1403 # get the right step. LD is from srcstep, ST is dststep
1404 op
= yield self
.dec2
.e
.do
.insn_type
1406 if op
== MicrOp
.OP_LOAD
.value
:
1408 offsmul
= yield self
.dec2
.in1_step
1409 log("D-field REMAP src", imm
, offsmul
)
1412 log("D-field src", imm
, offsmul
)
1413 elif op
== MicrOp
.OP_STORE
.value
:
1414 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1416 log("D-field dst", imm
, offsmul
)
1417 # bit-reverse mode, rev already done through get_src_dst_steps()
1418 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1419 # manually look up RC, sigh
1420 RC
= yield self
.dec2
.dec
.RC
[0:5]
1422 log ("LD-SHIFT:", "VL", vl
,
1423 "RC", RC
.value
, "imm", imm
,
1424 "offs", bin(offsmul
),
1426 imm
= SelectableInt((imm
* offsmul
) << RC
.value
, 32)
1427 # Unit-Strided LD/ST adds offset*width to immediate
1428 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1429 ldst_len
= yield self
.dec2
.e
.do
.data_len
1430 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1432 # Element-strided multiplies the immediate by element step
1433 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1434 imm
= SelectableInt(imm
* offsmul
, 32)
1437 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1438 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1439 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1440 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1441 # new replacement D... errr.. DS
1443 if info
.form
== 'DS':
1444 # TODO: assert 2 LSBs are zero?
1445 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1446 imm
.value
= imm
.value
>> 2
1447 self
.namespace
['DS'] = imm
1449 self
.namespace
['D'] = imm
1451 # "special" registers
1452 for special
in info
.special_regs
:
1453 if special
in special_sprs
:
1454 inputs
.append(self
.spr
[special
])
1456 inputs
.append(self
.namespace
[special
])
1458 # clear trap (trap) NIA
1459 self
.trap_nia
= None
1461 # check if this was an sv.bc* and create an indicator that
1462 # this is the last check to be made as a loop. combined with
1463 # the ALL/ANY mode we can early-exit
1464 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
1465 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
1466 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
1467 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
1469 # execute actual instruction here (finally)
1470 log("inputs", inputs
)
1471 results
= info
.func(self
, *inputs
)
1472 log("results", results
)
1474 # "inject" decorator takes namespace from function locals: we need to
1475 # overwrite NIA being overwritten (sigh)
1476 if self
.trap_nia
is not None:
1477 self
.namespace
['NIA'] = self
.trap_nia
1479 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1481 # check if op was a LD/ST so that debugging can check the
1483 if int_op
in [MicrOp
.OP_STORE
.value
,
1485 self
.last_st_addr
= self
.mem
.last_st_addr
1486 if int_op
in [MicrOp
.OP_LOAD
.value
,
1488 self
.last_ld_addr
= self
.mem
.last_ld_addr
1489 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1490 self
.last_st_addr
, self
.last_ld_addr
)
1492 # detect if CA/CA32 already in outputs (sra*, basically)
1495 output_names
= create_args(info
.write_regs
)
1496 for name
in output_names
:
1502 log("carry already done?", bin(already_done
))
1503 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1504 carry_en
= yield self
.dec2
.e
.do
.output_carry
1508 yield from self
.handle_carry_(inputs
, results
, already_done
)
1510 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1511 # detect if overflow was in return result
1514 for name
, output
in zip(output_names
, results
):
1515 if name
== 'overflow':
1518 if hasattr(self
.dec2
.e
.do
, "oe"):
1519 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1520 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1524 log("internal overflow", overflow
, ov_en
, ov_ok
)
1526 yield from self
.handle_overflow(inputs
, results
, overflow
)
1528 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1530 if not self
.is_svp64_mode
or not pred_dst_zero
:
1531 if hasattr(self
.dec2
.e
.do
, "rc"):
1532 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1533 if rc_en
and ins_name
not in ['svstep']:
1534 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1535 self
.handle_comparison(results
, regnum
)
1537 # any modified return results?
1539 for name
, output
in zip(output_names
, results
):
1540 if name
== 'overflow': # ignore, done already (above)
1542 if isinstance(output
, int):
1543 output
= SelectableInt(output
, 256)
1544 if name
in ['CA', 'CA32']:
1546 log("writing %s to XER" % name
, output
)
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 if name
in special_sprs
:
1553 self
.spr
[name
] = output
1555 self
.namespace
[name
].eq(output
)
1557 log('msr written', hex(self
.msr
.value
))
1559 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
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 pred_dst_zero
:
1569 log('zeroing reg %d %s' % (regnum
, str(output
)),
1571 output
= SelectableInt(0, 256)
1577 log('writing %s %s %s' % (ftype
, regnum
, str(output
)),
1579 if output
.bits
> 64:
1580 output
= SelectableInt(output
.value
, 64)
1582 self
.fpr
[regnum
] = output
1584 self
.gpr
[regnum
] = output
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
1603 results
= [SelectableInt(0, 64)]
1604 self
.handle_comparison(results
) # CR0
1606 if self
.allow_next_step_inc
== 2:
1607 log ("SVSTATE_NEXT: read")
1608 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1610 log ("SVSTATE_NEXT: post-inc")
1611 # use actual src/dst-step here to check end, do NOT
1612 # use bit-reversed version
1613 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1614 remaps
= self
.get_remap_indices()
1615 remap_idxs
= self
.remap_idxs
1616 vl
= self
.svstate
.vl
1617 end_src
= srcstep
== vl
-1
1618 end_dst
= dststep
== vl
-1
1619 if self
.allow_next_step_inc
!= 2:
1621 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1623 self
.svstate
.dststep
+= SelectableInt(1, 7)
1624 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1625 # set CR0 (if Rc=1) based on end
1627 srcstep
= self
.svstate
.srcstep
1628 dststep
= self
.svstate
.srcstep
1629 endtest
= 1 if (end_src
or end_dst
) else 0
1630 #results = [SelectableInt(endtest, 64)]
1631 #self.handle_comparison(results) # CR0
1633 # see if svstep was requested, if so, which SVSTATE
1635 if self
.svstate_next_mode
> 0:
1636 shape_idx
= self
.svstate_next_mode
.value
-1
1637 endings
= self
.remap_loopends
[shape_idx
]
1638 cr_field
= SelectableInt((~endings
)<<1 | endtest
, 4)
1639 print ("svstep Rc=1, CR0", cr_field
)
1640 self
.crl
[0].eq(cr_field
) # CR0
1641 if end_src
or end_dst
:
1642 # reset at end of loop including exit Vertical Mode
1643 log ("SVSTATE_NEXT: after increments, reset")
1644 self
.svp64_reset_loop()
1645 self
.svstate
.vfirst
= 0
1647 elif self
.is_svp64_mode
:
1648 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
1650 # XXX only in non-SVP64 mode!
1651 # 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
== 'svremap'
1658 self
.update_pc_next()
1660 def SVSTATE_NEXT(self
, mode
, submode
):
1661 """explicitly moves srcstep/dststep on to next element, for
1662 "Vertical-First" mode. this function is called from
1663 setvl pseudo-code, as a pseudo-op "svstep"
1665 WARNING: this function uses information that was created EARLIER
1666 due to it being in the middle of a yield, but this function is
1667 *NOT* called from yield (it's called from compiled pseudocode).
1669 self
.allow_next_step_inc
= submode
.value
+ 1
1670 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
1671 self
.svstate_next_mode
= mode
1672 if self
.svstate_next_mode
> 0:
1673 shape_idx
= self
.svstate_next_mode
.value
-1
1674 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1675 return SelectableInt(0, 7)
1677 def svstate_pre_inc(self
):
1678 """check if srcstep/dststep need to skip over masked-out predicate bits
1680 # get SVSTATE VL (oh and print out some debug stuff)
1681 vl
= self
.svstate
.vl
1682 srcstep
= self
.svstate
.srcstep
1683 dststep
= self
.svstate
.dststep
1684 sv_a_nz
= yield self
.dec2
.sv_a_nz
1685 fft_mode
= yield self
.dec2
.use_svp64_fft
1686 in1
= yield self
.dec2
.e
.read_reg1
.data
1687 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft, svp64",
1688 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
,
1691 # get predicate mask
1692 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1694 pmode
= yield self
.dec2
.rm_dec
.predmode
1695 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1696 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1697 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1698 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1699 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1700 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1701 if pmode
== SVP64PredMode
.INT
.value
:
1702 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1703 if sv_ptype
== SVPtype
.P2
.value
:
1704 srcmask
= get_predint(self
.gpr
, srcpred
)
1705 elif pmode
== SVP64PredMode
.CR
.value
:
1706 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1707 if sv_ptype
== SVPtype
.P2
.value
:
1708 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1709 log (" pmode", pmode
)
1710 log (" reverse", reverse_gear
)
1711 log (" ptype", sv_ptype
)
1712 log (" srcpred", bin(srcpred
))
1713 log (" dstpred", bin(dstpred
))
1714 log (" srcmask", bin(srcmask
))
1715 log (" dstmask", bin(dstmask
))
1716 log (" pred_sz", bin(pred_src_zero
))
1717 log (" pred_dz", bin(pred_dst_zero
))
1719 # okaaay, so here we simply advance srcstep (TODO dststep)
1720 # until the predicate mask has a "1" bit... or we run out of VL
1721 # let srcstep==VL be the indicator to move to next instruction
1722 if not pred_src_zero
:
1723 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1724 log (" skip", bin(1<<srcstep
))
1727 if not pred_dst_zero
:
1728 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1729 log (" skip", bin(1<<dststep
))
1732 # now work out if the relevant mask bits require zeroing
1734 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1736 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1738 # store new srcstep / dststep
1739 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1740 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1741 log (" new srcstep", srcstep
)
1742 log (" new dststep", dststep
)
1744 def get_src_dststeps(self
):
1745 """gets srcstep and dststep
1747 return self
.new_srcstep
, self
.new_dststep
1749 def update_new_svstate_steps(self
):
1750 # note, do not get the bit-reversed srcstep here!
1751 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1753 # update SVSTATE with new srcstep
1754 self
.svstate
.srcstep
= srcstep
1755 self
.svstate
.dststep
= dststep
1756 self
.namespace
['SVSTATE'] = self
.svstate
1757 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1758 yield Settle() # let decoder update
1759 srcstep
= self
.svstate
.srcstep
1760 dststep
= self
.svstate
.dststep
1761 vl
= self
.svstate
.vl
1762 log (" srcstep", srcstep
)
1763 log (" dststep", dststep
)
1766 # check if end reached (we let srcstep overrun, above)
1767 # nothing needs doing (TODO zeroing): just do next instruction
1768 return srcstep
== vl
or dststep
== vl
1770 def svstate_post_inc(self
, insn_name
, vf
=0):
1771 # check if SV "Vertical First" mode is enabled
1772 vfirst
= self
.svstate
.vfirst
1773 log (" SV Vertical First", vf
, vfirst
)
1774 if not vf
and vfirst
== 1:
1778 # check if it is the SVSTATE.src/dest step that needs incrementing
1779 # this is our Sub-Program-Counter loop from 0 to VL-1
1780 # XXX twin predication TODO
1781 vl
= self
.svstate
.vl
1782 mvl
= self
.svstate
.maxvl
1783 srcstep
= self
.svstate
.srcstep
1784 dststep
= self
.svstate
.dststep
1785 rm_mode
= yield self
.dec2
.rm_dec
.mode
1786 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1787 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1788 out_vec
= not (yield self
.dec2
.no_out_vec
)
1789 in_vec
= not (yield self
.dec2
.no_in_vec
)
1790 log (" svstate.vl", vl
)
1791 log (" svstate.mvl", mvl
)
1792 log (" svstate.srcstep", srcstep
)
1793 log (" svstate.dststep", dststep
)
1794 log (" mode", rm_mode
)
1795 log (" reverse", reverse_gear
)
1796 log (" out_vec", out_vec
)
1797 log (" in_vec", in_vec
)
1798 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1799 # check if srcstep needs incrementing by one, stop PC advancing
1800 # svp64 loop can end early if the dest is scalar for single-pred
1801 # but for 2-pred both src/dest have to be checked.
1802 # XXX this might not be true! it may just be LD/ST
1803 if sv_ptype
== SVPtype
.P2
.value
:
1804 svp64_is_vector
= (out_vec
or in_vec
)
1806 svp64_is_vector
= out_vec
1807 # check if this was an sv.bc* and if so did it succeed
1808 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1809 end_loop
= self
.namespace
['end_loop']
1810 log("branch %s end_loop" % insn_name
, end_loop
)
1812 self
.svp64_reset_loop()
1813 self
.update_pc_next()
1815 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1816 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1817 self
.svstate
.dststep
+= SelectableInt(1, 7)
1818 self
.namespace
['SVSTATE'] = self
.svstate
1819 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1820 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1821 # this way we keep repeating the same instruction (with new steps)
1822 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1823 self
.namespace
['NIA'] = self
.pc
.NIA
1824 log("end of sub-pc call", self
.namespace
['CIA'],
1825 self
.namespace
['NIA'])
1826 return False # DO NOT allow PC update whilst Sub-PC loop running
1828 # reset loop to zero and update NIA
1829 self
.svp64_reset_loop()
1834 def update_pc_next(self
):
1835 # UPDATE program counter
1836 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1837 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1838 log("end of call", self
.namespace
['CIA'],
1839 self
.namespace
['NIA'],
1840 self
.namespace
['SVSTATE'])
1842 def svp64_reset_loop(self
):
1843 self
.svstate
.srcstep
= 0
1844 self
.svstate
.dststep
= 0
1845 log (" svstate.srcstep loop end (PC to update)")
1846 self
.namespace
['SVSTATE'] = self
.svstate
1848 def update_nia(self
):
1849 self
.pc
.update_nia(self
.is_svp64_mode
)
1850 self
.namespace
['NIA'] = self
.pc
.NIA
1854 """Decorator factory.
1856 this decorator will "inject" variables into the function's namespace,
1857 from the *dictionary* in self.namespace. it therefore becomes possible
1858 to make it look like a whole stack of variables which would otherwise
1859 need "self." inserted in front of them (*and* for those variables to be
1860 added to the instance) "appear" in the function.
1862 "self.namespace['SI']" for example becomes accessible as just "SI" but
1863 *only* inside the function, when decorated.
1865 def variable_injector(func
):
1867 def decorator(*args
, **kwargs
):
1869 func_globals
= func
.__globals
__ # Python 2.6+
1870 except AttributeError:
1871 func_globals
= func
.func_globals
# Earlier versions.
1873 context
= args
[0].namespace
# variables to be injected
1874 saved_values
= func_globals
.copy() # Shallow copy of dict.
1875 log("globals before", context
.keys())
1876 func_globals
.update(context
)
1877 result
= func(*args
, **kwargs
)
1878 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1879 log("args[0]", args
[0].namespace
['CIA'],
1880 args
[0].namespace
['NIA'],
1881 args
[0].namespace
['SVSTATE'])
1882 if 'end_loop' in func_globals
:
1883 log("args[0] end_loop", func_globals
['end_loop'])
1884 args
[0].namespace
= func_globals
1885 #exec (func.__code__, func_globals)
1888 # func_globals = saved_values # Undo changes.
1894 return variable_injector