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
81 "overflow": 7, # should definitely be last
84 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
87 def create_args(reglist
, extra
=None):
88 retval
= list(OrderedSet(reglist
))
89 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
91 return [extra
] + retval
97 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
100 self
.isacaller
= isacaller
101 self
.svstate
= svstate
102 for i
in range(len(regfile
)):
103 self
[i
] = SelectableInt(regfile
[i
], 64)
105 def __call__(self
, ridx
):
108 def set_form(self
, form
):
111 def getz(self
, rnum
):
112 # rnum = rnum.value # only SelectableInt allowed
113 log("GPR getzero?", rnum
)
115 return SelectableInt(0, 64)
118 def _get_regnum(self
, attr
):
119 getform
= self
.sd
.sigforms
[self
.form
]
120 rnum
= getattr(getform
, attr
)
123 def ___getitem__(self
, attr
):
124 """ XXX currently not used
126 rnum
= self
._get
_regnum
(attr
)
127 log("GPR getitem", attr
, rnum
)
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 # TODO, really should just be using PowerDecoder2
377 def get_pdecode_idx_in(dec2
, name
):
379 in1_sel
= yield op
.in1_sel
380 in2_sel
= yield op
.in2_sel
381 in3_sel
= yield op
.in3_sel
382 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
383 in1
= yield dec2
.e
.read_reg1
.data
384 in2
= yield dec2
.e
.read_reg2
.data
385 in3
= yield dec2
.e
.read_reg3
.data
386 in1_isvec
= yield dec2
.in1_isvec
387 in2_isvec
= yield dec2
.in2_isvec
388 in3_isvec
= yield dec2
.in3_isvec
389 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
391 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
393 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
395 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
397 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
399 # identify which regnames map to in1/2/3
401 if (in1_sel
== In1Sel
.RA
.value
or
402 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
403 return in1
, in1_isvec
404 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
405 return in1
, in1_isvec
407 if in2_sel
== In2Sel
.RB
.value
:
408 return in2
, in2_isvec
409 if in3_sel
== In3Sel
.RB
.value
:
410 return in3
, in3_isvec
411 # XXX TODO, RC doesn't exist yet!
413 assert False, "RC does not exist yet"
415 if in1_sel
== In1Sel
.RS
.value
:
416 return in1
, in1_isvec
417 if in2_sel
== In2Sel
.RS
.value
:
418 return in2
, in2_isvec
419 if in3_sel
== In3Sel
.RS
.value
:
420 return in3
, in3_isvec
422 if in1_sel
== In1Sel
.FRA
.value
:
423 return in1
, in1_isvec
425 if in2_sel
== In2Sel
.FRB
.value
:
426 return in2
, in2_isvec
428 if in3_sel
== In3Sel
.FRC
.value
:
429 return in3
, in3_isvec
431 if in1_sel
== In1Sel
.FRS
.value
:
432 return in1
, in1_isvec
433 if in3_sel
== In3Sel
.FRS
.value
:
434 return in3
, in3_isvec
438 # TODO, really should just be using PowerDecoder2
439 def get_pdecode_cr_out(dec2
, name
):
441 out_sel
= yield op
.cr_out
442 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
443 sv_cr_out
= yield op
.sv_cr_out
444 spec
= yield dec2
.crout_svdec
.spec
445 sv_override
= yield dec2
.dec_cr_out
.sv_override
446 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
447 out
= yield dec2
.e
.write_cr
.data
448 o_isvec
= yield dec2
.o_isvec
449 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
450 log (" sv_cr_out", sv_cr_out
)
451 log (" cr_bf", out_bitfield
)
453 log (" override", sv_override
)
454 # identify which regnames map to out / o2
456 if out_sel
== CROutSel
.CR0
.value
:
458 log ("get_pdecode_cr_out not found", name
)
462 # TODO, really should just be using PowerDecoder2
463 def get_pdecode_idx_out(dec2
, name
):
465 out_sel
= yield op
.out_sel
466 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
467 out
= yield dec2
.e
.write_reg
.data
468 o_isvec
= yield dec2
.o_isvec
469 # identify which regnames map to out / o2
471 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
472 if out_sel
== OutSel
.RA
.value
:
475 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
476 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
)
477 if out_sel
== OutSel
.RT
.value
:
480 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
481 if out_sel
== OutSel
.FRA
.value
:
484 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
485 OutSel
.FRT
.value
, out
, o_isvec
)
486 if out_sel
== OutSel
.FRT
.value
:
488 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
492 # TODO, really should just be using PowerDecoder2
493 def get_pdecode_idx_out2(dec2
, name
):
494 # check first if register is activated for write
496 out_sel
= yield op
.out_sel
497 out
= yield dec2
.e
.write_ea
.data
498 o_isvec
= yield dec2
.o2_isvec
499 out_ok
= yield dec2
.e
.write_ea
.ok
500 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, 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
:
514 int_op
= yield dec2
.dec
.op
.internal_op
515 fft_en
= yield dec2
.use_svp64_fft
516 if int_op
== MicrOp
.OP_FP_MADD
.value
and fft_en
:
517 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
524 # decoder2 - an instance of power_decoder2
525 # regfile - a list of initial values for the registers
526 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
527 # respect_pc - tracks the program counter. requires initial_insns
528 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
529 initial_mem
=None, initial_msr
=0,
540 self
.bigendian
= bigendian
542 self
.is_svp64_mode
= False
543 self
.respect_pc
= respect_pc
544 if initial_sprs
is None:
546 if initial_mem
is None:
548 if fpregfile
is None:
550 if initial_insns
is None:
552 assert self
.respect_pc
== False, "instructions required to honor pc"
554 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
555 log("ISACaller initial_msr", initial_msr
)
557 # "fake program counter" mode (for unit testing)
561 if isinstance(initial_mem
, tuple):
562 self
.fake_pc
= initial_mem
[0]
563 disasm_start
= self
.fake_pc
565 disasm_start
= initial_pc
567 # disassembly: we need this for now (not given from the decoder)
568 self
.disassembly
= {}
570 for i
, code
in enumerate(disassembly
):
571 self
.disassembly
[i
*4 + disasm_start
] = code
573 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
574 self
.svp64rm
= SVP64RM()
575 if initial_svstate
is None:
577 if isinstance(initial_svstate
, int):
578 initial_svstate
= SVP64State(initial_svstate
)
579 # SVSTATE, MSR and PC
580 self
.svstate
= initial_svstate
581 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
583 # GPR FPR SPR registers
584 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
585 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
586 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
588 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
589 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
590 # MMU mode, redirect underlying Mem through RADIX
592 self
.mem
= RADIX(self
.mem
, self
)
594 self
.imem
= RADIX(self
.imem
, self
)
597 # FPR (same as GPR except for FP nums)
598 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
599 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
600 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
601 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
603 # 2.3.2 LR (actually SPR #8) -- Done
604 # 2.3.3 CTR (actually SPR #9) -- Done
605 # 2.3.4 TAR (actually SPR #815)
606 # 3.2.2 p45 XER (actually SPR #1) -- Done
607 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
609 # create CR then allow portions of it to be "selectable" (below)
610 self
.cr_fields
= CRFields(initial_cr
)
611 self
.cr
= self
.cr_fields
.cr
613 # "undefined", just set to variable-bit-width int (use exts "max")
614 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
617 self
.namespace
.update(self
.spr
)
618 self
.namespace
.update({'GPR': self
.gpr
,
622 'memassign': self
.memassign
,
625 'SVSTATE': self
.svstate
.spr
,
628 'undefined': undefined
,
629 'mode_is_64bit': True,
633 # update pc to requested start point
634 self
.set_pc(initial_pc
)
636 # field-selectable versions of Condition Register
637 self
.crl
= self
.cr_fields
.crl
639 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
641 self
.decoder
= decoder2
.dec
644 def call_trap(self
, trap_addr
, trap_bit
):
645 """calls TRAP and sets up NIA to the new execution location.
646 next instruction will begin at trap_addr.
648 self
.TRAP(trap_addr
, trap_bit
)
649 self
.namespace
['NIA'] = self
.trap_nia
650 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
652 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
653 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
655 TRAP function is callable from inside the pseudocode itself,
656 hence the default arguments. when calling from inside ISACaller
657 it is best to use call_trap()
659 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
660 # store CIA(+4?) in SRR0, set NIA to 0x700
661 # store MSR in SRR1, set MSR to um errr something, have to check spec
662 # store SVSTATE (if enabled) in SVSRR0
663 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
664 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
665 if self
.is_svp64_mode
:
666 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
667 self
.trap_nia
= SelectableInt(trap_addr
, 64)
668 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
670 # set exception bits. TODO: this should, based on the address
671 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
672 # bits appropriately. however it turns out that *for now* in all
673 # cases (all trap_addrs) the exact same thing is needed.
674 self
.msr
[MSRb
.IR
] = 0
675 self
.msr
[MSRb
.DR
] = 0
676 self
.msr
[MSRb
.FE0
] = 0
677 self
.msr
[MSRb
.FE1
] = 0
678 self
.msr
[MSRb
.EE
] = 0
679 self
.msr
[MSRb
.RI
] = 0
680 self
.msr
[MSRb
.SF
] = 1
681 self
.msr
[MSRb
.TM
] = 0
682 self
.msr
[MSRb
.VEC
] = 0
683 self
.msr
[MSRb
.VSX
] = 0
684 self
.msr
[MSRb
.PR
] = 0
685 self
.msr
[MSRb
.FP
] = 0
686 self
.msr
[MSRb
.PMM
] = 0
687 self
.msr
[MSRb
.TEs
] = 0
688 self
.msr
[MSRb
.TEe
] = 0
689 self
.msr
[MSRb
.UND
] = 0
690 self
.msr
[MSRb
.LE
] = 1
692 def memassign(self
, ea
, sz
, val
):
693 self
.mem
.memassign(ea
, sz
, val
)
695 def prep_namespace(self
, formname
, op_fields
):
696 # TODO: get field names from form in decoder*1* (not decoder2)
697 # decoder2 is hand-created, and decoder1.sigform is auto-generated
699 # then "yield" fields only from op_fields rather than hard-coded
701 fields
= self
.decoder
.sigforms
[formname
]
702 for name
in op_fields
:
704 sig
= getattr(fields
, name
.upper())
706 sig
= getattr(fields
, name
)
708 # these are all opcode fields involved in index-selection of CR,
709 # and need to do "standard" arithmetic. CR[BA+32] for example
710 # would, if using SelectableInt, only be 5-bit.
711 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
712 self
.namespace
[name
] = val
714 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
716 self
.namespace
['XER'] = self
.spr
['XER']
717 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
718 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
720 # add some SVSTATE convenience variables
721 vl
= self
.svstate
.vl
.asint(msb0
=True)
722 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
723 self
.namespace
['VL'] = vl
724 self
.namespace
['srcstep'] = srcstep
726 def handle_carry_(self
, inputs
, outputs
, already_done
):
727 inv_a
= yield self
.dec2
.e
.do
.invert_in
729 inputs
[0] = ~inputs
[0]
731 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
733 imm
= yield self
.dec2
.e
.do
.imm_data
.data
734 inputs
.append(SelectableInt(imm
, 64))
735 assert len(outputs
) >= 1
736 log("outputs", repr(outputs
))
737 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
743 log("gt input", x
, output
)
744 gt
= (gtu(x
, output
))
747 cy
= 1 if any(gts
) else 0
749 if not (1 & already_done
):
750 self
.spr
['XER'][XER_bits
['CA']] = cy
752 log("inputs", already_done
, inputs
)
754 # ARGH... different for OP_ADD... *sigh*...
755 op
= yield self
.dec2
.e
.do
.insn_type
756 if op
== MicrOp
.OP_ADD
.value
:
757 res32
= (output
.value
& (1 << 32)) != 0
758 a32
= (inputs
[0].value
& (1 << 32)) != 0
760 b32
= (inputs
[1].value
& (1 << 32)) != 0
763 cy32
= res32 ^ a32 ^ b32
764 log("CA32 ADD", cy32
)
768 log("input", x
, output
)
769 log(" x[32:64]", x
, x
[32:64])
770 log(" o[32:64]", output
, output
[32:64])
771 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
773 cy32
= 1 if any(gts
) else 0
774 log("CA32", cy32
, gts
)
775 if not (2 & already_done
):
776 self
.spr
['XER'][XER_bits
['CA32']] = cy32
778 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
779 if hasattr(self
.dec2
.e
.do
, "invert_in"):
780 inv_a
= yield self
.dec2
.e
.do
.invert_in
782 inputs
[0] = ~inputs
[0]
784 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
786 imm
= yield self
.dec2
.e
.do
.imm_data
.data
787 inputs
.append(SelectableInt(imm
, 64))
788 assert len(outputs
) >= 1
789 log("handle_overflow", inputs
, outputs
, div_overflow
)
790 if len(inputs
) < 2 and div_overflow
is None:
793 # div overflow is different: it's returned by the pseudo-code
794 # because it's more complex than can be done by analysing the output
795 if div_overflow
is not None:
796 ov
, ov32
= div_overflow
, div_overflow
797 # arithmetic overflow can be done by analysing the input and output
798 elif len(inputs
) >= 2:
802 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
803 output_sgn
= exts(output
.value
, output
.bits
) < 0
804 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
805 output_sgn
!= input_sgn
[0] else 0
808 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
809 output32_sgn
= exts(output
.value
, 32) < 0
810 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
811 output32_sgn
!= input32_sgn
[0] else 0
813 self
.spr
['XER'][XER_bits
['OV']] = ov
814 self
.spr
['XER'][XER_bits
['OV32']] = ov32
815 so
= self
.spr
['XER'][XER_bits
['SO']]
817 self
.spr
['XER'][XER_bits
['SO']] = so
819 def handle_comparison(self
, outputs
, cr_idx
=0):
821 assert isinstance(out
, SelectableInt
), \
822 "out zero not a SelectableInt %s" % repr(outputs
)
823 log("handle_comparison", out
.bits
, hex(out
.value
))
824 # TODO - XXX *processor* in 32-bit mode
825 # https://bugs.libre-soc.org/show_bug.cgi?id=424
827 # o32 = exts(out.value, 32)
828 # print ("handle_comparison exts 32 bit", hex(o32))
829 out
= exts(out
.value
, out
.bits
)
830 log("handle_comparison exts", hex(out
))
831 zero
= SelectableInt(out
== 0, 1)
832 positive
= SelectableInt(out
> 0, 1)
833 negative
= SelectableInt(out
< 0, 1)
834 SO
= self
.spr
['XER'][XER_bits
['SO']]
835 log("handle_comparison SO", SO
)
836 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
837 self
.crl
[cr_idx
].eq(cr_field
)
839 def set_pc(self
, pc_val
):
840 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
841 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
843 def get_next_insn(self
):
847 pc
= self
.pc
.CIA
.value
850 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
852 raise KeyError("no instruction at 0x%x" % pc
)
856 """set up one instruction
858 pc
, insn
= self
.get_next_insn()
859 yield from self
.setup_next_insn(pc
, insn
)
861 def setup_next_insn(self
, pc
, ins
):
862 """set up next instruction
865 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
866 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
868 yield self
.dec2
.sv_rm
.eq(0)
869 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
870 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
871 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
872 yield self
.dec2
.state
.pc
.eq(pc
)
873 if self
.svstate
is not None:
874 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
876 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
878 opcode
= yield self
.dec2
.dec
.opcode_in
879 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
880 pfx
.insn
.value
= opcode
881 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
882 log ("prefix test: opcode:", major
, bin(major
),
883 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
884 self
.is_svp64_mode
= ((major
== 0b000001) and
885 pfx
.insn
[7].value
== 0b1 and
886 pfx
.insn
[9].value
== 0b1)
887 self
.pc
.update_nia(self
.is_svp64_mode
)
888 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
889 self
.namespace
['NIA'] = self
.pc
.NIA
890 self
.namespace
['SVSTATE'] = self
.svstate
.spr
891 if not self
.is_svp64_mode
:
894 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
895 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
896 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
897 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
898 sv_rm
= pfx
.rm
.asint(msb0
=True)
899 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
900 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
901 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
902 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
905 def execute_one(self
):
906 """execute one instruction
908 # get the disassembly code for this instruction
909 if self
.is_svp64_mode
:
910 if not self
.disassembly
:
911 code
= yield from self
.get_assembly_name()
913 code
= self
.disassembly
[self
._pc
+4]
914 log(" svp64 sim-execute", hex(self
._pc
), code
)
916 if not self
.disassembly
:
917 code
= yield from self
.get_assembly_name()
919 code
= self
.disassembly
[self
._pc
]
920 log("sim-execute", hex(self
._pc
), code
)
921 opname
= code
.split(' ')[0]
923 yield from self
.call(opname
) # execute the instruction
924 except MemException
as e
: # check for memory errors
925 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
926 raise e
# ... re-raise
927 # run a Trap but set DAR first
928 print ("memory unaligned exception, DAR", e
.dar
)
929 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
930 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
933 # don't use this except in special circumstances
934 if not self
.respect_pc
:
937 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
939 def get_assembly_name(self
):
940 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
941 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
942 dec_insn
= yield self
.dec2
.e
.do
.insn
943 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
944 asmcode
= yield self
.dec2
.dec
.op
.asmcode
945 int_op
= yield self
.dec2
.dec
.op
.internal_op
946 log("get assembly name asmcode", asmcode
, int_op
,
947 hex(dec_insn
), bin(insn_1_11
))
948 asmop
= insns
.get(asmcode
, None)
950 # sigh reconstruct the assembly instruction name
951 if hasattr(self
.dec2
.e
.do
, "oe"):
952 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
953 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
957 if hasattr(self
.dec2
.e
.do
, "rc"):
958 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
959 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
963 # grrrr have to special-case MUL op (see DecodeOE)
964 log("ov %d en %d rc %d en %d op %d" %
965 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
966 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
971 if not asmop
.endswith("."): # don't add "." to "andis."
974 if hasattr(self
.dec2
.e
.do
, "lk"):
975 lk
= yield self
.dec2
.e
.do
.lk
978 log("int_op", int_op
)
979 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
980 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
984 spr_msb
= yield from self
.get_spr_msb()
985 if int_op
== MicrOp
.OP_MFCR
.value
:
990 # XXX TODO: for whatever weird reason this doesn't work
991 # https://bugs.libre-soc.org/show_bug.cgi?id=390
992 if int_op
== MicrOp
.OP_MTCRF
.value
:
999 def get_spr_msb(self
):
1000 dec_insn
= yield self
.dec2
.e
.do
.insn
1001 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1003 def call(self
, name
):
1004 """call(opcode) - the primary execution point for instructions
1006 self
.last_st_addr
= None # reset the last known store address
1007 self
.last_ld_addr
= None # etc.
1009 name
= name
.strip() # remove spaces if not already done so
1011 log("halted - not executing", name
)
1014 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1015 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1016 asmop
= yield from self
.get_assembly_name()
1017 log("call", name
, asmop
)
1020 int_op
= yield self
.dec2
.dec
.op
.internal_op
1021 spr_msb
= yield from self
.get_spr_msb()
1023 instr_is_privileged
= False
1024 if int_op
in [MicrOp
.OP_ATTN
.value
,
1025 MicrOp
.OP_MFMSR
.value
,
1026 MicrOp
.OP_MTMSR
.value
,
1027 MicrOp
.OP_MTMSRD
.value
,
1029 MicrOp
.OP_RFID
.value
]:
1030 instr_is_privileged
= True
1031 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1032 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1033 instr_is_privileged
= True
1035 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1037 # check MSR priv bit and whether op is privileged: if so, throw trap
1038 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1039 self
.call_trap(0x700, PIb
.PRIV
)
1042 # check halted condition
1047 # check illegal instruction
1049 if name
not in ['mtcrf', 'mtocrf']:
1050 illegal
= name
!= asmop
1052 # sigh deal with setvl not being supported by binutils (.long)
1053 if asmop
.startswith('setvl'):
1057 # sigh also deal with ffmadds not being supported by binutils (.long)
1058 if asmop
== 'ffmadds':
1063 print("illegal", name
, asmop
)
1064 self
.call_trap(0x700, PIb
.ILLEG
)
1065 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1066 (name
, asmop
, self
.pc
.CIA
.value
))
1069 # nop has to be supported, we could let the actual op calculate
1070 # but PowerDecoder has a pattern for nop
1072 self
.update_pc_next()
1075 info
= self
.instrs
[name
]
1076 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1078 # preserve order of register names
1079 input_names
= create_args(list(info
.read_regs
) +
1080 list(info
.uninit_regs
))
1083 # get SVP64 entry for the current instruction
1084 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1085 if sv_rm
is not None:
1086 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1088 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1089 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1091 # get SVSTATE VL (oh and print out some debug stuff)
1092 if self
.is_svp64_mode
:
1093 vl
= self
.svstate
.vl
.asint(msb0
=True)
1094 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1095 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1096 sv_a_nz
= yield self
.dec2
.sv_a_nz
1097 fft_mode
= yield self
.dec2
.use_svp64_fft
1098 in1
= yield self
.dec2
.e
.read_reg1
.data
1099 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1100 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1102 # get predicate mask
1103 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1104 if self
.is_svp64_mode
:
1105 pmode
= yield self
.dec2
.rm_dec
.predmode
1106 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1107 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1108 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1109 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1110 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1111 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1112 if pmode
== SVP64PredMode
.INT
.value
:
1113 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1114 if sv_ptype
== SVPtype
.P2
.value
:
1115 srcmask
= get_predint(self
.gpr
, srcpred
)
1116 elif pmode
== SVP64PredMode
.CR
.value
:
1117 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1118 if sv_ptype
== SVPtype
.P2
.value
:
1119 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1120 log (" pmode", pmode
)
1121 log (" reverse", reverse_gear
)
1122 log (" ptype", sv_ptype
)
1123 log (" srcpred", bin(srcpred
))
1124 log (" dstpred", bin(dstpred
))
1125 log (" srcmask", bin(srcmask
))
1126 log (" dstmask", bin(dstmask
))
1127 log (" pred_sz", bin(pred_src_zero
))
1128 log (" pred_dz", bin(pred_dst_zero
))
1130 # okaaay, so here we simply advance srcstep (TODO dststep)
1131 # until the predicate mask has a "1" bit... or we run out of VL
1132 # let srcstep==VL be the indicator to move to next instruction
1133 if not pred_src_zero
:
1134 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1135 log (" skip", bin(1<<srcstep
))
1138 if not pred_dst_zero
:
1139 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1140 log (" skip", bin(1<<dststep
))
1143 # now work out if the relevant mask bits require zeroing
1145 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1147 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1149 # update SVSTATE with new srcstep
1150 self
.svstate
.srcstep
[0:7] = srcstep
1151 self
.svstate
.dststep
[0:7] = dststep
1152 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1153 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1154 yield Settle() # let decoder update
1155 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1156 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1157 log (" srcstep", srcstep
)
1158 log (" dststep", dststep
)
1160 # check if end reached (we let srcstep overrun, above)
1161 # nothing needs doing (TODO zeroing): just do next instruction
1162 if srcstep
== vl
or dststep
== vl
:
1163 self
.svp64_reset_loop()
1164 self
.update_pc_next()
1167 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1168 if self
.is_svp64_mode
and vl
== 0:
1169 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1170 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1171 self
.namespace
['NIA'])
1174 # main input registers (RT, RA ...)
1176 for name
in input_names
:
1177 # using PowerDecoder2, first, find the decoder index.
1178 # (mapping name RA RB RC RS to in1, in2, in3)
1179 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1181 # doing this is not part of svp64, it's because output
1182 # registers, to be modified, need to be in the namespace.
1183 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1185 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1188 # in case getting the register number is needed, _RA, _RB
1189 regname
= "_" + name
1190 self
.namespace
[regname
] = regnum
1191 if not self
.is_svp64_mode
or not pred_src_zero
:
1192 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1194 reg_val
= self
.fpr(regnum
)
1196 reg_val
= self
.gpr(regnum
)
1198 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1200 inputs
.append(reg_val
)
1202 # in SVP64 mode for LD/ST work out immediate
1203 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1204 # use info.form to detect
1205 replace_d
= False # update / replace constant in pseudocode
1206 if self
.is_svp64_mode
:
1207 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1208 # bitreverse mode reads SVD (or SVDS - TODO)
1209 # *BUT*... because this is "overloading" of LD operations,
1210 # it gets *STORED* into D (or DS, TODO)
1211 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1212 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1213 imm
= exts(imm
, 11) # sign-extend to integer
1214 print ("bitrev SVD", imm
)
1217 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1218 imm
= exts(imm
, 16) # sign-extend to integer
1219 # get the right step. LD is from srcstep, ST is dststep
1220 op
= yield self
.dec2
.e
.do
.insn_type
1222 if op
== MicrOp
.OP_LOAD
.value
:
1224 log("D-field src", imm
, offsmul
)
1225 elif op
== MicrOp
.OP_STORE
.value
:
1227 log("D-field dst", imm
, offsmul
)
1229 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1230 # manually look up RC, sigh
1231 RC
= yield self
.dec2
.dec
.RC
[0:5]
1233 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1234 "rev", bin(bitrev(offsmul
, vl
)))
1235 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1236 # Unit-Strided LD/ST adds offset*width to immediate
1237 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1238 ldst_len
= yield self
.dec2
.e
.do
.data_len
1239 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1241 # Element-strided multiplies the immediate by element step
1242 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1243 imm
= SelectableInt(imm
* offsmul
, 32)
1245 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1246 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1247 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1248 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1251 self
.namespace
['D'] = imm
1253 # "special" registers
1254 for special
in info
.special_regs
:
1255 if special
in special_sprs
:
1256 inputs
.append(self
.spr
[special
])
1258 inputs
.append(self
.namespace
[special
])
1260 # clear trap (trap) NIA
1261 self
.trap_nia
= None
1263 # execute actual instruction here (finally)
1264 log("inputs", inputs
)
1265 results
= info
.func(self
, *inputs
)
1266 log("results", results
)
1268 # "inject" decorator takes namespace from function locals: we need to
1269 # overwrite NIA being overwritten (sigh)
1270 if self
.trap_nia
is not None:
1271 self
.namespace
['NIA'] = self
.trap_nia
1273 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1275 # check if op was a LD/ST so that debugging can check the
1277 if int_op
in [MicrOp
.OP_STORE
.value
,
1279 self
.last_st_addr
= self
.mem
.last_st_addr
1280 if int_op
in [MicrOp
.OP_LOAD
.value
,
1282 self
.last_ld_addr
= self
.mem
.last_ld_addr
1283 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1284 self
.last_st_addr
, self
.last_ld_addr
)
1286 # detect if CA/CA32 already in outputs (sra*, basically)
1289 output_names
= create_args(info
.write_regs
)
1290 for name
in output_names
:
1296 log("carry already done?", bin(already_done
))
1297 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1298 carry_en
= yield self
.dec2
.e
.do
.output_carry
1302 yield from self
.handle_carry_(inputs
, results
, already_done
)
1304 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1305 # detect if overflow was in return result
1308 for name
, output
in zip(output_names
, results
):
1309 if name
== 'overflow':
1312 if hasattr(self
.dec2
.e
.do
, "oe"):
1313 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1314 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1318 log("internal overflow", overflow
, ov_en
, ov_ok
)
1320 yield from self
.handle_overflow(inputs
, results
, overflow
)
1322 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1324 if not self
.is_svp64_mode
or not pred_dst_zero
:
1325 if hasattr(self
.dec2
.e
.do
, "rc"):
1326 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1328 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1329 self
.handle_comparison(results
, regnum
)
1331 # any modified return results?
1333 for name
, output
in zip(output_names
, results
):
1334 if name
== 'overflow': # ignore, done already (above)
1336 if isinstance(output
, int):
1337 output
= SelectableInt(output
, 256)
1338 if name
in ['CA', 'CA32']:
1340 log("writing %s to XER" % name
, output
)
1341 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1343 log("NOT writing %s to XER" % name
, output
)
1344 elif name
in info
.special_regs
:
1345 log('writing special %s' % name
, output
, special_sprs
)
1346 if name
in special_sprs
:
1347 self
.spr
[name
] = output
1349 self
.namespace
[name
].eq(output
)
1351 log('msr written', hex(self
.msr
.value
))
1353 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1356 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1359 # temporary hack for not having 2nd output
1360 regnum
= yield getattr(self
.decoder
, name
)
1362 if self
.is_svp64_mode
and pred_dst_zero
:
1363 log('zeroing reg %d %s' % (regnum
, str(output
)),
1365 output
= SelectableInt(0, 256)
1371 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1373 if output
.bits
> 64:
1374 output
= SelectableInt(output
.value
, 64)
1376 self
.fpr
[regnum
] = output
1378 self
.gpr
[regnum
] = output
1380 # check if it is the SVSTATE.src/dest step that needs incrementing
1381 # this is our Sub-Program-Counter loop from 0 to VL-1
1382 if self
.is_svp64_mode
:
1383 # XXX twin predication TODO
1384 vl
= self
.svstate
.vl
.asint(msb0
=True)
1385 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1386 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1387 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1388 rm_mode
= yield self
.dec2
.rm_dec
.mode
1389 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1390 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1391 out_vec
= not (yield self
.dec2
.no_out_vec
)
1392 in_vec
= not (yield self
.dec2
.no_in_vec
)
1393 log (" svstate.vl", vl
)
1394 log (" svstate.mvl", mvl
)
1395 log (" svstate.srcstep", srcstep
)
1396 log (" svstate.dststep", dststep
)
1397 log (" mode", rm_mode
)
1398 log (" reverse", reverse_gear
)
1399 log (" out_vec", out_vec
)
1400 log (" in_vec", in_vec
)
1401 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1402 # check if srcstep needs incrementing by one, stop PC advancing
1403 # svp64 loop can end early if the dest is scalar for single-pred
1404 # but for 2-pred both src/dest have to be checked.
1405 # XXX this might not be true! it may just be LD/ST
1406 if sv_ptype
== SVPtype
.P2
.value
:
1407 svp64_is_vector
= (out_vec
or in_vec
)
1409 svp64_is_vector
= out_vec
1410 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1411 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1412 self
.svstate
.dststep
+= SelectableInt(1, 7)
1413 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1414 self
.namespace
['NIA'] = self
.pc
.NIA
1415 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1416 log("end of sub-pc call", self
.namespace
['CIA'],
1417 self
.namespace
['NIA'])
1418 return # DO NOT allow PC to update whilst Sub-PC loop running
1419 # reset loop to zero
1420 self
.svp64_reset_loop()
1422 self
.update_pc_next()
1424 def update_pc_next(self
):
1425 # UPDATE program counter
1426 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1427 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1428 log("end of call", self
.namespace
['CIA'],
1429 self
.namespace
['NIA'],
1430 self
.namespace
['SVSTATE'])
1432 def svp64_reset_loop(self
):
1433 self
.svstate
.srcstep
[0:7] = 0
1434 self
.svstate
.dststep
[0:7] = 0
1435 log (" svstate.srcstep loop end (PC to update)")
1436 self
.pc
.update_nia(self
.is_svp64_mode
)
1437 self
.namespace
['NIA'] = self
.pc
.NIA
1438 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1442 """Decorator factory.
1444 this decorator will "inject" variables into the function's namespace,
1445 from the *dictionary* in self.namespace. it therefore becomes possible
1446 to make it look like a whole stack of variables which would otherwise
1447 need "self." inserted in front of them (*and* for those variables to be
1448 added to the instance) "appear" in the function.
1450 "self.namespace['SI']" for example becomes accessible as just "SI" but
1451 *only* inside the function, when decorated.
1453 def variable_injector(func
):
1455 def decorator(*args
, **kwargs
):
1457 func_globals
= func
.__globals
__ # Python 2.6+
1458 except AttributeError:
1459 func_globals
= func
.func_globals
# Earlier versions.
1461 context
= args
[0].namespace
# variables to be injected
1462 saved_values
= func_globals
.copy() # Shallow copy of dict.
1463 func_globals
.update(context
)
1464 result
= func(*args
, **kwargs
)
1465 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1466 log("args[0]", args
[0].namespace
['CIA'],
1467 args
[0].namespace
['NIA'],
1468 args
[0].namespace
['SVSTATE'])
1469 args
[0].namespace
= func_globals
1470 #exec (func.__code__, func_globals)
1473 # func_globals = saved_values # Undo changes.
1479 return variable_injector