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
, CROutSel
, LDSTMode
,
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
, out_sel
, out
, o_isvec
)
465 def get_pdecode_idx_out2(dec2
, name
):
466 # check first if register is activated for write
467 out_ok
= yield dec2
.e
.write_ea
.ok
472 out_sel
= yield op
.out_sel
473 out
= yield dec2
.e
.write_ea
.data
474 o_isvec
= yield dec2
.o2_isvec
475 print ("get_pdecode_idx_out2", name
, out_sel
, out
, o_isvec
)
477 if hasattr(op
, "upd"):
478 # update mode LD/ST uses read-reg A also as an output
480 print ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
481 out_sel
, OutSel
.RA
.value
,
483 if upd
== LDSTMode
.update
.value
:
489 # decoder2 - an instance of power_decoder2
490 # regfile - a list of initial values for the registers
491 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
492 # respect_pc - tracks the program counter. requires initial_insns
493 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
494 initial_mem
=None, initial_msr
=0,
505 self
.bigendian
= bigendian
507 self
.is_svp64_mode
= False
508 self
.respect_pc
= respect_pc
509 if initial_sprs
is None:
511 if initial_mem
is None:
513 if fpregfile
is None:
515 if initial_insns
is None:
517 assert self
.respect_pc
== False, "instructions required to honor pc"
519 print("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
520 print("ISACaller initial_msr", initial_msr
)
522 # "fake program counter" mode (for unit testing)
526 if isinstance(initial_mem
, tuple):
527 self
.fake_pc
= initial_mem
[0]
528 disasm_start
= self
.fake_pc
530 disasm_start
= initial_pc
532 # disassembly: we need this for now (not given from the decoder)
533 self
.disassembly
= {}
535 for i
, code
in enumerate(disassembly
):
536 self
.disassembly
[i
*4 + disasm_start
] = code
538 # set up registers, instruction memory, data memory, PC, SPRs, MSR
539 self
.svp64rm
= SVP64RM()
540 if initial_svstate
is None:
542 if isinstance(initial_svstate
, int):
543 initial_svstate
= SVP64State(initial_svstate
)
544 self
.svstate
= initial_svstate
545 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
546 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
547 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
548 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
549 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
550 # MMU mode, redirect underlying Mem through RADIX
551 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
553 self
.mem
= RADIX(self
.mem
, self
)
555 self
.imem
= RADIX(self
.imem
, self
)
559 # FPR (same as GPR except for FP nums)
560 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
561 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
562 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
563 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
565 # 2.3.2 LR (actually SPR #8) -- Done
566 # 2.3.3 CTR (actually SPR #9) -- Done
567 # 2.3.4 TAR (actually SPR #815)
568 # 3.2.2 p45 XER (actually SPR #1) -- Done
569 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
571 # create CR then allow portions of it to be "selectable" (below)
572 self
.cr_fields
= CRFields(initial_cr
)
573 self
.cr
= self
.cr_fields
.cr
575 # "undefined", just set to variable-bit-width int (use exts "max")
576 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
579 self
.namespace
.update(self
.spr
)
580 self
.namespace
.update({'GPR': self
.gpr
,
584 'memassign': self
.memassign
,
587 'SVSTATE': self
.svstate
.spr
,
590 'undefined': undefined
,
591 'mode_is_64bit': True,
595 # update pc to requested start point
596 self
.set_pc(initial_pc
)
598 # field-selectable versions of Condition Register
599 self
.crl
= self
.cr_fields
.crl
601 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
603 self
.decoder
= decoder2
.dec
606 def call_trap(self
, trap_addr
, trap_bit
):
607 """calls TRAP and sets up NIA to the new execution location.
608 next instruction will begin at trap_addr.
610 self
.TRAP(trap_addr
, trap_bit
)
611 self
.namespace
['NIA'] = self
.trap_nia
612 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
614 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
615 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
617 TRAP function is callable from inside the pseudocode itself,
618 hence the default arguments. when calling from inside ISACaller
619 it is best to use call_trap()
621 print("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
622 # store CIA(+4?) in SRR0, set NIA to 0x700
623 # store MSR in SRR1, set MSR to um errr something, have to check spec
624 # store SVSTATE (if enabled) in SVSRR0
625 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
626 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
627 if self
.is_svp64_mode
:
628 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
629 self
.trap_nia
= SelectableInt(trap_addr
, 64)
630 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
632 # set exception bits. TODO: this should, based on the address
633 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
634 # bits appropriately. however it turns out that *for now* in all
635 # cases (all trap_addrs) the exact same thing is needed.
636 self
.msr
[MSRb
.IR
] = 0
637 self
.msr
[MSRb
.DR
] = 0
638 self
.msr
[MSRb
.FE0
] = 0
639 self
.msr
[MSRb
.FE1
] = 0
640 self
.msr
[MSRb
.EE
] = 0
641 self
.msr
[MSRb
.RI
] = 0
642 self
.msr
[MSRb
.SF
] = 1
643 self
.msr
[MSRb
.TM
] = 0
644 self
.msr
[MSRb
.VEC
] = 0
645 self
.msr
[MSRb
.VSX
] = 0
646 self
.msr
[MSRb
.PR
] = 0
647 self
.msr
[MSRb
.FP
] = 0
648 self
.msr
[MSRb
.PMM
] = 0
649 self
.msr
[MSRb
.TEs
] = 0
650 self
.msr
[MSRb
.TEe
] = 0
651 self
.msr
[MSRb
.UND
] = 0
652 self
.msr
[MSRb
.LE
] = 1
654 def memassign(self
, ea
, sz
, val
):
655 self
.mem
.memassign(ea
, sz
, val
)
657 def prep_namespace(self
, formname
, op_fields
):
658 # TODO: get field names from form in decoder*1* (not decoder2)
659 # decoder2 is hand-created, and decoder1.sigform is auto-generated
661 # then "yield" fields only from op_fields rather than hard-coded
663 fields
= self
.decoder
.sigforms
[formname
]
664 for name
in op_fields
:
666 sig
= getattr(fields
, name
.upper())
668 sig
= getattr(fields
, name
)
670 # these are all opcode fields involved in index-selection of CR,
671 # and need to do "standard" arithmetic. CR[BA+32] for example
672 # would, if using SelectableInt, only be 5-bit.
673 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
674 self
.namespace
[name
] = val
676 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
678 self
.namespace
['XER'] = self
.spr
['XER']
679 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
680 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
682 def handle_carry_(self
, inputs
, outputs
, already_done
):
683 inv_a
= yield self
.dec2
.e
.do
.invert_in
685 inputs
[0] = ~inputs
[0]
687 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
689 imm
= yield self
.dec2
.e
.do
.imm_data
.data
690 inputs
.append(SelectableInt(imm
, 64))
691 assert len(outputs
) >= 1
692 print("outputs", repr(outputs
))
693 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
699 print("gt input", x
, output
)
700 gt
= (gtu(x
, output
))
703 cy
= 1 if any(gts
) else 0
705 if not (1 & already_done
):
706 self
.spr
['XER'][XER_bits
['CA']] = cy
708 print("inputs", already_done
, inputs
)
710 # ARGH... different for OP_ADD... *sigh*...
711 op
= yield self
.dec2
.e
.do
.insn_type
712 if op
== MicrOp
.OP_ADD
.value
:
713 res32
= (output
.value
& (1 << 32)) != 0
714 a32
= (inputs
[0].value
& (1 << 32)) != 0
716 b32
= (inputs
[1].value
& (1 << 32)) != 0
719 cy32
= res32 ^ a32 ^ b32
720 print("CA32 ADD", cy32
)
724 print("input", x
, output
)
725 print(" x[32:64]", x
, x
[32:64])
726 print(" o[32:64]", output
, output
[32:64])
727 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
729 cy32
= 1 if any(gts
) else 0
730 print("CA32", cy32
, gts
)
731 if not (2 & already_done
):
732 self
.spr
['XER'][XER_bits
['CA32']] = cy32
734 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
735 if hasattr(self
.dec2
.e
.do
, "invert_in"):
736 inv_a
= yield self
.dec2
.e
.do
.invert_in
738 inputs
[0] = ~inputs
[0]
740 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
742 imm
= yield self
.dec2
.e
.do
.imm_data
.data
743 inputs
.append(SelectableInt(imm
, 64))
744 assert len(outputs
) >= 1
745 print("handle_overflow", inputs
, outputs
, div_overflow
)
746 if len(inputs
) < 2 and div_overflow
is None:
749 # div overflow is different: it's returned by the pseudo-code
750 # because it's more complex than can be done by analysing the output
751 if div_overflow
is not None:
752 ov
, ov32
= div_overflow
, div_overflow
753 # arithmetic overflow can be done by analysing the input and output
754 elif len(inputs
) >= 2:
758 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
759 output_sgn
= exts(output
.value
, output
.bits
) < 0
760 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
761 output_sgn
!= input_sgn
[0] else 0
764 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
765 output32_sgn
= exts(output
.value
, 32) < 0
766 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
767 output32_sgn
!= input32_sgn
[0] else 0
769 self
.spr
['XER'][XER_bits
['OV']] = ov
770 self
.spr
['XER'][XER_bits
['OV32']] = ov32
771 so
= self
.spr
['XER'][XER_bits
['SO']]
773 self
.spr
['XER'][XER_bits
['SO']] = so
775 def handle_comparison(self
, outputs
, cr_idx
=0):
777 assert isinstance(out
, SelectableInt
), \
778 "out zero not a SelectableInt %s" % repr(outputs
)
779 print("handle_comparison", out
.bits
, hex(out
.value
))
780 # TODO - XXX *processor* in 32-bit mode
781 # https://bugs.libre-soc.org/show_bug.cgi?id=424
783 # o32 = exts(out.value, 32)
784 # print ("handle_comparison exts 32 bit", hex(o32))
785 out
= exts(out
.value
, out
.bits
)
786 print("handle_comparison exts", hex(out
))
787 zero
= SelectableInt(out
== 0, 1)
788 positive
= SelectableInt(out
> 0, 1)
789 negative
= SelectableInt(out
< 0, 1)
790 SO
= self
.spr
['XER'][XER_bits
['SO']]
791 print("handle_comparison SO", SO
)
792 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
793 self
.crl
[cr_idx
].eq(cr_field
)
795 def set_pc(self
, pc_val
):
796 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
797 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
800 """set up one instruction
803 pc
= self
.pc
.CIA
.value
807 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
809 raise KeyError("no instruction at 0x%x" % pc
)
810 print("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
811 print("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
813 yield self
.dec2
.sv_rm
.eq(0)
814 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
815 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
816 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
817 yield self
.dec2
.state
.pc
.eq(pc
)
818 if self
.svstate
is not None:
819 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
821 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
823 opcode
= yield self
.dec2
.dec
.opcode_in
824 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
825 pfx
.insn
.value
= opcode
826 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
827 print ("prefix test: opcode:", major
, bin(major
),
828 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
829 self
.is_svp64_mode
= ((major
== 0b000001) and
830 pfx
.insn
[7].value
== 0b1 and
831 pfx
.insn
[9].value
== 0b1)
832 self
.pc
.update_nia(self
.is_svp64_mode
)
833 self
.namespace
['NIA'] = self
.pc
.NIA
834 self
.namespace
['SVSTATE'] = self
.svstate
.spr
835 if not self
.is_svp64_mode
:
838 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
839 print ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
840 print (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
841 print (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
842 sv_rm
= pfx
.rm
.asint(msb0
=True)
843 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
844 print(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
845 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
846 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
849 def execute_one(self
):
850 """execute one instruction
852 # get the disassembly code for this instruction
853 if self
.is_svp64_mode
:
854 if not self
.disassembly
:
855 code
= yield from self
.get_assembly_name()
857 code
= self
.disassembly
[self
._pc
+4]
858 print(" svp64 sim-execute", hex(self
._pc
), code
)
860 if not self
.disassembly
:
861 code
= yield from self
.get_assembly_name()
863 code
= self
.disassembly
[self
._pc
]
864 print("sim-execute", hex(self
._pc
), code
)
865 opname
= code
.split(' ')[0]
867 yield from self
.call(opname
) # execute the instruction
868 except MemException
as e
: # check for memory errors
869 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
870 raise e
# ... re-raise
871 # run a Trap but set DAR first
872 print ("memory unaligned exception, DAR", e
.dar
)
873 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
874 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
877 # don't use this except in special circumstances
878 if not self
.respect_pc
:
881 print("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
883 def get_assembly_name(self
):
884 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
885 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
886 dec_insn
= yield self
.dec2
.e
.do
.insn
887 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
888 asmcode
= yield self
.dec2
.dec
.op
.asmcode
889 int_op
= yield self
.dec2
.dec
.op
.internal_op
890 print("get assembly name asmcode", asmcode
, int_op
,
891 hex(dec_insn
), bin(insn_1_11
))
892 asmop
= insns
.get(asmcode
, None)
894 # sigh reconstruct the assembly instruction name
895 if hasattr(self
.dec2
.e
.do
, "oe"):
896 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
897 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
901 if hasattr(self
.dec2
.e
.do
, "rc"):
902 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
903 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
907 # grrrr have to special-case MUL op (see DecodeOE)
908 print("ov %d en %d rc %d en %d op %d" %
909 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
910 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
915 if not asmop
.endswith("."): # don't add "." to "andis."
918 if hasattr(self
.dec2
.e
.do
, "lk"):
919 lk
= yield self
.dec2
.e
.do
.lk
922 print("int_op", int_op
)
923 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
924 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
928 spr_msb
= yield from self
.get_spr_msb()
929 if int_op
== MicrOp
.OP_MFCR
.value
:
934 # XXX TODO: for whatever weird reason this doesn't work
935 # https://bugs.libre-soc.org/show_bug.cgi?id=390
936 if int_op
== MicrOp
.OP_MTCRF
.value
:
943 def get_spr_msb(self
):
944 dec_insn
= yield self
.dec2
.e
.do
.insn
945 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
947 def call(self
, name
):
948 """call(opcode) - the primary execution point for instructions
950 name
= name
.strip() # remove spaces if not already done so
952 print("halted - not executing", name
)
955 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
956 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
957 asmop
= yield from self
.get_assembly_name()
958 print("call", name
, asmop
)
961 int_op
= yield self
.dec2
.dec
.op
.internal_op
962 spr_msb
= yield from self
.get_spr_msb()
964 instr_is_privileged
= False
965 if int_op
in [MicrOp
.OP_ATTN
.value
,
966 MicrOp
.OP_MFMSR
.value
,
967 MicrOp
.OP_MTMSR
.value
,
968 MicrOp
.OP_MTMSRD
.value
,
970 MicrOp
.OP_RFID
.value
]:
971 instr_is_privileged
= True
972 if int_op
in [MicrOp
.OP_MFSPR
.value
,
973 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
974 instr_is_privileged
= True
976 print("is priv", instr_is_privileged
, hex(self
.msr
.value
),
978 # check MSR priv bit and whether op is privileged: if so, throw trap
979 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
980 self
.call_trap(0x700, PIb
.PRIV
)
983 # check halted condition
988 # check illegal instruction
990 if name
not in ['mtcrf', 'mtocrf']:
991 illegal
= name
!= asmop
993 # sigh deal with setvl not being supported by binutils (.long)
994 if asmop
.startswith('setvl'):
999 print("illegal", name
, asmop
)
1000 self
.call_trap(0x700, PIb
.ILLEG
)
1001 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1002 (name
, asmop
, self
.pc
.CIA
.value
))
1005 info
= self
.instrs
[name
]
1006 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1008 # preserve order of register names
1009 input_names
= create_args(list(info
.read_regs
) +
1010 list(info
.uninit_regs
))
1013 # get SVP64 entry for the current instruction
1014 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1015 if sv_rm
is not None:
1016 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1018 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1019 print ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1021 # get SVSTATE VL (oh and print out some debug stuff)
1022 if self
.is_svp64_mode
:
1023 vl
= self
.svstate
.vl
.asint(msb0
=True)
1024 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1025 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1026 sv_a_nz
= yield self
.dec2
.sv_a_nz
1027 in1
= yield self
.dec2
.e
.read_reg1
.data
1028 print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
1029 vl
, srcstep
, dststep
, sv_a_nz
, in1
)
1031 # get predicate mask
1032 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1033 if self
.is_svp64_mode
:
1034 pmode
= yield self
.dec2
.rm_dec
.predmode
1035 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1036 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1037 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1038 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1039 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1040 if pmode
== SVP64PredMode
.INT
.value
:
1041 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1042 if sv_ptype
== SVPtype
.P2
.value
:
1043 srcmask
= get_predint(self
.gpr
, srcpred
)
1044 elif pmode
== SVP64PredMode
.CR
.value
:
1045 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1046 if sv_ptype
== SVPtype
.P2
.value
:
1047 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1048 print (" pmode", pmode
)
1049 print (" ptype", sv_ptype
)
1050 print (" srcpred", bin(srcpred
))
1051 print (" dstpred", bin(dstpred
))
1052 print (" srcmask", bin(srcmask
))
1053 print (" dstmask", bin(dstmask
))
1054 print (" pred_sz", bin(pred_src_zero
))
1055 print (" pred_dz", bin(pred_dst_zero
))
1057 # okaaay, so here we simply advance srcstep (TODO dststep)
1058 # until the predicate mask has a "1" bit... or we run out of VL
1059 # let srcstep==VL be the indicator to move to next instruction
1060 if not pred_src_zero
:
1061 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1062 print (" skip", bin(1<<srcstep
))
1065 if not pred_dst_zero
:
1066 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1067 print (" skip", bin(1<<dststep
))
1070 # now work out if the relevant mask bits require zeroing
1072 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1074 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1076 # update SVSTATE with new srcstep
1077 self
.svstate
.srcstep
[0:7] = srcstep
1078 self
.svstate
.dststep
[0:7] = dststep
1079 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1080 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1081 yield Settle() # let decoder update
1082 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1083 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1084 print (" srcstep", srcstep
)
1085 print (" dststep", dststep
)
1087 # check if end reached (we let srcstep overrun, above)
1088 # nothing needs doing (TODO zeroing): just do next instruction
1089 if srcstep
== vl
or dststep
== vl
:
1090 self
.svp64_reset_loop()
1091 self
.update_pc_next()
1094 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1095 if self
.is_svp64_mode
and vl
== 0:
1096 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1097 print("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1098 self
.namespace
['NIA'])
1101 # main input registers (RT, RA ...)
1103 for name
in input_names
:
1104 # using PowerDecoder2, first, find the decoder index.
1105 # (mapping name RA RB RC RS to in1, in2, in3)
1106 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1108 # doing this is not part of svp64, it's because output
1109 # registers, to be modified, need to be in the namespace.
1110 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1112 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1115 # in case getting the register number is needed, _RA, _RB
1116 regname
= "_" + name
1117 self
.namespace
[regname
] = regnum
1118 if not self
.is_svp64_mode
or not pred_src_zero
:
1119 print('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1121 reg_val
= self
.fpr(regnum
)
1123 reg_val
= self
.gpr(regnum
)
1125 print('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1127 inputs
.append(reg_val
)
1129 # "special" registers
1130 for special
in info
.special_regs
:
1131 if special
in special_sprs
:
1132 inputs
.append(self
.spr
[special
])
1134 inputs
.append(self
.namespace
[special
])
1136 # clear trap (trap) NIA
1137 self
.trap_nia
= None
1139 # execute actual instruction here
1140 print("inputs", inputs
)
1141 results
= info
.func(self
, *inputs
)
1142 print("results", results
)
1144 # "inject" decorator takes namespace from function locals: we need to
1145 # overwrite NIA being overwritten (sigh)
1146 if self
.trap_nia
is not None:
1147 self
.namespace
['NIA'] = self
.trap_nia
1149 print("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1151 # detect if CA/CA32 already in outputs (sra*, basically)
1154 output_names
= create_args(info
.write_regs
)
1155 for name
in output_names
:
1161 print("carry already done?", bin(already_done
))
1162 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1163 carry_en
= yield self
.dec2
.e
.do
.output_carry
1167 yield from self
.handle_carry_(inputs
, results
, already_done
)
1169 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1170 # detect if overflow was in return result
1173 for name
, output
in zip(output_names
, results
):
1174 if name
== 'overflow':
1177 if hasattr(self
.dec2
.e
.do
, "oe"):
1178 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1179 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1183 print("internal overflow", overflow
, ov_en
, ov_ok
)
1185 yield from self
.handle_overflow(inputs
, results
, overflow
)
1187 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1189 if not self
.is_svp64_mode
or not pred_dst_zero
:
1190 if hasattr(self
.dec2
.e
.do
, "rc"):
1191 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1193 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1194 self
.handle_comparison(results
, regnum
)
1196 # any modified return results?
1198 for name
, output
in zip(output_names
, results
):
1199 if name
== 'overflow': # ignore, done already (above)
1201 if isinstance(output
, int):
1202 output
= SelectableInt(output
, 256)
1203 if name
in ['CA', 'CA32']:
1205 print("writing %s to XER" % name
, output
)
1206 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1208 print("NOT writing %s to XER" % name
, output
)
1209 elif name
in info
.special_regs
:
1210 print('writing special %s' % name
, output
, special_sprs
)
1211 if name
in special_sprs
:
1212 self
.spr
[name
] = output
1214 self
.namespace
[name
].eq(output
)
1216 print('msr written', hex(self
.msr
.value
))
1218 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1221 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1224 # temporary hack for not having 2nd output
1225 regnum
= yield getattr(self
.decoder
, name
)
1227 if self
.is_svp64_mode
and pred_dst_zero
:
1228 print('zeroing reg %d %s' % (regnum
, str(output
)),
1230 output
= SelectableInt(0, 256)
1236 print('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1238 if output
.bits
> 64:
1239 output
= SelectableInt(output
.value
, 64)
1241 self
.fpr
[regnum
] = output
1243 self
.gpr
[regnum
] = output
1245 # check if it is the SVSTATE.src/dest step that needs incrementing
1246 # this is our Sub-Program-Counter loop from 0 to VL-1
1247 if self
.is_svp64_mode
:
1248 # XXX twin predication TODO
1249 vl
= self
.svstate
.vl
.asint(msb0
=True)
1250 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1251 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1252 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1253 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1254 no_out_vec
= not (yield self
.dec2
.no_out_vec
)
1255 no_in_vec
= not (yield self
.dec2
.no_in_vec
)
1256 print (" svstate.vl", vl
)
1257 print (" svstate.mvl", mvl
)
1258 print (" svstate.srcstep", srcstep
)
1259 print (" svstate.dststep", dststep
)
1260 print (" no_out_vec", no_out_vec
)
1261 print (" no_in_vec", no_in_vec
)
1262 print (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1263 # check if srcstep needs incrementing by one, stop PC advancing
1264 # svp64 loop can end early if the dest is scalar for single-pred
1265 # but for 2-pred both src/dest have to be checked.
1266 # XXX this might not be true! it may just be LD/ST
1267 if sv_ptype
== SVPtype
.P2
.value
:
1268 svp64_is_vector
= (no_out_vec
or no_in_vec
)
1270 svp64_is_vector
= no_out_vec
1271 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1272 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1273 self
.svstate
.dststep
+= SelectableInt(1, 7)
1274 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1275 self
.namespace
['NIA'] = self
.pc
.NIA
1276 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1277 print("end of sub-pc call", self
.namespace
['CIA'],
1278 self
.namespace
['NIA'])
1279 return # DO NOT allow PC to update whilst Sub-PC loop running
1280 # reset loop to zero
1281 self
.svp64_reset_loop()
1283 self
.update_pc_next()
1285 def update_pc_next(self
):
1286 # UPDATE program counter
1287 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1288 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1289 print("end of call", self
.namespace
['CIA'],
1290 self
.namespace
['NIA'],
1291 self
.namespace
['SVSTATE'])
1293 def svp64_reset_loop(self
):
1294 self
.svstate
.srcstep
[0:7] = 0
1295 self
.svstate
.dststep
[0:7] = 0
1296 print (" svstate.srcstep loop end (PC to update)")
1297 self
.pc
.update_nia(self
.is_svp64_mode
)
1298 self
.namespace
['NIA'] = self
.pc
.NIA
1299 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1302 """Decorator factory.
1304 this decorator will "inject" variables into the function's namespace,
1305 from the *dictionary* in self.namespace. it therefore becomes possible
1306 to make it look like a whole stack of variables which would otherwise
1307 need "self." inserted in front of them (*and* for those variables to be
1308 added to the instance) "appear" in the function.
1310 "self.namespace['SI']" for example becomes accessible as just "SI" but
1311 *only* inside the function, when decorated.
1313 def variable_injector(func
):
1315 def decorator(*args
, **kwargs
):
1317 func_globals
= func
.__globals
__ # Python 2.6+
1318 except AttributeError:
1319 func_globals
= func
.func_globals
# Earlier versions.
1321 context
= args
[0].namespace
# variables to be injected
1322 saved_values
= func_globals
.copy() # Shallow copy of dict.
1323 func_globals
.update(context
)
1324 result
= func(*args
, **kwargs
)
1325 print("globals after", func_globals
['CIA'], func_globals
['NIA'])
1326 print("args[0]", args
[0].namespace
['CIA'],
1327 args
[0].namespace
['NIA'],
1328 args
[0].namespace
['SVSTATE'])
1329 args
[0].namespace
= func_globals
1330 #exec (func.__code__, func_globals)
1333 # func_globals = saved_values # Undo changes.
1339 return variable_injector