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
):
110 if isinstance(ridx
, SelectableInt
):
114 def set_form(self
, form
):
117 def __setitem__(self
, rnum
, value
):
118 # rnum = rnum.value # only SelectableInt allowed
119 log("GPR setitem", rnum
, value
)
120 if isinstance(rnum
, SelectableInt
):
122 dict.__setitem
__(self
, rnum
, value
)
124 def getz(self
, rnum
):
125 # rnum = rnum.value # only SelectableInt allowed
126 log("GPR getzero?", rnum
)
128 return SelectableInt(0, 64)
131 def _get_regnum(self
, attr
):
132 getform
= self
.sd
.sigforms
[self
.form
]
133 rnum
= getattr(getform
, attr
)
136 def ___getitem__(self
, attr
):
137 """ XXX currently not used
139 rnum
= self
._get
_regnum
(attr
)
140 log("GPR getitem", attr
, rnum
)
141 return self
.regfile
[rnum
]
143 def dump(self
, printout
=True):
145 for i
in range(len(self
)):
146 res
.append(self
[i
].value
)
148 for i
in range(0, len(res
), 8):
151 s
.append("%08x" % res
[i
+j
])
153 print("reg", "%2d" % i
, s
)
158 def __init__(self
, dec2
, initial_sprs
={}):
161 for key
, v
in initial_sprs
.items():
162 if isinstance(key
, SelectableInt
):
164 key
= special_sprs
.get(key
, key
)
165 if isinstance(key
, int):
168 info
= spr_byname
[key
]
169 if not isinstance(v
, SelectableInt
):
170 v
= SelectableInt(v
, info
.length
)
173 def __getitem__(self
, key
):
175 log("dict", self
.items())
176 # if key in special_sprs get the special spr, otherwise return key
177 if isinstance(key
, SelectableInt
):
179 if isinstance(key
, int):
180 key
= spr_dict
[key
].SPR
181 key
= special_sprs
.get(key
, key
)
182 if key
== 'HSRR0': # HACK!
184 if key
== 'HSRR1': # HACK!
187 res
= dict.__getitem
__(self
, key
)
189 if isinstance(key
, int):
192 info
= spr_byname
[key
]
193 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
194 res
= dict.__getitem
__(self
, key
)
195 log("spr returning", key
, res
)
198 def __setitem__(self
, key
, value
):
199 if isinstance(key
, SelectableInt
):
201 if isinstance(key
, int):
202 key
= spr_dict
[key
].SPR
204 key
= special_sprs
.get(key
, key
)
205 if key
== 'HSRR0': # HACK!
206 self
.__setitem
__('SRR0', value
)
207 if key
== 'HSRR1': # HACK!
208 self
.__setitem
__('SRR1', value
)
209 log("setting spr", key
, value
)
210 dict.__setitem
__(self
, key
, value
)
212 def __call__(self
, ridx
):
215 def dump(self
, printout
=True):
217 keys
= list(self
.keys())
220 sprname
= spr_dict
.get(k
, None)
224 sprname
= sprname
.SPR
225 res
.append((sprname
, self
[k
].value
))
227 for sprname
, value
in res
:
228 print(" ", sprname
, hex(value
))
233 def __init__(self
, pc_init
=0):
234 self
.CIA
= SelectableInt(pc_init
, 64)
235 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
237 def update_nia(self
, is_svp64
):
238 increment
= 8 if is_svp64
else 4
239 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
241 def update(self
, namespace
, is_svp64
):
242 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
244 self
.CIA
= namespace
['NIA'].narrow(64)
245 self
.update_nia(is_svp64
)
246 namespace
['CIA'] = self
.CIA
247 namespace
['NIA'] = self
.NIA
250 # Simple-V: see https://libre-soc.org/openpower/sv
252 def __init__(self
, init
=0):
253 self
.spr
= SelectableInt(init
, 32)
254 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
255 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
256 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
257 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
258 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
259 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
260 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
265 def __init__(self
, init
=0):
266 self
.spr
= SelectableInt(init
, 24)
267 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
268 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
269 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
270 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
271 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
272 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
273 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
274 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
275 # these cover the same extra field, split into parts as EXTRA2
276 self
.extra2
= list(range(4))
277 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
278 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
279 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
280 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
281 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
282 # and here as well, but EXTRA3
283 self
.extra3
= list(range(3))
284 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
285 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
286 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
289 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
290 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
291 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
292 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
293 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
294 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
295 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
296 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
297 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
300 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
301 class SVP64PrefixFields
:
303 self
.insn
= SelectableInt(0, 32)
304 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
305 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
306 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
307 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
308 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
311 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
312 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
313 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
317 # See PowerISA Version 3.0 B Book 1
318 # Section 2.3.1 Condition Register pages 30 - 31
320 LT
= FL
= 0 # negative, less than, floating-point less than
321 GT
= FG
= 1 # positive, greater than, floating-point greater than
322 EQ
= FE
= 2 # equal, floating-point equal
323 SO
= FU
= 3 # summary overflow, floating-point unordered
325 def __init__(self
, init
=0):
326 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
327 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
328 self
.cr
= SelectableInt(init
, 64) # underlying reg
329 # field-selectable versions of Condition Register TODO check bitranges?
332 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
333 _cr
= FieldSelectableInt(self
.cr
, bits
)
336 # decode SVP64 predicate integer to reg number and invert
337 def get_predint(gpr
, mask
):
340 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
341 if mask
== SVP64PredInt
.ALWAYS
.value
:
342 return 0xffff_ffff_ffff_ffff
343 if mask
== SVP64PredInt
.R3_UNARY
.value
:
344 return 1 << (gpr(3).value
& 0b111111)
345 if mask
== SVP64PredInt
.R3
.value
:
347 if mask
== SVP64PredInt
.R3_N
.value
:
349 if mask
== SVP64PredInt
.R10
.value
:
351 if mask
== SVP64PredInt
.R10_N
.value
:
352 return ~
gpr(10).value
353 if mask
== SVP64PredInt
.R30
.value
:
355 if mask
== SVP64PredInt
.R30_N
.value
:
356 return ~
gpr(30).value
358 # decode SVP64 predicate CR to reg number and invert status
359 def _get_predcr(mask
):
360 if mask
== SVP64PredCR
.LT
.value
:
362 if mask
== SVP64PredCR
.GE
.value
:
364 if mask
== SVP64PredCR
.GT
.value
:
366 if mask
== SVP64PredCR
.LE
.value
:
368 if mask
== SVP64PredCR
.EQ
.value
:
370 if mask
== SVP64PredCR
.NE
.value
:
372 if mask
== SVP64PredCR
.SO
.value
:
374 if mask
== SVP64PredCR
.NS
.value
:
377 # read individual CR fields (0..VL-1), extract the required bit
378 # and construct the mask
379 def get_predcr(crl
, mask
, vl
):
380 idx
, noninv
= _get_predcr(mask
)
383 cr
= crl
[i
+SVP64CROffs
.CRPred
]
384 if cr
[idx
].value
== noninv
:
389 # TODO, really should just be using PowerDecoder2
390 def get_pdecode_idx_in(dec2
, name
):
392 in1_sel
= yield op
.in1_sel
393 in2_sel
= yield op
.in2_sel
394 in3_sel
= yield op
.in3_sel
395 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
396 in1
= yield dec2
.e
.read_reg1
.data
397 in2
= yield dec2
.e
.read_reg2
.data
398 in3
= yield dec2
.e
.read_reg3
.data
399 in1_isvec
= yield dec2
.in1_isvec
400 in2_isvec
= yield dec2
.in2_isvec
401 in3_isvec
= yield dec2
.in3_isvec
402 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
404 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
406 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
408 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
410 log ("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
412 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
414 # identify which regnames map to in1/2/3
416 if (in1_sel
== In1Sel
.RA
.value
or
417 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
418 return in1
, in1_isvec
419 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
420 return in1
, in1_isvec
422 if in2_sel
== In2Sel
.RB
.value
:
423 return in2
, in2_isvec
424 if in3_sel
== In3Sel
.RB
.value
:
425 return in3
, in3_isvec
426 # XXX TODO, RC doesn't exist yet!
428 assert False, "RC does not exist yet"
430 if in1_sel
== In1Sel
.RS
.value
:
431 return in1
, in1_isvec
432 if in2_sel
== In2Sel
.RS
.value
:
433 return in2
, in2_isvec
434 if in3_sel
== In3Sel
.RS
.value
:
435 return in3
, in3_isvec
437 if in1_sel
== In1Sel
.FRA
.value
:
438 return in1
, in1_isvec
440 if in2_sel
== In2Sel
.FRB
.value
:
441 return in2
, in2_isvec
443 if in3_sel
== In3Sel
.FRC
.value
:
444 return in3
, in3_isvec
446 if in1_sel
== In1Sel
.FRS
.value
:
447 return in1
, in1_isvec
448 if in3_sel
== In3Sel
.FRS
.value
:
449 return in3
, in3_isvec
453 # TODO, really should just be using PowerDecoder2
454 def get_pdecode_cr_out(dec2
, name
):
456 out_sel
= yield op
.cr_out
457 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
458 sv_cr_out
= yield op
.sv_cr_out
459 spec
= yield dec2
.crout_svdec
.spec
460 sv_override
= yield dec2
.dec_cr_out
.sv_override
461 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
462 out
= yield dec2
.e
.write_cr
.data
463 o_isvec
= yield dec2
.o_isvec
464 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
465 log (" sv_cr_out", sv_cr_out
)
466 log (" cr_bf", out_bitfield
)
468 log (" override", sv_override
)
469 # identify which regnames map to out / o2
471 if out_sel
== CROutSel
.CR0
.value
:
473 log ("get_pdecode_cr_out not found", name
)
477 # TODO, really should just be using PowerDecoder2
478 def get_pdecode_idx_out(dec2
, name
):
480 out_sel
= yield op
.out_sel
481 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
482 out
= yield dec2
.e
.write_reg
.data
483 o_isvec
= yield dec2
.o_isvec
484 # identify which regnames map to out / o2
486 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
487 if out_sel
== OutSel
.RA
.value
:
490 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
491 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
493 if out_sel
== OutSel
.RT
.value
:
496 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
497 if out_sel
== OutSel
.FRA
.value
:
500 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
501 OutSel
.FRT
.value
, out
, o_isvec
)
502 if out_sel
== OutSel
.FRT
.value
:
504 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
508 # TODO, really should just be using PowerDecoder2
509 def get_pdecode_idx_out2(dec2
, name
):
510 # check first if register is activated for write
512 out_sel
= yield op
.out_sel
513 out
= yield dec2
.e
.write_ea
.data
514 o_isvec
= yield dec2
.o2_isvec
515 out_ok
= yield dec2
.e
.write_ea
.ok
516 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
521 if hasattr(op
, "upd"):
522 # update mode LD/ST uses read-reg A also as an output
524 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
525 out_sel
, OutSel
.RA
.value
,
527 if upd
== LDSTMode
.update
.value
:
530 int_op
= yield dec2
.dec
.op
.internal_op
531 fft_en
= yield dec2
.use_svp64_fft
532 if int_op
== MicrOp
.OP_FP_MADD
.value
and fft_en
:
533 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
540 # decoder2 - an instance of power_decoder2
541 # regfile - a list of initial values for the registers
542 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
543 # respect_pc - tracks the program counter. requires initial_insns
544 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
545 initial_mem
=None, initial_msr
=0,
556 self
.bigendian
= bigendian
558 self
.is_svp64_mode
= False
559 self
.respect_pc
= respect_pc
560 if initial_sprs
is None:
562 if initial_mem
is None:
564 if fpregfile
is None:
566 if initial_insns
is None:
568 assert self
.respect_pc
== False, "instructions required to honor pc"
570 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
571 log("ISACaller initial_msr", initial_msr
)
573 # "fake program counter" mode (for unit testing)
577 if isinstance(initial_mem
, tuple):
578 self
.fake_pc
= initial_mem
[0]
579 disasm_start
= self
.fake_pc
581 disasm_start
= initial_pc
583 # disassembly: we need this for now (not given from the decoder)
584 self
.disassembly
= {}
586 for i
, code
in enumerate(disassembly
):
587 self
.disassembly
[i
*4 + disasm_start
] = code
589 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
590 self
.svp64rm
= SVP64RM()
591 if initial_svstate
is None:
593 if isinstance(initial_svstate
, int):
594 initial_svstate
= SVP64State(initial_svstate
)
595 # SVSTATE, MSR and PC
596 self
.svstate
= initial_svstate
597 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
599 # GPR FPR SPR registers
600 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
601 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
602 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
604 # set up 4 dummy SVSHAPEs if they aren't already set up
606 sname
= 'SVSHAPE%d' % i
607 if sname
not in self
.spr
:
608 self
.spr
[sname
] = SVSHAPE(0)
610 # make sure it's an SVSHAPE
611 val
= self
.spr
[sname
].value
612 self
.spr
[sname
] = SVSHAPE(val
)
613 self
.last_op_svshape
= False
616 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
617 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
618 # MMU mode, redirect underlying Mem through RADIX
620 self
.mem
= RADIX(self
.mem
, self
)
622 self
.imem
= RADIX(self
.imem
, self
)
625 # FPR (same as GPR except for FP nums)
626 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
627 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
628 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
629 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
631 # 2.3.2 LR (actually SPR #8) -- Done
632 # 2.3.3 CTR (actually SPR #9) -- Done
633 # 2.3.4 TAR (actually SPR #815)
634 # 3.2.2 p45 XER (actually SPR #1) -- Done
635 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
637 # create CR then allow portions of it to be "selectable" (below)
638 self
.cr_fields
= CRFields(initial_cr
)
639 self
.cr
= self
.cr_fields
.cr
641 # "undefined", just set to variable-bit-width int (use exts "max")
642 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
645 self
.namespace
.update(self
.spr
)
646 self
.namespace
.update({'GPR': self
.gpr
,
650 'memassign': self
.memassign
,
653 'SVSTATE': self
.svstate
.spr
,
654 'SVSHAPE0': self
.spr
['SVSHAPE0'],
655 'SVSHAPE1': self
.spr
['SVSHAPE1'],
656 'SVSHAPE2': self
.spr
['SVSHAPE2'],
657 'SVSHAPE3': self
.spr
['SVSHAPE3'],
660 'undefined': undefined
,
661 'mode_is_64bit': True,
665 # update pc to requested start point
666 self
.set_pc(initial_pc
)
668 # field-selectable versions of Condition Register
669 self
.crl
= self
.cr_fields
.crl
671 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
673 self
.decoder
= decoder2
.dec
676 def call_trap(self
, trap_addr
, trap_bit
):
677 """calls TRAP and sets up NIA to the new execution location.
678 next instruction will begin at trap_addr.
680 self
.TRAP(trap_addr
, trap_bit
)
681 self
.namespace
['NIA'] = self
.trap_nia
682 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
684 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
685 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
687 TRAP function is callable from inside the pseudocode itself,
688 hence the default arguments. when calling from inside ISACaller
689 it is best to use call_trap()
691 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
692 # store CIA(+4?) in SRR0, set NIA to 0x700
693 # store MSR in SRR1, set MSR to um errr something, have to check spec
694 # store SVSTATE (if enabled) in SVSRR0
695 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
696 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
697 if self
.is_svp64_mode
:
698 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
699 self
.trap_nia
= SelectableInt(trap_addr
, 64)
700 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
702 # set exception bits. TODO: this should, based on the address
703 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
704 # bits appropriately. however it turns out that *for now* in all
705 # cases (all trap_addrs) the exact same thing is needed.
706 self
.msr
[MSRb
.IR
] = 0
707 self
.msr
[MSRb
.DR
] = 0
708 self
.msr
[MSRb
.FE0
] = 0
709 self
.msr
[MSRb
.FE1
] = 0
710 self
.msr
[MSRb
.EE
] = 0
711 self
.msr
[MSRb
.RI
] = 0
712 self
.msr
[MSRb
.SF
] = 1
713 self
.msr
[MSRb
.TM
] = 0
714 self
.msr
[MSRb
.VEC
] = 0
715 self
.msr
[MSRb
.VSX
] = 0
716 self
.msr
[MSRb
.PR
] = 0
717 self
.msr
[MSRb
.FP
] = 0
718 self
.msr
[MSRb
.PMM
] = 0
719 self
.msr
[MSRb
.TEs
] = 0
720 self
.msr
[MSRb
.TEe
] = 0
721 self
.msr
[MSRb
.UND
] = 0
722 self
.msr
[MSRb
.LE
] = 1
724 def memassign(self
, ea
, sz
, val
):
725 self
.mem
.memassign(ea
, sz
, val
)
727 def prep_namespace(self
, formname
, op_fields
):
728 # TODO: get field names from form in decoder*1* (not decoder2)
729 # decoder2 is hand-created, and decoder1.sigform is auto-generated
731 # then "yield" fields only from op_fields rather than hard-coded
733 fields
= self
.decoder
.sigforms
[formname
]
734 for name
in op_fields
:
736 sig
= getattr(fields
, name
.upper())
738 sig
= getattr(fields
, name
)
740 # these are all opcode fields involved in index-selection of CR,
741 # and need to do "standard" arithmetic. CR[BA+32] for example
742 # would, if using SelectableInt, only be 5-bit.
743 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
744 self
.namespace
[name
] = val
746 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
748 self
.namespace
['XER'] = self
.spr
['XER']
749 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
750 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
752 # add some SVSTATE convenience variables
753 vl
= self
.svstate
.vl
.asint(msb0
=True)
754 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
755 self
.namespace
['VL'] = vl
756 self
.namespace
['srcstep'] = srcstep
758 def handle_carry_(self
, inputs
, outputs
, already_done
):
759 inv_a
= yield self
.dec2
.e
.do
.invert_in
761 inputs
[0] = ~inputs
[0]
763 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
765 imm
= yield self
.dec2
.e
.do
.imm_data
.data
766 inputs
.append(SelectableInt(imm
, 64))
767 assert len(outputs
) >= 1
768 log("outputs", repr(outputs
))
769 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
775 log("gt input", x
, output
)
776 gt
= (gtu(x
, output
))
779 cy
= 1 if any(gts
) else 0
781 if not (1 & already_done
):
782 self
.spr
['XER'][XER_bits
['CA']] = cy
784 log("inputs", already_done
, inputs
)
786 # ARGH... different for OP_ADD... *sigh*...
787 op
= yield self
.dec2
.e
.do
.insn_type
788 if op
== MicrOp
.OP_ADD
.value
:
789 res32
= (output
.value
& (1 << 32)) != 0
790 a32
= (inputs
[0].value
& (1 << 32)) != 0
792 b32
= (inputs
[1].value
& (1 << 32)) != 0
795 cy32
= res32 ^ a32 ^ b32
796 log("CA32 ADD", cy32
)
800 log("input", x
, output
)
801 log(" x[32:64]", x
, x
[32:64])
802 log(" o[32:64]", output
, output
[32:64])
803 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
805 cy32
= 1 if any(gts
) else 0
806 log("CA32", cy32
, gts
)
807 if not (2 & already_done
):
808 self
.spr
['XER'][XER_bits
['CA32']] = cy32
810 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
811 if hasattr(self
.dec2
.e
.do
, "invert_in"):
812 inv_a
= yield self
.dec2
.e
.do
.invert_in
814 inputs
[0] = ~inputs
[0]
816 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
818 imm
= yield self
.dec2
.e
.do
.imm_data
.data
819 inputs
.append(SelectableInt(imm
, 64))
820 assert len(outputs
) >= 1
821 log("handle_overflow", inputs
, outputs
, div_overflow
)
822 if len(inputs
) < 2 and div_overflow
is None:
825 # div overflow is different: it's returned by the pseudo-code
826 # because it's more complex than can be done by analysing the output
827 if div_overflow
is not None:
828 ov
, ov32
= div_overflow
, div_overflow
829 # arithmetic overflow can be done by analysing the input and output
830 elif len(inputs
) >= 2:
834 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
835 output_sgn
= exts(output
.value
, output
.bits
) < 0
836 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
837 output_sgn
!= input_sgn
[0] else 0
840 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
841 output32_sgn
= exts(output
.value
, 32) < 0
842 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
843 output32_sgn
!= input32_sgn
[0] else 0
845 self
.spr
['XER'][XER_bits
['OV']] = ov
846 self
.spr
['XER'][XER_bits
['OV32']] = ov32
847 so
= self
.spr
['XER'][XER_bits
['SO']]
849 self
.spr
['XER'][XER_bits
['SO']] = so
851 def handle_comparison(self
, outputs
, cr_idx
=0):
853 assert isinstance(out
, SelectableInt
), \
854 "out zero not a SelectableInt %s" % repr(outputs
)
855 log("handle_comparison", out
.bits
, hex(out
.value
))
856 # TODO - XXX *processor* in 32-bit mode
857 # https://bugs.libre-soc.org/show_bug.cgi?id=424
859 # o32 = exts(out.value, 32)
860 # print ("handle_comparison exts 32 bit", hex(o32))
861 out
= exts(out
.value
, out
.bits
)
862 log("handle_comparison exts", hex(out
))
863 zero
= SelectableInt(out
== 0, 1)
864 positive
= SelectableInt(out
> 0, 1)
865 negative
= SelectableInt(out
< 0, 1)
866 SO
= self
.spr
['XER'][XER_bits
['SO']]
867 log("handle_comparison SO", SO
)
868 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
869 self
.crl
[cr_idx
].eq(cr_field
)
871 def set_pc(self
, pc_val
):
872 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
873 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
875 def get_next_insn(self
):
879 pc
= self
.pc
.CIA
.value
882 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
884 raise KeyError("no instruction at 0x%x" % pc
)
888 """set up one instruction
890 pc
, insn
= self
.get_next_insn()
891 yield from self
.setup_next_insn(pc
, insn
)
893 def setup_next_insn(self
, pc
, ins
):
894 """set up next instruction
897 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
898 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
900 yield self
.dec2
.sv_rm
.eq(0)
901 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
902 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
903 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
904 yield self
.dec2
.state
.pc
.eq(pc
)
905 if self
.svstate
is not None:
906 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
908 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
910 opcode
= yield self
.dec2
.dec
.opcode_in
911 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
912 pfx
.insn
.value
= opcode
913 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
914 log ("prefix test: opcode:", major
, bin(major
),
915 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
916 self
.is_svp64_mode
= ((major
== 0b000001) and
917 pfx
.insn
[7].value
== 0b1 and
918 pfx
.insn
[9].value
== 0b1)
919 self
.pc
.update_nia(self
.is_svp64_mode
)
920 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
921 self
.namespace
['NIA'] = self
.pc
.NIA
922 self
.namespace
['SVSTATE'] = self
.svstate
.spr
923 if not self
.is_svp64_mode
:
926 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
927 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
928 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
929 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
930 sv_rm
= pfx
.rm
.asint(msb0
=True)
931 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
932 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
933 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
934 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
937 def execute_one(self
):
938 """execute one instruction
940 # get the disassembly code for this instruction
941 if self
.is_svp64_mode
:
942 if not self
.disassembly
:
943 code
= yield from self
.get_assembly_name()
945 code
= self
.disassembly
[self
._pc
+4]
946 log(" svp64 sim-execute", hex(self
._pc
), code
)
948 if not self
.disassembly
:
949 code
= yield from self
.get_assembly_name()
951 code
= self
.disassembly
[self
._pc
]
952 log("sim-execute", hex(self
._pc
), code
)
953 opname
= code
.split(' ')[0]
955 yield from self
.call(opname
) # execute the instruction
956 except MemException
as e
: # check for memory errors
957 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
958 raise e
# ... re-raise
959 # run a Trap but set DAR first
960 print ("memory unaligned exception, DAR", e
.dar
)
961 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
962 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
965 # don't use this except in special circumstances
966 if not self
.respect_pc
:
969 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
971 def get_assembly_name(self
):
972 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
973 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
974 dec_insn
= yield self
.dec2
.e
.do
.insn
975 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
976 asmcode
= yield self
.dec2
.dec
.op
.asmcode
977 int_op
= yield self
.dec2
.dec
.op
.internal_op
978 log("get assembly name asmcode", asmcode
, int_op
,
979 hex(dec_insn
), bin(insn_1_11
))
980 asmop
= insns
.get(asmcode
, None)
982 # sigh reconstruct the assembly instruction name
983 if hasattr(self
.dec2
.e
.do
, "oe"):
984 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
985 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
989 if hasattr(self
.dec2
.e
.do
, "rc"):
990 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
991 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
995 # grrrr have to special-case MUL op (see DecodeOE)
996 log("ov %d en %d rc %d en %d op %d" %
997 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
998 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1003 if not asmop
.endswith("."): # don't add "." to "andis."
1006 if hasattr(self
.dec2
.e
.do
, "lk"):
1007 lk
= yield self
.dec2
.e
.do
.lk
1010 log("int_op", int_op
)
1011 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1012 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1016 spr_msb
= yield from self
.get_spr_msb()
1017 if int_op
== MicrOp
.OP_MFCR
.value
:
1022 # XXX TODO: for whatever weird reason this doesn't work
1023 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1024 if int_op
== MicrOp
.OP_MTCRF
.value
:
1031 def get_spr_msb(self
):
1032 dec_insn
= yield self
.dec2
.e
.do
.insn
1033 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1035 def call(self
, name
):
1036 """call(opcode) - the primary execution point for instructions
1038 self
.last_st_addr
= None # reset the last known store address
1039 self
.last_ld_addr
= None # etc.
1041 name
= name
.strip() # remove spaces if not already done so
1043 log("halted - not executing", name
)
1046 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1047 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1048 asmop
= yield from self
.get_assembly_name()
1049 log("call", name
, asmop
)
1052 int_op
= yield self
.dec2
.dec
.op
.internal_op
1053 spr_msb
= yield from self
.get_spr_msb()
1055 instr_is_privileged
= False
1056 if int_op
in [MicrOp
.OP_ATTN
.value
,
1057 MicrOp
.OP_MFMSR
.value
,
1058 MicrOp
.OP_MTMSR
.value
,
1059 MicrOp
.OP_MTMSRD
.value
,
1061 MicrOp
.OP_RFID
.value
]:
1062 instr_is_privileged
= True
1063 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1064 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1065 instr_is_privileged
= True
1067 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1069 # check MSR priv bit and whether op is privileged: if so, throw trap
1070 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1071 self
.call_trap(0x700, PIb
.PRIV
)
1074 # check halted condition
1079 # check illegal instruction
1081 if name
not in ['mtcrf', 'mtocrf']:
1082 illegal
= name
!= asmop
1084 # sigh deal with setvl not being supported by binutils (.long)
1085 if asmop
.startswith('setvl'):
1089 # and svremap not being supported by binutils (.long)
1090 if asmop
.startswith('svremap'):
1094 # sigh also deal with ffmadds not being supported by binutils (.long)
1095 if asmop
== 'ffmadds':
1100 print("illegal", name
, asmop
)
1101 self
.call_trap(0x700, PIb
.ILLEG
)
1102 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1103 (name
, asmop
, self
.pc
.CIA
.value
))
1106 # nop has to be supported, we could let the actual op calculate
1107 # but PowerDecoder has a pattern for nop
1109 self
.update_pc_next()
1112 info
= self
.instrs
[name
]
1113 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1115 # preserve order of register names
1116 input_names
= create_args(list(info
.read_regs
) +
1117 list(info
.uninit_regs
))
1120 # get SVP64 entry for the current instruction
1121 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1122 if sv_rm
is not None:
1123 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1125 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1126 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1128 # see if srcstep/dststep need skipping over masked-out predicate bits
1129 if self
.is_svp64_mode
:
1130 self
.update_new_svstate_steps()
1131 pre
= yield from self
.svstate_pre_inc()
1133 self
.svp64_reset_loop()
1135 self
.update_pc_next()
1137 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1138 vl
= self
.svstate
.vl
.asint(msb0
=True)
1139 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1140 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1142 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1143 if self
.is_svp64_mode
and vl
== 0:
1144 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1145 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1146 self
.namespace
['NIA'])
1149 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1150 # using pre-arranged schedule. all of this is awful but it is a
1151 # start. next job will be to put the proper activation in place
1152 yield self
.dec2
.remap_active
.eq(1 if self
.last_op_svshape
else 0)
1153 if self
.is_svp64_mode
and self
.last_op_svshape
:
1154 # get four SVSHAPEs. here we are hard-coding
1155 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1156 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1157 SVSHAPE0
= self
.spr
['SVSHAPE0']
1158 SVSHAPE1
= self
.spr
['SVSHAPE1']
1159 SVSHAPE2
= self
.spr
['SVSHAPE2']
1160 SVSHAPE3
= self
.spr
['SVSHAPE3']
1162 sname
= 'SVSHAPE%d' % i
1163 shape
= self
.spr
[sname
]
1164 print (sname
, bin(shape
.value
))
1165 print (" lims", shape
.lims
)
1166 print (" mode", shape
.mode
)
1167 print (" skip", shape
.skip
)
1169 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1170 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1171 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1172 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1175 for i
, (shape
, remap
) in enumerate(remaps
):
1176 # zero is "disabled"
1177 if shape
.value
== 0x0:
1179 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1180 if shape
.mode
== 0b00: # multiply mode
1181 step
= dststep
if (i
== 0) else srcstep
1182 if shape
.mode
== 0b01: # FFT butterfly mode
1183 step
= srcstep
# XXX HACK - for now only use srcstep
1184 # this is terrible. O(N^2) looking for the match. but hey.
1185 for idx
, remap_idx
in enumerate(remap
):
1189 if shape
.mode
== 0b00:
1191 yield self
.dec2
.o_step
.eq(remap_idx
) # RT
1192 yield self
.dec2
.o2_step
.eq(remap_idx
) # EA
1194 yield self
.dec2
.in1_step
.eq(remap_idx
) # RA
1196 yield self
.dec2
.in3_step
.eq(remap_idx
) # RB
1198 yield self
.dec2
.in2_step
.eq(remap_idx
) # RC
1199 # FFT butterfly mode
1200 if shape
.mode
== 0b01:
1202 yield self
.dec2
.o_step
.eq(remap_idx
) # RT
1203 yield self
.dec2
.in2_step
.eq(remap_idx
) # RB
1205 yield self
.dec2
.in1_step
.eq(remap_idx
) # RA
1206 yield self
.dec2
.o2_step
.eq(remap_idx
) # EA (FRS)
1208 yield self
.dec2
.in3_step
.eq(remap_idx
) # RC
1211 rremaps
.append((shape
.mode
, i
, idx
, remap_idx
)) # debug printing
1213 print ("shape remap", x
)
1214 # after that, settle down (combinatorial) to let Vector reg numbers
1215 # work themselves out
1217 remap_active
= yield self
.dec2
.remap_active
1218 print ("remap active", remap_active
)
1220 # main input registers (RT, RA ...)
1222 for name
in input_names
:
1223 # using PowerDecoder2, first, find the decoder index.
1224 # (mapping name RA RB RC RS to in1, in2, in3)
1225 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1227 # doing this is not part of svp64, it's because output
1228 # registers, to be modified, need to be in the namespace.
1229 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1231 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1234 # in case getting the register number is needed, _RA, _RB
1235 regname
= "_" + name
1236 self
.namespace
[regname
] = regnum
1237 if not self
.is_svp64_mode
or not pred_src_zero
:
1238 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1240 reg_val
= self
.fpr(regnum
)
1241 elif name
is not None:
1242 reg_val
= self
.gpr(regnum
)
1244 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1246 inputs
.append(reg_val
)
1247 # arrrrgh, awful hack, to get _RT into namespace
1248 if asmop
== 'setvl':
1250 RT
= yield self
.dec2
.dec
.RT
1251 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1253 # in SVP64 mode for LD/ST work out immediate
1254 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1255 # use info.form to detect
1256 replace_d
= False # update / replace constant in pseudocode
1257 if self
.is_svp64_mode
:
1258 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1259 # bitreverse mode reads SVD (or SVDS - TODO)
1260 # *BUT*... because this is "overloading" of LD operations,
1261 # it gets *STORED* into D (or DS, TODO)
1262 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1263 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1264 imm
= exts(imm
, 11) # sign-extend to integer
1265 print ("bitrev SVD", imm
)
1268 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1269 imm
= exts(imm
, 16) # sign-extend to integer
1270 # get the right step. LD is from srcstep, ST is dststep
1271 op
= yield self
.dec2
.e
.do
.insn_type
1273 if op
== MicrOp
.OP_LOAD
.value
:
1275 log("D-field src", imm
, offsmul
)
1276 elif op
== MicrOp
.OP_STORE
.value
:
1278 log("D-field dst", imm
, offsmul
)
1280 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1281 # manually look up RC, sigh
1282 RC
= yield self
.dec2
.dec
.RC
[0:5]
1284 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1285 "rev", bin(bitrev(offsmul
, vl
)))
1286 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1287 # Unit-Strided LD/ST adds offset*width to immediate
1288 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1289 ldst_len
= yield self
.dec2
.e
.do
.data_len
1290 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1292 # Element-strided multiplies the immediate by element step
1293 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1294 imm
= SelectableInt(imm
* offsmul
, 32)
1296 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1297 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1298 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1299 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1302 self
.namespace
['D'] = imm
1304 # "special" registers
1305 for special
in info
.special_regs
:
1306 if special
in special_sprs
:
1307 inputs
.append(self
.spr
[special
])
1309 inputs
.append(self
.namespace
[special
])
1311 # clear trap (trap) NIA
1312 self
.trap_nia
= None
1314 # execute actual instruction here (finally)
1315 log("inputs", inputs
)
1316 results
= info
.func(self
, *inputs
)
1317 log("results", results
)
1319 # "inject" decorator takes namespace from function locals: we need to
1320 # overwrite NIA being overwritten (sigh)
1321 if self
.trap_nia
is not None:
1322 self
.namespace
['NIA'] = self
.trap_nia
1324 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1326 # check if op was a LD/ST so that debugging can check the
1328 if int_op
in [MicrOp
.OP_STORE
.value
,
1330 self
.last_st_addr
= self
.mem
.last_st_addr
1331 if int_op
in [MicrOp
.OP_LOAD
.value
,
1333 self
.last_ld_addr
= self
.mem
.last_ld_addr
1334 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1335 self
.last_st_addr
, self
.last_ld_addr
)
1337 # detect if CA/CA32 already in outputs (sra*, basically)
1340 output_names
= create_args(info
.write_regs
)
1341 for name
in output_names
:
1347 log("carry already done?", bin(already_done
))
1348 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1349 carry_en
= yield self
.dec2
.e
.do
.output_carry
1353 yield from self
.handle_carry_(inputs
, results
, already_done
)
1355 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1356 # detect if overflow was in return result
1359 for name
, output
in zip(output_names
, results
):
1360 if name
== 'overflow':
1363 if hasattr(self
.dec2
.e
.do
, "oe"):
1364 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1365 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1369 log("internal overflow", overflow
, ov_en
, ov_ok
)
1371 yield from self
.handle_overflow(inputs
, results
, overflow
)
1373 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1375 if not self
.is_svp64_mode
or not pred_dst_zero
:
1376 if hasattr(self
.dec2
.e
.do
, "rc"):
1377 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1379 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1380 self
.handle_comparison(results
, regnum
)
1382 # any modified return results?
1384 for name
, output
in zip(output_names
, results
):
1385 if name
== 'overflow': # ignore, done already (above)
1387 if isinstance(output
, int):
1388 output
= SelectableInt(output
, 256)
1389 if name
in ['CA', 'CA32']:
1391 log("writing %s to XER" % name
, output
)
1392 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1394 log("NOT writing %s to XER" % name
, output
)
1395 elif name
in info
.special_regs
:
1396 log('writing special %s' % name
, output
, special_sprs
)
1397 if name
in special_sprs
:
1398 self
.spr
[name
] = output
1400 self
.namespace
[name
].eq(output
)
1402 log('msr written', hex(self
.msr
.value
))
1404 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1407 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1410 # temporary hack for not having 2nd output
1411 regnum
= yield getattr(self
.decoder
, name
)
1413 if self
.is_svp64_mode
and pred_dst_zero
:
1414 log('zeroing reg %d %s' % (regnum
, str(output
)),
1416 output
= SelectableInt(0, 256)
1422 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1424 if output
.bits
> 64:
1425 output
= SelectableInt(output
.value
, 64)
1427 self
.fpr
[regnum
] = output
1429 self
.gpr
[regnum
] = output
1431 # check if it is the SVSTATE.src/dest step that needs incrementing
1432 # this is our Sub-Program-Counter loop from 0 to VL-1
1433 if self
.is_svp64_mode
:
1434 post
= yield from self
.svstate_post_inc()
1436 # reset loop to zero
1437 self
.svp64_reset_loop()
1440 # XXX only in non-SVP64 mode!
1441 # record state of whether the current operation was an svshape,
1442 # to be able to know if it should apply in the next instruction.
1443 # also (if going to use this instruction) should disable ability
1444 # to interrupt in between. sigh.
1445 self
.last_op_svshape
= asmop
== 'svremap'
1447 self
.update_pc_next()
1449 def SVSTATE_NEXT(self
):
1450 """explicitly moves srcstep/dststep on to next element, for
1451 "Vertical-First" mode. this function is called from
1452 setvl pseudo-code, as a pseudo-op "svstep"
1455 self
.allow_next_step_inc
= True
1457 def svstate_pre_inc(self
):
1458 """check if srcstep/dststep need to skip over masked-out predicate bits
1460 # get SVSTATE VL (oh and print out some debug stuff)
1461 vl
= self
.svstate
.vl
.asint(msb0
=True)
1462 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1463 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1464 sv_a_nz
= yield self
.dec2
.sv_a_nz
1465 fft_mode
= yield self
.dec2
.use_svp64_fft
1466 in1
= yield self
.dec2
.e
.read_reg1
.data
1467 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1468 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1470 # get predicate mask
1471 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1473 pmode
= yield self
.dec2
.rm_dec
.predmode
1474 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1475 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1476 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1477 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1478 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1479 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1480 if pmode
== SVP64PredMode
.INT
.value
:
1481 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1482 if sv_ptype
== SVPtype
.P2
.value
:
1483 srcmask
= get_predint(self
.gpr
, srcpred
)
1484 elif pmode
== SVP64PredMode
.CR
.value
:
1485 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1486 if sv_ptype
== SVPtype
.P2
.value
:
1487 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1488 log (" pmode", pmode
)
1489 log (" reverse", reverse_gear
)
1490 log (" ptype", sv_ptype
)
1491 log (" srcpred", bin(srcpred
))
1492 log (" dstpred", bin(dstpred
))
1493 log (" srcmask", bin(srcmask
))
1494 log (" dstmask", bin(dstmask
))
1495 log (" pred_sz", bin(pred_src_zero
))
1496 log (" pred_dz", bin(pred_dst_zero
))
1498 # okaaay, so here we simply advance srcstep (TODO dststep)
1499 # until the predicate mask has a "1" bit... or we run out of VL
1500 # let srcstep==VL be the indicator to move to next instruction
1501 if not pred_src_zero
:
1502 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1503 log (" skip", bin(1<<srcstep
))
1506 if not pred_dst_zero
:
1507 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1508 log (" skip", bin(1<<dststep
))
1511 # now work out if the relevant mask bits require zeroing
1513 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1515 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1517 # store new srcstep / dststep
1518 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1520 def update_new_svstate_steps(self
):
1521 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1523 # update SVSTATE with new srcstep
1524 self
.svstate
.srcstep
[0:7] = srcstep
1525 self
.svstate
.dststep
[0:7] = dststep
1526 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1527 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1528 yield Settle() # let decoder update
1529 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1530 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1531 log (" srcstep", srcstep
)
1532 log (" dststep", dststep
)
1534 # check if end reached (we let srcstep overrun, above)
1535 # nothing needs doing (TODO zeroing): just do next instruction
1536 return srcstep
== vl
or dststep
== vl
1538 def svstate_post_inc(self
):
1539 # check if it is the SVSTATE.src/dest step that needs incrementing
1540 # this is our Sub-Program-Counter loop from 0 to VL-1
1541 # XXX twin predication TODO
1542 vl
= self
.svstate
.vl
.asint(msb0
=True)
1543 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1544 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1545 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1546 rm_mode
= yield self
.dec2
.rm_dec
.mode
1547 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1548 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1549 out_vec
= not (yield self
.dec2
.no_out_vec
)
1550 in_vec
= not (yield self
.dec2
.no_in_vec
)
1551 log (" svstate.vl", vl
)
1552 log (" svstate.mvl", mvl
)
1553 log (" svstate.srcstep", srcstep
)
1554 log (" svstate.dststep", dststep
)
1555 log (" mode", rm_mode
)
1556 log (" reverse", reverse_gear
)
1557 log (" out_vec", out_vec
)
1558 log (" in_vec", in_vec
)
1559 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1560 # check if srcstep needs incrementing by one, stop PC advancing
1561 # svp64 loop can end early if the dest is scalar for single-pred
1562 # but for 2-pred both src/dest have to be checked.
1563 # XXX this might not be true! it may just be LD/ST
1564 if sv_ptype
== SVPtype
.P2
.value
:
1565 svp64_is_vector
= (out_vec
or in_vec
)
1567 svp64_is_vector
= out_vec
1568 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1569 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1570 self
.svstate
.dststep
+= SelectableInt(1, 7)
1571 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1572 self
.namespace
['NIA'] = self
.pc
.NIA
1573 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1574 log("end of sub-pc call", self
.namespace
['CIA'],
1575 self
.namespace
['NIA'])
1576 return False # DO NOT allow PC update whilst Sub-PC loop running
1579 def update_pc_next(self
):
1580 # UPDATE program counter
1581 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1582 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1583 log("end of call", self
.namespace
['CIA'],
1584 self
.namespace
['NIA'],
1585 self
.namespace
['SVSTATE'])
1587 def svp64_reset_loop(self
):
1588 self
.svstate
.srcstep
[0:7] = 0
1589 self
.svstate
.dststep
[0:7] = 0
1590 log (" svstate.srcstep loop end (PC to update)")
1591 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1593 def update_nia(self
):
1594 self
.pc
.update_nia(self
.is_svp64_mode
)
1595 self
.namespace
['NIA'] = self
.pc
.NIA
1598 """Decorator factory.
1600 this decorator will "inject" variables into the function's namespace,
1601 from the *dictionary* in self.namespace. it therefore becomes possible
1602 to make it look like a whole stack of variables which would otherwise
1603 need "self." inserted in front of them (*and* for those variables to be
1604 added to the instance) "appear" in the function.
1606 "self.namespace['SI']" for example becomes accessible as just "SI" but
1607 *only* inside the function, when decorated.
1609 def variable_injector(func
):
1611 def decorator(*args
, **kwargs
):
1613 func_globals
= func
.__globals
__ # Python 2.6+
1614 except AttributeError:
1615 func_globals
= func
.func_globals
# Earlier versions.
1617 context
= args
[0].namespace
# variables to be injected
1618 saved_values
= func_globals
.copy() # Shallow copy of dict.
1619 func_globals
.update(context
)
1620 result
= func(*args
, **kwargs
)
1621 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1622 log("args[0]", args
[0].namespace
['CIA'],
1623 args
[0].namespace
['NIA'],
1624 args
[0].namespace
['SVSTATE'])
1625 args
[0].namespace
= func_globals
1626 #exec (func.__code__, func_globals)
1629 # func_globals = saved_values # Undo changes.
1635 return variable_injector