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
)
32 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
33 from openpower
.consts
import (SVP64MODE
,
36 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
38 from openpower
.decoder
.isa
.radixmmu
import RADIX
39 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
40 from openpower
.decoder
.isa
.svshape
import SVSHAPE
41 from openpower
.decoder
.isa
.svstate
import SVP64State
44 from openpower
.util
import log
46 from collections
import namedtuple
50 instruction_info
= namedtuple('instruction_info',
51 'func read_regs uninit_regs write_regs ' +
52 'special_regs op_fields form asmregs')
63 # TODO (lkcl): adjust other registers that should be in a particular order
64 # probably CA, CA32, and CR
90 "overflow": 7, # should definitely be last
93 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
96 def create_args(reglist
, extra
=None):
97 retval
= list(OrderedSet(reglist
))
98 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
100 return [extra
] + retval
106 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
109 self
.isacaller
= isacaller
110 self
.svstate
= svstate
111 for i
in range(len(regfile
)):
112 self
[i
] = SelectableInt(regfile
[i
], 64)
114 def __call__(self
, ridx
):
115 if isinstance(ridx
, SelectableInt
):
119 def set_form(self
, form
):
122 def __setitem__(self
, rnum
, value
):
123 # rnum = rnum.value # only SelectableInt allowed
124 log("GPR setitem", rnum
, value
)
125 if isinstance(rnum
, SelectableInt
):
127 dict.__setitem
__(self
, rnum
, value
)
129 def getz(self
, rnum
):
130 # rnum = rnum.value # only SelectableInt allowed
131 log("GPR getzero?", rnum
)
133 return SelectableInt(0, 64)
136 def _get_regnum(self
, attr
):
137 getform
= self
.sd
.sigforms
[self
.form
]
138 rnum
= getattr(getform
, attr
)
141 def ___getitem__(self
, attr
):
142 """ XXX currently not used
144 rnum
= self
._get
_regnum
(attr
)
145 log("GPR getitem", attr
, rnum
)
146 return self
.regfile
[rnum
]
148 def dump(self
, printout
=True):
150 for i
in range(len(self
)):
151 res
.append(self
[i
].value
)
153 for i
in range(0, len(res
), 8):
156 s
.append("%08x" % res
[i
+j
])
158 print("reg", "%2d" % i
, s
)
163 def __init__(self
, dec2
, initial_sprs
={}):
166 for key
, v
in initial_sprs
.items():
167 if isinstance(key
, SelectableInt
):
169 key
= special_sprs
.get(key
, key
)
170 if isinstance(key
, int):
173 info
= spr_byname
[key
]
174 if not isinstance(v
, SelectableInt
):
175 v
= SelectableInt(v
, info
.length
)
178 def __getitem__(self
, key
):
180 log("dict", self
.items())
181 # if key in special_sprs get the special spr, otherwise return key
182 if isinstance(key
, SelectableInt
):
184 if isinstance(key
, int):
185 key
= spr_dict
[key
].SPR
186 key
= special_sprs
.get(key
, key
)
187 if key
== 'HSRR0': # HACK!
189 if key
== 'HSRR1': # HACK!
192 res
= dict.__getitem
__(self
, key
)
194 if isinstance(key
, int):
197 info
= spr_byname
[key
]
198 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
199 res
= dict.__getitem
__(self
, key
)
200 log("spr returning", key
, res
)
203 def __setitem__(self
, key
, value
):
204 if isinstance(key
, SelectableInt
):
206 if isinstance(key
, int):
207 key
= spr_dict
[key
].SPR
209 key
= special_sprs
.get(key
, key
)
210 if key
== 'HSRR0': # HACK!
211 self
.__setitem
__('SRR0', value
)
212 if key
== 'HSRR1': # HACK!
213 self
.__setitem
__('SRR1', value
)
214 log("setting spr", key
, value
)
215 dict.__setitem
__(self
, key
, value
)
217 def __call__(self
, ridx
):
220 def dump(self
, printout
=True):
222 keys
= list(self
.keys())
225 sprname
= spr_dict
.get(k
, None)
229 sprname
= sprname
.SPR
230 res
.append((sprname
, self
[k
].value
))
232 for sprname
, value
in res
:
233 print(" ", sprname
, hex(value
))
238 def __init__(self
, pc_init
=0):
239 self
.CIA
= SelectableInt(pc_init
, 64)
240 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
242 def update_nia(self
, is_svp64
):
243 increment
= 8 if is_svp64
else 4
244 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
246 def update(self
, namespace
, is_svp64
):
247 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
249 self
.CIA
= namespace
['NIA'].narrow(64)
250 self
.update_nia(is_svp64
)
251 namespace
['CIA'] = self
.CIA
252 namespace
['NIA'] = self
.NIA
257 def __init__(self
, init
=0):
258 self
.spr
= SelectableInt(init
, 24)
259 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
260 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
261 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
262 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
263 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
264 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
265 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
266 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
267 # these cover the same extra field, split into parts as EXTRA2
268 self
.extra2
= list(range(4))
269 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
270 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
271 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
272 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
273 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
274 # and here as well, but EXTRA3
275 self
.extra3
= list(range(3))
276 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
277 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
278 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
281 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
282 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
283 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
284 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
285 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
286 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
287 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
288 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
289 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
292 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
293 class SVP64PrefixFields
:
295 self
.insn
= SelectableInt(0, 32)
296 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
297 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
298 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
299 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
300 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
303 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
304 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
305 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
309 # See PowerISA Version 3.0 B Book 1
310 # Section 2.3.1 Condition Register pages 30 - 31
312 LT
= FL
= 0 # negative, less than, floating-point less than
313 GT
= FG
= 1 # positive, greater than, floating-point greater than
314 EQ
= FE
= 2 # equal, floating-point equal
315 SO
= FU
= 3 # summary overflow, floating-point unordered
317 def __init__(self
, init
=0):
318 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
319 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
320 self
.cr
= SelectableInt(init
, 64) # underlying reg
321 # field-selectable versions of Condition Register TODO check bitranges?
324 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
325 _cr
= FieldSelectableInt(self
.cr
, bits
)
328 # decode SVP64 predicate integer to reg number and invert
329 def get_predint(gpr
, mask
):
332 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
333 if mask
== SVP64PredInt
.ALWAYS
.value
:
334 return 0xffff_ffff_ffff_ffff
335 if mask
== SVP64PredInt
.R3_UNARY
.value
:
336 return 1 << (gpr(3).value
& 0b111111)
337 if mask
== SVP64PredInt
.R3
.value
:
339 if mask
== SVP64PredInt
.R3_N
.value
:
341 if mask
== SVP64PredInt
.R10
.value
:
343 if mask
== SVP64PredInt
.R10_N
.value
:
344 return ~
gpr(10).value
345 if mask
== SVP64PredInt
.R30
.value
:
347 if mask
== SVP64PredInt
.R30_N
.value
:
348 return ~
gpr(30).value
350 # decode SVP64 predicate CR to reg number and invert status
351 def _get_predcr(mask
):
352 if mask
== SVP64PredCR
.LT
.value
:
354 if mask
== SVP64PredCR
.GE
.value
:
356 if mask
== SVP64PredCR
.GT
.value
:
358 if mask
== SVP64PredCR
.LE
.value
:
360 if mask
== SVP64PredCR
.EQ
.value
:
362 if mask
== SVP64PredCR
.NE
.value
:
364 if mask
== SVP64PredCR
.SO
.value
:
366 if mask
== SVP64PredCR
.NS
.value
:
369 # read individual CR fields (0..VL-1), extract the required bit
370 # and construct the mask
371 def get_predcr(crl
, mask
, vl
):
372 idx
, noninv
= _get_predcr(mask
)
375 cr
= crl
[i
+SVP64CROffs
.CRPred
]
376 if cr
[idx
].value
== noninv
:
381 # TODO, really should just be using PowerDecoder2
382 def get_pdecode_idx_in(dec2
, name
):
384 in1_sel
= yield op
.in1_sel
385 in2_sel
= yield op
.in2_sel
386 in3_sel
= yield op
.in3_sel
387 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
388 in1
= yield dec2
.e
.read_reg1
.data
389 in2
= yield dec2
.e
.read_reg2
.data
390 in3
= yield dec2
.e
.read_reg3
.data
391 in1_isvec
= yield dec2
.in1_isvec
392 in2_isvec
= yield dec2
.in2_isvec
393 in3_isvec
= yield dec2
.in3_isvec
394 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
396 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
398 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
400 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
402 log ("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
404 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
406 # identify which regnames map to in1/2/3
408 if (in1_sel
== In1Sel
.RA
.value
or
409 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
410 return in1
, in1_isvec
411 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
412 return in1
, in1_isvec
414 if in2_sel
== In2Sel
.RB
.value
:
415 return in2
, in2_isvec
416 if in3_sel
== In3Sel
.RB
.value
:
417 return in3
, in3_isvec
418 # XXX TODO, RC doesn't exist yet!
420 assert False, "RC does not exist yet"
422 if in1_sel
== In1Sel
.RS
.value
:
423 return in1
, in1_isvec
424 if in2_sel
== In2Sel
.RS
.value
:
425 return in2
, in2_isvec
426 if in3_sel
== In3Sel
.RS
.value
:
427 return in3
, in3_isvec
429 if in1_sel
== In1Sel
.FRA
.value
:
430 return in1
, in1_isvec
432 if in2_sel
== In2Sel
.FRB
.value
:
433 return in2
, in2_isvec
435 if in3_sel
== In3Sel
.FRC
.value
:
436 return in3
, in3_isvec
438 if in1_sel
== In1Sel
.FRS
.value
:
439 return in1
, in1_isvec
440 if in3_sel
== In3Sel
.FRS
.value
:
441 return in3
, in3_isvec
445 # TODO, really should just be using PowerDecoder2
446 def get_pdecode_cr_in(dec2
, name
):
448 in_sel
= yield op
.cr_in
449 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
450 sv_cr_in
= yield op
.sv_cr_in
451 spec
= yield dec2
.crin_svdec
.spec
452 sv_override
= yield dec2
.dec_cr_in
.sv_override
453 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
454 in1
= yield dec2
.e
.read_cr1
.data
455 cr_isvec
= yield dec2
.cr_in_isvec
456 log ("get_pdecode_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
457 log (" sv_cr_in", sv_cr_in
)
458 log (" cr_bf", in_bitfield
)
460 log (" override", sv_override
)
461 # identify which regnames map to in / o2
463 if in_sel
== CRInSel
.BI
.value
:
465 log ("get_pdecode_cr_in not found", name
)
469 # TODO, really should just be using PowerDecoder2
470 def get_pdecode_cr_out(dec2
, name
):
472 out_sel
= yield op
.cr_out
473 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
474 sv_cr_out
= yield op
.sv_cr_out
475 spec
= yield dec2
.crout_svdec
.spec
476 sv_override
= yield dec2
.dec_cr_out
.sv_override
477 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
478 out
= yield dec2
.e
.write_cr
.data
479 o_isvec
= yield dec2
.o_isvec
480 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
481 log (" sv_cr_out", sv_cr_out
)
482 log (" cr_bf", out_bitfield
)
484 log (" override", sv_override
)
485 # identify which regnames map to out / o2
487 if out_sel
== CROutSel
.CR0
.value
:
489 log ("get_pdecode_cr_out not found", name
)
493 # TODO, really should just be using PowerDecoder2
494 def get_pdecode_idx_out(dec2
, name
):
496 out_sel
= yield op
.out_sel
497 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
498 out
= yield dec2
.e
.write_reg
.data
499 o_isvec
= yield dec2
.o_isvec
500 # identify which regnames map to out / o2
502 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
503 if out_sel
== OutSel
.RA
.value
:
506 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
507 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
509 if out_sel
== OutSel
.RT
.value
:
511 elif name
== 'RT_OR_ZERO':
512 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
513 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
515 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
518 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
519 if out_sel
== OutSel
.FRA
.value
:
522 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
523 OutSel
.FRT
.value
, out
, o_isvec
)
524 if out_sel
== OutSel
.FRT
.value
:
526 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
530 # TODO, really should just be using PowerDecoder2
531 def get_pdecode_idx_out2(dec2
, name
):
532 # check first if register is activated for write
534 out_sel
= yield op
.out_sel
535 out
= yield dec2
.e
.write_ea
.data
536 o_isvec
= yield dec2
.o2_isvec
537 out_ok
= yield dec2
.e
.write_ea
.ok
538 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
543 if hasattr(op
, "upd"):
544 # update mode LD/ST uses read-reg A also as an output
546 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
547 out_sel
, OutSel
.RA
.value
,
549 if upd
== LDSTMode
.update
.value
:
552 int_op
= yield dec2
.dec
.op
.internal_op
553 fft_en
= yield dec2
.use_svp64_fft
554 #if int_op == MicrOp.OP_FP_MADD.value and fft_en:
556 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
563 # decoder2 - an instance of power_decoder2
564 # regfile - a list of initial values for the registers
565 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
566 # respect_pc - tracks the program counter. requires initial_insns
567 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
568 initial_mem
=None, initial_msr
=0,
579 self
.bigendian
= bigendian
581 self
.is_svp64_mode
= False
582 self
.respect_pc
= respect_pc
583 if initial_sprs
is None:
585 if initial_mem
is None:
587 if fpregfile
is None:
589 if initial_insns
is None:
591 assert self
.respect_pc
== False, "instructions required to honor pc"
593 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
594 log("ISACaller initial_msr", initial_msr
)
596 # "fake program counter" mode (for unit testing)
600 if isinstance(initial_mem
, tuple):
601 self
.fake_pc
= initial_mem
[0]
602 disasm_start
= self
.fake_pc
604 disasm_start
= initial_pc
606 # disassembly: we need this for now (not given from the decoder)
607 self
.disassembly
= {}
609 for i
, code
in enumerate(disassembly
):
610 self
.disassembly
[i
*4 + disasm_start
] = code
612 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
613 self
.svp64rm
= SVP64RM()
614 if initial_svstate
is None:
616 if isinstance(initial_svstate
, int):
617 initial_svstate
= SVP64State(initial_svstate
)
618 # SVSTATE, MSR and PC
619 self
.svstate
= initial_svstate
620 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
622 # GPR FPR SPR registers
623 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
624 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
625 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
627 # set up 4 dummy SVSHAPEs if they aren't already set up
629 sname
= 'SVSHAPE%d' % i
630 if sname
not in self
.spr
:
631 self
.spr
[sname
] = SVSHAPE(0)
633 # make sure it's an SVSHAPE
634 val
= self
.spr
[sname
].value
635 self
.spr
[sname
] = SVSHAPE(val
)
636 self
.last_op_svshape
= False
639 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
640 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
641 # MMU mode, redirect underlying Mem through RADIX
643 self
.mem
= RADIX(self
.mem
, self
)
645 self
.imem
= RADIX(self
.imem
, self
)
648 # FPR (same as GPR except for FP nums)
649 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
650 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
651 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
652 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
654 # 2.3.2 LR (actually SPR #8) -- Done
655 # 2.3.3 CTR (actually SPR #9) -- Done
656 # 2.3.4 TAR (actually SPR #815)
657 # 3.2.2 p45 XER (actually SPR #1) -- Done
658 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
660 # create CR then allow portions of it to be "selectable" (below)
661 self
.cr_fields
= CRFields(initial_cr
)
662 self
.cr
= self
.cr_fields
.cr
664 # "undefined", just set to variable-bit-width int (use exts "max")
665 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
668 self
.namespace
.update(self
.spr
)
669 self
.namespace
.update({'GPR': self
.gpr
,
673 'memassign': self
.memassign
,
676 'SVSTATE': self
.svstate
,
677 'SVSHAPE0': self
.spr
['SVSHAPE0'],
678 'SVSHAPE1': self
.spr
['SVSHAPE1'],
679 'SVSHAPE2': self
.spr
['SVSHAPE2'],
680 'SVSHAPE3': self
.spr
['SVSHAPE3'],
683 'undefined': undefined
,
684 'mode_is_64bit': True,
688 # update pc to requested start point
689 self
.set_pc(initial_pc
)
691 # field-selectable versions of Condition Register
692 self
.crl
= self
.cr_fields
.crl
694 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
696 self
.decoder
= decoder2
.dec
699 def call_trap(self
, trap_addr
, trap_bit
):
700 """calls TRAP and sets up NIA to the new execution location.
701 next instruction will begin at trap_addr.
703 self
.TRAP(trap_addr
, trap_bit
)
704 self
.namespace
['NIA'] = self
.trap_nia
705 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
707 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
708 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
710 TRAP function is callable from inside the pseudocode itself,
711 hence the default arguments. when calling from inside ISACaller
712 it is best to use call_trap()
714 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
715 # store CIA(+4?) in SRR0, set NIA to 0x700
716 # store MSR in SRR1, set MSR to um errr something, have to check spec
717 # store SVSTATE (if enabled) in SVSRR0
718 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
719 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
720 if self
.is_svp64_mode
:
721 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
722 self
.trap_nia
= SelectableInt(trap_addr
, 64)
723 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
725 # set exception bits. TODO: this should, based on the address
726 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
727 # bits appropriately. however it turns out that *for now* in all
728 # cases (all trap_addrs) the exact same thing is needed.
729 self
.msr
[MSRb
.IR
] = 0
730 self
.msr
[MSRb
.DR
] = 0
731 self
.msr
[MSRb
.FE0
] = 0
732 self
.msr
[MSRb
.FE1
] = 0
733 self
.msr
[MSRb
.EE
] = 0
734 self
.msr
[MSRb
.RI
] = 0
735 self
.msr
[MSRb
.SF
] = 1
736 self
.msr
[MSRb
.TM
] = 0
737 self
.msr
[MSRb
.VEC
] = 0
738 self
.msr
[MSRb
.VSX
] = 0
739 self
.msr
[MSRb
.PR
] = 0
740 self
.msr
[MSRb
.FP
] = 0
741 self
.msr
[MSRb
.PMM
] = 0
742 self
.msr
[MSRb
.TEs
] = 0
743 self
.msr
[MSRb
.TEe
] = 0
744 self
.msr
[MSRb
.UND
] = 0
745 self
.msr
[MSRb
.LE
] = 1
747 def memassign(self
, ea
, sz
, val
):
748 self
.mem
.memassign(ea
, sz
, val
)
750 def prep_namespace(self
, insn_name
, formname
, op_fields
):
751 # TODO: get field names from form in decoder*1* (not decoder2)
752 # decoder2 is hand-created, and decoder1.sigform is auto-generated
754 # then "yield" fields only from op_fields rather than hard-coded
756 fields
= self
.decoder
.sigforms
[formname
]
757 log("prep_namespace", formname
, op_fields
)
758 for name
in op_fields
:
759 # CR immediates. deal with separately. needs modifying
761 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
762 # BI is a 5-bit, must reconstruct the value
763 regnum
, is_vec
= yield from get_pdecode_cr_in(self
.dec2
, name
)
764 sig
= getattr(fields
, name
)
766 # low 2 LSBs (CR field selector) remain same, CR num extended
767 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
768 val
= (val
& 0b11) |
(regnum
<<2)
771 sig
= getattr(fields
, name
.upper())
773 sig
= getattr(fields
, name
)
775 # these are all opcode fields involved in index-selection of CR,
776 # and need to do "standard" arithmetic. CR[BA+32] for example
777 # would, if using SelectableInt, only be 5-bit.
778 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
779 self
.namespace
[name
] = val
781 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
783 self
.namespace
['XER'] = self
.spr
['XER']
784 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
785 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
787 # add some SVSTATE convenience variables
789 srcstep
= self
.svstate
.srcstep
790 self
.namespace
['VL'] = vl
791 self
.namespace
['srcstep'] = srcstep
793 # sv.bc* need some extra fields
794 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
795 # blegh grab bits manually
796 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
797 bc_vlset
= (mode
& SVP64MODE
.BC_VLSET
) != 0
798 bc_vli
= (mode
& SVP64MODE
.BC_VLI
) != 0
799 bc_snz
= (mode
& SVP64MODE
.BC_SNZ
) != 0
800 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
801 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
802 sz
= yield self
.dec2
.rm_dec
.pred_sz
803 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
804 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
805 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
806 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
807 self
.namespace
['sz'] = SelectableInt(sz
, 1)
808 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
809 # use these to detect if the branch took place
810 self
.namespace
['ctr_ok'] = SelectableInt(0, 1)
811 self
.namespace
['cond_ok'] = SelectableInt(0, 1)
813 def handle_carry_(self
, inputs
, outputs
, already_done
):
814 inv_a
= yield self
.dec2
.e
.do
.invert_in
816 inputs
[0] = ~inputs
[0]
818 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
820 imm
= yield self
.dec2
.e
.do
.imm_data
.data
821 inputs
.append(SelectableInt(imm
, 64))
822 assert len(outputs
) >= 1
823 log("outputs", repr(outputs
))
824 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
830 log("gt input", x
, output
)
831 gt
= (gtu(x
, output
))
834 cy
= 1 if any(gts
) else 0
836 if not (1 & already_done
):
837 self
.spr
['XER'][XER_bits
['CA']] = cy
839 log("inputs", already_done
, inputs
)
841 # ARGH... different for OP_ADD... *sigh*...
842 op
= yield self
.dec2
.e
.do
.insn_type
843 if op
== MicrOp
.OP_ADD
.value
:
844 res32
= (output
.value
& (1 << 32)) != 0
845 a32
= (inputs
[0].value
& (1 << 32)) != 0
847 b32
= (inputs
[1].value
& (1 << 32)) != 0
850 cy32
= res32 ^ a32 ^ b32
851 log("CA32 ADD", cy32
)
855 log("input", x
, output
)
856 log(" x[32:64]", x
, x
[32:64])
857 log(" o[32:64]", output
, output
[32:64])
858 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
860 cy32
= 1 if any(gts
) else 0
861 log("CA32", cy32
, gts
)
862 if not (2 & already_done
):
863 self
.spr
['XER'][XER_bits
['CA32']] = cy32
865 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
866 if hasattr(self
.dec2
.e
.do
, "invert_in"):
867 inv_a
= yield self
.dec2
.e
.do
.invert_in
869 inputs
[0] = ~inputs
[0]
871 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
873 imm
= yield self
.dec2
.e
.do
.imm_data
.data
874 inputs
.append(SelectableInt(imm
, 64))
875 assert len(outputs
) >= 1
876 log("handle_overflow", inputs
, outputs
, div_overflow
)
877 if len(inputs
) < 2 and div_overflow
is None:
880 # div overflow is different: it's returned by the pseudo-code
881 # because it's more complex than can be done by analysing the output
882 if div_overflow
is not None:
883 ov
, ov32
= div_overflow
, div_overflow
884 # arithmetic overflow can be done by analysing the input and output
885 elif len(inputs
) >= 2:
889 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
890 output_sgn
= exts(output
.value
, output
.bits
) < 0
891 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
892 output_sgn
!= input_sgn
[0] else 0
895 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
896 output32_sgn
= exts(output
.value
, 32) < 0
897 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
898 output32_sgn
!= input32_sgn
[0] else 0
900 self
.spr
['XER'][XER_bits
['OV']] = ov
901 self
.spr
['XER'][XER_bits
['OV32']] = ov32
902 so
= self
.spr
['XER'][XER_bits
['SO']]
904 self
.spr
['XER'][XER_bits
['SO']] = so
906 def handle_comparison(self
, outputs
, cr_idx
=0):
908 assert isinstance(out
, SelectableInt
), \
909 "out zero not a SelectableInt %s" % repr(outputs
)
910 log("handle_comparison", out
.bits
, hex(out
.value
))
911 # TODO - XXX *processor* in 32-bit mode
912 # https://bugs.libre-soc.org/show_bug.cgi?id=424
914 # o32 = exts(out.value, 32)
915 # print ("handle_comparison exts 32 bit", hex(o32))
916 out
= exts(out
.value
, out
.bits
)
917 log("handle_comparison exts", hex(out
))
918 zero
= SelectableInt(out
== 0, 1)
919 positive
= SelectableInt(out
> 0, 1)
920 negative
= SelectableInt(out
< 0, 1)
921 SO
= self
.spr
['XER'][XER_bits
['SO']]
922 log("handle_comparison SO", SO
)
923 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
924 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
925 self
.crl
[cr_idx
].eq(cr_field
)
927 def set_pc(self
, pc_val
):
928 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
929 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
931 def get_next_insn(self
):
935 pc
= self
.pc
.CIA
.value
938 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
940 raise KeyError("no instruction at 0x%x" % pc
)
944 """set up one instruction
946 pc
, insn
= self
.get_next_insn()
947 yield from self
.setup_next_insn(pc
, insn
)
949 def setup_next_insn(self
, pc
, ins
):
950 """set up next instruction
953 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
954 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
956 yield self
.dec2
.sv_rm
.eq(0)
957 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
958 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
959 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
960 yield self
.dec2
.state
.pc
.eq(pc
)
961 if self
.svstate
is not None:
962 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
964 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
966 opcode
= yield self
.dec2
.dec
.opcode_in
967 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
968 pfx
.insn
.value
= opcode
969 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
970 log ("prefix test: opcode:", major
, bin(major
),
971 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
972 self
.is_svp64_mode
= ((major
== 0b000001) and
973 pfx
.insn
[7].value
== 0b1 and
974 pfx
.insn
[9].value
== 0b1)
975 self
.pc
.update_nia(self
.is_svp64_mode
)
976 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
977 self
.namespace
['NIA'] = self
.pc
.NIA
978 self
.namespace
['SVSTATE'] = self
.svstate
979 if not self
.is_svp64_mode
:
982 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
983 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
984 log (" svstate.vl", self
.svstate
.vl
)
985 log (" svstate.mvl", self
.svstate
.maxvl
)
986 sv_rm
= pfx
.rm
.asint(msb0
=True)
987 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
988 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
989 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
990 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
993 def execute_one(self
):
994 """execute one instruction
996 # get the disassembly code for this instruction
997 if self
.is_svp64_mode
:
998 if not self
.disassembly
:
999 code
= yield from self
.get_assembly_name()
1001 code
= self
.disassembly
[self
._pc
+4]
1002 log(" svp64 sim-execute", hex(self
._pc
), code
)
1004 if not self
.disassembly
:
1005 code
= yield from self
.get_assembly_name()
1007 code
= self
.disassembly
[self
._pc
]
1008 log("sim-execute", hex(self
._pc
), code
)
1009 opname
= code
.split(' ')[0]
1011 yield from self
.call(opname
) # execute the instruction
1012 except MemException
as e
: # check for memory errors
1013 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
1014 raise e
# ... re-raise
1015 # run a Trap but set DAR first
1016 print ("memory unaligned exception, DAR", e
.dar
)
1017 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1018 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1021 # don't use this except in special circumstances
1022 if not self
.respect_pc
:
1025 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1027 def get_assembly_name(self
):
1028 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1029 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1030 dec_insn
= yield self
.dec2
.e
.do
.insn
1031 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1032 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1033 int_op
= yield self
.dec2
.dec
.op
.internal_op
1034 log("get assembly name asmcode", asmcode
, int_op
,
1035 hex(dec_insn
), bin(insn_1_11
))
1036 asmop
= insns
.get(asmcode
, None)
1038 # sigh reconstruct the assembly instruction name
1039 if hasattr(self
.dec2
.e
.do
, "oe"):
1040 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1041 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1045 if hasattr(self
.dec2
.e
.do
, "rc"):
1046 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1047 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1051 # grrrr have to special-case MUL op (see DecodeOE)
1052 log("ov %d en %d rc %d en %d op %d" %
1053 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1054 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1059 if not asmop
.endswith("."): # don't add "." to "andis."
1062 if hasattr(self
.dec2
.e
.do
, "lk"):
1063 lk
= yield self
.dec2
.e
.do
.lk
1066 log("int_op", int_op
)
1067 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1068 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1072 spr_msb
= yield from self
.get_spr_msb()
1073 if int_op
== MicrOp
.OP_MFCR
.value
:
1078 # XXX TODO: for whatever weird reason this doesn't work
1079 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1080 if int_op
== MicrOp
.OP_MTCRF
.value
:
1087 def get_remap_indices(self
):
1088 """WARNING, this function stores remap_idxs and remap_loopends
1089 in the class for later use. this to avoid problems with yield
1091 # go through all iterators in lock-step, advance to next remap_idx
1092 srcstep
, dststep
= self
.get_src_dststeps()
1093 # get four SVSHAPEs. here we are hard-coding
1094 SVSHAPE0
= self
.spr
['SVSHAPE0']
1095 SVSHAPE1
= self
.spr
['SVSHAPE1']
1096 SVSHAPE2
= self
.spr
['SVSHAPE2']
1097 SVSHAPE3
= self
.spr
['SVSHAPE3']
1098 # set up the iterators
1099 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1100 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1101 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1102 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1105 self
.remap_loopends
= [0] * 4
1106 self
.remap_idxs
= [0, 1, 2, 3]
1108 for i
, (shape
, remap
) in enumerate(remaps
):
1109 # zero is "disabled"
1110 if shape
.value
== 0x0:
1111 self
.remap_idxs
[i
] = 0
1112 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1113 step
= dststep
if (i
in [3, 4]) else srcstep
1114 # this is terrible. O(N^2) looking for the match. but hey.
1115 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1118 self
.remap_idxs
[i
] = remap_idx
1119 self
.remap_loopends
[i
] = loopends
1120 dbg
.append((i
, step
, remap_idx
, loopends
))
1121 for (i
, step
, remap_idx
, loopends
) in dbg
:
1122 log ("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1125 def get_spr_msb(self
):
1126 dec_insn
= yield self
.dec2
.e
.do
.insn
1127 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1129 def call(self
, name
):
1130 """call(opcode) - the primary execution point for instructions
1132 self
.last_st_addr
= None # reset the last known store address
1133 self
.last_ld_addr
= None # etc.
1135 ins_name
= name
.strip() # remove spaces if not already done so
1137 log("halted - not executing", ins_name
)
1140 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1141 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1142 asmop
= yield from self
.get_assembly_name()
1143 log("call", ins_name
, asmop
)
1146 int_op
= yield self
.dec2
.dec
.op
.internal_op
1147 spr_msb
= yield from self
.get_spr_msb()
1149 instr_is_privileged
= False
1150 if int_op
in [MicrOp
.OP_ATTN
.value
,
1151 MicrOp
.OP_MFMSR
.value
,
1152 MicrOp
.OP_MTMSR
.value
,
1153 MicrOp
.OP_MTMSRD
.value
,
1155 MicrOp
.OP_RFID
.value
]:
1156 instr_is_privileged
= True
1157 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1158 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1159 instr_is_privileged
= True
1161 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1163 # check MSR priv bit and whether op is privileged: if so, throw trap
1164 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1165 self
.call_trap(0x700, PIb
.PRIV
)
1168 # check halted condition
1169 if ins_name
== 'attn':
1173 # check illegal instruction
1175 if ins_name
not in ['mtcrf', 'mtocrf']:
1176 illegal
= ins_name
!= asmop
1178 # sigh deal with setvl not being supported by binutils (.long)
1179 if asmop
.startswith('setvl'):
1183 # and svstep not being supported by binutils (.long)
1184 if asmop
.startswith('svstep'):
1188 # and svremap not being supported by binutils (.long)
1189 if asmop
.startswith('svremap'):
1191 ins_name
= 'svremap'
1193 # and svshape not being supported by binutils (.long)
1194 if asmop
.startswith('svshape'):
1196 ins_name
= 'svshape'
1199 if asmop
== 'fsins':
1202 if asmop
== 'fcoss':
1206 # sigh also deal with ffmadds not being supported by binutils (.long)
1207 if asmop
== 'ffmadds':
1209 ins_name
= 'ffmadds'
1211 # and fdmadds not being supported by binutils (.long)
1212 if asmop
== 'fdmadds':
1214 ins_name
= 'fdmadds'
1216 # and ffadds not being supported by binutils (.long)
1217 if asmop
== 'ffadds':
1221 # branch-conditional redirects to sv.bc
1222 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1223 ins_name
= 'sv.%s' % ins_name
1225 log(" post-processed name", ins_name
, asmop
)
1227 # illegal instructions call TRAP at 0x700
1229 print("illegal", ins_name
, asmop
)
1230 self
.call_trap(0x700, PIb
.ILLEG
)
1231 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1232 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1235 # this is for setvl "Vertical" mode: if set true,
1236 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1237 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1238 self
.allow_next_step_inc
= False
1239 self
.svstate_next_mode
= 0
1241 # nop has to be supported, we could let the actual op calculate
1242 # but PowerDecoder has a pattern for nop
1243 if ins_name
is 'nop':
1244 self
.update_pc_next()
1247 # look up instruction in ISA.instrs, prepare namespace
1248 info
= self
.instrs
[ins_name
]
1249 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
)
1251 # preserve order of register names
1252 input_names
= create_args(list(info
.read_regs
) +
1253 list(info
.uninit_regs
))
1254 log("input names", input_names
)
1256 # get SVP64 entry for the current instruction
1257 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1258 if sv_rm
is not None:
1259 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1261 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1262 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1264 # see if srcstep/dststep need skipping over masked-out predicate bits
1265 if (self
.is_svp64_mode
or ins_name
== 'setvl' or
1266 ins_name
in ['svremap', 'svstate']):
1267 yield from self
.svstate_pre_inc()
1268 if self
.is_svp64_mode
:
1269 pre
= yield from self
.update_new_svstate_steps()
1271 self
.svp64_reset_loop()
1273 self
.update_pc_next()
1275 srcstep
, dststep
= self
.get_src_dststeps()
1276 pred_dst_zero
= self
.pred_dst_zero
1277 pred_src_zero
= self
.pred_src_zero
1278 vl
= self
.svstate
.vl
1280 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1281 if self
.is_svp64_mode
and vl
== 0:
1282 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1283 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1284 self
.namespace
['NIA'])
1287 # for when SVREMAP is active, using pre-arranged schedule.
1288 # note: modifying PowerDecoder2 needs to "settle"
1289 remap_en
= self
.svstate
.SVme
1290 persist
= self
.svstate
.RMpst
1291 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1292 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1294 if persist
or self
.last_op_svshape
:
1295 remaps
= self
.get_remap_indices()
1296 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1297 # just some convenient debug info
1299 sname
= 'SVSHAPE%d' % i
1300 shape
= self
.spr
[sname
]
1301 log (sname
, bin(shape
.value
))
1302 log (" lims", shape
.lims
)
1303 log (" mode", shape
.mode
)
1304 log (" skip", shape
.skip
)
1306 # set up the list of steps to remap
1307 mi0
= self
.svstate
.mi0
1308 mi1
= self
.svstate
.mi1
1309 mi2
= self
.svstate
.mi2
1310 mo0
= self
.svstate
.mo0
1311 mo1
= self
.svstate
.mo1
1312 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1313 (self
.dec2
.in2_step
, mi1
), # RB
1314 (self
.dec2
.in3_step
, mi2
), # RC
1315 (self
.dec2
.o_step
, mo0
), # RT
1316 (self
.dec2
.o2_step
, mo1
), # EA
1318 remap_idxs
= self
.remap_idxs
1320 # now cross-index the required SHAPE for each of 3-in 2-out regs
1321 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1322 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1323 (shape
, remap
) = remaps
[shape_idx
]
1324 remap_idx
= remap_idxs
[shape_idx
]
1325 # zero is "disabled"
1326 if shape
.value
== 0x0:
1328 # now set the actual requested step to the current index
1329 yield dstep
.eq(remap_idx
)
1331 # debug printout info
1332 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
,
1335 log ("shape remap", x
)
1336 # after that, settle down (combinatorial) to let Vector reg numbers
1337 # work themselves out
1339 remap_active
= yield self
.dec2
.remap_active
1340 log ("remap active", bin(remap_active
))
1342 # main input registers (RT, RA ...)
1344 for name
in input_names
:
1345 # using PowerDecoder2, first, find the decoder index.
1346 # (mapping name RA RB RC RS to in1, in2, in3)
1347 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1349 # doing this is not part of svp64, it's because output
1350 # registers, to be modified, need to be in the namespace.
1351 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1353 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1356 # in case getting the register number is needed, _RA, _RB
1357 regname
= "_" + name
1358 self
.namespace
[regname
] = regnum
1359 if not self
.is_svp64_mode
or not pred_src_zero
:
1360 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1362 reg_val
= self
.fpr(regnum
)
1363 elif name
is not None:
1364 reg_val
= self
.gpr(regnum
)
1366 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1368 inputs
.append(reg_val
)
1369 # arrrrgh, awful hack, to get _RT into namespace
1370 if ins_name
in ['setvl', 'svstep']:
1372 RT
= yield self
.dec2
.dec
.RT
1373 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1375 self
.namespace
["RT"] = SelectableInt(0, 5)
1376 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, "RT")
1377 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
1379 # in SVP64 mode for LD/ST work out immediate
1380 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1381 # use info.form to detect
1382 replace_d
= False # update / replace constant in pseudocode
1383 if self
.is_svp64_mode
:
1384 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1385 # shift mode reads SVD (or SVDS - TODO)
1386 # *BUT*... because this is "overloading" of LD operations,
1387 # it gets *STORED* into D (or DS, TODO)
1388 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1389 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1390 imm
= exts(imm
, 11) # sign-extend to integer
1391 log ("shift SVD", imm
)
1394 if info
.form
== 'DS':
1395 # DS-Form, multiply by 4 then knock 2 bits off after
1396 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
1398 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1399 imm
= exts(imm
, 16) # sign-extend to integer
1400 # get the right step. LD is from srcstep, ST is dststep
1401 op
= yield self
.dec2
.e
.do
.insn_type
1403 if op
== MicrOp
.OP_LOAD
.value
:
1405 offsmul
= yield self
.dec2
.in1_step
1406 log("D-field REMAP src", imm
, offsmul
)
1409 log("D-field src", imm
, offsmul
)
1410 elif op
== MicrOp
.OP_STORE
.value
:
1411 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1413 log("D-field dst", imm
, offsmul
)
1414 # bit-reverse mode, rev already done through get_src_dst_steps()
1415 if ldstmode
== SVP64LDSTmode
.SHIFT
.value
:
1416 # manually look up RC, sigh
1417 RC
= yield self
.dec2
.dec
.RC
[0:5]
1419 log ("LD-SHIFT:", "VL", vl
,
1420 "RC", RC
.value
, "imm", imm
,
1421 "offs", bin(offsmul
),
1423 imm
= SelectableInt((imm
* offsmul
) << RC
.value
, 32)
1424 # Unit-Strided LD/ST adds offset*width to immediate
1425 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1426 ldst_len
= yield self
.dec2
.e
.do
.data_len
1427 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1429 # Element-strided multiplies the immediate by element step
1430 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1431 imm
= SelectableInt(imm
* offsmul
, 32)
1434 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1435 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1436 log("LDSTmode", SVP64LDSTmode(ldstmode
),
1437 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1438 # new replacement D... errr.. DS
1440 if info
.form
== 'DS':
1441 # TODO: assert 2 LSBs are zero?
1442 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
1443 imm
.value
= imm
.value
>> 2
1444 self
.namespace
['DS'] = imm
1446 self
.namespace
['D'] = imm
1448 # "special" registers
1449 for special
in info
.special_regs
:
1450 if special
in special_sprs
:
1451 inputs
.append(self
.spr
[special
])
1453 inputs
.append(self
.namespace
[special
])
1455 # clear trap (trap) NIA
1456 self
.trap_nia
= None
1458 # execute actual instruction here (finally)
1459 log("inputs", inputs
)
1460 results
= info
.func(self
, *inputs
)
1461 log("results", results
)
1463 # "inject" decorator takes namespace from function locals: we need to
1464 # overwrite NIA being overwritten (sigh)
1465 if self
.trap_nia
is not None:
1466 self
.namespace
['NIA'] = self
.trap_nia
1468 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1470 # check if op was a LD/ST so that debugging can check the
1472 if int_op
in [MicrOp
.OP_STORE
.value
,
1474 self
.last_st_addr
= self
.mem
.last_st_addr
1475 if int_op
in [MicrOp
.OP_LOAD
.value
,
1477 self
.last_ld_addr
= self
.mem
.last_ld_addr
1478 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1479 self
.last_st_addr
, self
.last_ld_addr
)
1481 # detect if CA/CA32 already in outputs (sra*, basically)
1484 output_names
= create_args(info
.write_regs
)
1485 for name
in output_names
:
1491 log("carry already done?", bin(already_done
))
1492 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1493 carry_en
= yield self
.dec2
.e
.do
.output_carry
1497 yield from self
.handle_carry_(inputs
, results
, already_done
)
1499 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1500 # detect if overflow was in return result
1503 for name
, output
in zip(output_names
, results
):
1504 if name
== 'overflow':
1507 if hasattr(self
.dec2
.e
.do
, "oe"):
1508 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1509 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1513 log("internal overflow", overflow
, ov_en
, ov_ok
)
1515 yield from self
.handle_overflow(inputs
, results
, overflow
)
1517 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1519 if not self
.is_svp64_mode
or not pred_dst_zero
:
1520 if hasattr(self
.dec2
.e
.do
, "rc"):
1521 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1522 if rc_en
and ins_name
not in ['svstep']:
1523 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1524 self
.handle_comparison(results
, regnum
)
1526 # any modified return results?
1528 for name
, output
in zip(output_names
, results
):
1529 if name
== 'overflow': # ignore, done already (above)
1531 if isinstance(output
, int):
1532 output
= SelectableInt(output
, 256)
1533 if name
in ['CA', 'CA32']:
1535 log("writing %s to XER" % name
, output
)
1536 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1538 log("NOT writing %s to XER" % name
, output
)
1539 elif name
in info
.special_regs
:
1540 log('writing special %s' % name
, output
, special_sprs
)
1541 if name
in special_sprs
:
1542 self
.spr
[name
] = output
1544 self
.namespace
[name
].eq(output
)
1546 log('msr written', hex(self
.msr
.value
))
1548 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1551 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1554 # temporary hack for not having 2nd output
1555 regnum
= yield getattr(self
.decoder
, name
)
1557 if self
.is_svp64_mode
and pred_dst_zero
:
1558 log('zeroing reg %d %s' % (regnum
, str(output
)),
1560 output
= SelectableInt(0, 256)
1566 log('writing %s %s %s' % (ftype
, regnum
, str(output
)),
1568 if output
.bits
> 64:
1569 output
= SelectableInt(output
.value
, 64)
1571 self
.fpr
[regnum
] = output
1573 self
.gpr
[regnum
] = output
1575 # check if it is the SVSTATE.src/dest step that needs incrementing
1576 # this is our Sub-Program-Counter loop from 0 to VL-1
1579 if self
.allow_next_step_inc
:
1580 log("SVSTATE_NEXT: inc requested, mode",
1581 self
.svstate_next_mode
, self
.allow_next_step_inc
)
1582 yield from self
.svstate_pre_inc()
1583 pre
= yield from self
.update_new_svstate_steps()
1585 # reset at end of loop including exit Vertical Mode
1586 log ("SVSTATE_NEXT: end of loop, reset")
1587 self
.svp64_reset_loop()
1588 self
.svstate
.vfirst
= 0
1591 results
= [SelectableInt(0, 64)]
1592 self
.handle_comparison(results
) # CR0
1594 if self
.allow_next_step_inc
== 2:
1595 log ("SVSTATE_NEXT: read")
1596 yield from self
.svstate_post_inc(ins_name
)
1598 log ("SVSTATE_NEXT: post-inc")
1599 # use actual src/dst-step here to check end, do NOT
1600 # use bit-reversed version
1601 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1602 remaps
= self
.get_remap_indices()
1603 remap_idxs
= self
.remap_idxs
1604 vl
= self
.svstate
.vl
1605 end_src
= srcstep
== vl
-1
1606 end_dst
= dststep
== vl
-1
1607 if self
.allow_next_step_inc
!= 2:
1609 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1611 self
.svstate
.dststep
+= SelectableInt(1, 7)
1612 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1613 # set CR0 (if Rc=1) based on end
1615 srcstep
= self
.svstate
.srcstep
1616 dststep
= self
.svstate
.srcstep
1617 endtest
= 1 if (end_src
or end_dst
) else 0
1618 #results = [SelectableInt(endtest, 64)]
1619 #self.handle_comparison(results) # CR0
1621 # see if svstep was requested, if so, which SVSTATE
1623 if self
.svstate_next_mode
> 0:
1624 shape_idx
= self
.svstate_next_mode
.value
-1
1625 endings
= self
.remap_loopends
[shape_idx
]
1626 cr_field
= SelectableInt((~endings
)<<1 | endtest
, 4)
1627 print ("svstep Rc=1, CR0", cr_field
)
1628 self
.crl
[0].eq(cr_field
) # CR0
1629 if end_src
or end_dst
:
1630 # reset at end of loop including exit Vertical Mode
1631 log ("SVSTATE_NEXT: after increments, reset")
1632 self
.svp64_reset_loop()
1633 self
.svstate
.vfirst
= 0
1635 elif self
.is_svp64_mode
:
1636 yield from self
.svstate_post_inc(ins_name
)
1638 # XXX only in non-SVP64 mode!
1639 # record state of whether the current operation was an svshape,
1640 # to be able to know if it should apply in the next instruction.
1641 # also (if going to use this instruction) should disable ability
1642 # to interrupt in between. sigh.
1643 self
.last_op_svshape
= asmop
== 'svremap'
1645 self
.update_pc_next()
1647 def SVSTATE_NEXT(self
, mode
, submode
):
1648 """explicitly moves srcstep/dststep on to next element, for
1649 "Vertical-First" mode. this function is called from
1650 setvl pseudo-code, as a pseudo-op "svstep"
1652 WARNING: this function uses information that was created EARLIER
1653 due to it being in the middle of a yield, but this function is
1654 *NOT* called from yield (it's called from compiled pseudocode).
1656 self
.allow_next_step_inc
= submode
.value
+ 1
1657 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
1658 self
.svstate_next_mode
= mode
1659 if self
.svstate_next_mode
> 0:
1660 shape_idx
= self
.svstate_next_mode
.value
-1
1661 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1662 return SelectableInt(0, 7)
1664 def svstate_pre_inc(self
):
1665 """check if srcstep/dststep need to skip over masked-out predicate bits
1667 # get SVSTATE VL (oh and print out some debug stuff)
1668 vl
= self
.svstate
.vl
1669 srcstep
= self
.svstate
.srcstep
1670 dststep
= self
.svstate
.dststep
1671 sv_a_nz
= yield self
.dec2
.sv_a_nz
1672 fft_mode
= yield self
.dec2
.use_svp64_fft
1673 in1
= yield self
.dec2
.e
.read_reg1
.data
1674 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft, svp64",
1675 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
,
1678 # get predicate mask
1679 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1681 pmode
= yield self
.dec2
.rm_dec
.predmode
1682 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1683 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1684 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1685 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1686 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1687 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1688 if pmode
== SVP64PredMode
.INT
.value
:
1689 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1690 if sv_ptype
== SVPtype
.P2
.value
:
1691 srcmask
= get_predint(self
.gpr
, srcpred
)
1692 elif pmode
== SVP64PredMode
.CR
.value
:
1693 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1694 if sv_ptype
== SVPtype
.P2
.value
:
1695 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1696 log (" pmode", pmode
)
1697 log (" reverse", reverse_gear
)
1698 log (" ptype", sv_ptype
)
1699 log (" srcpred", bin(srcpred
))
1700 log (" dstpred", bin(dstpred
))
1701 log (" srcmask", bin(srcmask
))
1702 log (" dstmask", bin(dstmask
))
1703 log (" pred_sz", bin(pred_src_zero
))
1704 log (" pred_dz", bin(pred_dst_zero
))
1706 # okaaay, so here we simply advance srcstep (TODO dststep)
1707 # until the predicate mask has a "1" bit... or we run out of VL
1708 # let srcstep==VL be the indicator to move to next instruction
1709 if not pred_src_zero
:
1710 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1711 log (" skip", bin(1<<srcstep
))
1714 if not pred_dst_zero
:
1715 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1716 log (" skip", bin(1<<dststep
))
1719 # now work out if the relevant mask bits require zeroing
1721 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1723 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1725 # store new srcstep / dststep
1726 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1727 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1728 log (" new srcstep", srcstep
)
1729 log (" new dststep", dststep
)
1731 def get_src_dststeps(self
):
1732 """gets srcstep and dststep
1734 return self
.new_srcstep
, self
.new_dststep
1736 def update_new_svstate_steps(self
):
1737 # note, do not get the bit-reversed srcstep here!
1738 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1740 # update SVSTATE with new srcstep
1741 self
.svstate
.srcstep
= srcstep
1742 self
.svstate
.dststep
= dststep
1743 self
.namespace
['SVSTATE'] = self
.svstate
1744 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1745 yield Settle() # let decoder update
1746 srcstep
= self
.svstate
.srcstep
1747 dststep
= self
.svstate
.dststep
1748 vl
= self
.svstate
.vl
1749 log (" srcstep", srcstep
)
1750 log (" dststep", dststep
)
1753 # check if end reached (we let srcstep overrun, above)
1754 # nothing needs doing (TODO zeroing): just do next instruction
1755 return srcstep
== vl
or dststep
== vl
1757 def svstate_post_inc(self
, insn_name
, vf
=0):
1758 # check if SV "Vertical First" mode is enabled
1759 vfirst
= self
.svstate
.vfirst
1760 log (" SV Vertical First", vf
, vfirst
)
1761 if not vf
and vfirst
== 1:
1765 # check if it is the SVSTATE.src/dest step that needs incrementing
1766 # this is our Sub-Program-Counter loop from 0 to VL-1
1767 # XXX twin predication TODO
1768 vl
= self
.svstate
.vl
1769 mvl
= self
.svstate
.maxvl
1770 srcstep
= self
.svstate
.srcstep
1771 dststep
= self
.svstate
.dststep
1772 rm_mode
= yield self
.dec2
.rm_dec
.mode
1773 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1774 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1775 out_vec
= not (yield self
.dec2
.no_out_vec
)
1776 in_vec
= not (yield self
.dec2
.no_in_vec
)
1777 log (" svstate.vl", vl
)
1778 log (" svstate.mvl", mvl
)
1779 log (" svstate.srcstep", srcstep
)
1780 log (" svstate.dststep", dststep
)
1781 log (" mode", rm_mode
)
1782 log (" reverse", reverse_gear
)
1783 log (" out_vec", out_vec
)
1784 log (" in_vec", in_vec
)
1785 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1786 # check if srcstep needs incrementing by one, stop PC advancing
1787 # svp64 loop can end early if the dest is scalar for single-pred
1788 # but for 2-pred both src/dest have to be checked.
1789 # XXX this might not be true! it may just be LD/ST
1790 if sv_ptype
== SVPtype
.P2
.value
:
1791 svp64_is_vector
= (out_vec
or in_vec
)
1793 svp64_is_vector
= out_vec
1794 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1795 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1796 self
.svstate
.dststep
+= SelectableInt(1, 7)
1797 self
.namespace
['SVSTATE'] = self
.svstate
1798 # check if this was an sv.bc* and if so did it succeed
1799 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1800 ctr_ok
= self
.namespace
['ctr_ok']
1801 cond_ok
= self
.namespace
['cond_ok']
1802 log("branch ctr/cond", ctr_ok
, cond_ok
)
1803 if ctr_ok
.value
and cond_ok
.value
:
1804 self
.svp64_reset_loop()
1805 self
.update_pc_next()
1807 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1808 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1809 # this way we keep repeating the same instruction (with new steps)
1810 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1811 self
.namespace
['NIA'] = self
.pc
.NIA
1812 log("end of sub-pc call", self
.namespace
['CIA'],
1813 self
.namespace
['NIA'])
1814 return False # DO NOT allow PC update whilst Sub-PC loop running
1816 # reset loop to zero and update NIA
1817 self
.svp64_reset_loop()
1822 def update_pc_next(self
):
1823 # UPDATE program counter
1824 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1825 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1826 log("end of call", self
.namespace
['CIA'],
1827 self
.namespace
['NIA'],
1828 self
.namespace
['SVSTATE'])
1830 def svp64_reset_loop(self
):
1831 self
.svstate
.srcstep
= 0
1832 self
.svstate
.dststep
= 0
1833 log (" svstate.srcstep loop end (PC to update)")
1834 self
.namespace
['SVSTATE'] = self
.svstate
1836 def update_nia(self
):
1837 self
.pc
.update_nia(self
.is_svp64_mode
)
1838 self
.namespace
['NIA'] = self
.pc
.NIA
1842 """Decorator factory.
1844 this decorator will "inject" variables into the function's namespace,
1845 from the *dictionary* in self.namespace. it therefore becomes possible
1846 to make it look like a whole stack of variables which would otherwise
1847 need "self." inserted in front of them (*and* for those variables to be
1848 added to the instance) "appear" in the function.
1850 "self.namespace['SI']" for example becomes accessible as just "SI" but
1851 *only* inside the function, when decorated.
1853 def variable_injector(func
):
1855 def decorator(*args
, **kwargs
):
1857 func_globals
= func
.__globals
__ # Python 2.6+
1858 except AttributeError:
1859 func_globals
= func
.func_globals
# Earlier versions.
1861 context
= args
[0].namespace
# variables to be injected
1862 saved_values
= func_globals
.copy() # Shallow copy of dict.
1863 log("globals before", context
.keys())
1864 func_globals
.update(context
)
1865 result
= func(*args
, **kwargs
)
1866 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1867 log("args[0]", args
[0].namespace
['CIA'],
1868 args
[0].namespace
['NIA'],
1869 args
[0].namespace
['SVSTATE'])
1870 args
[0].namespace
= func_globals
1871 if 'cond_ok' in args
[0].namespace
:
1872 log("args[0] cond_ok ctr_ok",
1873 args
[0].namespace
['cond_ok'],
1874 args
[0].namespace
['ctr_ok'])
1875 #exec (func.__code__, func_globals)
1878 # func_globals = saved_values # Undo changes.
1884 return variable_injector