d57a8fc12387dfa63e231ec952ad6a59d169f823
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 # this is for setvl "Vertical" mode: if set true,
1107 # srcstep/dststep is explicitly advanced
1108 self
.allow_next_step_inc
= False
1110 # nop has to be supported, we could let the actual op calculate
1111 # but PowerDecoder has a pattern for nop
1113 self
.update_pc_next()
1116 info
= self
.instrs
[name
]
1117 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1119 # preserve order of register names
1120 input_names
= create_args(list(info
.read_regs
) +
1121 list(info
.uninit_regs
))
1124 # get SVP64 entry for the current instruction
1125 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1126 if sv_rm
is not None:
1127 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1129 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1130 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1132 # see if srcstep/dststep need skipping over masked-out predicate bits
1133 if self
.is_svp64_mode
:
1134 yield from self
.svstate_pre_inc()
1135 pre
= yield from self
.update_new_svstate_steps()
1137 self
.svp64_reset_loop()
1139 self
.update_pc_next()
1141 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1142 pred_dst_zero
= self
.pred_dst_zero
1143 pred_src_zero
= self
.pred_src_zero
1144 vl
= self
.svstate
.vl
.asint(msb0
=True)
1146 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1147 if self
.is_svp64_mode
and vl
== 0:
1148 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1149 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1150 self
.namespace
['NIA'])
1153 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1154 # using pre-arranged schedule. all of this is awful but it is a
1155 # start. next job will be to put the proper activation in place
1156 yield self
.dec2
.remap_active
.eq(1 if self
.last_op_svshape
else 0)
1158 if self
.is_svp64_mode
and self
.last_op_svshape
:
1159 # get four SVSHAPEs. here we are hard-coding
1160 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1161 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1162 SVSHAPE0
= self
.spr
['SVSHAPE0']
1163 SVSHAPE1
= self
.spr
['SVSHAPE1']
1164 SVSHAPE2
= self
.spr
['SVSHAPE2']
1165 SVSHAPE3
= self
.spr
['SVSHAPE3']
1167 sname
= 'SVSHAPE%d' % i
1168 shape
= self
.spr
[sname
]
1169 print (sname
, bin(shape
.value
))
1170 print (" lims", shape
.lims
)
1171 print (" mode", shape
.mode
)
1172 print (" skip", shape
.skip
)
1174 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1175 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1176 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1177 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1180 for i
, (shape
, remap
) in enumerate(remaps
):
1181 # zero is "disabled"
1182 if shape
.value
== 0x0:
1184 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1185 if shape
.mode
== 0b00: # multiply mode
1186 step
= dststep
if (i
== 0) else srcstep
1187 if shape
.mode
== 0b01: # FFT butterfly mode
1188 step
= srcstep
# XXX HACK - for now only use srcstep
1189 # this is terrible. O(N^2) looking for the match. but hey.
1190 for idx
, remap_idx
in enumerate(remap
):
1194 if shape
.mode
== 0b00:
1196 yield self
.dec2
.o_step
.eq(remap_idx
) # RT
1197 yield self
.dec2
.o2_step
.eq(remap_idx
) # EA
1199 yield self
.dec2
.in1_step
.eq(remap_idx
) # RA
1201 yield self
.dec2
.in3_step
.eq(remap_idx
) # RB
1203 yield self
.dec2
.in2_step
.eq(remap_idx
) # RC
1204 # FFT butterfly mode
1205 if shape
.mode
== 0b01:
1207 yield self
.dec2
.o_step
.eq(remap_idx
) # RT
1208 yield self
.dec2
.in2_step
.eq(remap_idx
) # RB
1210 yield self
.dec2
.in1_step
.eq(remap_idx
) # RA
1211 yield self
.dec2
.o2_step
.eq(remap_idx
) # EA (FRS)
1213 yield self
.dec2
.in3_step
.eq(remap_idx
) # RC
1216 rremaps
.append((shape
.mode
, i
, idx
, remap_idx
)) # debug printing
1218 print ("shape remap", x
)
1219 # after that, settle down (combinatorial) to let Vector reg numbers
1220 # work themselves out
1222 remap_active
= yield self
.dec2
.remap_active
1223 print ("remap active", remap_active
)
1225 # main input registers (RT, RA ...)
1227 for name
in input_names
:
1228 # using PowerDecoder2, first, find the decoder index.
1229 # (mapping name RA RB RC RS to in1, in2, in3)
1230 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1232 # doing this is not part of svp64, it's because output
1233 # registers, to be modified, need to be in the namespace.
1234 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1236 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1239 # in case getting the register number is needed, _RA, _RB
1240 regname
= "_" + name
1241 self
.namespace
[regname
] = regnum
1242 if not self
.is_svp64_mode
or not pred_src_zero
:
1243 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1245 reg_val
= self
.fpr(regnum
)
1246 elif name
is not None:
1247 reg_val
= self
.gpr(regnum
)
1249 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1251 inputs
.append(reg_val
)
1252 # arrrrgh, awful hack, to get _RT into namespace
1253 if asmop
== 'setvl':
1255 RT
= yield self
.dec2
.dec
.RT
1256 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1258 # in SVP64 mode for LD/ST work out immediate
1259 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1260 # use info.form to detect
1261 replace_d
= False # update / replace constant in pseudocode
1262 if self
.is_svp64_mode
:
1263 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1264 # bitreverse mode reads SVD (or SVDS - TODO)
1265 # *BUT*... because this is "overloading" of LD operations,
1266 # it gets *STORED* into D (or DS, TODO)
1267 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1268 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1269 imm
= exts(imm
, 11) # sign-extend to integer
1270 print ("bitrev SVD", imm
)
1273 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1274 imm
= exts(imm
, 16) # sign-extend to integer
1275 # get the right step. LD is from srcstep, ST is dststep
1276 op
= yield self
.dec2
.e
.do
.insn_type
1278 if op
== MicrOp
.OP_LOAD
.value
:
1280 log("D-field src", imm
, offsmul
)
1281 elif op
== MicrOp
.OP_STORE
.value
:
1283 log("D-field dst", imm
, offsmul
)
1285 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1286 # manually look up RC, sigh
1287 RC
= yield self
.dec2
.dec
.RC
[0:5]
1289 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1290 "rev", bin(bitrev(offsmul
, vl
)))
1291 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1292 # Unit-Strided LD/ST adds offset*width to immediate
1293 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1294 ldst_len
= yield self
.dec2
.e
.do
.data_len
1295 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1297 # Element-strided multiplies the immediate by element step
1298 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1299 imm
= SelectableInt(imm
* offsmul
, 32)
1301 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1302 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1303 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1304 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1307 self
.namespace
['D'] = imm
1309 # "special" registers
1310 for special
in info
.special_regs
:
1311 if special
in special_sprs
:
1312 inputs
.append(self
.spr
[special
])
1314 inputs
.append(self
.namespace
[special
])
1316 # clear trap (trap) NIA
1317 self
.trap_nia
= None
1319 # execute actual instruction here (finally)
1320 log("inputs", inputs
)
1321 results
= info
.func(self
, *inputs
)
1322 log("results", results
)
1324 # "inject" decorator takes namespace from function locals: we need to
1325 # overwrite NIA being overwritten (sigh)
1326 if self
.trap_nia
is not None:
1327 self
.namespace
['NIA'] = self
.trap_nia
1329 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1331 # check if op was a LD/ST so that debugging can check the
1333 if int_op
in [MicrOp
.OP_STORE
.value
,
1335 self
.last_st_addr
= self
.mem
.last_st_addr
1336 if int_op
in [MicrOp
.OP_LOAD
.value
,
1338 self
.last_ld_addr
= self
.mem
.last_ld_addr
1339 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1340 self
.last_st_addr
, self
.last_ld_addr
)
1342 # detect if CA/CA32 already in outputs (sra*, basically)
1345 output_names
= create_args(info
.write_regs
)
1346 for name
in output_names
:
1352 log("carry already done?", bin(already_done
))
1353 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1354 carry_en
= yield self
.dec2
.e
.do
.output_carry
1358 yield from self
.handle_carry_(inputs
, results
, already_done
)
1360 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1361 # detect if overflow was in return result
1364 for name
, output
in zip(output_names
, results
):
1365 if name
== 'overflow':
1368 if hasattr(self
.dec2
.e
.do
, "oe"):
1369 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1370 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1374 log("internal overflow", overflow
, ov_en
, ov_ok
)
1376 yield from self
.handle_overflow(inputs
, results
, overflow
)
1378 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1380 if not self
.is_svp64_mode
or not pred_dst_zero
:
1381 if hasattr(self
.dec2
.e
.do
, "rc"):
1382 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1384 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1385 self
.handle_comparison(results
, regnum
)
1387 # any modified return results?
1389 for name
, output
in zip(output_names
, results
):
1390 if name
== 'overflow': # ignore, done already (above)
1392 if isinstance(output
, int):
1393 output
= SelectableInt(output
, 256)
1394 if name
in ['CA', 'CA32']:
1396 log("writing %s to XER" % name
, output
)
1397 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1399 log("NOT writing %s to XER" % name
, output
)
1400 elif name
in info
.special_regs
:
1401 log('writing special %s' % name
, output
, special_sprs
)
1402 if name
in special_sprs
:
1403 self
.spr
[name
] = output
1405 self
.namespace
[name
].eq(output
)
1407 log('msr written', hex(self
.msr
.value
))
1409 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1412 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1415 # temporary hack for not having 2nd output
1416 regnum
= yield getattr(self
.decoder
, name
)
1418 if self
.is_svp64_mode
and pred_dst_zero
:
1419 log('zeroing reg %d %s' % (regnum
, str(output
)),
1421 output
= SelectableInt(0, 256)
1427 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1429 if output
.bits
> 64:
1430 output
= SelectableInt(output
.value
, 64)
1432 self
.fpr
[regnum
] = output
1434 self
.gpr
[regnum
] = output
1436 # check if it is the SVSTATE.src/dest step that needs incrementing
1437 # this is our Sub-Program-Counter loop from 0 to VL-1
1440 if self
.allow_next_step_inc
:
1441 log("SVSTATE_NEXT: inc requested")
1442 yield from self
.svstate_pre_inc()
1443 pre
= yield from self
.update_new_svstate_steps()
1445 log ("SVSTATE_NEXT: end of loop, reset (TODO, update CR0)")
1446 self
.svp64_reset_loop()
1449 log ("SVSTATE_NEXT: post-inc")
1450 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1451 vl
= self
.svstate
.vl
.asint(msb0
=True)
1452 end_src
= srcstep
== vl
-1
1453 end_dst
= dststep
== vl
-1
1455 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1457 self
.svstate
.dststep
+= SelectableInt(1, 7)
1458 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1459 if end_src
or end_dst
:
1460 self
.svp64_reset_loop()
1461 # TODO: set CR0 (if Rc=1) based on end
1462 elif self
.is_svp64_mode
:
1463 yield from self
.svstate_post_inc()
1465 # XXX only in non-SVP64 mode!
1466 # record state of whether the current operation was an svshape,
1467 # to be able to know if it should apply in the next instruction.
1468 # also (if going to use this instruction) should disable ability
1469 # to interrupt in between. sigh.
1470 self
.last_op_svshape
= asmop
== 'svremap'
1472 self
.update_pc_next()
1474 def SVSTATE_NEXT(self
):
1475 """explicitly moves srcstep/dststep on to next element, for
1476 "Vertical-First" mode. this function is called from
1477 setvl pseudo-code, as a pseudo-op "svstep"
1480 self
.allow_next_step_inc
= True
1482 def svstate_pre_inc(self
):
1483 """check if srcstep/dststep need to skip over masked-out predicate bits
1485 # get SVSTATE VL (oh and print out some debug stuff)
1486 vl
= self
.svstate
.vl
.asint(msb0
=True)
1487 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1488 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1489 sv_a_nz
= yield self
.dec2
.sv_a_nz
1490 fft_mode
= yield self
.dec2
.use_svp64_fft
1491 in1
= yield self
.dec2
.e
.read_reg1
.data
1492 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1493 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1495 # get predicate mask
1496 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1498 pmode
= yield self
.dec2
.rm_dec
.predmode
1499 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1500 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1501 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1502 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1503 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1504 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1505 if pmode
== SVP64PredMode
.INT
.value
:
1506 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1507 if sv_ptype
== SVPtype
.P2
.value
:
1508 srcmask
= get_predint(self
.gpr
, srcpred
)
1509 elif pmode
== SVP64PredMode
.CR
.value
:
1510 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1511 if sv_ptype
== SVPtype
.P2
.value
:
1512 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1513 log (" pmode", pmode
)
1514 log (" reverse", reverse_gear
)
1515 log (" ptype", sv_ptype
)
1516 log (" srcpred", bin(srcpred
))
1517 log (" dstpred", bin(dstpred
))
1518 log (" srcmask", bin(srcmask
))
1519 log (" dstmask", bin(dstmask
))
1520 log (" pred_sz", bin(pred_src_zero
))
1521 log (" pred_dz", bin(pred_dst_zero
))
1523 # okaaay, so here we simply advance srcstep (TODO dststep)
1524 # until the predicate mask has a "1" bit... or we run out of VL
1525 # let srcstep==VL be the indicator to move to next instruction
1526 if not pred_src_zero
:
1527 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1528 log (" skip", bin(1<<srcstep
))
1531 if not pred_dst_zero
:
1532 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1533 log (" skip", bin(1<<dststep
))
1536 # now work out if the relevant mask bits require zeroing
1538 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1540 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1542 # store new srcstep / dststep
1543 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1544 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1545 log (" new srcstep", srcstep
)
1546 log (" new dststep", dststep
)
1548 def update_new_svstate_steps(self
):
1549 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1551 # update SVSTATE with new srcstep
1552 self
.svstate
.srcstep
[0:7] = srcstep
1553 self
.svstate
.dststep
[0:7] = dststep
1554 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1555 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1556 yield Settle() # let decoder update
1557 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1558 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1559 vl
= self
.svstate
.vl
.asint(msb0
=True)
1560 log (" srcstep", srcstep
)
1561 log (" dststep", dststep
)
1563 # check if end reached (we let srcstep overrun, above)
1564 # nothing needs doing (TODO zeroing): just do next instruction
1565 return srcstep
== vl
or dststep
== vl
1567 def svstate_post_inc(self
, vf
=0):
1568 # check if SV "Vertical First" mode is enabled
1569 log (" SV Vertical First", vf
, self
.msr
[MSRb
.SVF
].value
)
1570 if not vf
and self
.msr
[MSRb
.SVF
].value
== 1:
1574 # check if it is the SVSTATE.src/dest step that needs incrementing
1575 # this is our Sub-Program-Counter loop from 0 to VL-1
1576 # XXX twin predication TODO
1577 vl
= self
.svstate
.vl
.asint(msb0
=True)
1578 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1579 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1580 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1581 rm_mode
= yield self
.dec2
.rm_dec
.mode
1582 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1583 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1584 out_vec
= not (yield self
.dec2
.no_out_vec
)
1585 in_vec
= not (yield self
.dec2
.no_in_vec
)
1586 log (" svstate.vl", vl
)
1587 log (" svstate.mvl", mvl
)
1588 log (" svstate.srcstep", srcstep
)
1589 log (" svstate.dststep", dststep
)
1590 log (" mode", rm_mode
)
1591 log (" reverse", reverse_gear
)
1592 log (" out_vec", out_vec
)
1593 log (" in_vec", in_vec
)
1594 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1595 # check if srcstep needs incrementing by one, stop PC advancing
1596 # svp64 loop can end early if the dest is scalar for single-pred
1597 # but for 2-pred both src/dest have to be checked.
1598 # XXX this might not be true! it may just be LD/ST
1599 if sv_ptype
== SVPtype
.P2
.value
:
1600 svp64_is_vector
= (out_vec
or in_vec
)
1602 svp64_is_vector
= out_vec
1603 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1604 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1605 self
.svstate
.dststep
+= SelectableInt(1, 7)
1606 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1607 self
.namespace
['NIA'] = self
.pc
.NIA
1608 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1609 log("end of sub-pc call", self
.namespace
['CIA'],
1610 self
.namespace
['NIA'])
1611 return False # DO NOT allow PC update whilst Sub-PC loop running
1613 # reset loop to zero and update NIA
1614 self
.svp64_reset_loop()
1619 def update_pc_next(self
):
1620 # UPDATE program counter
1621 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1622 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1623 log("end of call", self
.namespace
['CIA'],
1624 self
.namespace
['NIA'],
1625 self
.namespace
['SVSTATE'])
1627 def svp64_reset_loop(self
):
1628 self
.svstate
.srcstep
[0:7] = 0
1629 self
.svstate
.dststep
[0:7] = 0
1630 log (" svstate.srcstep loop end (PC to update)")
1631 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1633 def update_nia(self
):
1634 self
.pc
.update_nia(self
.is_svp64_mode
)
1635 self
.namespace
['NIA'] = self
.pc
.NIA
1638 """Decorator factory.
1640 this decorator will "inject" variables into the function's namespace,
1641 from the *dictionary* in self.namespace. it therefore becomes possible
1642 to make it look like a whole stack of variables which would otherwise
1643 need "self." inserted in front of them (*and* for those variables to be
1644 added to the instance) "appear" in the function.
1646 "self.namespace['SI']" for example becomes accessible as just "SI" but
1647 *only* inside the function, when decorated.
1649 def variable_injector(func
):
1651 def decorator(*args
, **kwargs
):
1653 func_globals
= func
.__globals
__ # Python 2.6+
1654 except AttributeError:
1655 func_globals
= func
.func_globals
# Earlier versions.
1657 context
= args
[0].namespace
# variables to be injected
1658 saved_values
= func_globals
.copy() # Shallow copy of dict.
1659 func_globals
.update(context
)
1660 result
= func(*args
, **kwargs
)
1661 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1662 log("args[0]", args
[0].namespace
['CIA'],
1663 args
[0].namespace
['NIA'],
1664 args
[0].namespace
['SVSTATE'])
1665 args
[0].namespace
= func_globals
1666 #exec (func.__code__, func_globals)
1669 # func_globals = saved_values # Undo changes.
1675 return variable_injector