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
, bitrev
)
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
38 from openpower
.decoder
.isa
.svshape
import SVSHAPE
40 from openpower
.util
import log
42 from collections
import namedtuple
46 instruction_info
= namedtuple('instruction_info',
47 'func read_regs uninit_regs write_regs ' +
48 'special_regs op_fields form asmregs')
59 # TODO (lkcl): adjust other registers that should be in a particular order
60 # probably CA, CA32, and CR
85 "overflow": 7, # should definitely be last
88 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
91 def create_args(reglist
, extra
=None):
92 retval
= list(OrderedSet(reglist
))
93 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
95 return [extra
] + retval
101 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
104 self
.isacaller
= isacaller
105 self
.svstate
= svstate
106 for i
in range(len(regfile
)):
107 self
[i
] = SelectableInt(regfile
[i
], 64)
109 def __call__(self
, ridx
):
112 def set_form(self
, form
):
115 def getz(self
, rnum
):
116 # rnum = rnum.value # only SelectableInt allowed
117 log("GPR getzero?", rnum
)
119 return SelectableInt(0, 64)
122 def _get_regnum(self
, attr
):
123 getform
= self
.sd
.sigforms
[self
.form
]
124 rnum
= getattr(getform
, attr
)
127 def ___getitem__(self
, attr
):
128 """ XXX currently not used
130 rnum
= self
._get
_regnum
(attr
)
131 log("GPR getitem", 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 # TODO, really should just be using PowerDecoder2
381 def get_pdecode_idx_in(dec2
, name
):
383 in1_sel
= yield op
.in1_sel
384 in2_sel
= yield op
.in2_sel
385 in3_sel
= yield op
.in3_sel
386 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
387 in1
= yield dec2
.e
.read_reg1
.data
388 in2
= yield dec2
.e
.read_reg2
.data
389 in3
= yield dec2
.e
.read_reg3
.data
390 in1_isvec
= yield dec2
.in1_isvec
391 in2_isvec
= yield dec2
.in2_isvec
392 in3_isvec
= yield dec2
.in3_isvec
393 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
395 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
397 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
399 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
401 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
403 # identify which regnames map to in1/2/3
405 if (in1_sel
== In1Sel
.RA
.value
or
406 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
407 return in1
, in1_isvec
408 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
409 return in1
, in1_isvec
411 if in2_sel
== In2Sel
.RB
.value
:
412 return in2
, in2_isvec
413 if in3_sel
== In3Sel
.RB
.value
:
414 return in3
, in3_isvec
415 # XXX TODO, RC doesn't exist yet!
417 assert False, "RC does not exist yet"
419 if in1_sel
== In1Sel
.RS
.value
:
420 return in1
, in1_isvec
421 if in2_sel
== In2Sel
.RS
.value
:
422 return in2
, in2_isvec
423 if in3_sel
== In3Sel
.RS
.value
:
424 return in3
, in3_isvec
426 if in1_sel
== In1Sel
.FRA
.value
:
427 return in1
, in1_isvec
429 if in2_sel
== In2Sel
.FRB
.value
:
430 return in2
, in2_isvec
432 if in3_sel
== In3Sel
.FRC
.value
:
433 return in3
, in3_isvec
435 if in1_sel
== In1Sel
.FRS
.value
:
436 return in1
, in1_isvec
437 if in3_sel
== In3Sel
.FRS
.value
:
438 return in3
, in3_isvec
442 # TODO, really should just be using PowerDecoder2
443 def get_pdecode_cr_out(dec2
, name
):
445 out_sel
= yield op
.cr_out
446 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
447 sv_cr_out
= yield op
.sv_cr_out
448 spec
= yield dec2
.crout_svdec
.spec
449 sv_override
= yield dec2
.dec_cr_out
.sv_override
450 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
451 out
= yield dec2
.e
.write_cr
.data
452 o_isvec
= yield dec2
.o_isvec
453 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
454 log (" sv_cr_out", sv_cr_out
)
455 log (" cr_bf", out_bitfield
)
457 log (" override", sv_override
)
458 # identify which regnames map to out / o2
460 if out_sel
== CROutSel
.CR0
.value
:
462 log ("get_pdecode_cr_out not found", name
)
466 # TODO, really should just be using PowerDecoder2
467 def get_pdecode_idx_out(dec2
, name
):
469 out_sel
= yield op
.out_sel
470 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
471 out
= yield dec2
.e
.write_reg
.data
472 o_isvec
= yield dec2
.o_isvec
473 # identify which regnames map to out / o2
475 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
476 if out_sel
== OutSel
.RA
.value
:
479 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
480 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
)
481 if out_sel
== OutSel
.RT
.value
:
484 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
485 if out_sel
== OutSel
.FRA
.value
:
488 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
489 OutSel
.FRT
.value
, out
, o_isvec
)
490 if out_sel
== OutSel
.FRT
.value
:
492 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
496 # TODO, really should just be using PowerDecoder2
497 def get_pdecode_idx_out2(dec2
, name
):
498 # check first if register is activated for write
500 out_sel
= yield op
.out_sel
501 out
= yield dec2
.e
.write_ea
.data
502 o_isvec
= yield dec2
.o2_isvec
503 out_ok
= yield dec2
.e
.write_ea
.ok
504 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
509 if hasattr(op
, "upd"):
510 # update mode LD/ST uses read-reg A also as an output
512 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
513 out_sel
, OutSel
.RA
.value
,
515 if upd
== LDSTMode
.update
.value
:
518 int_op
= yield dec2
.dec
.op
.internal_op
519 fft_en
= yield dec2
.use_svp64_fft
520 if int_op
== MicrOp
.OP_FP_MADD
.value
and fft_en
:
521 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
528 # decoder2 - an instance of power_decoder2
529 # regfile - a list of initial values for the registers
530 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
531 # respect_pc - tracks the program counter. requires initial_insns
532 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
533 initial_mem
=None, initial_msr
=0,
544 self
.bigendian
= bigendian
546 self
.is_svp64_mode
= False
547 self
.respect_pc
= respect_pc
548 if initial_sprs
is None:
550 if initial_mem
is None:
552 if fpregfile
is None:
554 if initial_insns
is None:
556 assert self
.respect_pc
== False, "instructions required to honor pc"
558 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
559 log("ISACaller initial_msr", initial_msr
)
561 # "fake program counter" mode (for unit testing)
565 if isinstance(initial_mem
, tuple):
566 self
.fake_pc
= initial_mem
[0]
567 disasm_start
= self
.fake_pc
569 disasm_start
= initial_pc
571 # disassembly: we need this for now (not given from the decoder)
572 self
.disassembly
= {}
574 for i
, code
in enumerate(disassembly
):
575 self
.disassembly
[i
*4 + disasm_start
] = code
577 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
578 self
.svp64rm
= SVP64RM()
579 if initial_svstate
is None:
581 if isinstance(initial_svstate
, int):
582 initial_svstate
= SVP64State(initial_svstate
)
583 # SVSTATE, MSR and PC
584 self
.svstate
= initial_svstate
585 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
587 # GPR FPR SPR registers
588 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
589 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
590 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
592 sname
= 'SVSHAPE%d' % i
593 if sname
not in self
.spr
:
594 self
.spr
[sname
] = SVSHAPE(0)
597 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
598 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
599 # MMU mode, redirect underlying Mem through RADIX
601 self
.mem
= RADIX(self
.mem
, self
)
603 self
.imem
= RADIX(self
.imem
, self
)
606 # FPR (same as GPR except for FP nums)
607 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
608 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
609 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
610 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
612 # 2.3.2 LR (actually SPR #8) -- Done
613 # 2.3.3 CTR (actually SPR #9) -- Done
614 # 2.3.4 TAR (actually SPR #815)
615 # 3.2.2 p45 XER (actually SPR #1) -- Done
616 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
618 # create CR then allow portions of it to be "selectable" (below)
619 self
.cr_fields
= CRFields(initial_cr
)
620 self
.cr
= self
.cr_fields
.cr
622 # "undefined", just set to variable-bit-width int (use exts "max")
623 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
626 self
.namespace
.update(self
.spr
)
627 self
.namespace
.update({'GPR': self
.gpr
,
631 'memassign': self
.memassign
,
634 'SVSTATE': self
.svstate
.spr
,
635 'SVSHAPE0': self
.spr
['SVSHAPE0'],
636 'SVSHAPE1': self
.spr
['SVSHAPE1'],
637 'SVSHAPE2': self
.spr
['SVSHAPE2'],
638 'SVSHAPE3': self
.spr
['SVSHAPE3'],
641 'undefined': undefined
,
642 'mode_is_64bit': True,
646 # update pc to requested start point
647 self
.set_pc(initial_pc
)
649 # field-selectable versions of Condition Register
650 self
.crl
= self
.cr_fields
.crl
652 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
654 self
.decoder
= decoder2
.dec
657 def call_trap(self
, trap_addr
, trap_bit
):
658 """calls TRAP and sets up NIA to the new execution location.
659 next instruction will begin at trap_addr.
661 self
.TRAP(trap_addr
, trap_bit
)
662 self
.namespace
['NIA'] = self
.trap_nia
663 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
665 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
666 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
668 TRAP function is callable from inside the pseudocode itself,
669 hence the default arguments. when calling from inside ISACaller
670 it is best to use call_trap()
672 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
673 # store CIA(+4?) in SRR0, set NIA to 0x700
674 # store MSR in SRR1, set MSR to um errr something, have to check spec
675 # store SVSTATE (if enabled) in SVSRR0
676 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
677 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
678 if self
.is_svp64_mode
:
679 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
680 self
.trap_nia
= SelectableInt(trap_addr
, 64)
681 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
683 # set exception bits. TODO: this should, based on the address
684 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
685 # bits appropriately. however it turns out that *for now* in all
686 # cases (all trap_addrs) the exact same thing is needed.
687 self
.msr
[MSRb
.IR
] = 0
688 self
.msr
[MSRb
.DR
] = 0
689 self
.msr
[MSRb
.FE0
] = 0
690 self
.msr
[MSRb
.FE1
] = 0
691 self
.msr
[MSRb
.EE
] = 0
692 self
.msr
[MSRb
.RI
] = 0
693 self
.msr
[MSRb
.SF
] = 1
694 self
.msr
[MSRb
.TM
] = 0
695 self
.msr
[MSRb
.VEC
] = 0
696 self
.msr
[MSRb
.VSX
] = 0
697 self
.msr
[MSRb
.PR
] = 0
698 self
.msr
[MSRb
.FP
] = 0
699 self
.msr
[MSRb
.PMM
] = 0
700 self
.msr
[MSRb
.TEs
] = 0
701 self
.msr
[MSRb
.TEe
] = 0
702 self
.msr
[MSRb
.UND
] = 0
703 self
.msr
[MSRb
.LE
] = 1
705 def memassign(self
, ea
, sz
, val
):
706 self
.mem
.memassign(ea
, sz
, val
)
708 def prep_namespace(self
, formname
, op_fields
):
709 # TODO: get field names from form in decoder*1* (not decoder2)
710 # decoder2 is hand-created, and decoder1.sigform is auto-generated
712 # then "yield" fields only from op_fields rather than hard-coded
714 fields
= self
.decoder
.sigforms
[formname
]
715 for name
in op_fields
:
717 sig
= getattr(fields
, name
.upper())
719 sig
= getattr(fields
, name
)
721 # these are all opcode fields involved in index-selection of CR,
722 # and need to do "standard" arithmetic. CR[BA+32] for example
723 # would, if using SelectableInt, only be 5-bit.
724 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
725 self
.namespace
[name
] = val
727 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
729 self
.namespace
['XER'] = self
.spr
['XER']
730 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
731 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
733 # add some SVSTATE convenience variables
734 vl
= self
.svstate
.vl
.asint(msb0
=True)
735 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
736 self
.namespace
['VL'] = vl
737 self
.namespace
['srcstep'] = srcstep
739 def handle_carry_(self
, inputs
, outputs
, already_done
):
740 inv_a
= yield self
.dec2
.e
.do
.invert_in
742 inputs
[0] = ~inputs
[0]
744 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
746 imm
= yield self
.dec2
.e
.do
.imm_data
.data
747 inputs
.append(SelectableInt(imm
, 64))
748 assert len(outputs
) >= 1
749 log("outputs", repr(outputs
))
750 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
756 log("gt input", x
, output
)
757 gt
= (gtu(x
, output
))
760 cy
= 1 if any(gts
) else 0
762 if not (1 & already_done
):
763 self
.spr
['XER'][XER_bits
['CA']] = cy
765 log("inputs", already_done
, inputs
)
767 # ARGH... different for OP_ADD... *sigh*...
768 op
= yield self
.dec2
.e
.do
.insn_type
769 if op
== MicrOp
.OP_ADD
.value
:
770 res32
= (output
.value
& (1 << 32)) != 0
771 a32
= (inputs
[0].value
& (1 << 32)) != 0
773 b32
= (inputs
[1].value
& (1 << 32)) != 0
776 cy32
= res32 ^ a32 ^ b32
777 log("CA32 ADD", cy32
)
781 log("input", x
, output
)
782 log(" x[32:64]", x
, x
[32:64])
783 log(" o[32:64]", output
, output
[32:64])
784 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
786 cy32
= 1 if any(gts
) else 0
787 log("CA32", cy32
, gts
)
788 if not (2 & already_done
):
789 self
.spr
['XER'][XER_bits
['CA32']] = cy32
791 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
792 if hasattr(self
.dec2
.e
.do
, "invert_in"):
793 inv_a
= yield self
.dec2
.e
.do
.invert_in
795 inputs
[0] = ~inputs
[0]
797 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
799 imm
= yield self
.dec2
.e
.do
.imm_data
.data
800 inputs
.append(SelectableInt(imm
, 64))
801 assert len(outputs
) >= 1
802 log("handle_overflow", inputs
, outputs
, div_overflow
)
803 if len(inputs
) < 2 and div_overflow
is None:
806 # div overflow is different: it's returned by the pseudo-code
807 # because it's more complex than can be done by analysing the output
808 if div_overflow
is not None:
809 ov
, ov32
= div_overflow
, div_overflow
810 # arithmetic overflow can be done by analysing the input and output
811 elif len(inputs
) >= 2:
815 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
816 output_sgn
= exts(output
.value
, output
.bits
) < 0
817 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
818 output_sgn
!= input_sgn
[0] else 0
821 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
822 output32_sgn
= exts(output
.value
, 32) < 0
823 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
824 output32_sgn
!= input32_sgn
[0] else 0
826 self
.spr
['XER'][XER_bits
['OV']] = ov
827 self
.spr
['XER'][XER_bits
['OV32']] = ov32
828 so
= self
.spr
['XER'][XER_bits
['SO']]
830 self
.spr
['XER'][XER_bits
['SO']] = so
832 def handle_comparison(self
, outputs
, cr_idx
=0):
834 assert isinstance(out
, SelectableInt
), \
835 "out zero not a SelectableInt %s" % repr(outputs
)
836 log("handle_comparison", out
.bits
, hex(out
.value
))
837 # TODO - XXX *processor* in 32-bit mode
838 # https://bugs.libre-soc.org/show_bug.cgi?id=424
840 # o32 = exts(out.value, 32)
841 # print ("handle_comparison exts 32 bit", hex(o32))
842 out
= exts(out
.value
, out
.bits
)
843 log("handle_comparison exts", hex(out
))
844 zero
= SelectableInt(out
== 0, 1)
845 positive
= SelectableInt(out
> 0, 1)
846 negative
= SelectableInt(out
< 0, 1)
847 SO
= self
.spr
['XER'][XER_bits
['SO']]
848 log("handle_comparison SO", SO
)
849 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
850 self
.crl
[cr_idx
].eq(cr_field
)
852 def set_pc(self
, pc_val
):
853 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
854 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
856 def get_next_insn(self
):
860 pc
= self
.pc
.CIA
.value
863 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
865 raise KeyError("no instruction at 0x%x" % pc
)
869 """set up one instruction
871 pc
, insn
= self
.get_next_insn()
872 yield from self
.setup_next_insn(pc
, insn
)
874 def setup_next_insn(self
, pc
, ins
):
875 """set up next instruction
878 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
879 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
881 yield self
.dec2
.sv_rm
.eq(0)
882 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
883 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
884 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
885 yield self
.dec2
.state
.pc
.eq(pc
)
886 if self
.svstate
is not None:
887 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
889 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
891 opcode
= yield self
.dec2
.dec
.opcode_in
892 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
893 pfx
.insn
.value
= opcode
894 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
895 log ("prefix test: opcode:", major
, bin(major
),
896 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
897 self
.is_svp64_mode
= ((major
== 0b000001) and
898 pfx
.insn
[7].value
== 0b1 and
899 pfx
.insn
[9].value
== 0b1)
900 self
.pc
.update_nia(self
.is_svp64_mode
)
901 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
902 self
.namespace
['NIA'] = self
.pc
.NIA
903 self
.namespace
['SVSTATE'] = self
.svstate
.spr
904 if not self
.is_svp64_mode
:
907 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
908 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
909 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
910 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
911 sv_rm
= pfx
.rm
.asint(msb0
=True)
912 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
913 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
914 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
915 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
918 def execute_one(self
):
919 """execute one instruction
921 # get the disassembly code for this instruction
922 if self
.is_svp64_mode
:
923 if not self
.disassembly
:
924 code
= yield from self
.get_assembly_name()
926 code
= self
.disassembly
[self
._pc
+4]
927 log(" svp64 sim-execute", hex(self
._pc
), code
)
929 if not self
.disassembly
:
930 code
= yield from self
.get_assembly_name()
932 code
= self
.disassembly
[self
._pc
]
933 log("sim-execute", hex(self
._pc
), code
)
934 opname
= code
.split(' ')[0]
936 yield from self
.call(opname
) # execute the instruction
937 except MemException
as e
: # check for memory errors
938 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
939 raise e
# ... re-raise
940 # run a Trap but set DAR first
941 print ("memory unaligned exception, DAR", e
.dar
)
942 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
943 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
946 # don't use this except in special circumstances
947 if not self
.respect_pc
:
950 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
952 def get_assembly_name(self
):
953 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
954 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
955 dec_insn
= yield self
.dec2
.e
.do
.insn
956 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
957 asmcode
= yield self
.dec2
.dec
.op
.asmcode
958 int_op
= yield self
.dec2
.dec
.op
.internal_op
959 log("get assembly name asmcode", asmcode
, int_op
,
960 hex(dec_insn
), bin(insn_1_11
))
961 asmop
= insns
.get(asmcode
, None)
963 # sigh reconstruct the assembly instruction name
964 if hasattr(self
.dec2
.e
.do
, "oe"):
965 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
966 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
970 if hasattr(self
.dec2
.e
.do
, "rc"):
971 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
972 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
976 # grrrr have to special-case MUL op (see DecodeOE)
977 log("ov %d en %d rc %d en %d op %d" %
978 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
979 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
984 if not asmop
.endswith("."): # don't add "." to "andis."
987 if hasattr(self
.dec2
.e
.do
, "lk"):
988 lk
= yield self
.dec2
.e
.do
.lk
991 log("int_op", int_op
)
992 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
993 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
997 spr_msb
= yield from self
.get_spr_msb()
998 if int_op
== MicrOp
.OP_MFCR
.value
:
1003 # XXX TODO: for whatever weird reason this doesn't work
1004 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1005 if int_op
== MicrOp
.OP_MTCRF
.value
:
1012 def get_spr_msb(self
):
1013 dec_insn
= yield self
.dec2
.e
.do
.insn
1014 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1016 def call(self
, name
):
1017 """call(opcode) - the primary execution point for instructions
1019 self
.last_st_addr
= None # reset the last known store address
1020 self
.last_ld_addr
= None # etc.
1022 name
= name
.strip() # remove spaces if not already done so
1024 log("halted - not executing", name
)
1027 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1028 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1029 asmop
= yield from self
.get_assembly_name()
1030 log("call", name
, asmop
)
1033 int_op
= yield self
.dec2
.dec
.op
.internal_op
1034 spr_msb
= yield from self
.get_spr_msb()
1036 instr_is_privileged
= False
1037 if int_op
in [MicrOp
.OP_ATTN
.value
,
1038 MicrOp
.OP_MFMSR
.value
,
1039 MicrOp
.OP_MTMSR
.value
,
1040 MicrOp
.OP_MTMSRD
.value
,
1042 MicrOp
.OP_RFID
.value
]:
1043 instr_is_privileged
= True
1044 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1045 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1046 instr_is_privileged
= True
1048 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1050 # check MSR priv bit and whether op is privileged: if so, throw trap
1051 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1052 self
.call_trap(0x700, PIb
.PRIV
)
1055 # check halted condition
1060 # check illegal instruction
1062 if name
not in ['mtcrf', 'mtocrf']:
1063 illegal
= name
!= asmop
1065 # sigh deal with setvl not being supported by binutils (.long)
1066 if asmop
.startswith('setvl'):
1070 # and svremap not being supported by binutils (.long)
1071 if asmop
.startswith('svremap'):
1075 # sigh also deal with ffmadds not being supported by binutils (.long)
1076 if asmop
== 'ffmadds':
1081 print("illegal", name
, asmop
)
1082 self
.call_trap(0x700, PIb
.ILLEG
)
1083 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1084 (name
, asmop
, self
.pc
.CIA
.value
))
1087 # nop has to be supported, we could let the actual op calculate
1088 # but PowerDecoder has a pattern for nop
1090 self
.update_pc_next()
1093 info
= self
.instrs
[name
]
1094 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1096 # preserve order of register names
1097 input_names
= create_args(list(info
.read_regs
) +
1098 list(info
.uninit_regs
))
1101 # get SVP64 entry for the current instruction
1102 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1103 if sv_rm
is not None:
1104 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1106 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1107 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1109 # get SVSTATE VL (oh and print out some debug stuff)
1110 if self
.is_svp64_mode
:
1111 vl
= self
.svstate
.vl
.asint(msb0
=True)
1112 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1113 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1114 sv_a_nz
= yield self
.dec2
.sv_a_nz
1115 fft_mode
= yield self
.dec2
.use_svp64_fft
1116 in1
= yield self
.dec2
.e
.read_reg1
.data
1117 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1118 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1120 # get predicate mask
1121 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1122 if self
.is_svp64_mode
:
1123 pmode
= yield self
.dec2
.rm_dec
.predmode
1124 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1125 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1126 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1127 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1128 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1129 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1130 if pmode
== SVP64PredMode
.INT
.value
:
1131 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1132 if sv_ptype
== SVPtype
.P2
.value
:
1133 srcmask
= get_predint(self
.gpr
, srcpred
)
1134 elif pmode
== SVP64PredMode
.CR
.value
:
1135 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1136 if sv_ptype
== SVPtype
.P2
.value
:
1137 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1138 log (" pmode", pmode
)
1139 log (" reverse", reverse_gear
)
1140 log (" ptype", sv_ptype
)
1141 log (" srcpred", bin(srcpred
))
1142 log (" dstpred", bin(dstpred
))
1143 log (" srcmask", bin(srcmask
))
1144 log (" dstmask", bin(dstmask
))
1145 log (" pred_sz", bin(pred_src_zero
))
1146 log (" pred_dz", bin(pred_dst_zero
))
1148 # okaaay, so here we simply advance srcstep (TODO dststep)
1149 # until the predicate mask has a "1" bit... or we run out of VL
1150 # let srcstep==VL be the indicator to move to next instruction
1151 if not pred_src_zero
:
1152 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1153 log (" skip", bin(1<<srcstep
))
1156 if not pred_dst_zero
:
1157 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1158 log (" skip", bin(1<<dststep
))
1161 # now work out if the relevant mask bits require zeroing
1163 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1165 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1167 # update SVSTATE with new srcstep
1168 self
.svstate
.srcstep
[0:7] = srcstep
1169 self
.svstate
.dststep
[0:7] = dststep
1170 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1171 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1172 yield Settle() # let decoder update
1173 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1174 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1175 log (" srcstep", srcstep
)
1176 log (" dststep", dststep
)
1178 # check if end reached (we let srcstep overrun, above)
1179 # nothing needs doing (TODO zeroing): just do next instruction
1180 if srcstep
== vl
or dststep
== vl
:
1181 self
.svp64_reset_loop()
1182 self
.update_pc_next()
1185 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1186 if self
.is_svp64_mode
and vl
== 0:
1187 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1188 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1189 self
.namespace
['NIA'])
1192 # main input registers (RT, RA ...)
1194 for name
in input_names
:
1195 # using PowerDecoder2, first, find the decoder index.
1196 # (mapping name RA RB RC RS to in1, in2, in3)
1197 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1199 # doing this is not part of svp64, it's because output
1200 # registers, to be modified, need to be in the namespace.
1201 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1203 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1206 # in case getting the register number is needed, _RA, _RB
1207 regname
= "_" + name
1208 self
.namespace
[regname
] = regnum
1209 if not self
.is_svp64_mode
or not pred_src_zero
:
1210 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1212 reg_val
= self
.fpr(regnum
)
1214 reg_val
= self
.gpr(regnum
)
1216 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1218 inputs
.append(reg_val
)
1220 # in SVP64 mode for LD/ST work out immediate
1221 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1222 # use info.form to detect
1223 replace_d
= False # update / replace constant in pseudocode
1224 if self
.is_svp64_mode
:
1225 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1226 # bitreverse mode reads SVD (or SVDS - TODO)
1227 # *BUT*... because this is "overloading" of LD operations,
1228 # it gets *STORED* into D (or DS, TODO)
1229 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1230 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1231 imm
= exts(imm
, 11) # sign-extend to integer
1232 print ("bitrev SVD", imm
)
1235 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1236 imm
= exts(imm
, 16) # sign-extend to integer
1237 # get the right step. LD is from srcstep, ST is dststep
1238 op
= yield self
.dec2
.e
.do
.insn_type
1240 if op
== MicrOp
.OP_LOAD
.value
:
1242 log("D-field src", imm
, offsmul
)
1243 elif op
== MicrOp
.OP_STORE
.value
:
1245 log("D-field dst", imm
, offsmul
)
1247 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1248 # manually look up RC, sigh
1249 RC
= yield self
.dec2
.dec
.RC
[0:5]
1251 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1252 "rev", bin(bitrev(offsmul
, vl
)))
1253 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1254 # Unit-Strided LD/ST adds offset*width to immediate
1255 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1256 ldst_len
= yield self
.dec2
.e
.do
.data_len
1257 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1259 # Element-strided multiplies the immediate by element step
1260 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1261 imm
= SelectableInt(imm
* offsmul
, 32)
1263 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1264 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1265 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1266 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1269 self
.namespace
['D'] = imm
1271 # "special" registers
1272 for special
in info
.special_regs
:
1273 if special
in special_sprs
:
1274 inputs
.append(self
.spr
[special
])
1276 inputs
.append(self
.namespace
[special
])
1278 # clear trap (trap) NIA
1279 self
.trap_nia
= None
1281 # execute actual instruction here (finally)
1282 log("inputs", inputs
)
1283 results
= info
.func(self
, *inputs
)
1284 log("results", results
)
1286 # "inject" decorator takes namespace from function locals: we need to
1287 # overwrite NIA being overwritten (sigh)
1288 if self
.trap_nia
is not None:
1289 self
.namespace
['NIA'] = self
.trap_nia
1291 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1293 # check if op was a LD/ST so that debugging can check the
1295 if int_op
in [MicrOp
.OP_STORE
.value
,
1297 self
.last_st_addr
= self
.mem
.last_st_addr
1298 if int_op
in [MicrOp
.OP_LOAD
.value
,
1300 self
.last_ld_addr
= self
.mem
.last_ld_addr
1301 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1302 self
.last_st_addr
, self
.last_ld_addr
)
1304 # detect if CA/CA32 already in outputs (sra*, basically)
1307 output_names
= create_args(info
.write_regs
)
1308 for name
in output_names
:
1314 log("carry already done?", bin(already_done
))
1315 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1316 carry_en
= yield self
.dec2
.e
.do
.output_carry
1320 yield from self
.handle_carry_(inputs
, results
, already_done
)
1322 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1323 # detect if overflow was in return result
1326 for name
, output
in zip(output_names
, results
):
1327 if name
== 'overflow':
1330 if hasattr(self
.dec2
.e
.do
, "oe"):
1331 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1332 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1336 log("internal overflow", overflow
, ov_en
, ov_ok
)
1338 yield from self
.handle_overflow(inputs
, results
, overflow
)
1340 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1342 if not self
.is_svp64_mode
or not pred_dst_zero
:
1343 if hasattr(self
.dec2
.e
.do
, "rc"):
1344 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1346 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1347 self
.handle_comparison(results
, regnum
)
1349 # any modified return results?
1351 for name
, output
in zip(output_names
, results
):
1352 if name
== 'overflow': # ignore, done already (above)
1354 if isinstance(output
, int):
1355 output
= SelectableInt(output
, 256)
1356 if name
in ['CA', 'CA32']:
1358 log("writing %s to XER" % name
, output
)
1359 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1361 log("NOT writing %s to XER" % name
, output
)
1362 elif name
in info
.special_regs
:
1363 log('writing special %s' % name
, output
, special_sprs
)
1364 if name
in special_sprs
:
1365 self
.spr
[name
] = output
1367 self
.namespace
[name
].eq(output
)
1369 log('msr written', hex(self
.msr
.value
))
1371 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1374 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1377 # temporary hack for not having 2nd output
1378 regnum
= yield getattr(self
.decoder
, name
)
1380 if self
.is_svp64_mode
and pred_dst_zero
:
1381 log('zeroing reg %d %s' % (regnum
, str(output
)),
1383 output
= SelectableInt(0, 256)
1389 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1391 if output
.bits
> 64:
1392 output
= SelectableInt(output
.value
, 64)
1394 self
.fpr
[regnum
] = output
1396 self
.gpr
[regnum
] = output
1398 # check if it is the SVSTATE.src/dest step that needs incrementing
1399 # this is our Sub-Program-Counter loop from 0 to VL-1
1400 if self
.is_svp64_mode
:
1401 # XXX twin predication TODO
1402 vl
= self
.svstate
.vl
.asint(msb0
=True)
1403 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1404 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1405 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1406 rm_mode
= yield self
.dec2
.rm_dec
.mode
1407 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1408 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1409 out_vec
= not (yield self
.dec2
.no_out_vec
)
1410 in_vec
= not (yield self
.dec2
.no_in_vec
)
1411 log (" svstate.vl", vl
)
1412 log (" svstate.mvl", mvl
)
1413 log (" svstate.srcstep", srcstep
)
1414 log (" svstate.dststep", dststep
)
1415 log (" mode", rm_mode
)
1416 log (" reverse", reverse_gear
)
1417 log (" out_vec", out_vec
)
1418 log (" in_vec", in_vec
)
1419 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1420 # check if srcstep needs incrementing by one, stop PC advancing
1421 # svp64 loop can end early if the dest is scalar for single-pred
1422 # but for 2-pred both src/dest have to be checked.
1423 # XXX this might not be true! it may just be LD/ST
1424 if sv_ptype
== SVPtype
.P2
.value
:
1425 svp64_is_vector
= (out_vec
or in_vec
)
1427 svp64_is_vector
= out_vec
1428 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1429 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1430 self
.svstate
.dststep
+= SelectableInt(1, 7)
1431 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1432 self
.namespace
['NIA'] = self
.pc
.NIA
1433 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1434 log("end of sub-pc call", self
.namespace
['CIA'],
1435 self
.namespace
['NIA'])
1436 return # DO NOT allow PC to update whilst Sub-PC loop running
1437 # reset loop to zero
1438 self
.svp64_reset_loop()
1440 self
.update_pc_next()
1442 def update_pc_next(self
):
1443 # UPDATE program counter
1444 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1445 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1446 log("end of call", self
.namespace
['CIA'],
1447 self
.namespace
['NIA'],
1448 self
.namespace
['SVSTATE'])
1450 def svp64_reset_loop(self
):
1451 self
.svstate
.srcstep
[0:7] = 0
1452 self
.svstate
.dststep
[0:7] = 0
1453 log (" svstate.srcstep loop end (PC to update)")
1454 self
.pc
.update_nia(self
.is_svp64_mode
)
1455 self
.namespace
['NIA'] = self
.pc
.NIA
1456 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1460 """Decorator factory.
1462 this decorator will "inject" variables into the function's namespace,
1463 from the *dictionary* in self.namespace. it therefore becomes possible
1464 to make it look like a whole stack of variables which would otherwise
1465 need "self." inserted in front of them (*and* for those variables to be
1466 added to the instance) "appear" in the function.
1468 "self.namespace['SI']" for example becomes accessible as just "SI" but
1469 *only* inside the function, when decorated.
1471 def variable_injector(func
):
1473 def decorator(*args
, **kwargs
):
1475 func_globals
= func
.__globals
__ # Python 2.6+
1476 except AttributeError:
1477 func_globals
= func
.func_globals
# Earlier versions.
1479 context
= args
[0].namespace
# variables to be injected
1480 saved_values
= func_globals
.copy() # Shallow copy of dict.
1481 func_globals
.update(context
)
1482 result
= func(*args
, **kwargs
)
1483 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1484 log("args[0]", args
[0].namespace
['CIA'],
1485 args
[0].namespace
['NIA'],
1486 args
[0].namespace
['SVSTATE'])
1487 args
[0].namespace
= func_globals
1488 #exec (func.__code__, func_globals)
1491 # func_globals = saved_values # Undo changes.
1497 return variable_injector