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 # XXX TODO, this needs sorting! (1) reverse gear for mapreduce
127 # and (2) when doing element-width overrides. used by
128 # GPR(x) or GPR[x] in pseudocode
129 offs
= self
.svstate
.srcstep
130 log("GPR getitem TODO mapreduce reverse-gear", attr
, rnum
,
132 return self
.regfile
[rnum
]
134 def dump(self
, printout
=True):
136 for i
in range(len(self
)):
137 res
.append(self
[i
].value
)
139 for i
in range(0, len(res
), 8):
142 s
.append("%08x" % res
[i
+j
])
144 print("reg", "%2d" % i
, s
)
149 def __init__(self
, dec2
, initial_sprs
={}):
152 for key
, v
in initial_sprs
.items():
153 if isinstance(key
, SelectableInt
):
155 key
= special_sprs
.get(key
, key
)
156 if isinstance(key
, int):
159 info
= spr_byname
[key
]
160 if not isinstance(v
, SelectableInt
):
161 v
= SelectableInt(v
, info
.length
)
164 def __getitem__(self
, key
):
166 log("dict", self
.items())
167 # if key in special_sprs get the special spr, otherwise return key
168 if isinstance(key
, SelectableInt
):
170 if isinstance(key
, int):
171 key
= spr_dict
[key
].SPR
172 key
= special_sprs
.get(key
, key
)
173 if key
== 'HSRR0': # HACK!
175 if key
== 'HSRR1': # HACK!
178 res
= dict.__getitem
__(self
, key
)
180 if isinstance(key
, int):
183 info
= spr_byname
[key
]
184 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
185 res
= dict.__getitem
__(self
, key
)
186 log("spr returning", key
, res
)
189 def __setitem__(self
, key
, value
):
190 if isinstance(key
, SelectableInt
):
192 if isinstance(key
, int):
193 key
= spr_dict
[key
].SPR
195 key
= special_sprs
.get(key
, key
)
196 if key
== 'HSRR0': # HACK!
197 self
.__setitem
__('SRR0', value
)
198 if key
== 'HSRR1': # HACK!
199 self
.__setitem
__('SRR1', value
)
200 log("setting spr", key
, value
)
201 dict.__setitem
__(self
, key
, value
)
203 def __call__(self
, ridx
):
206 def dump(self
, printout
=True):
208 keys
= list(self
.keys())
211 sprname
= spr_dict
.get(k
, None)
215 sprname
= sprname
.SPR
216 res
.append((sprname
, self
[k
].value
))
218 for sprname
, value
in res
:
219 print(" ", sprname
, hex(value
))
224 def __init__(self
, pc_init
=0):
225 self
.CIA
= SelectableInt(pc_init
, 64)
226 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
228 def update_nia(self
, is_svp64
):
229 increment
= 8 if is_svp64
else 4
230 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
232 def update(self
, namespace
, is_svp64
):
233 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
235 self
.CIA
= namespace
['NIA'].narrow(64)
236 self
.update_nia(is_svp64
)
237 namespace
['CIA'] = self
.CIA
238 namespace
['NIA'] = self
.NIA
241 # Simple-V: see https://libre-soc.org/openpower/sv
243 def __init__(self
, init
=0):
244 self
.spr
= SelectableInt(init
, 32)
245 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
246 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
247 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
248 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
249 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
250 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
251 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
256 def __init__(self
, init
=0):
257 self
.spr
= SelectableInt(init
, 24)
258 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
259 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
260 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
261 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
262 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
263 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
264 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
265 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
266 # these cover the same extra field, split into parts as EXTRA2
267 self
.extra2
= list(range(4))
268 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
269 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
270 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
271 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
272 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
273 # and here as well, but EXTRA3
274 self
.extra3
= list(range(3))
275 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
276 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
277 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
280 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
281 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
282 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
283 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
284 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
285 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
286 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
287 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
288 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
291 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
292 class SVP64PrefixFields
:
294 self
.insn
= SelectableInt(0, 32)
295 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
296 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
297 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
298 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
299 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
302 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
303 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
304 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
308 # See PowerISA Version 3.0 B Book 1
309 # Section 2.3.1 Condition Register pages 30 - 31
311 LT
= FL
= 0 # negative, less than, floating-point less than
312 GT
= FG
= 1 # positive, greater than, floating-point greater than
313 EQ
= FE
= 2 # equal, floating-point equal
314 SO
= FU
= 3 # summary overflow, floating-point unordered
316 def __init__(self
, init
=0):
317 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
318 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
319 self
.cr
= SelectableInt(init
, 64) # underlying reg
320 # field-selectable versions of Condition Register TODO check bitranges?
323 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
324 _cr
= FieldSelectableInt(self
.cr
, bits
)
327 # decode SVP64 predicate integer to reg number and invert
328 def get_predint(gpr
, mask
):
331 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
332 if mask
== SVP64PredInt
.ALWAYS
.value
:
333 return 0xffff_ffff_ffff_ffff
334 if mask
== SVP64PredInt
.R3_UNARY
.value
:
335 return 1 << (gpr(3).value
& 0b111111)
336 if mask
== SVP64PredInt
.R3
.value
:
338 if mask
== SVP64PredInt
.R3_N
.value
:
340 if mask
== SVP64PredInt
.R10
.value
:
342 if mask
== SVP64PredInt
.R10_N
.value
:
343 return ~
gpr(10).value
344 if mask
== SVP64PredInt
.R30
.value
:
346 if mask
== SVP64PredInt
.R30_N
.value
:
347 return ~
gpr(30).value
349 # decode SVP64 predicate CR to reg number and invert status
350 def _get_predcr(mask
):
351 if mask
== SVP64PredCR
.LT
.value
:
353 if mask
== SVP64PredCR
.GE
.value
:
355 if mask
== SVP64PredCR
.GT
.value
:
357 if mask
== SVP64PredCR
.LE
.value
:
359 if mask
== SVP64PredCR
.EQ
.value
:
361 if mask
== SVP64PredCR
.NE
.value
:
363 if mask
== SVP64PredCR
.SO
.value
:
365 if mask
== SVP64PredCR
.NS
.value
:
368 # read individual CR fields (0..VL-1), extract the required bit
369 # and construct the mask
370 def get_predcr(crl
, mask
, vl
):
371 idx
, noninv
= _get_predcr(mask
)
374 cr
= crl
[i
+SVP64CROffs
.CRPred
]
375 if cr
[idx
].value
== noninv
:
380 def get_pdecode_idx_in(dec2
, name
):
382 in1_sel
= yield op
.in1_sel
383 in2_sel
= yield op
.in2_sel
384 in3_sel
= yield op
.in3_sel
385 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
386 in1
= yield dec2
.e
.read_reg1
.data
387 in2
= yield dec2
.e
.read_reg2
.data
388 in3
= yield dec2
.e
.read_reg3
.data
389 in1_isvec
= yield dec2
.in1_isvec
390 in2_isvec
= yield dec2
.in2_isvec
391 in3_isvec
= yield dec2
.in3_isvec
392 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
394 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
396 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
398 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
400 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
402 # identify which regnames map to in1/2/3
404 if (in1_sel
== In1Sel
.RA
.value
or
405 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
406 return in1
, in1_isvec
407 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
408 return in1
, in1_isvec
410 if in2_sel
== In2Sel
.RB
.value
:
411 return in2
, in2_isvec
412 if in3_sel
== In3Sel
.RB
.value
:
413 return in3
, in3_isvec
414 # XXX TODO, RC doesn't exist yet!
416 assert False, "RC does not exist yet"
418 if in1_sel
== In1Sel
.RS
.value
:
419 return in1
, in1_isvec
420 if in2_sel
== In2Sel
.RS
.value
:
421 return in2
, in2_isvec
422 if in3_sel
== In3Sel
.RS
.value
:
423 return in3
, in3_isvec
425 if in1_sel
== In1Sel
.FRA
.value
:
426 return in1
, in1_isvec
428 if in2_sel
== In2Sel
.FRB
.value
:
429 return in2
, in2_isvec
431 if in3_sel
== In3Sel
.FRC
.value
:
432 return in3
, in3_isvec
434 if in1_sel
== In1Sel
.FRS
.value
:
435 return in1
, in1_isvec
436 if in3_sel
== In3Sel
.FRS
.value
:
437 return in3
, in3_isvec
441 def get_pdecode_cr_out(dec2
, name
):
443 out_sel
= yield op
.cr_out
444 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
445 sv_cr_out
= yield op
.sv_cr_out
446 spec
= yield dec2
.crout_svdec
.spec
447 sv_override
= yield dec2
.dec_cr_out
.sv_override
448 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
449 out
= yield dec2
.e
.write_cr
.data
450 o_isvec
= yield dec2
.o_isvec
451 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
452 log (" sv_cr_out", sv_cr_out
)
453 log (" cr_bf", out_bitfield
)
455 log (" override", sv_override
)
456 # identify which regnames map to out / o2
458 if out_sel
== CROutSel
.CR0
.value
:
460 log ("get_pdecode_cr_out not found", name
)
464 def get_pdecode_idx_out(dec2
, name
):
466 out_sel
= yield op
.out_sel
467 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
468 out
= yield dec2
.e
.write_reg
.data
469 o_isvec
= yield dec2
.o_isvec
470 # identify which regnames map to out / o2
472 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
473 if out_sel
== OutSel
.RA
.value
:
476 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
477 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
)
478 if out_sel
== OutSel
.RT
.value
:
481 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
482 if out_sel
== OutSel
.FRA
.value
:
485 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
486 OutSel
.FRT
.value
, out
, o_isvec
)
487 if out_sel
== OutSel
.FRT
.value
:
489 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
493 def get_pdecode_idx_out2(dec2
, name
):
494 # check first if register is activated for write
495 out_ok
= yield dec2
.e
.write_ea
.ok
500 out_sel
= yield op
.out_sel
501 out
= yield dec2
.e
.write_ea
.data
502 o_isvec
= yield dec2
.o2_isvec
503 log ("get_pdecode_idx_out2", name
, out_sel
, out
, o_isvec
)
505 if hasattr(op
, "upd"):
506 # update mode LD/ST uses read-reg A also as an output
508 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
509 out_sel
, OutSel
.RA
.value
,
511 if upd
== LDSTMode
.update
.value
:
517 # decoder2 - an instance of power_decoder2
518 # regfile - a list of initial values for the registers
519 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
520 # respect_pc - tracks the program counter. requires initial_insns
521 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
522 initial_mem
=None, initial_msr
=0,
533 self
.bigendian
= bigendian
535 self
.is_svp64_mode
= False
536 self
.respect_pc
= respect_pc
537 if initial_sprs
is None:
539 if initial_mem
is None:
541 if fpregfile
is None:
543 if initial_insns
is None:
545 assert self
.respect_pc
== False, "instructions required to honor pc"
547 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
548 log("ISACaller initial_msr", initial_msr
)
550 # "fake program counter" mode (for unit testing)
554 if isinstance(initial_mem
, tuple):
555 self
.fake_pc
= initial_mem
[0]
556 disasm_start
= self
.fake_pc
558 disasm_start
= initial_pc
560 # disassembly: we need this for now (not given from the decoder)
561 self
.disassembly
= {}
563 for i
, code
in enumerate(disassembly
):
564 self
.disassembly
[i
*4 + disasm_start
] = code
566 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
567 self
.svp64rm
= SVP64RM()
568 if initial_svstate
is None:
570 if isinstance(initial_svstate
, int):
571 initial_svstate
= SVP64State(initial_svstate
)
572 # SVSTATE, MSR and PC
573 self
.svstate
= initial_svstate
574 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
576 # GPR FPR SPR registers
577 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
578 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
579 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
581 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
582 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
583 # MMU mode, redirect underlying Mem through RADIX
585 self
.mem
= RADIX(self
.mem
, self
)
587 self
.imem
= RADIX(self
.imem
, self
)
590 # FPR (same as GPR except for FP nums)
591 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
592 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
593 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
594 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
596 # 2.3.2 LR (actually SPR #8) -- Done
597 # 2.3.3 CTR (actually SPR #9) -- Done
598 # 2.3.4 TAR (actually SPR #815)
599 # 3.2.2 p45 XER (actually SPR #1) -- Done
600 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
602 # create CR then allow portions of it to be "selectable" (below)
603 self
.cr_fields
= CRFields(initial_cr
)
604 self
.cr
= self
.cr_fields
.cr
606 # "undefined", just set to variable-bit-width int (use exts "max")
607 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
610 self
.namespace
.update(self
.spr
)
611 self
.namespace
.update({'GPR': self
.gpr
,
615 'memassign': self
.memassign
,
618 'SVSTATE': self
.svstate
.spr
,
621 'undefined': undefined
,
622 'mode_is_64bit': True,
626 # update pc to requested start point
627 self
.set_pc(initial_pc
)
629 # field-selectable versions of Condition Register
630 self
.crl
= self
.cr_fields
.crl
632 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
634 self
.decoder
= decoder2
.dec
637 def call_trap(self
, trap_addr
, trap_bit
):
638 """calls TRAP and sets up NIA to the new execution location.
639 next instruction will begin at trap_addr.
641 self
.TRAP(trap_addr
, trap_bit
)
642 self
.namespace
['NIA'] = self
.trap_nia
643 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
645 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
646 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
648 TRAP function is callable from inside the pseudocode itself,
649 hence the default arguments. when calling from inside ISACaller
650 it is best to use call_trap()
652 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
653 # store CIA(+4?) in SRR0, set NIA to 0x700
654 # store MSR in SRR1, set MSR to um errr something, have to check spec
655 # store SVSTATE (if enabled) in SVSRR0
656 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
657 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
658 if self
.is_svp64_mode
:
659 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
660 self
.trap_nia
= SelectableInt(trap_addr
, 64)
661 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
663 # set exception bits. TODO: this should, based on the address
664 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
665 # bits appropriately. however it turns out that *for now* in all
666 # cases (all trap_addrs) the exact same thing is needed.
667 self
.msr
[MSRb
.IR
] = 0
668 self
.msr
[MSRb
.DR
] = 0
669 self
.msr
[MSRb
.FE0
] = 0
670 self
.msr
[MSRb
.FE1
] = 0
671 self
.msr
[MSRb
.EE
] = 0
672 self
.msr
[MSRb
.RI
] = 0
673 self
.msr
[MSRb
.SF
] = 1
674 self
.msr
[MSRb
.TM
] = 0
675 self
.msr
[MSRb
.VEC
] = 0
676 self
.msr
[MSRb
.VSX
] = 0
677 self
.msr
[MSRb
.PR
] = 0
678 self
.msr
[MSRb
.FP
] = 0
679 self
.msr
[MSRb
.PMM
] = 0
680 self
.msr
[MSRb
.TEs
] = 0
681 self
.msr
[MSRb
.TEe
] = 0
682 self
.msr
[MSRb
.UND
] = 0
683 self
.msr
[MSRb
.LE
] = 1
685 def memassign(self
, ea
, sz
, val
):
686 self
.mem
.memassign(ea
, sz
, val
)
688 def prep_namespace(self
, formname
, op_fields
):
689 # TODO: get field names from form in decoder*1* (not decoder2)
690 # decoder2 is hand-created, and decoder1.sigform is auto-generated
692 # then "yield" fields only from op_fields rather than hard-coded
694 fields
= self
.decoder
.sigforms
[formname
]
695 for name
in op_fields
:
697 sig
= getattr(fields
, name
.upper())
699 sig
= getattr(fields
, name
)
701 # these are all opcode fields involved in index-selection of CR,
702 # and need to do "standard" arithmetic. CR[BA+32] for example
703 # would, if using SelectableInt, only be 5-bit.
704 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
705 self
.namespace
[name
] = val
707 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
709 self
.namespace
['XER'] = self
.spr
['XER']
710 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
711 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
713 def handle_carry_(self
, inputs
, outputs
, already_done
):
714 inv_a
= yield self
.dec2
.e
.do
.invert_in
716 inputs
[0] = ~inputs
[0]
718 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
720 imm
= yield self
.dec2
.e
.do
.imm_data
.data
721 inputs
.append(SelectableInt(imm
, 64))
722 assert len(outputs
) >= 1
723 log("outputs", repr(outputs
))
724 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
730 log("gt input", x
, output
)
731 gt
= (gtu(x
, output
))
734 cy
= 1 if any(gts
) else 0
736 if not (1 & already_done
):
737 self
.spr
['XER'][XER_bits
['CA']] = cy
739 log("inputs", already_done
, inputs
)
741 # ARGH... different for OP_ADD... *sigh*...
742 op
= yield self
.dec2
.e
.do
.insn_type
743 if op
== MicrOp
.OP_ADD
.value
:
744 res32
= (output
.value
& (1 << 32)) != 0
745 a32
= (inputs
[0].value
& (1 << 32)) != 0
747 b32
= (inputs
[1].value
& (1 << 32)) != 0
750 cy32
= res32 ^ a32 ^ b32
751 log("CA32 ADD", cy32
)
755 log("input", x
, output
)
756 log(" x[32:64]", x
, x
[32:64])
757 log(" o[32:64]", output
, output
[32:64])
758 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
760 cy32
= 1 if any(gts
) else 0
761 log("CA32", cy32
, gts
)
762 if not (2 & already_done
):
763 self
.spr
['XER'][XER_bits
['CA32']] = cy32
765 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
766 if hasattr(self
.dec2
.e
.do
, "invert_in"):
767 inv_a
= yield self
.dec2
.e
.do
.invert_in
769 inputs
[0] = ~inputs
[0]
771 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
773 imm
= yield self
.dec2
.e
.do
.imm_data
.data
774 inputs
.append(SelectableInt(imm
, 64))
775 assert len(outputs
) >= 1
776 log("handle_overflow", inputs
, outputs
, div_overflow
)
777 if len(inputs
) < 2 and div_overflow
is None:
780 # div overflow is different: it's returned by the pseudo-code
781 # because it's more complex than can be done by analysing the output
782 if div_overflow
is not None:
783 ov
, ov32
= div_overflow
, div_overflow
784 # arithmetic overflow can be done by analysing the input and output
785 elif len(inputs
) >= 2:
789 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
790 output_sgn
= exts(output
.value
, output
.bits
) < 0
791 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
792 output_sgn
!= input_sgn
[0] else 0
795 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
796 output32_sgn
= exts(output
.value
, 32) < 0
797 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
798 output32_sgn
!= input32_sgn
[0] else 0
800 self
.spr
['XER'][XER_bits
['OV']] = ov
801 self
.spr
['XER'][XER_bits
['OV32']] = ov32
802 so
= self
.spr
['XER'][XER_bits
['SO']]
804 self
.spr
['XER'][XER_bits
['SO']] = so
806 def handle_comparison(self
, outputs
, cr_idx
=0):
808 assert isinstance(out
, SelectableInt
), \
809 "out zero not a SelectableInt %s" % repr(outputs
)
810 log("handle_comparison", out
.bits
, hex(out
.value
))
811 # TODO - XXX *processor* in 32-bit mode
812 # https://bugs.libre-soc.org/show_bug.cgi?id=424
814 # o32 = exts(out.value, 32)
815 # print ("handle_comparison exts 32 bit", hex(o32))
816 out
= exts(out
.value
, out
.bits
)
817 log("handle_comparison exts", hex(out
))
818 zero
= SelectableInt(out
== 0, 1)
819 positive
= SelectableInt(out
> 0, 1)
820 negative
= SelectableInt(out
< 0, 1)
821 SO
= self
.spr
['XER'][XER_bits
['SO']]
822 log("handle_comparison SO", SO
)
823 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
824 self
.crl
[cr_idx
].eq(cr_field
)
826 def set_pc(self
, pc_val
):
827 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
828 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
830 def get_next_insn(self
):
834 pc
= self
.pc
.CIA
.value
837 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
839 raise KeyError("no instruction at 0x%x" % pc
)
843 """set up one instruction
845 pc
, insn
= self
.get_next_insn()
846 yield from self
.setup_next_insn(pc
, insn
)
848 def setup_next_insn(self
, pc
, ins
):
849 """set up next instruction
852 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
853 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
855 yield self
.dec2
.sv_rm
.eq(0)
856 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
857 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
858 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
859 yield self
.dec2
.state
.pc
.eq(pc
)
860 if self
.svstate
is not None:
861 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
863 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
865 opcode
= yield self
.dec2
.dec
.opcode_in
866 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
867 pfx
.insn
.value
= opcode
868 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
869 log ("prefix test: opcode:", major
, bin(major
),
870 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
871 self
.is_svp64_mode
= ((major
== 0b000001) and
872 pfx
.insn
[7].value
== 0b1 and
873 pfx
.insn
[9].value
== 0b1)
874 self
.pc
.update_nia(self
.is_svp64_mode
)
875 self
.namespace
['NIA'] = self
.pc
.NIA
876 self
.namespace
['SVSTATE'] = self
.svstate
.spr
877 if not self
.is_svp64_mode
:
880 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
881 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
882 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
883 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
884 sv_rm
= pfx
.rm
.asint(msb0
=True)
885 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
886 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
887 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
888 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
891 def execute_one(self
):
892 """execute one instruction
894 # get the disassembly code for this instruction
895 if self
.is_svp64_mode
:
896 if not self
.disassembly
:
897 code
= yield from self
.get_assembly_name()
899 code
= self
.disassembly
[self
._pc
+4]
900 log(" svp64 sim-execute", hex(self
._pc
), code
)
902 if not self
.disassembly
:
903 code
= yield from self
.get_assembly_name()
905 code
= self
.disassembly
[self
._pc
]
906 log("sim-execute", hex(self
._pc
), code
)
907 opname
= code
.split(' ')[0]
909 yield from self
.call(opname
) # execute the instruction
910 except MemException
as e
: # check for memory errors
911 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
912 raise e
# ... re-raise
913 # run a Trap but set DAR first
914 print ("memory unaligned exception, DAR", e
.dar
)
915 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
916 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
919 # don't use this except in special circumstances
920 if not self
.respect_pc
:
923 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
925 def get_assembly_name(self
):
926 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
927 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
928 dec_insn
= yield self
.dec2
.e
.do
.insn
929 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
930 asmcode
= yield self
.dec2
.dec
.op
.asmcode
931 int_op
= yield self
.dec2
.dec
.op
.internal_op
932 log("get assembly name asmcode", asmcode
, int_op
,
933 hex(dec_insn
), bin(insn_1_11
))
934 asmop
= insns
.get(asmcode
, None)
936 # sigh reconstruct the assembly instruction name
937 if hasattr(self
.dec2
.e
.do
, "oe"):
938 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
939 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
943 if hasattr(self
.dec2
.e
.do
, "rc"):
944 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
945 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
949 # grrrr have to special-case MUL op (see DecodeOE)
950 log("ov %d en %d rc %d en %d op %d" %
951 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
952 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
957 if not asmop
.endswith("."): # don't add "." to "andis."
960 if hasattr(self
.dec2
.e
.do
, "lk"):
961 lk
= yield self
.dec2
.e
.do
.lk
964 log("int_op", int_op
)
965 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
966 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
970 spr_msb
= yield from self
.get_spr_msb()
971 if int_op
== MicrOp
.OP_MFCR
.value
:
976 # XXX TODO: for whatever weird reason this doesn't work
977 # https://bugs.libre-soc.org/show_bug.cgi?id=390
978 if int_op
== MicrOp
.OP_MTCRF
.value
:
985 def get_spr_msb(self
):
986 dec_insn
= yield self
.dec2
.e
.do
.insn
987 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
989 def call(self
, name
):
990 """call(opcode) - the primary execution point for instructions
992 self
.last_st_addr
= None # reset the last known store address
993 self
.last_ld_addr
= None # etc.
995 name
= name
.strip() # remove spaces if not already done so
997 log("halted - not executing", name
)
1000 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1001 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1002 asmop
= yield from self
.get_assembly_name()
1003 log("call", name
, asmop
)
1006 int_op
= yield self
.dec2
.dec
.op
.internal_op
1007 spr_msb
= yield from self
.get_spr_msb()
1009 instr_is_privileged
= False
1010 if int_op
in [MicrOp
.OP_ATTN
.value
,
1011 MicrOp
.OP_MFMSR
.value
,
1012 MicrOp
.OP_MTMSR
.value
,
1013 MicrOp
.OP_MTMSRD
.value
,
1015 MicrOp
.OP_RFID
.value
]:
1016 instr_is_privileged
= True
1017 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1018 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1019 instr_is_privileged
= True
1021 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1023 # check MSR priv bit and whether op is privileged: if so, throw trap
1024 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1025 self
.call_trap(0x700, PIb
.PRIV
)
1028 # check halted condition
1033 # check illegal instruction
1035 if name
not in ['mtcrf', 'mtocrf']:
1036 illegal
= name
!= asmop
1038 # sigh deal with setvl not being supported by binutils (.long)
1039 if asmop
.startswith('setvl'):
1044 print("illegal", name
, asmop
)
1045 self
.call_trap(0x700, PIb
.ILLEG
)
1046 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1047 (name
, asmop
, self
.pc
.CIA
.value
))
1050 # nop has to be supported, we could let the actual op calculate
1051 # but PowerDecoder has a pattern for nop
1053 self
.update_pc_next()
1056 info
= self
.instrs
[name
]
1057 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1059 # preserve order of register names
1060 input_names
= create_args(list(info
.read_regs
) +
1061 list(info
.uninit_regs
))
1064 # get SVP64 entry for the current instruction
1065 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1066 if sv_rm
is not None:
1067 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1069 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1070 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1072 # get SVSTATE VL (oh and print out some debug stuff)
1073 if self
.is_svp64_mode
:
1074 vl
= self
.svstate
.vl
.asint(msb0
=True)
1075 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1076 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1077 sv_a_nz
= yield self
.dec2
.sv_a_nz
1078 in1
= yield self
.dec2
.e
.read_reg1
.data
1079 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
1080 vl
, srcstep
, dststep
, sv_a_nz
, in1
)
1082 # get predicate mask
1083 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1084 if self
.is_svp64_mode
:
1085 pmode
= yield self
.dec2
.rm_dec
.predmode
1086 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1087 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1088 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1089 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1090 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1091 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1092 if pmode
== SVP64PredMode
.INT
.value
:
1093 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1094 if sv_ptype
== SVPtype
.P2
.value
:
1095 srcmask
= get_predint(self
.gpr
, srcpred
)
1096 elif pmode
== SVP64PredMode
.CR
.value
:
1097 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1098 if sv_ptype
== SVPtype
.P2
.value
:
1099 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1100 log (" pmode", pmode
)
1101 log (" reverse", reverse_gear
)
1102 log (" ptype", sv_ptype
)
1103 log (" srcpred", bin(srcpred
))
1104 log (" dstpred", bin(dstpred
))
1105 log (" srcmask", bin(srcmask
))
1106 log (" dstmask", bin(dstmask
))
1107 log (" pred_sz", bin(pred_src_zero
))
1108 log (" pred_dz", bin(pred_dst_zero
))
1110 # okaaay, so here we simply advance srcstep (TODO dststep)
1111 # until the predicate mask has a "1" bit... or we run out of VL
1112 # let srcstep==VL be the indicator to move to next instruction
1113 if not pred_src_zero
:
1114 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1115 log (" skip", bin(1<<srcstep
))
1118 if not pred_dst_zero
:
1119 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1120 log (" skip", bin(1<<dststep
))
1123 # now work out if the relevant mask bits require zeroing
1125 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1127 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1129 # update SVSTATE with new srcstep
1130 self
.svstate
.srcstep
[0:7] = srcstep
1131 self
.svstate
.dststep
[0:7] = dststep
1132 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1133 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1134 yield Settle() # let decoder update
1135 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1136 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1137 log (" srcstep", srcstep
)
1138 log (" dststep", dststep
)
1140 # check if end reached (we let srcstep overrun, above)
1141 # nothing needs doing (TODO zeroing): just do next instruction
1142 if srcstep
== vl
or dststep
== vl
:
1143 self
.svp64_reset_loop()
1144 self
.update_pc_next()
1147 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1148 if self
.is_svp64_mode
and vl
== 0:
1149 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1150 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1151 self
.namespace
['NIA'])
1154 # in SVP64 mode for LD/ST work out immediate
1155 replace_d
= False # replace constant in pseudocode
1156 if self
.is_svp64_mode
:
1157 D
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1158 D
= exts(D
, 16) # sign-extend to integer
1159 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1160 # get the right step. LD is from srcstep, ST is dststep
1161 op
= yield self
.dec2
.e
.do
.insn_type
1163 if op
== MicrOp
.OP_LOAD
.value
:
1165 log("D-field src", D
, offsmul
)
1166 elif op
== MicrOp
.OP_STORE
.value
:
1168 log("D-field dst", D
, offsmul
)
1169 # Unit-Strided LD/ST adds offset*width to immediate
1170 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1171 ldst_len
= yield self
.dec2
.e
.do
.data_len
1172 D
= SelectableInt(D
+ offsmul
* ldst_len
, 32)
1174 # Element-strided multiplies the immediate by element step
1175 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1176 D
= SelectableInt(D
* offsmul
, 32)
1178 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1179 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1180 log("LDSTmode", ldstmode
, offsmul
, D
, ldst_ra_vec
, ldst_imz_in
)
1183 self
.namespace
['D'] = D
1185 # main input registers (RT, RA ...)
1187 for name
in input_names
:
1188 # using PowerDecoder2, first, find the decoder index.
1189 # (mapping name RA RB RC RS to in1, in2, in3)
1190 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1192 # doing this is not part of svp64, it's because output
1193 # registers, to be modified, need to be in the namespace.
1194 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1196 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1199 # in case getting the register number is needed, _RA, _RB
1200 regname
= "_" + name
1201 self
.namespace
[regname
] = regnum
1202 if not self
.is_svp64_mode
or not pred_src_zero
:
1203 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1205 reg_val
= self
.fpr(regnum
)
1207 reg_val
= self
.gpr(regnum
)
1209 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1211 inputs
.append(reg_val
)
1213 # "special" registers
1214 for special
in info
.special_regs
:
1215 if special
in special_sprs
:
1216 inputs
.append(self
.spr
[special
])
1218 inputs
.append(self
.namespace
[special
])
1220 # clear trap (trap) NIA
1221 self
.trap_nia
= None
1223 # execute actual instruction here (finally)
1224 log("inputs", inputs
)
1225 results
= info
.func(self
, *inputs
)
1226 log("results", results
)
1228 # "inject" decorator takes namespace from function locals: we need to
1229 # overwrite NIA being overwritten (sigh)
1230 if self
.trap_nia
is not None:
1231 self
.namespace
['NIA'] = self
.trap_nia
1233 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1235 # check if op was a LD/ST so that debugging can check the
1237 if int_op
in [MicrOp
.OP_STORE
.value
,
1239 self
.last_st_addr
= self
.mem
.last_st_addr
1240 if int_op
in [MicrOp
.OP_LOAD
.value
,
1242 self
.last_ld_addr
= self
.mem
.last_ld_addr
1243 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1244 self
.last_st_addr
, self
.last_ld_addr
)
1246 # detect if CA/CA32 already in outputs (sra*, basically)
1249 output_names
= create_args(info
.write_regs
)
1250 for name
in output_names
:
1256 log("carry already done?", bin(already_done
))
1257 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1258 carry_en
= yield self
.dec2
.e
.do
.output_carry
1262 yield from self
.handle_carry_(inputs
, results
, already_done
)
1264 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1265 # detect if overflow was in return result
1268 for name
, output
in zip(output_names
, results
):
1269 if name
== 'overflow':
1272 if hasattr(self
.dec2
.e
.do
, "oe"):
1273 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1274 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1278 log("internal overflow", overflow
, ov_en
, ov_ok
)
1280 yield from self
.handle_overflow(inputs
, results
, overflow
)
1282 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1284 if not self
.is_svp64_mode
or not pred_dst_zero
:
1285 if hasattr(self
.dec2
.e
.do
, "rc"):
1286 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1288 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1289 self
.handle_comparison(results
, regnum
)
1291 # any modified return results?
1293 for name
, output
in zip(output_names
, results
):
1294 if name
== 'overflow': # ignore, done already (above)
1296 if isinstance(output
, int):
1297 output
= SelectableInt(output
, 256)
1298 if name
in ['CA', 'CA32']:
1300 log("writing %s to XER" % name
, output
)
1301 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1303 log("NOT writing %s to XER" % name
, output
)
1304 elif name
in info
.special_regs
:
1305 log('writing special %s' % name
, output
, special_sprs
)
1306 if name
in special_sprs
:
1307 self
.spr
[name
] = output
1309 self
.namespace
[name
].eq(output
)
1311 log('msr written', hex(self
.msr
.value
))
1313 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1316 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1319 # temporary hack for not having 2nd output
1320 regnum
= yield getattr(self
.decoder
, name
)
1322 if self
.is_svp64_mode
and pred_dst_zero
:
1323 log('zeroing reg %d %s' % (regnum
, str(output
)),
1325 output
= SelectableInt(0, 256)
1331 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1333 if output
.bits
> 64:
1334 output
= SelectableInt(output
.value
, 64)
1336 self
.fpr
[regnum
] = output
1338 self
.gpr
[regnum
] = output
1340 # check if it is the SVSTATE.src/dest step that needs incrementing
1341 # this is our Sub-Program-Counter loop from 0 to VL-1
1342 if self
.is_svp64_mode
:
1343 # XXX twin predication TODO
1344 vl
= self
.svstate
.vl
.asint(msb0
=True)
1345 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1346 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1347 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1348 rm_mode
= yield self
.dec2
.rm_dec
.mode
1349 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1350 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1351 out_vec
= not (yield self
.dec2
.no_out_vec
)
1352 in_vec
= not (yield self
.dec2
.no_in_vec
)
1353 log (" svstate.vl", vl
)
1354 log (" svstate.mvl", mvl
)
1355 log (" svstate.srcstep", srcstep
)
1356 log (" svstate.dststep", dststep
)
1357 log (" mode", rm_mode
)
1358 log (" reverse", reverse_gear
)
1359 log (" out_vec", out_vec
)
1360 log (" in_vec", in_vec
)
1361 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1362 # check if srcstep needs incrementing by one, stop PC advancing
1363 # svp64 loop can end early if the dest is scalar for single-pred
1364 # but for 2-pred both src/dest have to be checked.
1365 # XXX this might not be true! it may just be LD/ST
1366 if sv_ptype
== SVPtype
.P2
.value
:
1367 svp64_is_vector
= (out_vec
or in_vec
)
1369 svp64_is_vector
= out_vec
1370 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1371 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1372 self
.svstate
.dststep
+= SelectableInt(1, 7)
1373 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1374 self
.namespace
['NIA'] = self
.pc
.NIA
1375 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1376 log("end of sub-pc call", self
.namespace
['CIA'],
1377 self
.namespace
['NIA'])
1378 return # DO NOT allow PC to update whilst Sub-PC loop running
1379 # reset loop to zero
1380 self
.svp64_reset_loop()
1382 self
.update_pc_next()
1384 def update_pc_next(self
):
1385 # UPDATE program counter
1386 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1387 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1388 log("end of call", self
.namespace
['CIA'],
1389 self
.namespace
['NIA'],
1390 self
.namespace
['SVSTATE'])
1392 def svp64_reset_loop(self
):
1393 self
.svstate
.srcstep
[0:7] = 0
1394 self
.svstate
.dststep
[0:7] = 0
1395 log (" svstate.srcstep loop end (PC to update)")
1396 self
.pc
.update_nia(self
.is_svp64_mode
)
1397 self
.namespace
['NIA'] = self
.pc
.NIA
1398 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1401 """Decorator factory.
1403 this decorator will "inject" variables into the function's namespace,
1404 from the *dictionary* in self.namespace. it therefore becomes possible
1405 to make it look like a whole stack of variables which would otherwise
1406 need "self." inserted in front of them (*and* for those variables to be
1407 added to the instance) "appear" in the function.
1409 "self.namespace['SI']" for example becomes accessible as just "SI" but
1410 *only* inside the function, when decorated.
1412 def variable_injector(func
):
1414 def decorator(*args
, **kwargs
):
1416 func_globals
= func
.__globals
__ # Python 2.6+
1417 except AttributeError:
1418 func_globals
= func
.func_globals
# Earlier versions.
1420 context
= args
[0].namespace
# variables to be injected
1421 saved_values
= func_globals
.copy() # Shallow copy of dict.
1422 func_globals
.update(context
)
1423 result
= func(*args
, **kwargs
)
1424 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1425 log("args[0]", args
[0].namespace
['CIA'],
1426 args
[0].namespace
['NIA'],
1427 args
[0].namespace
['SVSTATE'])
1428 args
[0].namespace
= func_globals
1429 #exec (func.__code__, func_globals)
1432 # func_globals = saved_values # Undo changes.
1438 return variable_injector