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
,
25 SVP64RMMode
, SVP64PredMode
,
26 SVP64PredInt
, SVP64PredCR
)
28 from openpower
.decoder
.power_enums
import SVPtype
30 from openpower
.decoder
.helpers
import exts
, gtu
, ltu
, undefined
31 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
32 from openpower
.consts
import SVP64CROffs
33 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
35 from openpower
.decoder
.isa
.radixmmu
import RADIX
36 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
38 from collections
import namedtuple
42 instruction_info
= namedtuple('instruction_info',
43 'func read_regs uninit_regs write_regs ' +
44 'special_regs op_fields form asmregs')
55 # TODO (lkcl): adjust other registers that should be in a particular order
56 # probably CA, CA32, and CR
78 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
81 def create_args(reglist
, extra
=None):
82 retval
= list(OrderedSet(reglist
))
83 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
[reg
])
85 return [extra
] + retval
91 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
94 self
.isacaller
= isacaller
95 self
.svstate
= svstate
97 self
[i
] = SelectableInt(regfile
[i
], 64)
99 def __call__(self
, ridx
):
102 def set_form(self
, form
):
105 def getz(self
, rnum
):
106 # rnum = rnum.value # only SelectableInt allowed
107 print("GPR getzero?", rnum
)
109 return SelectableInt(0, 64)
112 def _get_regnum(self
, attr
):
113 getform
= self
.sd
.sigforms
[self
.form
]
114 rnum
= getattr(getform
, attr
)
117 def ___getitem__(self
, attr
):
118 """ XXX currently not used
120 rnum
= self
._get
_regnum
(attr
)
121 offs
= self
.svstate
.srcstep
122 print("GPR getitem", attr
, rnum
, "srcoffs", offs
)
123 return self
.regfile
[rnum
]
126 for i
in range(0, len(self
), 8):
129 s
.append("%08x" % self
[i
+j
].value
)
131 print("reg", "%2d" % i
, s
)
135 def __init__(self
, dec2
, initial_sprs
={}):
138 for key
, v
in initial_sprs
.items():
139 if isinstance(key
, SelectableInt
):
141 key
= special_sprs
.get(key
, key
)
142 if isinstance(key
, int):
145 info
= spr_byname
[key
]
146 if not isinstance(v
, SelectableInt
):
147 v
= SelectableInt(v
, info
.length
)
150 def __getitem__(self
, key
):
151 print("get spr", key
)
152 print("dict", self
.items())
153 # if key in special_sprs get the special spr, otherwise return key
154 if isinstance(key
, SelectableInt
):
156 if isinstance(key
, int):
157 key
= spr_dict
[key
].SPR
158 key
= special_sprs
.get(key
, key
)
159 if key
== 'HSRR0': # HACK!
161 if key
== 'HSRR1': # HACK!
164 res
= dict.__getitem
__(self
, key
)
166 if isinstance(key
, int):
169 info
= spr_byname
[key
]
170 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
171 res
= dict.__getitem
__(self
, key
)
172 print("spr returning", key
, res
)
175 def __setitem__(self
, key
, value
):
176 if isinstance(key
, SelectableInt
):
178 if isinstance(key
, int):
179 key
= spr_dict
[key
].SPR
180 print("spr key", key
)
181 key
= special_sprs
.get(key
, key
)
182 if key
== 'HSRR0': # HACK!
183 self
.__setitem
__('SRR0', value
)
184 if key
== 'HSRR1': # HACK!
185 self
.__setitem
__('SRR1', value
)
186 print("setting spr", key
, value
)
187 dict.__setitem
__(self
, key
, value
)
189 def __call__(self
, ridx
):
194 def __init__(self
, pc_init
=0):
195 self
.CIA
= SelectableInt(pc_init
, 64)
196 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
198 def update_nia(self
, is_svp64
):
199 increment
= 8 if is_svp64
else 4
200 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
202 def update(self
, namespace
, is_svp64
):
203 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
205 self
.CIA
= namespace
['NIA'].narrow(64)
206 self
.update_nia(is_svp64
)
207 namespace
['CIA'] = self
.CIA
208 namespace
['NIA'] = self
.NIA
211 # Simple-V: see https://libre-soc.org/openpower/sv
213 def __init__(self
, init
=0):
214 self
.spr
= SelectableInt(init
, 32)
215 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
216 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
217 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
218 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
219 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
220 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
221 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
226 def __init__(self
, init
=0):
227 self
.spr
= SelectableInt(init
, 24)
228 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
229 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
230 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
231 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
232 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
233 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
234 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
235 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
236 # these cover the same extra field, split into parts as EXTRA2
237 self
.extra2
= list(range(4))
238 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
239 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
240 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
241 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
242 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
243 # and here as well, but EXTRA3
244 self
.extra3
= list(range(3))
245 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
246 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
247 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
250 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
251 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
252 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
253 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
254 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
255 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
256 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
257 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
258 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
261 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
262 class SVP64PrefixFields
:
264 self
.insn
= SelectableInt(0, 32)
265 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
266 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
267 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
268 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
269 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
272 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
273 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
274 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
278 # See PowerISA Version 3.0 B Book 1
279 # Section 2.3.1 Condition Register pages 30 - 31
281 LT
= FL
= 0 # negative, less than, floating-point less than
282 GT
= FG
= 1 # positive, greater than, floating-point greater than
283 EQ
= FE
= 2 # equal, floating-point equal
284 SO
= FU
= 3 # summary overflow, floating-point unordered
286 def __init__(self
, init
=0):
287 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
288 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
289 self
.cr
= SelectableInt(init
, 64) # underlying reg
290 # field-selectable versions of Condition Register TODO check bitranges?
293 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
294 _cr
= FieldSelectableInt(self
.cr
, bits
)
297 # decode SVP64 predicate integer to reg number and invert
298 def get_predint(gpr
, mask
):
301 print ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
302 if mask
== SVP64PredInt
.ALWAYS
.value
:
303 return 0xffff_ffff_ffff_ffff
304 if mask
== SVP64PredInt
.R3_UNARY
.value
:
305 return 1 << (gpr(3).value
& 0b111111)
306 if mask
== SVP64PredInt
.R3
.value
:
308 if mask
== SVP64PredInt
.R3_N
.value
:
310 if mask
== SVP64PredInt
.R10
.value
:
312 if mask
== SVP64PredInt
.R10_N
.value
:
313 return ~
gpr(10).value
314 if mask
== SVP64PredInt
.R30
.value
:
316 if mask
== SVP64PredInt
.R30_N
.value
:
317 return ~
gpr(30).value
319 # decode SVP64 predicate CR to reg number and invert status
320 def _get_predcr(mask
):
321 if mask
== SVP64PredCR
.LT
.value
:
323 if mask
== SVP64PredCR
.GE
.value
:
325 if mask
== SVP64PredCR
.GT
.value
:
327 if mask
== SVP64PredCR
.LE
.value
:
329 if mask
== SVP64PredCR
.EQ
.value
:
331 if mask
== SVP64PredCR
.NE
.value
:
333 if mask
== SVP64PredCR
.SO
.value
:
335 if mask
== SVP64PredCR
.NS
.value
:
338 # read individual CR fields (0..VL-1), extract the required bit
339 # and construct the mask
340 def get_predcr(crl
, mask
, vl
):
341 idx
, noninv
= _get_predcr(mask
)
344 cr
= crl
[i
+SVP64CROffs
.CRPred
]
345 if cr
[idx
].value
== noninv
:
350 def get_pdecode_idx_in(dec2
, name
):
352 in1_sel
= yield op
.in1_sel
353 in2_sel
= yield op
.in2_sel
354 in3_sel
= yield op
.in3_sel
355 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
356 in1
= yield dec2
.e
.read_reg1
.data
357 in2
= yield dec2
.e
.read_reg2
.data
358 in3
= yield dec2
.e
.read_reg3
.data
359 in1_isvec
= yield dec2
.in1_isvec
360 in2_isvec
= yield dec2
.in2_isvec
361 in3_isvec
= yield dec2
.in3_isvec
362 print ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
364 print ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
366 print ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
368 # identify which regnames map to in1/2/3
370 if (in1_sel
== In1Sel
.RA
.value
or
371 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
372 return in1
, in1_isvec
373 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
374 return in1
, in1_isvec
376 if in2_sel
== In2Sel
.RB
.value
:
377 return in2
, in2_isvec
378 if in3_sel
== In3Sel
.RB
.value
:
379 return in3
, in3_isvec
380 # XXX TODO, RC doesn't exist yet!
382 assert False, "RC does not exist yet"
384 if in1_sel
== In1Sel
.RS
.value
:
385 return in1
, in1_isvec
386 if in2_sel
== In2Sel
.RS
.value
:
387 return in2
, in2_isvec
388 if in3_sel
== In3Sel
.RS
.value
:
389 return in3
, in3_isvec
391 if in1_sel
== In1Sel
.FRA
.value
:
392 return in1
, in1_isvec
394 if in2_sel
== In2Sel
.FRB
.value
:
395 return in2
, in2_isvec
397 if in3_sel
== In3Sel
.FRC
.value
:
398 return in3
, in3_isvec
400 if in1_sel
== In1Sel
.FRS
.value
:
401 return in1
, in1_isvec
402 if in2_sel
== In2Sel
.FRS
.value
:
403 return in2
, in2_isvec
407 def get_pdecode_cr_out(dec2
, name
):
409 out_sel
= yield op
.cr_out
410 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
411 sv_cr_out
= yield op
.sv_cr_out
412 spec
= yield dec2
.crout_svdec
.spec
413 sv_override
= yield dec2
.dec_cr_out
.sv_override
414 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
415 out
= yield dec2
.e
.write_cr
.data
416 o_isvec
= yield dec2
.o_isvec
417 print ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
418 print (" sv_cr_out", sv_cr_out
)
419 print (" cr_bf", out_bitfield
)
420 print (" spec", spec
)
421 print (" override", sv_override
)
422 # identify which regnames map to out / o2
424 if out_sel
== CROutSel
.CR0
.value
:
426 print ("get_pdecode_idx_out not found", name
)
430 def get_pdecode_idx_out(dec2
, name
):
432 out_sel
= yield op
.out_sel
433 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
434 out
= yield dec2
.e
.write_reg
.data
435 o_isvec
= yield dec2
.o_isvec
436 # identify which regnames map to out / o2
438 print ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
439 if out_sel
== OutSel
.RA
.value
:
442 print ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
443 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
)
444 if out_sel
== OutSel
.RT
.value
:
447 print ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
448 if out_sel
== OutSel
.FRA
.value
:
451 print ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
452 OutSel
.FRT
.value
, out
, o_isvec
)
453 if out_sel
== OutSel
.FRT
.value
:
455 print ("get_pdecode_idx_out not found", name
)
460 def get_pdecode_idx_out2(dec2
, name
):
462 print ("TODO: get_pdecode_idx_out2", name
)
467 # decoder2 - an instance of power_decoder2
468 # regfile - a list of initial values for the registers
469 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
470 # respect_pc - tracks the program counter. requires initial_insns
471 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
472 initial_mem
=None, initial_msr
=0,
483 self
.bigendian
= bigendian
485 self
.is_svp64_mode
= False
486 self
.respect_pc
= respect_pc
487 if initial_sprs
is None:
489 if initial_mem
is None:
491 if fpregfile
is None:
493 if initial_insns
is None:
495 assert self
.respect_pc
== False, "instructions required to honor pc"
497 print("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
498 print("ISACaller initial_msr", initial_msr
)
500 # "fake program counter" mode (for unit testing)
504 if isinstance(initial_mem
, tuple):
505 self
.fake_pc
= initial_mem
[0]
506 disasm_start
= self
.fake_pc
508 disasm_start
= initial_pc
510 # disassembly: we need this for now (not given from the decoder)
511 self
.disassembly
= {}
513 for i
, code
in enumerate(disassembly
):
514 self
.disassembly
[i
*4 + disasm_start
] = code
516 # set up registers, instruction memory, data memory, PC, SPRs, MSR
517 self
.svp64rm
= SVP64RM()
518 if initial_svstate
is None:
520 if isinstance(initial_svstate
, int):
521 initial_svstate
= SVP64State(initial_svstate
)
522 self
.svstate
= initial_svstate
523 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
524 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
525 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
526 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
527 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
528 # MMU mode, redirect underlying Mem through RADIX
529 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
531 self
.mem
= RADIX(self
.mem
, self
)
533 self
.imem
= RADIX(self
.imem
, self
)
537 # FPR (same as GPR except for FP nums)
538 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
539 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
540 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
541 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
543 # 2.3.2 LR (actually SPR #8) -- Done
544 # 2.3.3 CTR (actually SPR #9) -- Done
545 # 2.3.4 TAR (actually SPR #815)
546 # 3.2.2 p45 XER (actually SPR #1) -- Done
547 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
549 # create CR then allow portions of it to be "selectable" (below)
550 self
.cr_fields
= CRFields(initial_cr
)
551 self
.cr
= self
.cr_fields
.cr
553 # "undefined", just set to variable-bit-width int (use exts "max")
554 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
557 self
.namespace
.update(self
.spr
)
558 self
.namespace
.update({'GPR': self
.gpr
,
562 'memassign': self
.memassign
,
565 'SVSTATE': self
.svstate
.spr
,
568 'undefined': undefined
,
569 'mode_is_64bit': True,
573 # update pc to requested start point
574 self
.set_pc(initial_pc
)
576 # field-selectable versions of Condition Register
577 self
.crl
= self
.cr_fields
.crl
579 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
581 self
.decoder
= decoder2
.dec
584 def call_trap(self
, trap_addr
, trap_bit
):
585 """calls TRAP and sets up NIA to the new execution location.
586 next instruction will begin at trap_addr.
588 self
.TRAP(trap_addr
, trap_bit
)
589 self
.namespace
['NIA'] = self
.trap_nia
590 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
592 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
593 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
595 TRAP function is callable from inside the pseudocode itself,
596 hence the default arguments. when calling from inside ISACaller
597 it is best to use call_trap()
599 print("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
600 # store CIA(+4?) in SRR0, set NIA to 0x700
601 # store MSR in SRR1, set MSR to um errr something, have to check spec
602 # store SVSTATE (if enabled) in SVSRR0
603 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
604 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
605 if self
.is_svp64_mode
:
606 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
607 self
.trap_nia
= SelectableInt(trap_addr
, 64)
608 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
610 # set exception bits. TODO: this should, based on the address
611 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
612 # bits appropriately. however it turns out that *for now* in all
613 # cases (all trap_addrs) the exact same thing is needed.
614 self
.msr
[MSRb
.IR
] = 0
615 self
.msr
[MSRb
.DR
] = 0
616 self
.msr
[MSRb
.FE0
] = 0
617 self
.msr
[MSRb
.FE1
] = 0
618 self
.msr
[MSRb
.EE
] = 0
619 self
.msr
[MSRb
.RI
] = 0
620 self
.msr
[MSRb
.SF
] = 1
621 self
.msr
[MSRb
.TM
] = 0
622 self
.msr
[MSRb
.VEC
] = 0
623 self
.msr
[MSRb
.VSX
] = 0
624 self
.msr
[MSRb
.PR
] = 0
625 self
.msr
[MSRb
.FP
] = 0
626 self
.msr
[MSRb
.PMM
] = 0
627 self
.msr
[MSRb
.TEs
] = 0
628 self
.msr
[MSRb
.TEe
] = 0
629 self
.msr
[MSRb
.UND
] = 0
630 self
.msr
[MSRb
.LE
] = 1
632 def memassign(self
, ea
, sz
, val
):
633 self
.mem
.memassign(ea
, sz
, val
)
635 def prep_namespace(self
, formname
, op_fields
):
636 # TODO: get field names from form in decoder*1* (not decoder2)
637 # decoder2 is hand-created, and decoder1.sigform is auto-generated
639 # then "yield" fields only from op_fields rather than hard-coded
641 fields
= self
.decoder
.sigforms
[formname
]
642 for name
in op_fields
:
644 sig
= getattr(fields
, name
.upper())
646 sig
= getattr(fields
, name
)
648 # these are all opcode fields involved in index-selection of CR,
649 # and need to do "standard" arithmetic. CR[BA+32] for example
650 # would, if using SelectableInt, only be 5-bit.
651 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
652 self
.namespace
[name
] = val
654 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
656 self
.namespace
['XER'] = self
.spr
['XER']
657 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
658 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
660 def handle_carry_(self
, inputs
, outputs
, already_done
):
661 inv_a
= yield self
.dec2
.e
.do
.invert_in
663 inputs
[0] = ~inputs
[0]
665 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
667 imm
= yield self
.dec2
.e
.do
.imm_data
.data
668 inputs
.append(SelectableInt(imm
, 64))
669 assert len(outputs
) >= 1
670 print("outputs", repr(outputs
))
671 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
677 print("gt input", x
, output
)
678 gt
= (gtu(x
, output
))
681 cy
= 1 if any(gts
) else 0
683 if not (1 & already_done
):
684 self
.spr
['XER'][XER_bits
['CA']] = cy
686 print("inputs", already_done
, inputs
)
688 # ARGH... different for OP_ADD... *sigh*...
689 op
= yield self
.dec2
.e
.do
.insn_type
690 if op
== MicrOp
.OP_ADD
.value
:
691 res32
= (output
.value
& (1 << 32)) != 0
692 a32
= (inputs
[0].value
& (1 << 32)) != 0
694 b32
= (inputs
[1].value
& (1 << 32)) != 0
697 cy32
= res32 ^ a32 ^ b32
698 print("CA32 ADD", cy32
)
702 print("input", x
, output
)
703 print(" x[32:64]", x
, x
[32:64])
704 print(" o[32:64]", output
, output
[32:64])
705 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
707 cy32
= 1 if any(gts
) else 0
708 print("CA32", cy32
, gts
)
709 if not (2 & already_done
):
710 self
.spr
['XER'][XER_bits
['CA32']] = cy32
712 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
713 if hasattr(self
.dec2
.e
.do
, "invert_in"):
714 inv_a
= yield self
.dec2
.e
.do
.invert_in
716 inputs
[0] = ~inputs
[0]
718 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
720 imm
= yield self
.dec2
.e
.do
.imm_data
.data
721 inputs
.append(SelectableInt(imm
, 64))
722 assert len(outputs
) >= 1
723 print("handle_overflow", inputs
, outputs
, div_overflow
)
724 if len(inputs
) < 2 and div_overflow
is None:
727 # div overflow is different: it's returned by the pseudo-code
728 # because it's more complex than can be done by analysing the output
729 if div_overflow
is not None:
730 ov
, ov32
= div_overflow
, div_overflow
731 # arithmetic overflow can be done by analysing the input and output
732 elif len(inputs
) >= 2:
736 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
737 output_sgn
= exts(output
.value
, output
.bits
) < 0
738 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
739 output_sgn
!= input_sgn
[0] else 0
742 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
743 output32_sgn
= exts(output
.value
, 32) < 0
744 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
745 output32_sgn
!= input32_sgn
[0] else 0
747 self
.spr
['XER'][XER_bits
['OV']] = ov
748 self
.spr
['XER'][XER_bits
['OV32']] = ov32
749 so
= self
.spr
['XER'][XER_bits
['SO']]
751 self
.spr
['XER'][XER_bits
['SO']] = so
753 def handle_comparison(self
, outputs
, cr_idx
=0):
755 assert isinstance(out
, SelectableInt
), \
756 "out zero not a SelectableInt %s" % repr(outputs
)
757 print("handle_comparison", out
.bits
, hex(out
.value
))
758 # TODO - XXX *processor* in 32-bit mode
759 # https://bugs.libre-soc.org/show_bug.cgi?id=424
761 # o32 = exts(out.value, 32)
762 # print ("handle_comparison exts 32 bit", hex(o32))
763 out
= exts(out
.value
, out
.bits
)
764 print("handle_comparison exts", hex(out
))
765 zero
= SelectableInt(out
== 0, 1)
766 positive
= SelectableInt(out
> 0, 1)
767 negative
= SelectableInt(out
< 0, 1)
768 SO
= self
.spr
['XER'][XER_bits
['SO']]
769 print("handle_comparison SO", SO
)
770 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
771 self
.crl
[cr_idx
].eq(cr_field
)
773 def set_pc(self
, pc_val
):
774 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
775 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
778 """set up one instruction
781 pc
= self
.pc
.CIA
.value
785 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
787 raise KeyError("no instruction at 0x%x" % pc
)
788 print("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
789 print("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
791 yield self
.dec2
.sv_rm
.eq(0)
792 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
793 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
794 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
795 yield self
.dec2
.state
.pc
.eq(pc
)
796 if self
.svstate
is not None:
797 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
799 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
801 opcode
= yield self
.dec2
.dec
.opcode_in
802 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
803 pfx
.insn
.value
= opcode
804 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
805 print ("prefix test: opcode:", major
, bin(major
),
806 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
807 self
.is_svp64_mode
= ((major
== 0b000001) and
808 pfx
.insn
[7].value
== 0b1 and
809 pfx
.insn
[9].value
== 0b1)
810 self
.pc
.update_nia(self
.is_svp64_mode
)
811 self
.namespace
['NIA'] = self
.pc
.NIA
812 self
.namespace
['SVSTATE'] = self
.svstate
.spr
813 if not self
.is_svp64_mode
:
816 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
817 print ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
818 print (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
819 print (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
820 sv_rm
= pfx
.rm
.asint(msb0
=True)
821 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
822 print(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
823 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
824 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
827 def execute_one(self
):
828 """execute one instruction
830 # get the disassembly code for this instruction
831 if self
.is_svp64_mode
:
832 code
= self
.disassembly
[self
._pc
+4]
833 print(" svp64 sim-execute", hex(self
._pc
), code
)
835 code
= self
.disassembly
[self
._pc
]
836 print("sim-execute", hex(self
._pc
), code
)
837 opname
= code
.split(' ')[0]
839 yield from self
.call(opname
) # execute the instruction
840 except MemException
as e
: # check for memory errors
841 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
842 raise e
# ... re-raise
843 # run a Trap but set DAR first
844 print ("memory unaligned exception, DAR", e
.dar
)
845 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
846 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
849 # don't use this except in special circumstances
850 if not self
.respect_pc
:
853 print("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
855 def get_assembly_name(self
):
856 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
857 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
858 dec_insn
= yield self
.dec2
.e
.do
.insn
859 asmcode
= yield self
.dec2
.dec
.op
.asmcode
860 print("get assembly name asmcode", asmcode
, hex(dec_insn
))
861 asmop
= insns
.get(asmcode
, None)
862 int_op
= yield self
.dec2
.dec
.op
.internal_op
864 # sigh reconstruct the assembly instruction name
865 if hasattr(self
.dec2
.e
.do
, "oe"):
866 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
867 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
871 if hasattr(self
.dec2
.e
.do
, "rc"):
872 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
873 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
877 # grrrr have to special-case MUL op (see DecodeOE)
878 print("ov %d en %d rc %d en %d op %d" %
879 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
880 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
885 if not asmop
.endswith("."): # don't add "." to "andis."
888 if hasattr(self
.dec2
.e
.do
, "lk"):
889 lk
= yield self
.dec2
.e
.do
.lk
892 print("int_op", int_op
)
893 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
894 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
898 spr_msb
= yield from self
.get_spr_msb()
899 if int_op
== MicrOp
.OP_MFCR
.value
:
904 # XXX TODO: for whatever weird reason this doesn't work
905 # https://bugs.libre-soc.org/show_bug.cgi?id=390
906 if int_op
== MicrOp
.OP_MTCRF
.value
:
913 def get_spr_msb(self
):
914 dec_insn
= yield self
.dec2
.e
.do
.insn
915 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
917 def call(self
, name
):
918 """call(opcode) - the primary execution point for instructions
920 name
= name
.strip() # remove spaces if not already done so
922 print("halted - not executing", name
)
925 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
926 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
927 asmop
= yield from self
.get_assembly_name()
928 print("call", name
, asmop
)
931 int_op
= yield self
.dec2
.dec
.op
.internal_op
932 spr_msb
= yield from self
.get_spr_msb()
934 instr_is_privileged
= False
935 if int_op
in [MicrOp
.OP_ATTN
.value
,
936 MicrOp
.OP_MFMSR
.value
,
937 MicrOp
.OP_MTMSR
.value
,
938 MicrOp
.OP_MTMSRD
.value
,
940 MicrOp
.OP_RFID
.value
]:
941 instr_is_privileged
= True
942 if int_op
in [MicrOp
.OP_MFSPR
.value
,
943 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
944 instr_is_privileged
= True
946 print("is priv", instr_is_privileged
, hex(self
.msr
.value
),
948 # check MSR priv bit and whether op is privileged: if so, throw trap
949 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
950 self
.call_trap(0x700, PIb
.PRIV
)
953 # check halted condition
958 # check illegal instruction
960 if name
not in ['mtcrf', 'mtocrf']:
961 illegal
= name
!= asmop
963 # sigh deal with setvl not being supported by binutils (.long)
964 if asmop
.startswith('setvl'):
969 print("illegal", name
, asmop
)
970 self
.call_trap(0x700, PIb
.ILLEG
)
971 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
972 (name
, asmop
, self
.pc
.CIA
.value
))
975 info
= self
.instrs
[name
]
976 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
978 # preserve order of register names
979 input_names
= create_args(list(info
.read_regs
) +
980 list(info
.uninit_regs
))
983 # get SVP64 entry for the current instruction
984 sv_rm
= self
.svp64rm
.instrs
.get(name
)
985 if sv_rm
is not None:
986 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
988 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
989 print ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
991 # get SVSTATE VL (oh and print out some debug stuff)
992 if self
.is_svp64_mode
:
993 vl
= self
.svstate
.vl
.asint(msb0
=True)
994 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
995 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
996 sv_a_nz
= yield self
.dec2
.sv_a_nz
997 in1
= yield self
.dec2
.e
.read_reg1
.data
998 print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
999 vl
, srcstep
, dststep
, sv_a_nz
, in1
)
1001 # get predicate mask
1002 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1003 if self
.is_svp64_mode
:
1004 pmode
= yield self
.dec2
.rm_dec
.predmode
1005 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1006 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1007 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1008 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1009 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1010 if pmode
== SVP64PredMode
.INT
.value
:
1011 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1012 if sv_ptype
== SVPtype
.P2
.value
:
1013 srcmask
= get_predint(self
.gpr
, srcpred
)
1014 elif pmode
== SVP64PredMode
.CR
.value
:
1015 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1016 if sv_ptype
== SVPtype
.P2
.value
:
1017 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1018 print (" pmode", pmode
)
1019 print (" ptype", sv_ptype
)
1020 print (" srcpred", bin(srcpred
))
1021 print (" dstpred", bin(dstpred
))
1022 print (" srcmask", bin(srcmask
))
1023 print (" dstmask", bin(dstmask
))
1024 print (" pred_sz", bin(pred_src_zero
))
1025 print (" pred_dz", bin(pred_dst_zero
))
1027 # okaaay, so here we simply advance srcstep (TODO dststep)
1028 # until the predicate mask has a "1" bit... or we run out of VL
1029 # let srcstep==VL be the indicator to move to next instruction
1030 if not pred_src_zero
:
1031 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1032 print (" skip", bin(1<<srcstep
))
1035 if not pred_dst_zero
:
1036 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1037 print (" skip", bin(1<<dststep
))
1040 # now work out if the relevant mask bits require zeroing
1042 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1044 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1046 # update SVSTATE with new srcstep
1047 self
.svstate
.srcstep
[0:7] = srcstep
1048 self
.svstate
.dststep
[0:7] = dststep
1049 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1050 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1051 yield Settle() # let decoder update
1052 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1053 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1054 print (" srcstep", srcstep
)
1055 print (" dststep", dststep
)
1057 # check if end reached (we let srcstep overrun, above)
1058 # nothing needs doing (TODO zeroing): just do next instruction
1059 if srcstep
== vl
or dststep
== vl
:
1060 self
.svp64_reset_loop()
1061 self
.update_pc_next()
1064 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1065 if self
.is_svp64_mode
and vl
== 0:
1066 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1067 print("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1068 self
.namespace
['NIA'])
1071 # main input registers (RT, RA ...)
1073 for name
in input_names
:
1074 # using PowerDecoder2, first, find the decoder index.
1075 # (mapping name RA RB RC RS to in1, in2, in3)
1076 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1078 # doing this is not part of svp64, it's because output
1079 # registers, to be modified, need to be in the namespace.
1080 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1082 # in case getting the register number is needed, _RA, _RB
1083 regname
= "_" + name
1084 self
.namespace
[regname
] = regnum
1085 if not self
.is_svp64_mode
or not pred_src_zero
:
1086 print('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1088 reg_val
= self
.fpr(regnum
)
1090 reg_val
= self
.gpr(regnum
)
1092 print('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1094 inputs
.append(reg_val
)
1096 # "special" registers
1097 for special
in info
.special_regs
:
1098 if special
in special_sprs
:
1099 inputs
.append(self
.spr
[special
])
1101 inputs
.append(self
.namespace
[special
])
1103 # clear trap (trap) NIA
1104 self
.trap_nia
= None
1106 # execute actual instruction here
1107 print("inputs", inputs
)
1108 results
= info
.func(self
, *inputs
)
1109 print("results", results
)
1111 # "inject" decorator takes namespace from function locals: we need to
1112 # overwrite NIA being overwritten (sigh)
1113 if self
.trap_nia
is not None:
1114 self
.namespace
['NIA'] = self
.trap_nia
1116 print("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1118 # detect if CA/CA32 already in outputs (sra*, basically)
1121 output_names
= create_args(info
.write_regs
)
1122 for name
in output_names
:
1128 print("carry already done?", bin(already_done
))
1129 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1130 carry_en
= yield self
.dec2
.e
.do
.output_carry
1134 yield from self
.handle_carry_(inputs
, results
, already_done
)
1136 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1137 # detect if overflow was in return result
1140 for name
, output
in zip(output_names
, results
):
1141 if name
== 'overflow':
1144 if hasattr(self
.dec2
.e
.do
, "oe"):
1145 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1146 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1150 print("internal overflow", overflow
, ov_en
, ov_ok
)
1152 yield from self
.handle_overflow(inputs
, results
, overflow
)
1154 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1156 if not self
.is_svp64_mode
or not pred_dst_zero
:
1157 if hasattr(self
.dec2
.e
.do
, "rc"):
1158 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1160 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1161 self
.handle_comparison(results
, regnum
)
1163 # any modified return results?
1165 for name
, output
in zip(output_names
, results
):
1166 if name
== 'overflow': # ignore, done already (above)
1168 if isinstance(output
, int):
1169 output
= SelectableInt(output
, 256)
1170 if name
in ['CA', 'CA32']:
1172 print("writing %s to XER" % name
, output
)
1173 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1175 print("NOT writing %s to XER" % name
, output
)
1176 elif name
in info
.special_regs
:
1177 print('writing special %s' % name
, output
, special_sprs
)
1178 if name
in special_sprs
:
1179 self
.spr
[name
] = output
1181 self
.namespace
[name
].eq(output
)
1183 print('msr written', hex(self
.msr
.value
))
1185 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1188 # temporary hack for not having 2nd output
1189 regnum
= yield getattr(self
.decoder
, name
)
1191 if self
.is_svp64_mode
and pred_dst_zero
:
1192 print('zeroing reg %d %s' % (regnum
, str(output
)),
1194 output
= SelectableInt(0, 256)
1200 print('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1202 if output
.bits
> 64:
1203 output
= SelectableInt(output
.value
, 64)
1205 self
.fpr
[regnum
] = output
1207 self
.gpr
[regnum
] = output
1209 # check if it is the SVSTATE.src/dest step that needs incrementing
1210 # this is our Sub-Program-Counter loop from 0 to VL-1
1211 if self
.is_svp64_mode
:
1212 # XXX twin predication TODO
1213 vl
= self
.svstate
.vl
.asint(msb0
=True)
1214 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1215 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1216 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1217 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1218 no_out_vec
= not (yield self
.dec2
.no_out_vec
)
1219 no_in_vec
= not (yield self
.dec2
.no_in_vec
)
1220 print (" svstate.vl", vl
)
1221 print (" svstate.mvl", mvl
)
1222 print (" svstate.srcstep", srcstep
)
1223 print (" svstate.dststep", dststep
)
1224 print (" no_out_vec", no_out_vec
)
1225 print (" no_in_vec", no_in_vec
)
1226 print (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1227 # check if srcstep needs incrementing by one, stop PC advancing
1228 # svp64 loop can end early if the dest is scalar for single-pred
1229 # but for 2-pred both src/dest have to be checked.
1230 # XXX this might not be true! it may just be LD/ST
1231 if sv_ptype
== SVPtype
.P2
.value
:
1232 svp64_is_vector
= (no_out_vec
or no_in_vec
)
1234 svp64_is_vector
= no_out_vec
1235 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1236 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1237 self
.svstate
.dststep
+= SelectableInt(1, 7)
1238 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1239 self
.namespace
['NIA'] = self
.pc
.NIA
1240 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1241 print("end of sub-pc call", self
.namespace
['CIA'],
1242 self
.namespace
['NIA'])
1243 return # DO NOT allow PC to update whilst Sub-PC loop running
1244 # reset loop to zero
1245 self
.svp64_reset_loop()
1247 self
.update_pc_next()
1249 def update_pc_next(self
):
1250 # UPDATE program counter
1251 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1252 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1253 print("end of call", self
.namespace
['CIA'],
1254 self
.namespace
['NIA'],
1255 self
.namespace
['SVSTATE'])
1257 def svp64_reset_loop(self
):
1258 self
.svstate
.srcstep
[0:7] = 0
1259 self
.svstate
.dststep
[0:7] = 0
1260 print (" svstate.srcstep loop end (PC to update)")
1261 self
.pc
.update_nia(self
.is_svp64_mode
)
1262 self
.namespace
['NIA'] = self
.pc
.NIA
1263 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1266 """Decorator factory.
1268 this decorator will "inject" variables into the function's namespace,
1269 from the *dictionary* in self.namespace. it therefore becomes possible
1270 to make it look like a whole stack of variables which would otherwise
1271 need "self." inserted in front of them (*and* for those variables to be
1272 added to the instance) "appear" in the function.
1274 "self.namespace['SI']" for example becomes accessible as just "SI" but
1275 *only* inside the function, when decorated.
1277 def variable_injector(func
):
1279 def decorator(*args
, **kwargs
):
1281 func_globals
= func
.__globals
__ # Python 2.6+
1282 except AttributeError:
1283 func_globals
= func
.func_globals
# Earlier versions.
1285 context
= args
[0].namespace
# variables to be injected
1286 saved_values
= func_globals
.copy() # Shallow copy of dict.
1287 func_globals
.update(context
)
1288 result
= func(*args
, **kwargs
)
1289 print("globals after", func_globals
['CIA'], func_globals
['NIA'])
1290 print("args[0]", args
[0].namespace
['CIA'],
1291 args
[0].namespace
['NIA'],
1292 args
[0].namespace
['SVSTATE'])
1293 args
[0].namespace
= func_globals
1294 #exec (func.__code__, func_globals)
1297 # func_globals = saved_values # Undo changes.
1303 return variable_injector