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
77 "overflow": 7, # should definitely be last
80 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
83 def create_args(reglist
, extra
=None):
84 retval
= list(OrderedSet(reglist
))
85 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
87 return [extra
] + retval
93 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
96 self
.isacaller
= isacaller
97 self
.svstate
= svstate
99 self
[i
] = SelectableInt(regfile
[i
], 64)
101 def __call__(self
, ridx
):
104 def set_form(self
, form
):
107 def getz(self
, rnum
):
108 # rnum = rnum.value # only SelectableInt allowed
109 print("GPR getzero?", rnum
)
111 return SelectableInt(0, 64)
114 def _get_regnum(self
, attr
):
115 getform
= self
.sd
.sigforms
[self
.form
]
116 rnum
= getattr(getform
, attr
)
119 def ___getitem__(self
, attr
):
120 """ XXX currently not used
122 rnum
= self
._get
_regnum
(attr
)
123 offs
= self
.svstate
.srcstep
124 print("GPR getitem", attr
, rnum
, "srcoffs", offs
)
125 return self
.regfile
[rnum
]
128 for i
in range(0, len(self
), 8):
131 s
.append("%08x" % self
[i
+j
].value
)
133 print("reg", "%2d" % i
, s
)
137 def __init__(self
, dec2
, initial_sprs
={}):
140 for key
, v
in initial_sprs
.items():
141 if isinstance(key
, SelectableInt
):
143 key
= special_sprs
.get(key
, key
)
144 if isinstance(key
, int):
147 info
= spr_byname
[key
]
148 if not isinstance(v
, SelectableInt
):
149 v
= SelectableInt(v
, info
.length
)
152 def __getitem__(self
, key
):
153 print("get spr", key
)
154 print("dict", self
.items())
155 # if key in special_sprs get the special spr, otherwise return key
156 if isinstance(key
, SelectableInt
):
158 if isinstance(key
, int):
159 key
= spr_dict
[key
].SPR
160 key
= special_sprs
.get(key
, key
)
161 if key
== 'HSRR0': # HACK!
163 if key
== 'HSRR1': # HACK!
166 res
= dict.__getitem
__(self
, key
)
168 if isinstance(key
, int):
171 info
= spr_byname
[key
]
172 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
173 res
= dict.__getitem
__(self
, key
)
174 print("spr returning", key
, res
)
177 def __setitem__(self
, key
, value
):
178 if isinstance(key
, SelectableInt
):
180 if isinstance(key
, int):
181 key
= spr_dict
[key
].SPR
182 print("spr key", key
)
183 key
= special_sprs
.get(key
, key
)
184 if key
== 'HSRR0': # HACK!
185 self
.__setitem
__('SRR0', value
)
186 if key
== 'HSRR1': # HACK!
187 self
.__setitem
__('SRR1', value
)
188 print("setting spr", key
, value
)
189 dict.__setitem
__(self
, key
, value
)
191 def __call__(self
, ridx
):
196 def __init__(self
, pc_init
=0):
197 self
.CIA
= SelectableInt(pc_init
, 64)
198 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
200 def update_nia(self
, is_svp64
):
201 increment
= 8 if is_svp64
else 4
202 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
204 def update(self
, namespace
, is_svp64
):
205 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
207 self
.CIA
= namespace
['NIA'].narrow(64)
208 self
.update_nia(is_svp64
)
209 namespace
['CIA'] = self
.CIA
210 namespace
['NIA'] = self
.NIA
213 # Simple-V: see https://libre-soc.org/openpower/sv
215 def __init__(self
, init
=0):
216 self
.spr
= SelectableInt(init
, 32)
217 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
218 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
219 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
220 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
221 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
222 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
223 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
228 def __init__(self
, init
=0):
229 self
.spr
= SelectableInt(init
, 24)
230 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
231 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
232 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
233 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
234 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
235 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
236 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
237 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
238 # these cover the same extra field, split into parts as EXTRA2
239 self
.extra2
= list(range(4))
240 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
241 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
242 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
243 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
244 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
245 # and here as well, but EXTRA3
246 self
.extra3
= list(range(3))
247 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
248 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
249 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
252 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
253 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
254 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
255 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
256 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
257 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
258 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
259 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
260 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
263 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
264 class SVP64PrefixFields
:
266 self
.insn
= SelectableInt(0, 32)
267 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
268 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
269 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
270 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
271 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
274 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
275 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
276 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
280 # See PowerISA Version 3.0 B Book 1
281 # Section 2.3.1 Condition Register pages 30 - 31
283 LT
= FL
= 0 # negative, less than, floating-point less than
284 GT
= FG
= 1 # positive, greater than, floating-point greater than
285 EQ
= FE
= 2 # equal, floating-point equal
286 SO
= FU
= 3 # summary overflow, floating-point unordered
288 def __init__(self
, init
=0):
289 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
290 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
291 self
.cr
= SelectableInt(init
, 64) # underlying reg
292 # field-selectable versions of Condition Register TODO check bitranges?
295 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
296 _cr
= FieldSelectableInt(self
.cr
, bits
)
299 # decode SVP64 predicate integer to reg number and invert
300 def get_predint(gpr
, mask
):
303 print ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
304 if mask
== SVP64PredInt
.ALWAYS
.value
:
305 return 0xffff_ffff_ffff_ffff
306 if mask
== SVP64PredInt
.R3_UNARY
.value
:
307 return 1 << (gpr(3).value
& 0b111111)
308 if mask
== SVP64PredInt
.R3
.value
:
310 if mask
== SVP64PredInt
.R3_N
.value
:
312 if mask
== SVP64PredInt
.R10
.value
:
314 if mask
== SVP64PredInt
.R10_N
.value
:
315 return ~
gpr(10).value
316 if mask
== SVP64PredInt
.R30
.value
:
318 if mask
== SVP64PredInt
.R30_N
.value
:
319 return ~
gpr(30).value
321 # decode SVP64 predicate CR to reg number and invert status
322 def _get_predcr(mask
):
323 if mask
== SVP64PredCR
.LT
.value
:
325 if mask
== SVP64PredCR
.GE
.value
:
327 if mask
== SVP64PredCR
.GT
.value
:
329 if mask
== SVP64PredCR
.LE
.value
:
331 if mask
== SVP64PredCR
.EQ
.value
:
333 if mask
== SVP64PredCR
.NE
.value
:
335 if mask
== SVP64PredCR
.SO
.value
:
337 if mask
== SVP64PredCR
.NS
.value
:
340 # read individual CR fields (0..VL-1), extract the required bit
341 # and construct the mask
342 def get_predcr(crl
, mask
, vl
):
343 idx
, noninv
= _get_predcr(mask
)
346 cr
= crl
[i
+SVP64CROffs
.CRPred
]
347 if cr
[idx
].value
== noninv
:
352 def get_pdecode_idx_in(dec2
, name
):
354 in1_sel
= yield op
.in1_sel
355 in2_sel
= yield op
.in2_sel
356 in3_sel
= yield op
.in3_sel
357 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
358 in1
= yield dec2
.e
.read_reg1
.data
359 in2
= yield dec2
.e
.read_reg2
.data
360 in3
= yield dec2
.e
.read_reg3
.data
361 in1_isvec
= yield dec2
.in1_isvec
362 in2_isvec
= yield dec2
.in2_isvec
363 in3_isvec
= yield dec2
.in3_isvec
364 print ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
366 print ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
368 print ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
370 print ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
372 print ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
374 # identify which regnames map to in1/2/3
376 if (in1_sel
== In1Sel
.RA
.value
or
377 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
378 return in1
, in1_isvec
379 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
380 return in1
, in1_isvec
382 if in2_sel
== In2Sel
.RB
.value
:
383 return in2
, in2_isvec
384 if in3_sel
== In3Sel
.RB
.value
:
385 return in3
, in3_isvec
386 # XXX TODO, RC doesn't exist yet!
388 assert False, "RC does not exist yet"
390 if in1_sel
== In1Sel
.RS
.value
:
391 return in1
, in1_isvec
392 if in2_sel
== In2Sel
.RS
.value
:
393 return in2
, in2_isvec
394 if in3_sel
== In3Sel
.RS
.value
:
395 return in3
, in3_isvec
397 if in1_sel
== In1Sel
.FRA
.value
:
398 return in1
, in1_isvec
400 if in2_sel
== In2Sel
.FRB
.value
:
401 return in2
, in2_isvec
403 if in3_sel
== In3Sel
.FRC
.value
:
404 return in3
, in3_isvec
406 if in1_sel
== In1Sel
.FRS
.value
:
407 return in1
, in1_isvec
408 if in3_sel
== In3Sel
.FRS
.value
:
409 return in3
, in3_isvec
413 def get_pdecode_cr_out(dec2
, name
):
415 out_sel
= yield op
.cr_out
416 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
417 sv_cr_out
= yield op
.sv_cr_out
418 spec
= yield dec2
.crout_svdec
.spec
419 sv_override
= yield dec2
.dec_cr_out
.sv_override
420 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
421 out
= yield dec2
.e
.write_cr
.data
422 o_isvec
= yield dec2
.o_isvec
423 print ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
424 print (" sv_cr_out", sv_cr_out
)
425 print (" cr_bf", out_bitfield
)
426 print (" spec", spec
)
427 print (" override", sv_override
)
428 # identify which regnames map to out / o2
430 if out_sel
== CROutSel
.CR0
.value
:
432 print ("get_pdecode_cr_out not found", name
)
436 def get_pdecode_idx_out(dec2
, name
):
438 out_sel
= yield op
.out_sel
439 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
440 out
= yield dec2
.e
.write_reg
.data
441 o_isvec
= yield dec2
.o_isvec
442 # identify which regnames map to out / o2
444 print ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
445 if out_sel
== OutSel
.RA
.value
:
448 print ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
449 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
)
450 if out_sel
== OutSel
.RT
.value
:
453 print ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
454 if out_sel
== OutSel
.FRA
.value
:
457 print ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
458 OutSel
.FRT
.value
, out
, o_isvec
)
459 if out_sel
== OutSel
.FRT
.value
:
461 print ("get_pdecode_idx_out not found", name
)
466 def get_pdecode_idx_out2(dec2
, name
):
468 print ("TODO: get_pdecode_idx_out2", name
)
473 # decoder2 - an instance of power_decoder2
474 # regfile - a list of initial values for the registers
475 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
476 # respect_pc - tracks the program counter. requires initial_insns
477 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
478 initial_mem
=None, initial_msr
=0,
489 self
.bigendian
= bigendian
491 self
.is_svp64_mode
= False
492 self
.respect_pc
= respect_pc
493 if initial_sprs
is None:
495 if initial_mem
is None:
497 if fpregfile
is None:
499 if initial_insns
is None:
501 assert self
.respect_pc
== False, "instructions required to honor pc"
503 print("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
504 print("ISACaller initial_msr", initial_msr
)
506 # "fake program counter" mode (for unit testing)
510 if isinstance(initial_mem
, tuple):
511 self
.fake_pc
= initial_mem
[0]
512 disasm_start
= self
.fake_pc
514 disasm_start
= initial_pc
516 # disassembly: we need this for now (not given from the decoder)
517 self
.disassembly
= {}
519 for i
, code
in enumerate(disassembly
):
520 self
.disassembly
[i
*4 + disasm_start
] = code
522 # set up registers, instruction memory, data memory, PC, SPRs, MSR
523 self
.svp64rm
= SVP64RM()
524 if initial_svstate
is None:
526 if isinstance(initial_svstate
, int):
527 initial_svstate
= SVP64State(initial_svstate
)
528 self
.svstate
= initial_svstate
529 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
530 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
531 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
532 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
533 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
534 # MMU mode, redirect underlying Mem through RADIX
535 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
537 self
.mem
= RADIX(self
.mem
, self
)
539 self
.imem
= RADIX(self
.imem
, self
)
543 # FPR (same as GPR except for FP nums)
544 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
545 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
546 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
547 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
549 # 2.3.2 LR (actually SPR #8) -- Done
550 # 2.3.3 CTR (actually SPR #9) -- Done
551 # 2.3.4 TAR (actually SPR #815)
552 # 3.2.2 p45 XER (actually SPR #1) -- Done
553 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
555 # create CR then allow portions of it to be "selectable" (below)
556 self
.cr_fields
= CRFields(initial_cr
)
557 self
.cr
= self
.cr_fields
.cr
559 # "undefined", just set to variable-bit-width int (use exts "max")
560 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
563 self
.namespace
.update(self
.spr
)
564 self
.namespace
.update({'GPR': self
.gpr
,
568 'memassign': self
.memassign
,
571 'SVSTATE': self
.svstate
.spr
,
574 'undefined': undefined
,
575 'mode_is_64bit': True,
579 # update pc to requested start point
580 self
.set_pc(initial_pc
)
582 # field-selectable versions of Condition Register
583 self
.crl
= self
.cr_fields
.crl
585 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
587 self
.decoder
= decoder2
.dec
590 def call_trap(self
, trap_addr
, trap_bit
):
591 """calls TRAP and sets up NIA to the new execution location.
592 next instruction will begin at trap_addr.
594 self
.TRAP(trap_addr
, trap_bit
)
595 self
.namespace
['NIA'] = self
.trap_nia
596 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
598 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
599 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
601 TRAP function is callable from inside the pseudocode itself,
602 hence the default arguments. when calling from inside ISACaller
603 it is best to use call_trap()
605 print("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
606 # store CIA(+4?) in SRR0, set NIA to 0x700
607 # store MSR in SRR1, set MSR to um errr something, have to check spec
608 # store SVSTATE (if enabled) in SVSRR0
609 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
610 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
611 if self
.is_svp64_mode
:
612 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
613 self
.trap_nia
= SelectableInt(trap_addr
, 64)
614 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
616 # set exception bits. TODO: this should, based on the address
617 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
618 # bits appropriately. however it turns out that *for now* in all
619 # cases (all trap_addrs) the exact same thing is needed.
620 self
.msr
[MSRb
.IR
] = 0
621 self
.msr
[MSRb
.DR
] = 0
622 self
.msr
[MSRb
.FE0
] = 0
623 self
.msr
[MSRb
.FE1
] = 0
624 self
.msr
[MSRb
.EE
] = 0
625 self
.msr
[MSRb
.RI
] = 0
626 self
.msr
[MSRb
.SF
] = 1
627 self
.msr
[MSRb
.TM
] = 0
628 self
.msr
[MSRb
.VEC
] = 0
629 self
.msr
[MSRb
.VSX
] = 0
630 self
.msr
[MSRb
.PR
] = 0
631 self
.msr
[MSRb
.FP
] = 0
632 self
.msr
[MSRb
.PMM
] = 0
633 self
.msr
[MSRb
.TEs
] = 0
634 self
.msr
[MSRb
.TEe
] = 0
635 self
.msr
[MSRb
.UND
] = 0
636 self
.msr
[MSRb
.LE
] = 1
638 def memassign(self
, ea
, sz
, val
):
639 self
.mem
.memassign(ea
, sz
, val
)
641 def prep_namespace(self
, formname
, op_fields
):
642 # TODO: get field names from form in decoder*1* (not decoder2)
643 # decoder2 is hand-created, and decoder1.sigform is auto-generated
645 # then "yield" fields only from op_fields rather than hard-coded
647 fields
= self
.decoder
.sigforms
[formname
]
648 for name
in op_fields
:
650 sig
= getattr(fields
, name
.upper())
652 sig
= getattr(fields
, name
)
654 # these are all opcode fields involved in index-selection of CR,
655 # and need to do "standard" arithmetic. CR[BA+32] for example
656 # would, if using SelectableInt, only be 5-bit.
657 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
658 self
.namespace
[name
] = val
660 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
662 self
.namespace
['XER'] = self
.spr
['XER']
663 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
664 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
666 def handle_carry_(self
, inputs
, outputs
, already_done
):
667 inv_a
= yield self
.dec2
.e
.do
.invert_in
669 inputs
[0] = ~inputs
[0]
671 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
673 imm
= yield self
.dec2
.e
.do
.imm_data
.data
674 inputs
.append(SelectableInt(imm
, 64))
675 assert len(outputs
) >= 1
676 print("outputs", repr(outputs
))
677 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
683 print("gt input", x
, output
)
684 gt
= (gtu(x
, output
))
687 cy
= 1 if any(gts
) else 0
689 if not (1 & already_done
):
690 self
.spr
['XER'][XER_bits
['CA']] = cy
692 print("inputs", already_done
, inputs
)
694 # ARGH... different for OP_ADD... *sigh*...
695 op
= yield self
.dec2
.e
.do
.insn_type
696 if op
== MicrOp
.OP_ADD
.value
:
697 res32
= (output
.value
& (1 << 32)) != 0
698 a32
= (inputs
[0].value
& (1 << 32)) != 0
700 b32
= (inputs
[1].value
& (1 << 32)) != 0
703 cy32
= res32 ^ a32 ^ b32
704 print("CA32 ADD", cy32
)
708 print("input", x
, output
)
709 print(" x[32:64]", x
, x
[32:64])
710 print(" o[32:64]", output
, output
[32:64])
711 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
713 cy32
= 1 if any(gts
) else 0
714 print("CA32", cy32
, gts
)
715 if not (2 & already_done
):
716 self
.spr
['XER'][XER_bits
['CA32']] = cy32
718 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
719 if hasattr(self
.dec2
.e
.do
, "invert_in"):
720 inv_a
= yield self
.dec2
.e
.do
.invert_in
722 inputs
[0] = ~inputs
[0]
724 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
726 imm
= yield self
.dec2
.e
.do
.imm_data
.data
727 inputs
.append(SelectableInt(imm
, 64))
728 assert len(outputs
) >= 1
729 print("handle_overflow", inputs
, outputs
, div_overflow
)
730 if len(inputs
) < 2 and div_overflow
is None:
733 # div overflow is different: it's returned by the pseudo-code
734 # because it's more complex than can be done by analysing the output
735 if div_overflow
is not None:
736 ov
, ov32
= div_overflow
, div_overflow
737 # arithmetic overflow can be done by analysing the input and output
738 elif len(inputs
) >= 2:
742 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
743 output_sgn
= exts(output
.value
, output
.bits
) < 0
744 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
745 output_sgn
!= input_sgn
[0] else 0
748 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
749 output32_sgn
= exts(output
.value
, 32) < 0
750 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
751 output32_sgn
!= input32_sgn
[0] else 0
753 self
.spr
['XER'][XER_bits
['OV']] = ov
754 self
.spr
['XER'][XER_bits
['OV32']] = ov32
755 so
= self
.spr
['XER'][XER_bits
['SO']]
757 self
.spr
['XER'][XER_bits
['SO']] = so
759 def handle_comparison(self
, outputs
, cr_idx
=0):
761 assert isinstance(out
, SelectableInt
), \
762 "out zero not a SelectableInt %s" % repr(outputs
)
763 print("handle_comparison", out
.bits
, hex(out
.value
))
764 # TODO - XXX *processor* in 32-bit mode
765 # https://bugs.libre-soc.org/show_bug.cgi?id=424
767 # o32 = exts(out.value, 32)
768 # print ("handle_comparison exts 32 bit", hex(o32))
769 out
= exts(out
.value
, out
.bits
)
770 print("handle_comparison exts", hex(out
))
771 zero
= SelectableInt(out
== 0, 1)
772 positive
= SelectableInt(out
> 0, 1)
773 negative
= SelectableInt(out
< 0, 1)
774 SO
= self
.spr
['XER'][XER_bits
['SO']]
775 print("handle_comparison SO", SO
)
776 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
777 self
.crl
[cr_idx
].eq(cr_field
)
779 def set_pc(self
, pc_val
):
780 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
781 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
784 """set up one instruction
787 pc
= self
.pc
.CIA
.value
791 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
793 raise KeyError("no instruction at 0x%x" % pc
)
794 print("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
795 print("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
797 yield self
.dec2
.sv_rm
.eq(0)
798 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
799 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
800 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
801 yield self
.dec2
.state
.pc
.eq(pc
)
802 if self
.svstate
is not None:
803 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
805 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
807 opcode
= yield self
.dec2
.dec
.opcode_in
808 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
809 pfx
.insn
.value
= opcode
810 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
811 print ("prefix test: opcode:", major
, bin(major
),
812 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
813 self
.is_svp64_mode
= ((major
== 0b000001) and
814 pfx
.insn
[7].value
== 0b1 and
815 pfx
.insn
[9].value
== 0b1)
816 self
.pc
.update_nia(self
.is_svp64_mode
)
817 self
.namespace
['NIA'] = self
.pc
.NIA
818 self
.namespace
['SVSTATE'] = self
.svstate
.spr
819 if not self
.is_svp64_mode
:
822 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
823 print ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
824 print (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
825 print (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
826 sv_rm
= pfx
.rm
.asint(msb0
=True)
827 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
828 print(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
829 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
830 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
833 def execute_one(self
):
834 """execute one instruction
836 # get the disassembly code for this instruction
837 if self
.is_svp64_mode
:
838 code
= self
.disassembly
[self
._pc
+4]
839 print(" svp64 sim-execute", hex(self
._pc
), code
)
841 code
= self
.disassembly
[self
._pc
]
842 print("sim-execute", hex(self
._pc
), code
)
843 opname
= code
.split(' ')[0]
845 yield from self
.call(opname
) # execute the instruction
846 except MemException
as e
: # check for memory errors
847 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
848 raise e
# ... re-raise
849 # run a Trap but set DAR first
850 print ("memory unaligned exception, DAR", e
.dar
)
851 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
852 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
855 # don't use this except in special circumstances
856 if not self
.respect_pc
:
859 print("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
861 def get_assembly_name(self
):
862 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
863 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
864 dec_insn
= yield self
.dec2
.e
.do
.insn
865 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
866 asmcode
= yield self
.dec2
.dec
.op
.asmcode
867 int_op
= yield self
.dec2
.dec
.op
.internal_op
868 print("get assembly name asmcode", asmcode
, int_op
,
869 hex(dec_insn
), bin(insn_1_11
))
870 asmop
= insns
.get(asmcode
, None)
872 # sigh reconstruct the assembly instruction name
873 if hasattr(self
.dec2
.e
.do
, "oe"):
874 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
875 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
879 if hasattr(self
.dec2
.e
.do
, "rc"):
880 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
881 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
885 # grrrr have to special-case MUL op (see DecodeOE)
886 print("ov %d en %d rc %d en %d op %d" %
887 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
888 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
893 if not asmop
.endswith("."): # don't add "." to "andis."
896 if hasattr(self
.dec2
.e
.do
, "lk"):
897 lk
= yield self
.dec2
.e
.do
.lk
900 print("int_op", int_op
)
901 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
902 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
906 spr_msb
= yield from self
.get_spr_msb()
907 if int_op
== MicrOp
.OP_MFCR
.value
:
912 # XXX TODO: for whatever weird reason this doesn't work
913 # https://bugs.libre-soc.org/show_bug.cgi?id=390
914 if int_op
== MicrOp
.OP_MTCRF
.value
:
921 def get_spr_msb(self
):
922 dec_insn
= yield self
.dec2
.e
.do
.insn
923 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
925 def call(self
, name
):
926 """call(opcode) - the primary execution point for instructions
928 name
= name
.strip() # remove spaces if not already done so
930 print("halted - not executing", name
)
933 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
934 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
935 asmop
= yield from self
.get_assembly_name()
936 print("call", name
, asmop
)
939 int_op
= yield self
.dec2
.dec
.op
.internal_op
940 spr_msb
= yield from self
.get_spr_msb()
942 instr_is_privileged
= False
943 if int_op
in [MicrOp
.OP_ATTN
.value
,
944 MicrOp
.OP_MFMSR
.value
,
945 MicrOp
.OP_MTMSR
.value
,
946 MicrOp
.OP_MTMSRD
.value
,
948 MicrOp
.OP_RFID
.value
]:
949 instr_is_privileged
= True
950 if int_op
in [MicrOp
.OP_MFSPR
.value
,
951 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
952 instr_is_privileged
= True
954 print("is priv", instr_is_privileged
, hex(self
.msr
.value
),
956 # check MSR priv bit and whether op is privileged: if so, throw trap
957 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
958 self
.call_trap(0x700, PIb
.PRIV
)
961 # check halted condition
966 # check illegal instruction
968 if name
not in ['mtcrf', 'mtocrf']:
969 illegal
= name
!= asmop
971 # sigh deal with setvl not being supported by binutils (.long)
972 if asmop
.startswith('setvl'):
977 print("illegal", name
, asmop
)
978 self
.call_trap(0x700, PIb
.ILLEG
)
979 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
980 (name
, asmop
, self
.pc
.CIA
.value
))
983 info
= self
.instrs
[name
]
984 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
986 # preserve order of register names
987 input_names
= create_args(list(info
.read_regs
) +
988 list(info
.uninit_regs
))
991 # get SVP64 entry for the current instruction
992 sv_rm
= self
.svp64rm
.instrs
.get(name
)
993 if sv_rm
is not None:
994 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
996 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
997 print ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
999 # get SVSTATE VL (oh and print out some debug stuff)
1000 if self
.is_svp64_mode
:
1001 vl
= self
.svstate
.vl
.asint(msb0
=True)
1002 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1003 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1004 sv_a_nz
= yield self
.dec2
.sv_a_nz
1005 in1
= yield self
.dec2
.e
.read_reg1
.data
1006 print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
1007 vl
, srcstep
, dststep
, sv_a_nz
, in1
)
1009 # get predicate mask
1010 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1011 if self
.is_svp64_mode
:
1012 pmode
= yield self
.dec2
.rm_dec
.predmode
1013 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1014 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1015 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1016 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1017 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1018 if pmode
== SVP64PredMode
.INT
.value
:
1019 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1020 if sv_ptype
== SVPtype
.P2
.value
:
1021 srcmask
= get_predint(self
.gpr
, srcpred
)
1022 elif pmode
== SVP64PredMode
.CR
.value
:
1023 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1024 if sv_ptype
== SVPtype
.P2
.value
:
1025 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1026 print (" pmode", pmode
)
1027 print (" ptype", sv_ptype
)
1028 print (" srcpred", bin(srcpred
))
1029 print (" dstpred", bin(dstpred
))
1030 print (" srcmask", bin(srcmask
))
1031 print (" dstmask", bin(dstmask
))
1032 print (" pred_sz", bin(pred_src_zero
))
1033 print (" pred_dz", bin(pred_dst_zero
))
1035 # okaaay, so here we simply advance srcstep (TODO dststep)
1036 # until the predicate mask has a "1" bit... or we run out of VL
1037 # let srcstep==VL be the indicator to move to next instruction
1038 if not pred_src_zero
:
1039 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1040 print (" skip", bin(1<<srcstep
))
1043 if not pred_dst_zero
:
1044 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1045 print (" skip", bin(1<<dststep
))
1048 # now work out if the relevant mask bits require zeroing
1050 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1052 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1054 # update SVSTATE with new srcstep
1055 self
.svstate
.srcstep
[0:7] = srcstep
1056 self
.svstate
.dststep
[0:7] = dststep
1057 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1058 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1059 yield Settle() # let decoder update
1060 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1061 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1062 print (" srcstep", srcstep
)
1063 print (" dststep", dststep
)
1065 # check if end reached (we let srcstep overrun, above)
1066 # nothing needs doing (TODO zeroing): just do next instruction
1067 if srcstep
== vl
or dststep
== vl
:
1068 self
.svp64_reset_loop()
1069 self
.update_pc_next()
1072 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1073 if self
.is_svp64_mode
and vl
== 0:
1074 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1075 print("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1076 self
.namespace
['NIA'])
1079 # main input registers (RT, RA ...)
1081 for name
in input_names
:
1082 # using PowerDecoder2, first, find the decoder index.
1083 # (mapping name RA RB RC RS to in1, in2, in3)
1084 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1086 # doing this is not part of svp64, it's because output
1087 # registers, to be modified, need to be in the namespace.
1088 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1090 # in case getting the register number is needed, _RA, _RB
1091 regname
= "_" + name
1092 self
.namespace
[regname
] = regnum
1093 if not self
.is_svp64_mode
or not pred_src_zero
:
1094 print('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1096 reg_val
= self
.fpr(regnum
)
1098 reg_val
= self
.gpr(regnum
)
1100 print('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1102 inputs
.append(reg_val
)
1104 # "special" registers
1105 for special
in info
.special_regs
:
1106 if special
in special_sprs
:
1107 inputs
.append(self
.spr
[special
])
1109 inputs
.append(self
.namespace
[special
])
1111 # clear trap (trap) NIA
1112 self
.trap_nia
= None
1114 # execute actual instruction here
1115 print("inputs", inputs
)
1116 results
= info
.func(self
, *inputs
)
1117 print("results", results
)
1119 # "inject" decorator takes namespace from function locals: we need to
1120 # overwrite NIA being overwritten (sigh)
1121 if self
.trap_nia
is not None:
1122 self
.namespace
['NIA'] = self
.trap_nia
1124 print("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1126 # detect if CA/CA32 already in outputs (sra*, basically)
1129 output_names
= create_args(info
.write_regs
)
1130 for name
in output_names
:
1136 print("carry already done?", bin(already_done
))
1137 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1138 carry_en
= yield self
.dec2
.e
.do
.output_carry
1142 yield from self
.handle_carry_(inputs
, results
, already_done
)
1144 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1145 # detect if overflow was in return result
1148 for name
, output
in zip(output_names
, results
):
1149 if name
== 'overflow':
1152 if hasattr(self
.dec2
.e
.do
, "oe"):
1153 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1154 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1158 print("internal overflow", overflow
, ov_en
, ov_ok
)
1160 yield from self
.handle_overflow(inputs
, results
, overflow
)
1162 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1164 if not self
.is_svp64_mode
or not pred_dst_zero
:
1165 if hasattr(self
.dec2
.e
.do
, "rc"):
1166 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1168 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1169 self
.handle_comparison(results
, regnum
)
1171 # any modified return results?
1173 for name
, output
in zip(output_names
, results
):
1174 if name
== 'overflow': # ignore, done already (above)
1176 if isinstance(output
, int):
1177 output
= SelectableInt(output
, 256)
1178 if name
in ['CA', 'CA32']:
1180 print("writing %s to XER" % name
, output
)
1181 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1183 print("NOT writing %s to XER" % name
, output
)
1184 elif name
in info
.special_regs
:
1185 print('writing special %s' % name
, output
, special_sprs
)
1186 if name
in special_sprs
:
1187 self
.spr
[name
] = output
1189 self
.namespace
[name
].eq(output
)
1191 print('msr written', hex(self
.msr
.value
))
1193 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1196 # temporary hack for not having 2nd output
1197 regnum
= yield getattr(self
.decoder
, name
)
1199 if self
.is_svp64_mode
and pred_dst_zero
:
1200 print('zeroing reg %d %s' % (regnum
, str(output
)),
1202 output
= SelectableInt(0, 256)
1208 print('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1210 if output
.bits
> 64:
1211 output
= SelectableInt(output
.value
, 64)
1213 self
.fpr
[regnum
] = output
1215 self
.gpr
[regnum
] = output
1217 # check if it is the SVSTATE.src/dest step that needs incrementing
1218 # this is our Sub-Program-Counter loop from 0 to VL-1
1219 if self
.is_svp64_mode
:
1220 # XXX twin predication TODO
1221 vl
= self
.svstate
.vl
.asint(msb0
=True)
1222 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1223 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1224 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1225 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1226 no_out_vec
= not (yield self
.dec2
.no_out_vec
)
1227 no_in_vec
= not (yield self
.dec2
.no_in_vec
)
1228 print (" svstate.vl", vl
)
1229 print (" svstate.mvl", mvl
)
1230 print (" svstate.srcstep", srcstep
)
1231 print (" svstate.dststep", dststep
)
1232 print (" no_out_vec", no_out_vec
)
1233 print (" no_in_vec", no_in_vec
)
1234 print (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1235 # check if srcstep needs incrementing by one, stop PC advancing
1236 # svp64 loop can end early if the dest is scalar for single-pred
1237 # but for 2-pred both src/dest have to be checked.
1238 # XXX this might not be true! it may just be LD/ST
1239 if sv_ptype
== SVPtype
.P2
.value
:
1240 svp64_is_vector
= (no_out_vec
or no_in_vec
)
1242 svp64_is_vector
= no_out_vec
1243 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1244 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1245 self
.svstate
.dststep
+= SelectableInt(1, 7)
1246 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1247 self
.namespace
['NIA'] = self
.pc
.NIA
1248 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1249 print("end of sub-pc call", self
.namespace
['CIA'],
1250 self
.namespace
['NIA'])
1251 return # DO NOT allow PC to update whilst Sub-PC loop running
1252 # reset loop to zero
1253 self
.svp64_reset_loop()
1255 self
.update_pc_next()
1257 def update_pc_next(self
):
1258 # UPDATE program counter
1259 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1260 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1261 print("end of call", self
.namespace
['CIA'],
1262 self
.namespace
['NIA'],
1263 self
.namespace
['SVSTATE'])
1265 def svp64_reset_loop(self
):
1266 self
.svstate
.srcstep
[0:7] = 0
1267 self
.svstate
.dststep
[0:7] = 0
1268 print (" svstate.srcstep loop end (PC to update)")
1269 self
.pc
.update_nia(self
.is_svp64_mode
)
1270 self
.namespace
['NIA'] = self
.pc
.NIA
1271 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1274 """Decorator factory.
1276 this decorator will "inject" variables into the function's namespace,
1277 from the *dictionary* in self.namespace. it therefore becomes possible
1278 to make it look like a whole stack of variables which would otherwise
1279 need "self." inserted in front of them (*and* for those variables to be
1280 added to the instance) "appear" in the function.
1282 "self.namespace['SI']" for example becomes accessible as just "SI" but
1283 *only* inside the function, when decorated.
1285 def variable_injector(func
):
1287 def decorator(*args
, **kwargs
):
1289 func_globals
= func
.__globals
__ # Python 2.6+
1290 except AttributeError:
1291 func_globals
= func
.func_globals
# Earlier versions.
1293 context
= args
[0].namespace
# variables to be injected
1294 saved_values
= func_globals
.copy() # Shallow copy of dict.
1295 func_globals
.update(context
)
1296 result
= func(*args
, **kwargs
)
1297 print("globals after", func_globals
['CIA'], func_globals
['NIA'])
1298 print("args[0]", args
[0].namespace
['CIA'],
1299 args
[0].namespace
['NIA'],
1300 args
[0].namespace
['SVSTATE'])
1301 args
[0].namespace
= func_globals
1302 #exec (func.__code__, func_globals)
1305 # func_globals = saved_values # Undo changes.
1311 return variable_injector