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
,
29 from openpower
.decoder
.power_enums
import SVPtype
31 from openpower
.decoder
.helpers
import exts
, gtu
, ltu
, undefined
32 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
33 from openpower
.consts
import SVP64CROffs
34 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
36 from openpower
.decoder
.isa
.radixmmu
import RADIX
37 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
39 from openpower
.util
import log
41 from collections
import namedtuple
45 instruction_info
= namedtuple('instruction_info',
46 'func read_regs uninit_regs write_regs ' +
47 'special_regs op_fields form asmregs')
58 # TODO (lkcl): adjust other registers that should be in a particular order
59 # probably CA, CA32, and CR
80 "overflow": 7, # should definitely be last
83 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
86 def create_args(reglist
, extra
=None):
87 retval
= list(OrderedSet(reglist
))
88 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
90 return [extra
] + retval
96 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
99 self
.isacaller
= isacaller
100 self
.svstate
= svstate
102 self
[i
] = SelectableInt(regfile
[i
], 64)
104 def __call__(self
, ridx
):
107 def set_form(self
, form
):
110 def getz(self
, rnum
):
111 # rnum = rnum.value # only SelectableInt allowed
112 log("GPR getzero?", rnum
)
114 return SelectableInt(0, 64)
117 def _get_regnum(self
, attr
):
118 getform
= self
.sd
.sigforms
[self
.form
]
119 rnum
= getattr(getform
, attr
)
122 def ___getitem__(self
, attr
):
123 """ XXX currently not used
125 rnum
= self
._get
_regnum
(attr
)
126 offs
= self
.svstate
.srcstep
127 log("GPR getitem", attr
, rnum
, "srcoffs", offs
)
128 return self
.regfile
[rnum
]
130 def dump(self
, printout
=True):
132 for i
in range(len(self
)):
133 res
.append(self
[i
].value
)
135 for i
in range(0, len(res
), 8):
138 s
.append("%08x" % res
[i
+j
])
140 print("reg", "%2d" % i
, s
)
145 def __init__(self
, dec2
, initial_sprs
={}):
148 for key
, v
in initial_sprs
.items():
149 if isinstance(key
, SelectableInt
):
151 key
= special_sprs
.get(key
, key
)
152 if isinstance(key
, int):
155 info
= spr_byname
[key
]
156 if not isinstance(v
, SelectableInt
):
157 v
= SelectableInt(v
, info
.length
)
160 def __getitem__(self
, key
):
162 log("dict", self
.items())
163 # if key in special_sprs get the special spr, otherwise return key
164 if isinstance(key
, SelectableInt
):
166 if isinstance(key
, int):
167 key
= spr_dict
[key
].SPR
168 key
= special_sprs
.get(key
, key
)
169 if key
== 'HSRR0': # HACK!
171 if key
== 'HSRR1': # HACK!
174 res
= dict.__getitem
__(self
, key
)
176 if isinstance(key
, int):
179 info
= spr_byname
[key
]
180 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
181 res
= dict.__getitem
__(self
, key
)
182 log("spr returning", key
, res
)
185 def __setitem__(self
, key
, value
):
186 if isinstance(key
, SelectableInt
):
188 if isinstance(key
, int):
189 key
= spr_dict
[key
].SPR
191 key
= special_sprs
.get(key
, key
)
192 if key
== 'HSRR0': # HACK!
193 self
.__setitem
__('SRR0', value
)
194 if key
== 'HSRR1': # HACK!
195 self
.__setitem
__('SRR1', value
)
196 log("setting spr", key
, value
)
197 dict.__setitem
__(self
, key
, value
)
199 def __call__(self
, ridx
):
202 def dump(self
, printout
=True):
204 keys
= list(self
.keys())
207 sprname
= spr_dict
.get(k
, None)
211 sprname
= sprname
.SPR
212 res
.append((sprname
, self
[k
].value
))
214 for sprname
, value
in res
:
215 print(" ", sprname
, hex(value
))
220 def __init__(self
, pc_init
=0):
221 self
.CIA
= SelectableInt(pc_init
, 64)
222 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
224 def update_nia(self
, is_svp64
):
225 increment
= 8 if is_svp64
else 4
226 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
228 def update(self
, namespace
, is_svp64
):
229 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
231 self
.CIA
= namespace
['NIA'].narrow(64)
232 self
.update_nia(is_svp64
)
233 namespace
['CIA'] = self
.CIA
234 namespace
['NIA'] = self
.NIA
237 # Simple-V: see https://libre-soc.org/openpower/sv
239 def __init__(self
, init
=0):
240 self
.spr
= SelectableInt(init
, 32)
241 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
242 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
243 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
244 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
245 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
246 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
247 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
252 def __init__(self
, init
=0):
253 self
.spr
= SelectableInt(init
, 24)
254 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
255 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
256 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
257 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
258 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
259 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
260 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
261 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
262 # these cover the same extra field, split into parts as EXTRA2
263 self
.extra2
= list(range(4))
264 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
265 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
266 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
267 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
268 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
269 # and here as well, but EXTRA3
270 self
.extra3
= list(range(3))
271 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
272 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
273 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
276 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
277 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
278 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
279 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
280 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
281 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
282 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
283 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
284 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
287 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
288 class SVP64PrefixFields
:
290 self
.insn
= SelectableInt(0, 32)
291 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
292 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
293 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
294 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
295 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
298 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
299 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
300 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
304 # See PowerISA Version 3.0 B Book 1
305 # Section 2.3.1 Condition Register pages 30 - 31
307 LT
= FL
= 0 # negative, less than, floating-point less than
308 GT
= FG
= 1 # positive, greater than, floating-point greater than
309 EQ
= FE
= 2 # equal, floating-point equal
310 SO
= FU
= 3 # summary overflow, floating-point unordered
312 def __init__(self
, init
=0):
313 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
314 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
315 self
.cr
= SelectableInt(init
, 64) # underlying reg
316 # field-selectable versions of Condition Register TODO check bitranges?
319 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
320 _cr
= FieldSelectableInt(self
.cr
, bits
)
323 # decode SVP64 predicate integer to reg number and invert
324 def get_predint(gpr
, mask
):
327 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
328 if mask
== SVP64PredInt
.ALWAYS
.value
:
329 return 0xffff_ffff_ffff_ffff
330 if mask
== SVP64PredInt
.R3_UNARY
.value
:
331 return 1 << (gpr(3).value
& 0b111111)
332 if mask
== SVP64PredInt
.R3
.value
:
334 if mask
== SVP64PredInt
.R3_N
.value
:
336 if mask
== SVP64PredInt
.R10
.value
:
338 if mask
== SVP64PredInt
.R10_N
.value
:
339 return ~
gpr(10).value
340 if mask
== SVP64PredInt
.R30
.value
:
342 if mask
== SVP64PredInt
.R30_N
.value
:
343 return ~
gpr(30).value
345 # decode SVP64 predicate CR to reg number and invert status
346 def _get_predcr(mask
):
347 if mask
== SVP64PredCR
.LT
.value
:
349 if mask
== SVP64PredCR
.GE
.value
:
351 if mask
== SVP64PredCR
.GT
.value
:
353 if mask
== SVP64PredCR
.LE
.value
:
355 if mask
== SVP64PredCR
.EQ
.value
:
357 if mask
== SVP64PredCR
.NE
.value
:
359 if mask
== SVP64PredCR
.SO
.value
:
361 if mask
== SVP64PredCR
.NS
.value
:
364 # read individual CR fields (0..VL-1), extract the required bit
365 # and construct the mask
366 def get_predcr(crl
, mask
, vl
):
367 idx
, noninv
= _get_predcr(mask
)
370 cr
= crl
[i
+SVP64CROffs
.CRPred
]
371 if cr
[idx
].value
== noninv
:
376 def get_pdecode_idx_in(dec2
, name
):
378 in1_sel
= yield op
.in1_sel
379 in2_sel
= yield op
.in2_sel
380 in3_sel
= yield op
.in3_sel
381 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
382 in1
= yield dec2
.e
.read_reg1
.data
383 in2
= yield dec2
.e
.read_reg2
.data
384 in3
= yield dec2
.e
.read_reg3
.data
385 in1_isvec
= yield dec2
.in1_isvec
386 in2_isvec
= yield dec2
.in2_isvec
387 in3_isvec
= yield dec2
.in3_isvec
388 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
390 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
392 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
394 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
396 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
398 # identify which regnames map to in1/2/3
400 if (in1_sel
== In1Sel
.RA
.value
or
401 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
402 return in1
, in1_isvec
403 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
404 return in1
, in1_isvec
406 if in2_sel
== In2Sel
.RB
.value
:
407 return in2
, in2_isvec
408 if in3_sel
== In3Sel
.RB
.value
:
409 return in3
, in3_isvec
410 # XXX TODO, RC doesn't exist yet!
412 assert False, "RC does not exist yet"
414 if in1_sel
== In1Sel
.RS
.value
:
415 return in1
, in1_isvec
416 if in2_sel
== In2Sel
.RS
.value
:
417 return in2
, in2_isvec
418 if in3_sel
== In3Sel
.RS
.value
:
419 return in3
, in3_isvec
421 if in1_sel
== In1Sel
.FRA
.value
:
422 return in1
, in1_isvec
424 if in2_sel
== In2Sel
.FRB
.value
:
425 return in2
, in2_isvec
427 if in3_sel
== In3Sel
.FRC
.value
:
428 return in3
, in3_isvec
430 if in1_sel
== In1Sel
.FRS
.value
:
431 return in1
, in1_isvec
432 if in3_sel
== In3Sel
.FRS
.value
:
433 return in3
, in3_isvec
437 def get_pdecode_cr_out(dec2
, name
):
439 out_sel
= yield op
.cr_out
440 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
441 sv_cr_out
= yield op
.sv_cr_out
442 spec
= yield dec2
.crout_svdec
.spec
443 sv_override
= yield dec2
.dec_cr_out
.sv_override
444 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
445 out
= yield dec2
.e
.write_cr
.data
446 o_isvec
= yield dec2
.o_isvec
447 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
448 log (" sv_cr_out", sv_cr_out
)
449 log (" cr_bf", out_bitfield
)
451 log (" override", sv_override
)
452 # identify which regnames map to out / o2
454 if out_sel
== CROutSel
.CR0
.value
:
456 log ("get_pdecode_cr_out not found", name
)
460 def get_pdecode_idx_out(dec2
, name
):
462 out_sel
= yield op
.out_sel
463 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
464 out
= yield dec2
.e
.write_reg
.data
465 o_isvec
= yield dec2
.o_isvec
466 # identify which regnames map to out / o2
468 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
469 if out_sel
== OutSel
.RA
.value
:
472 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
473 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
)
474 if out_sel
== OutSel
.RT
.value
:
477 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
478 if out_sel
== OutSel
.FRA
.value
:
481 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
482 OutSel
.FRT
.value
, out
, o_isvec
)
483 if out_sel
== OutSel
.FRT
.value
:
485 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
489 def get_pdecode_idx_out2(dec2
, name
):
490 # check first if register is activated for write
491 out_ok
= yield dec2
.e
.write_ea
.ok
496 out_sel
= yield op
.out_sel
497 out
= yield dec2
.e
.write_ea
.data
498 o_isvec
= yield dec2
.o2_isvec
499 log ("get_pdecode_idx_out2", name
, out_sel
, out
, o_isvec
)
501 if hasattr(op
, "upd"):
502 # update mode LD/ST uses read-reg A also as an output
504 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
505 out_sel
, OutSel
.RA
.value
,
507 if upd
== LDSTMode
.update
.value
:
513 # decoder2 - an instance of power_decoder2
514 # regfile - a list of initial values for the registers
515 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
516 # respect_pc - tracks the program counter. requires initial_insns
517 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
518 initial_mem
=None, initial_msr
=0,
529 self
.bigendian
= bigendian
531 self
.is_svp64_mode
= False
532 self
.respect_pc
= respect_pc
533 if initial_sprs
is None:
535 if initial_mem
is None:
537 if fpregfile
is None:
539 if initial_insns
is None:
541 assert self
.respect_pc
== False, "instructions required to honor pc"
543 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
544 log("ISACaller initial_msr", initial_msr
)
546 # "fake program counter" mode (for unit testing)
550 if isinstance(initial_mem
, tuple):
551 self
.fake_pc
= initial_mem
[0]
552 disasm_start
= self
.fake_pc
554 disasm_start
= initial_pc
556 # disassembly: we need this for now (not given from the decoder)
557 self
.disassembly
= {}
559 for i
, code
in enumerate(disassembly
):
560 self
.disassembly
[i
*4 + disasm_start
] = code
562 # set up registers, instruction memory, data memory, PC, SPRs, MSR
563 self
.svp64rm
= SVP64RM()
564 if initial_svstate
is None:
566 if isinstance(initial_svstate
, int):
567 initial_svstate
= SVP64State(initial_svstate
)
568 self
.svstate
= initial_svstate
569 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
570 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
571 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
572 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
573 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
574 # MMU mode, redirect underlying Mem through RADIX
575 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
577 self
.mem
= RADIX(self
.mem
, self
)
579 self
.imem
= RADIX(self
.imem
, self
)
583 # FPR (same as GPR except for FP nums)
584 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
585 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
586 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
587 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
589 # 2.3.2 LR (actually SPR #8) -- Done
590 # 2.3.3 CTR (actually SPR #9) -- Done
591 # 2.3.4 TAR (actually SPR #815)
592 # 3.2.2 p45 XER (actually SPR #1) -- Done
593 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
595 # create CR then allow portions of it to be "selectable" (below)
596 self
.cr_fields
= CRFields(initial_cr
)
597 self
.cr
= self
.cr_fields
.cr
599 # "undefined", just set to variable-bit-width int (use exts "max")
600 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
603 self
.namespace
.update(self
.spr
)
604 self
.namespace
.update({'GPR': self
.gpr
,
608 'memassign': self
.memassign
,
611 'SVSTATE': self
.svstate
.spr
,
614 'undefined': undefined
,
615 'mode_is_64bit': True,
619 # update pc to requested start point
620 self
.set_pc(initial_pc
)
622 # field-selectable versions of Condition Register
623 self
.crl
= self
.cr_fields
.crl
625 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
627 self
.decoder
= decoder2
.dec
630 def call_trap(self
, trap_addr
, trap_bit
):
631 """calls TRAP and sets up NIA to the new execution location.
632 next instruction will begin at trap_addr.
634 self
.TRAP(trap_addr
, trap_bit
)
635 self
.namespace
['NIA'] = self
.trap_nia
636 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
638 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
639 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
641 TRAP function is callable from inside the pseudocode itself,
642 hence the default arguments. when calling from inside ISACaller
643 it is best to use call_trap()
645 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
646 # store CIA(+4?) in SRR0, set NIA to 0x700
647 # store MSR in SRR1, set MSR to um errr something, have to check spec
648 # store SVSTATE (if enabled) in SVSRR0
649 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
650 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
651 if self
.is_svp64_mode
:
652 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
653 self
.trap_nia
= SelectableInt(trap_addr
, 64)
654 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
656 # set exception bits. TODO: this should, based on the address
657 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
658 # bits appropriately. however it turns out that *for now* in all
659 # cases (all trap_addrs) the exact same thing is needed.
660 self
.msr
[MSRb
.IR
] = 0
661 self
.msr
[MSRb
.DR
] = 0
662 self
.msr
[MSRb
.FE0
] = 0
663 self
.msr
[MSRb
.FE1
] = 0
664 self
.msr
[MSRb
.EE
] = 0
665 self
.msr
[MSRb
.RI
] = 0
666 self
.msr
[MSRb
.SF
] = 1
667 self
.msr
[MSRb
.TM
] = 0
668 self
.msr
[MSRb
.VEC
] = 0
669 self
.msr
[MSRb
.VSX
] = 0
670 self
.msr
[MSRb
.PR
] = 0
671 self
.msr
[MSRb
.FP
] = 0
672 self
.msr
[MSRb
.PMM
] = 0
673 self
.msr
[MSRb
.TEs
] = 0
674 self
.msr
[MSRb
.TEe
] = 0
675 self
.msr
[MSRb
.UND
] = 0
676 self
.msr
[MSRb
.LE
] = 1
678 def memassign(self
, ea
, sz
, val
):
679 self
.mem
.memassign(ea
, sz
, val
)
681 def prep_namespace(self
, formname
, op_fields
):
682 # TODO: get field names from form in decoder*1* (not decoder2)
683 # decoder2 is hand-created, and decoder1.sigform is auto-generated
685 # then "yield" fields only from op_fields rather than hard-coded
687 fields
= self
.decoder
.sigforms
[formname
]
688 for name
in op_fields
:
690 sig
= getattr(fields
, name
.upper())
692 sig
= getattr(fields
, name
)
694 # these are all opcode fields involved in index-selection of CR,
695 # and need to do "standard" arithmetic. CR[BA+32] for example
696 # would, if using SelectableInt, only be 5-bit.
697 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
698 self
.namespace
[name
] = val
700 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
702 self
.namespace
['XER'] = self
.spr
['XER']
703 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
704 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
706 def handle_carry_(self
, inputs
, outputs
, already_done
):
707 inv_a
= yield self
.dec2
.e
.do
.invert_in
709 inputs
[0] = ~inputs
[0]
711 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
713 imm
= yield self
.dec2
.e
.do
.imm_data
.data
714 inputs
.append(SelectableInt(imm
, 64))
715 assert len(outputs
) >= 1
716 log("outputs", repr(outputs
))
717 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
723 log("gt input", x
, output
)
724 gt
= (gtu(x
, output
))
727 cy
= 1 if any(gts
) else 0
729 if not (1 & already_done
):
730 self
.spr
['XER'][XER_bits
['CA']] = cy
732 log("inputs", already_done
, inputs
)
734 # ARGH... different for OP_ADD... *sigh*...
735 op
= yield self
.dec2
.e
.do
.insn_type
736 if op
== MicrOp
.OP_ADD
.value
:
737 res32
= (output
.value
& (1 << 32)) != 0
738 a32
= (inputs
[0].value
& (1 << 32)) != 0
740 b32
= (inputs
[1].value
& (1 << 32)) != 0
743 cy32
= res32 ^ a32 ^ b32
744 log("CA32 ADD", cy32
)
748 log("input", x
, output
)
749 log(" x[32:64]", x
, x
[32:64])
750 log(" o[32:64]", output
, output
[32:64])
751 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
753 cy32
= 1 if any(gts
) else 0
754 log("CA32", cy32
, gts
)
755 if not (2 & already_done
):
756 self
.spr
['XER'][XER_bits
['CA32']] = cy32
758 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
759 if hasattr(self
.dec2
.e
.do
, "invert_in"):
760 inv_a
= yield self
.dec2
.e
.do
.invert_in
762 inputs
[0] = ~inputs
[0]
764 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
766 imm
= yield self
.dec2
.e
.do
.imm_data
.data
767 inputs
.append(SelectableInt(imm
, 64))
768 assert len(outputs
) >= 1
769 log("handle_overflow", inputs
, outputs
, div_overflow
)
770 if len(inputs
) < 2 and div_overflow
is None:
773 # div overflow is different: it's returned by the pseudo-code
774 # because it's more complex than can be done by analysing the output
775 if div_overflow
is not None:
776 ov
, ov32
= div_overflow
, div_overflow
777 # arithmetic overflow can be done by analysing the input and output
778 elif len(inputs
) >= 2:
782 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
783 output_sgn
= exts(output
.value
, output
.bits
) < 0
784 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
785 output_sgn
!= input_sgn
[0] else 0
788 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
789 output32_sgn
= exts(output
.value
, 32) < 0
790 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
791 output32_sgn
!= input32_sgn
[0] else 0
793 self
.spr
['XER'][XER_bits
['OV']] = ov
794 self
.spr
['XER'][XER_bits
['OV32']] = ov32
795 so
= self
.spr
['XER'][XER_bits
['SO']]
797 self
.spr
['XER'][XER_bits
['SO']] = so
799 def handle_comparison(self
, outputs
, cr_idx
=0):
801 assert isinstance(out
, SelectableInt
), \
802 "out zero not a SelectableInt %s" % repr(outputs
)
803 log("handle_comparison", out
.bits
, hex(out
.value
))
804 # TODO - XXX *processor* in 32-bit mode
805 # https://bugs.libre-soc.org/show_bug.cgi?id=424
807 # o32 = exts(out.value, 32)
808 # print ("handle_comparison exts 32 bit", hex(o32))
809 out
= exts(out
.value
, out
.bits
)
810 log("handle_comparison exts", hex(out
))
811 zero
= SelectableInt(out
== 0, 1)
812 positive
= SelectableInt(out
> 0, 1)
813 negative
= SelectableInt(out
< 0, 1)
814 SO
= self
.spr
['XER'][XER_bits
['SO']]
815 log("handle_comparison SO", SO
)
816 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
817 self
.crl
[cr_idx
].eq(cr_field
)
819 def set_pc(self
, pc_val
):
820 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
821 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
823 def get_next_insn(self
):
827 pc
= self
.pc
.CIA
.value
830 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
832 raise KeyError("no instruction at 0x%x" % pc
)
836 """set up one instruction
838 pc
, insn
= self
.get_next_insn()
839 yield from self
.setup_next_insn(pc
, insn
)
841 def setup_next_insn(self
, pc
, ins
):
842 """set up next instruction
845 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
846 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
848 yield self
.dec2
.sv_rm
.eq(0)
849 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
850 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
851 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
852 yield self
.dec2
.state
.pc
.eq(pc
)
853 if self
.svstate
is not None:
854 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
856 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
858 opcode
= yield self
.dec2
.dec
.opcode_in
859 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
860 pfx
.insn
.value
= opcode
861 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
862 log ("prefix test: opcode:", major
, bin(major
),
863 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
864 self
.is_svp64_mode
= ((major
== 0b000001) and
865 pfx
.insn
[7].value
== 0b1 and
866 pfx
.insn
[9].value
== 0b1)
867 self
.pc
.update_nia(self
.is_svp64_mode
)
868 self
.namespace
['NIA'] = self
.pc
.NIA
869 self
.namespace
['SVSTATE'] = self
.svstate
.spr
870 if not self
.is_svp64_mode
:
873 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
874 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
875 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
876 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
877 sv_rm
= pfx
.rm
.asint(msb0
=True)
878 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
879 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
880 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
881 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
884 def execute_one(self
):
885 """execute one instruction
887 # get the disassembly code for this instruction
888 if self
.is_svp64_mode
:
889 if not self
.disassembly
:
890 code
= yield from self
.get_assembly_name()
892 code
= self
.disassembly
[self
._pc
+4]
893 log(" svp64 sim-execute", hex(self
._pc
), code
)
895 if not self
.disassembly
:
896 code
= yield from self
.get_assembly_name()
898 code
= self
.disassembly
[self
._pc
]
899 log("sim-execute", hex(self
._pc
), code
)
900 opname
= code
.split(' ')[0]
902 yield from self
.call(opname
) # execute the instruction
903 except MemException
as e
: # check for memory errors
904 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
905 raise e
# ... re-raise
906 # run a Trap but set DAR first
907 print ("memory unaligned exception, DAR", e
.dar
)
908 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
909 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
912 # don't use this except in special circumstances
913 if not self
.respect_pc
:
916 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
918 def get_assembly_name(self
):
919 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
920 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
921 dec_insn
= yield self
.dec2
.e
.do
.insn
922 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
923 asmcode
= yield self
.dec2
.dec
.op
.asmcode
924 int_op
= yield self
.dec2
.dec
.op
.internal_op
925 log("get assembly name asmcode", asmcode
, int_op
,
926 hex(dec_insn
), bin(insn_1_11
))
927 asmop
= insns
.get(asmcode
, None)
929 # sigh reconstruct the assembly instruction name
930 if hasattr(self
.dec2
.e
.do
, "oe"):
931 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
932 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
936 if hasattr(self
.dec2
.e
.do
, "rc"):
937 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
938 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
942 # grrrr have to special-case MUL op (see DecodeOE)
943 log("ov %d en %d rc %d en %d op %d" %
944 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
945 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
950 if not asmop
.endswith("."): # don't add "." to "andis."
953 if hasattr(self
.dec2
.e
.do
, "lk"):
954 lk
= yield self
.dec2
.e
.do
.lk
957 log("int_op", int_op
)
958 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
959 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
963 spr_msb
= yield from self
.get_spr_msb()
964 if int_op
== MicrOp
.OP_MFCR
.value
:
969 # XXX TODO: for whatever weird reason this doesn't work
970 # https://bugs.libre-soc.org/show_bug.cgi?id=390
971 if int_op
== MicrOp
.OP_MTCRF
.value
:
978 def get_spr_msb(self
):
979 dec_insn
= yield self
.dec2
.e
.do
.insn
980 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
982 def call(self
, name
):
983 """call(opcode) - the primary execution point for instructions
985 name
= name
.strip() # remove spaces if not already done so
987 log("halted - not executing", name
)
990 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
991 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
992 asmop
= yield from self
.get_assembly_name()
993 log("call", name
, asmop
)
996 int_op
= yield self
.dec2
.dec
.op
.internal_op
997 spr_msb
= yield from self
.get_spr_msb()
999 instr_is_privileged
= False
1000 if int_op
in [MicrOp
.OP_ATTN
.value
,
1001 MicrOp
.OP_MFMSR
.value
,
1002 MicrOp
.OP_MTMSR
.value
,
1003 MicrOp
.OP_MTMSRD
.value
,
1005 MicrOp
.OP_RFID
.value
]:
1006 instr_is_privileged
= True
1007 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1008 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1009 instr_is_privileged
= True
1011 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1013 # check MSR priv bit and whether op is privileged: if so, throw trap
1014 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1015 self
.call_trap(0x700, PIb
.PRIV
)
1018 # check halted condition
1023 # check illegal instruction
1025 if name
not in ['mtcrf', 'mtocrf']:
1026 illegal
= name
!= asmop
1028 # sigh deal with setvl not being supported by binutils (.long)
1029 if asmop
.startswith('setvl'):
1034 print("illegal", name
, asmop
)
1035 self
.call_trap(0x700, PIb
.ILLEG
)
1036 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1037 (name
, asmop
, self
.pc
.CIA
.value
))
1040 # nop has to be supported, we could let the actual op calculate
1041 # but PowerDecoder has a pattern for nop
1043 self
.update_pc_next()
1046 info
= self
.instrs
[name
]
1047 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1049 # preserve order of register names
1050 input_names
= create_args(list(info
.read_regs
) +
1051 list(info
.uninit_regs
))
1054 # get SVP64 entry for the current instruction
1055 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1056 if sv_rm
is not None:
1057 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1059 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1060 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1062 # get SVSTATE VL (oh and print out some debug stuff)
1063 if self
.is_svp64_mode
:
1064 vl
= self
.svstate
.vl
.asint(msb0
=True)
1065 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1066 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1067 sv_a_nz
= yield self
.dec2
.sv_a_nz
1068 in1
= yield self
.dec2
.e
.read_reg1
.data
1069 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
1070 vl
, srcstep
, dststep
, sv_a_nz
, in1
)
1072 # get predicate mask
1073 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1074 if self
.is_svp64_mode
:
1075 pmode
= yield self
.dec2
.rm_dec
.predmode
1076 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1077 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1078 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1079 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1080 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1081 if pmode
== SVP64PredMode
.INT
.value
:
1082 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1083 if sv_ptype
== SVPtype
.P2
.value
:
1084 srcmask
= get_predint(self
.gpr
, srcpred
)
1085 elif pmode
== SVP64PredMode
.CR
.value
:
1086 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1087 if sv_ptype
== SVPtype
.P2
.value
:
1088 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1089 log (" pmode", pmode
)
1090 log (" ptype", sv_ptype
)
1091 log (" srcpred", bin(srcpred
))
1092 log (" dstpred", bin(dstpred
))
1093 log (" srcmask", bin(srcmask
))
1094 log (" dstmask", bin(dstmask
))
1095 log (" pred_sz", bin(pred_src_zero
))
1096 log (" pred_dz", bin(pred_dst_zero
))
1098 # okaaay, so here we simply advance srcstep (TODO dststep)
1099 # until the predicate mask has a "1" bit... or we run out of VL
1100 # let srcstep==VL be the indicator to move to next instruction
1101 if not pred_src_zero
:
1102 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1103 log (" skip", bin(1<<srcstep
))
1106 if not pred_dst_zero
:
1107 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1108 log (" skip", bin(1<<dststep
))
1111 # now work out if the relevant mask bits require zeroing
1113 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1115 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1117 # update SVSTATE with new srcstep
1118 self
.svstate
.srcstep
[0:7] = srcstep
1119 self
.svstate
.dststep
[0:7] = dststep
1120 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1121 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1122 yield Settle() # let decoder update
1123 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1124 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1125 log (" srcstep", srcstep
)
1126 log (" dststep", dststep
)
1128 # check if end reached (we let srcstep overrun, above)
1129 # nothing needs doing (TODO zeroing): just do next instruction
1130 if srcstep
== vl
or dststep
== vl
:
1131 self
.svp64_reset_loop()
1132 self
.update_pc_next()
1135 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1136 if self
.is_svp64_mode
and vl
== 0:
1137 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1138 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1139 self
.namespace
['NIA'])
1142 # in SVP64 mode for LD/ST work out immediate
1143 replace_d
= False # replace constant in pseudocode
1144 if self
.is_svp64_mode
:
1145 D
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1146 D
= exts(D
, 16) # sign-extend to integer
1147 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1148 # get the right step. LD is from srcstep, ST is dststep
1149 op
= yield self
.dec2
.e
.do
.insn_type
1151 if op
== MicrOp
.OP_LOAD
.value
:
1153 log("D-field src", D
, offsmul
)
1154 elif op
== MicrOp
.OP_STORE
.value
:
1156 log("D-field dst", D
, offsmul
)
1157 # Unit-Strided LD/ST adds offset*width to immediate
1158 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1159 ldst_len
= yield self
.dec2
.e
.do
.data_len
1160 D
= SelectableInt(D
+ offsmul
* ldst_len
, 32)
1162 # Element-strided multiplies the immediate by element step
1163 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1164 D
= SelectableInt(D
* offsmul
, 32)
1166 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1167 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1168 log("LDSTmode", ldstmode
, offsmul
, D
, ldst_ra_vec
, ldst_imz_in
)
1171 self
.namespace
['D'] = D
1173 # main input registers (RT, RA ...)
1175 for name
in input_names
:
1176 # using PowerDecoder2, first, find the decoder index.
1177 # (mapping name RA RB RC RS to in1, in2, in3)
1178 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1180 # doing this is not part of svp64, it's because output
1181 # registers, to be modified, need to be in the namespace.
1182 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1184 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1187 # in case getting the register number is needed, _RA, _RB
1188 regname
= "_" + name
1189 self
.namespace
[regname
] = regnum
1190 if not self
.is_svp64_mode
or not pred_src_zero
:
1191 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1193 reg_val
= self
.fpr(regnum
)
1195 reg_val
= self
.gpr(regnum
)
1197 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1199 inputs
.append(reg_val
)
1201 # "special" registers
1202 for special
in info
.special_regs
:
1203 if special
in special_sprs
:
1204 inputs
.append(self
.spr
[special
])
1206 inputs
.append(self
.namespace
[special
])
1208 # clear trap (trap) NIA
1209 self
.trap_nia
= None
1211 # execute actual instruction here
1212 log("inputs", inputs
)
1213 results
= info
.func(self
, *inputs
)
1214 log("results", results
)
1216 # "inject" decorator takes namespace from function locals: we need to
1217 # overwrite NIA being overwritten (sigh)
1218 if self
.trap_nia
is not None:
1219 self
.namespace
['NIA'] = self
.trap_nia
1221 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1223 # detect if CA/CA32 already in outputs (sra*, basically)
1226 output_names
= create_args(info
.write_regs
)
1227 for name
in output_names
:
1233 log("carry already done?", bin(already_done
))
1234 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1235 carry_en
= yield self
.dec2
.e
.do
.output_carry
1239 yield from self
.handle_carry_(inputs
, results
, already_done
)
1241 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1242 # detect if overflow was in return result
1245 for name
, output
in zip(output_names
, results
):
1246 if name
== 'overflow':
1249 if hasattr(self
.dec2
.e
.do
, "oe"):
1250 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1251 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1255 log("internal overflow", overflow
, ov_en
, ov_ok
)
1257 yield from self
.handle_overflow(inputs
, results
, overflow
)
1259 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1261 if not self
.is_svp64_mode
or not pred_dst_zero
:
1262 if hasattr(self
.dec2
.e
.do
, "rc"):
1263 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1265 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1266 self
.handle_comparison(results
, regnum
)
1268 # any modified return results?
1270 for name
, output
in zip(output_names
, results
):
1271 if name
== 'overflow': # ignore, done already (above)
1273 if isinstance(output
, int):
1274 output
= SelectableInt(output
, 256)
1275 if name
in ['CA', 'CA32']:
1277 log("writing %s to XER" % name
, output
)
1278 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1280 log("NOT writing %s to XER" % name
, output
)
1281 elif name
in info
.special_regs
:
1282 log('writing special %s' % name
, output
, special_sprs
)
1283 if name
in special_sprs
:
1284 self
.spr
[name
] = output
1286 self
.namespace
[name
].eq(output
)
1288 log('msr written', hex(self
.msr
.value
))
1290 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1293 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1296 # temporary hack for not having 2nd output
1297 regnum
= yield getattr(self
.decoder
, name
)
1299 if self
.is_svp64_mode
and pred_dst_zero
:
1300 log('zeroing reg %d %s' % (regnum
, str(output
)),
1302 output
= SelectableInt(0, 256)
1308 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1310 if output
.bits
> 64:
1311 output
= SelectableInt(output
.value
, 64)
1313 self
.fpr
[regnum
] = output
1315 self
.gpr
[regnum
] = output
1317 # check if it is the SVSTATE.src/dest step that needs incrementing
1318 # this is our Sub-Program-Counter loop from 0 to VL-1
1319 if self
.is_svp64_mode
:
1320 # XXX twin predication TODO
1321 vl
= self
.svstate
.vl
.asint(msb0
=True)
1322 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1323 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1324 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1325 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1326 no_out_vec
= not (yield self
.dec2
.no_out_vec
)
1327 no_in_vec
= not (yield self
.dec2
.no_in_vec
)
1328 log (" svstate.vl", vl
)
1329 log (" svstate.mvl", mvl
)
1330 log (" svstate.srcstep", srcstep
)
1331 log (" svstate.dststep", dststep
)
1332 log (" no_out_vec", no_out_vec
)
1333 log (" no_in_vec", no_in_vec
)
1334 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1335 # check if srcstep needs incrementing by one, stop PC advancing
1336 # svp64 loop can end early if the dest is scalar for single-pred
1337 # but for 2-pred both src/dest have to be checked.
1338 # XXX this might not be true! it may just be LD/ST
1339 if sv_ptype
== SVPtype
.P2
.value
:
1340 svp64_is_vector
= (no_out_vec
or no_in_vec
)
1342 svp64_is_vector
= no_out_vec
1343 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1344 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1345 self
.svstate
.dststep
+= SelectableInt(1, 7)
1346 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1347 self
.namespace
['NIA'] = self
.pc
.NIA
1348 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1349 log("end of sub-pc call", self
.namespace
['CIA'],
1350 self
.namespace
['NIA'])
1351 return # DO NOT allow PC to update whilst Sub-PC loop running
1352 # reset loop to zero
1353 self
.svp64_reset_loop()
1355 self
.update_pc_next()
1357 def update_pc_next(self
):
1358 # UPDATE program counter
1359 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1360 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1361 log("end of call", self
.namespace
['CIA'],
1362 self
.namespace
['NIA'],
1363 self
.namespace
['SVSTATE'])
1365 def svp64_reset_loop(self
):
1366 self
.svstate
.srcstep
[0:7] = 0
1367 self
.svstate
.dststep
[0:7] = 0
1368 log (" svstate.srcstep loop end (PC to update)")
1369 self
.pc
.update_nia(self
.is_svp64_mode
)
1370 self
.namespace
['NIA'] = self
.pc
.NIA
1371 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1374 """Decorator factory.
1376 this decorator will "inject" variables into the function's namespace,
1377 from the *dictionary* in self.namespace. it therefore becomes possible
1378 to make it look like a whole stack of variables which would otherwise
1379 need "self." inserted in front of them (*and* for those variables to be
1380 added to the instance) "appear" in the function.
1382 "self.namespace['SI']" for example becomes accessible as just "SI" but
1383 *only* inside the function, when decorated.
1385 def variable_injector(func
):
1387 def decorator(*args
, **kwargs
):
1389 func_globals
= func
.__globals
__ # Python 2.6+
1390 except AttributeError:
1391 func_globals
= func
.func_globals
# Earlier versions.
1393 context
= args
[0].namespace
# variables to be injected
1394 saved_values
= func_globals
.copy() # Shallow copy of dict.
1395 func_globals
.update(context
)
1396 result
= func(*args
, **kwargs
)
1397 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1398 log("args[0]", args
[0].namespace
['CIA'],
1399 args
[0].namespace
['NIA'],
1400 args
[0].namespace
['SVSTATE'])
1401 args
[0].namespace
= func_globals
1402 #exec (func.__code__, func_globals)
1405 # func_globals = saved_values # Undo changes.
1411 return variable_injector