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
39 from openpower
.decoder
.isa
.svremap
import SVREMAP
42 from openpower
.util
import log
44 from collections
import namedtuple
48 instruction_info
= namedtuple('instruction_info',
49 'func read_regs uninit_regs write_regs ' +
50 'special_regs op_fields form asmregs')
61 # TODO (lkcl): adjust other registers that should be in a particular order
62 # probably CA, CA32, and CR
88 "overflow": 7, # should definitely be last
91 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
94 def create_args(reglist
, extra
=None):
95 retval
= list(OrderedSet(reglist
))
96 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
98 return [extra
] + retval
104 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
107 self
.isacaller
= isacaller
108 self
.svstate
= svstate
109 for i
in range(len(regfile
)):
110 self
[i
] = SelectableInt(regfile
[i
], 64)
112 def __call__(self
, ridx
):
113 if isinstance(ridx
, SelectableInt
):
117 def set_form(self
, form
):
120 def __setitem__(self
, rnum
, value
):
121 # rnum = rnum.value # only SelectableInt allowed
122 log("GPR setitem", rnum
, value
)
123 if isinstance(rnum
, SelectableInt
):
125 dict.__setitem
__(self
, rnum
, value
)
127 def getz(self
, rnum
):
128 # rnum = rnum.value # only SelectableInt allowed
129 log("GPR getzero?", rnum
)
131 return SelectableInt(0, 64)
134 def _get_regnum(self
, attr
):
135 getform
= self
.sd
.sigforms
[self
.form
]
136 rnum
= getattr(getform
, attr
)
139 def ___getitem__(self
, attr
):
140 """ XXX currently not used
142 rnum
= self
._get
_regnum
(attr
)
143 log("GPR getitem", attr
, rnum
)
144 return self
.regfile
[rnum
]
146 def dump(self
, printout
=True):
148 for i
in range(len(self
)):
149 res
.append(self
[i
].value
)
151 for i
in range(0, len(res
), 8):
154 s
.append("%08x" % res
[i
+j
])
156 print("reg", "%2d" % i
, s
)
161 def __init__(self
, dec2
, initial_sprs
={}):
164 for key
, v
in initial_sprs
.items():
165 if isinstance(key
, SelectableInt
):
167 key
= special_sprs
.get(key
, key
)
168 if isinstance(key
, int):
171 info
= spr_byname
[key
]
172 if not isinstance(v
, SelectableInt
):
173 v
= SelectableInt(v
, info
.length
)
176 def __getitem__(self
, key
):
178 log("dict", self
.items())
179 # if key in special_sprs get the special spr, otherwise return key
180 if isinstance(key
, SelectableInt
):
182 if isinstance(key
, int):
183 key
= spr_dict
[key
].SPR
184 key
= special_sprs
.get(key
, key
)
185 if key
== 'HSRR0': # HACK!
187 if key
== 'HSRR1': # HACK!
190 res
= dict.__getitem
__(self
, key
)
192 if isinstance(key
, int):
195 info
= spr_byname
[key
]
196 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
197 res
= dict.__getitem
__(self
, key
)
198 log("spr returning", key
, res
)
201 def __setitem__(self
, key
, value
):
202 if isinstance(key
, SelectableInt
):
204 if isinstance(key
, int):
205 key
= spr_dict
[key
].SPR
207 key
= special_sprs
.get(key
, key
)
208 if key
== 'HSRR0': # HACK!
209 self
.__setitem
__('SRR0', value
)
210 if key
== 'HSRR1': # HACK!
211 self
.__setitem
__('SRR1', value
)
212 log("setting spr", key
, value
)
213 dict.__setitem
__(self
, key
, value
)
215 def __call__(self
, ridx
):
218 def dump(self
, printout
=True):
220 keys
= list(self
.keys())
223 sprname
= spr_dict
.get(k
, None)
227 sprname
= sprname
.SPR
228 res
.append((sprname
, self
[k
].value
))
230 for sprname
, value
in res
:
231 print(" ", sprname
, hex(value
))
236 def __init__(self
, pc_init
=0):
237 self
.CIA
= SelectableInt(pc_init
, 64)
238 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
240 def update_nia(self
, is_svp64
):
241 increment
= 8 if is_svp64
else 4
242 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
244 def update(self
, namespace
, is_svp64
):
245 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
247 self
.CIA
= namespace
['NIA'].narrow(64)
248 self
.update_nia(is_svp64
)
249 namespace
['CIA'] = self
.CIA
250 namespace
['NIA'] = self
.NIA
253 # Simple-V: see https://libre-soc.org/openpower/sv
255 def __init__(self
, init
=0):
256 self
.spr
= SelectableInt(init
, 64)
257 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
258 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
259 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
260 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
261 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
262 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
263 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
268 def __init__(self
, init
=0):
269 self
.spr
= SelectableInt(init
, 24)
270 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
271 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
272 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
273 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
274 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
275 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
276 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
277 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
278 # these cover the same extra field, split into parts as EXTRA2
279 self
.extra2
= list(range(4))
280 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
281 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
282 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
283 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
284 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
285 # and here as well, but EXTRA3
286 self
.extra3
= list(range(3))
287 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
288 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
289 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
292 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
293 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
294 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
295 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
296 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
297 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
298 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
299 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
300 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
303 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
304 class SVP64PrefixFields
:
306 self
.insn
= SelectableInt(0, 32)
307 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
308 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
309 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
310 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
311 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
314 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
315 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
316 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
320 # See PowerISA Version 3.0 B Book 1
321 # Section 2.3.1 Condition Register pages 30 - 31
323 LT
= FL
= 0 # negative, less than, floating-point less than
324 GT
= FG
= 1 # positive, greater than, floating-point greater than
325 EQ
= FE
= 2 # equal, floating-point equal
326 SO
= FU
= 3 # summary overflow, floating-point unordered
328 def __init__(self
, init
=0):
329 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
330 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
331 self
.cr
= SelectableInt(init
, 64) # underlying reg
332 # field-selectable versions of Condition Register TODO check bitranges?
335 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
336 _cr
= FieldSelectableInt(self
.cr
, bits
)
339 # decode SVP64 predicate integer to reg number and invert
340 def get_predint(gpr
, mask
):
343 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
344 if mask
== SVP64PredInt
.ALWAYS
.value
:
345 return 0xffff_ffff_ffff_ffff
346 if mask
== SVP64PredInt
.R3_UNARY
.value
:
347 return 1 << (gpr(3).value
& 0b111111)
348 if mask
== SVP64PredInt
.R3
.value
:
350 if mask
== SVP64PredInt
.R3_N
.value
:
352 if mask
== SVP64PredInt
.R10
.value
:
354 if mask
== SVP64PredInt
.R10_N
.value
:
355 return ~
gpr(10).value
356 if mask
== SVP64PredInt
.R30
.value
:
358 if mask
== SVP64PredInt
.R30_N
.value
:
359 return ~
gpr(30).value
361 # decode SVP64 predicate CR to reg number and invert status
362 def _get_predcr(mask
):
363 if mask
== SVP64PredCR
.LT
.value
:
365 if mask
== SVP64PredCR
.GE
.value
:
367 if mask
== SVP64PredCR
.GT
.value
:
369 if mask
== SVP64PredCR
.LE
.value
:
371 if mask
== SVP64PredCR
.EQ
.value
:
373 if mask
== SVP64PredCR
.NE
.value
:
375 if mask
== SVP64PredCR
.SO
.value
:
377 if mask
== SVP64PredCR
.NS
.value
:
380 # read individual CR fields (0..VL-1), extract the required bit
381 # and construct the mask
382 def get_predcr(crl
, mask
, vl
):
383 idx
, noninv
= _get_predcr(mask
)
386 cr
= crl
[i
+SVP64CROffs
.CRPred
]
387 if cr
[idx
].value
== noninv
:
392 # TODO, really should just be using PowerDecoder2
393 def get_pdecode_idx_in(dec2
, name
):
395 in1_sel
= yield op
.in1_sel
396 in2_sel
= yield op
.in2_sel
397 in3_sel
= yield op
.in3_sel
398 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
399 in1
= yield dec2
.e
.read_reg1
.data
400 in2
= yield dec2
.e
.read_reg2
.data
401 in3
= yield dec2
.e
.read_reg3
.data
402 in1_isvec
= yield dec2
.in1_isvec
403 in2_isvec
= yield dec2
.in2_isvec
404 in3_isvec
= yield dec2
.in3_isvec
405 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
407 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
409 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
411 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
413 log ("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
415 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
417 # identify which regnames map to in1/2/3
419 if (in1_sel
== In1Sel
.RA
.value
or
420 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
421 return in1
, in1_isvec
422 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
423 return in1
, in1_isvec
425 if in2_sel
== In2Sel
.RB
.value
:
426 return in2
, in2_isvec
427 if in3_sel
== In3Sel
.RB
.value
:
428 return in3
, in3_isvec
429 # XXX TODO, RC doesn't exist yet!
431 assert False, "RC does not exist yet"
433 if in1_sel
== In1Sel
.RS
.value
:
434 return in1
, in1_isvec
435 if in2_sel
== In2Sel
.RS
.value
:
436 return in2
, in2_isvec
437 if in3_sel
== In3Sel
.RS
.value
:
438 return in3
, in3_isvec
440 if in1_sel
== In1Sel
.FRA
.value
:
441 return in1
, in1_isvec
443 if in2_sel
== In2Sel
.FRB
.value
:
444 return in2
, in2_isvec
446 if in3_sel
== In3Sel
.FRC
.value
:
447 return in3
, in3_isvec
449 if in1_sel
== In1Sel
.FRS
.value
:
450 return in1
, in1_isvec
451 if in3_sel
== In3Sel
.FRS
.value
:
452 return in3
, in3_isvec
456 # TODO, really should just be using PowerDecoder2
457 def get_pdecode_cr_out(dec2
, name
):
459 out_sel
= yield op
.cr_out
460 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
461 sv_cr_out
= yield op
.sv_cr_out
462 spec
= yield dec2
.crout_svdec
.spec
463 sv_override
= yield dec2
.dec_cr_out
.sv_override
464 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
465 out
= yield dec2
.e
.write_cr
.data
466 o_isvec
= yield dec2
.o_isvec
467 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
468 log (" sv_cr_out", sv_cr_out
)
469 log (" cr_bf", out_bitfield
)
471 log (" override", sv_override
)
472 # identify which regnames map to out / o2
474 if out_sel
== CROutSel
.CR0
.value
:
476 log ("get_pdecode_cr_out not found", name
)
480 # TODO, really should just be using PowerDecoder2
481 def get_pdecode_idx_out(dec2
, name
):
483 out_sel
= yield op
.out_sel
484 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
485 out
= yield dec2
.e
.write_reg
.data
486 o_isvec
= yield dec2
.o_isvec
487 # identify which regnames map to out / o2
489 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
490 if out_sel
== OutSel
.RA
.value
:
493 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
494 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
496 if out_sel
== OutSel
.RT
.value
:
499 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
500 if out_sel
== OutSel
.FRA
.value
:
503 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
504 OutSel
.FRT
.value
, out
, o_isvec
)
505 if out_sel
== OutSel
.FRT
.value
:
507 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
511 # TODO, really should just be using PowerDecoder2
512 def get_pdecode_idx_out2(dec2
, name
):
513 # check first if register is activated for write
515 out_sel
= yield op
.out_sel
516 out
= yield dec2
.e
.write_ea
.data
517 o_isvec
= yield dec2
.o2_isvec
518 out_ok
= yield dec2
.e
.write_ea
.ok
519 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
524 if hasattr(op
, "upd"):
525 # update mode LD/ST uses read-reg A also as an output
527 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
528 out_sel
, OutSel
.RA
.value
,
530 if upd
== LDSTMode
.update
.value
:
533 int_op
= yield dec2
.dec
.op
.internal_op
534 fft_en
= yield dec2
.use_svp64_fft
535 #if int_op == MicrOp.OP_FP_MADD.value and fft_en:
537 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
544 # decoder2 - an instance of power_decoder2
545 # regfile - a list of initial values for the registers
546 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
547 # respect_pc - tracks the program counter. requires initial_insns
548 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
549 initial_mem
=None, initial_msr
=0,
560 self
.bigendian
= bigendian
562 self
.is_svp64_mode
= False
563 self
.respect_pc
= respect_pc
564 if initial_sprs
is None:
566 if initial_mem
is None:
568 if fpregfile
is None:
570 if initial_insns
is None:
572 assert self
.respect_pc
== False, "instructions required to honor pc"
574 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
575 log("ISACaller initial_msr", initial_msr
)
577 # "fake program counter" mode (for unit testing)
581 if isinstance(initial_mem
, tuple):
582 self
.fake_pc
= initial_mem
[0]
583 disasm_start
= self
.fake_pc
585 disasm_start
= initial_pc
587 # disassembly: we need this for now (not given from the decoder)
588 self
.disassembly
= {}
590 for i
, code
in enumerate(disassembly
):
591 self
.disassembly
[i
*4 + disasm_start
] = code
593 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
594 self
.svp64rm
= SVP64RM()
595 if initial_svstate
is None:
597 if isinstance(initial_svstate
, int):
598 initial_svstate
= SVP64State(initial_svstate
)
599 # SVSTATE, MSR and PC
600 self
.svstate
= initial_svstate
601 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
603 # GPR FPR SPR registers
604 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
605 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
606 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
608 # set up 4 dummy SVSHAPEs if they aren't already set up
610 sname
= 'SVSHAPE%d' % i
611 if sname
not in self
.spr
:
612 self
.spr
[sname
] = SVSHAPE(0)
614 # make sure it's an SVSHAPE
615 val
= self
.spr
[sname
].value
616 self
.spr
[sname
] = SVSHAPE(val
)
617 self
.last_op_svshape
= False
619 if 'SVREMAP' not in self
.spr
:
620 self
.spr
['SVREMAP'] = SVREMAP(0)
622 # make sure it's an SVREMAP
623 val
= self
.spr
['SVREMAP'].value
624 self
.spr
['SVREMAP'] = SVREMAP(val
)
627 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
628 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
629 # MMU mode, redirect underlying Mem through RADIX
631 self
.mem
= RADIX(self
.mem
, self
)
633 self
.imem
= RADIX(self
.imem
, self
)
636 # FPR (same as GPR except for FP nums)
637 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
638 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
639 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
640 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
642 # 2.3.2 LR (actually SPR #8) -- Done
643 # 2.3.3 CTR (actually SPR #9) -- Done
644 # 2.3.4 TAR (actually SPR #815)
645 # 3.2.2 p45 XER (actually SPR #1) -- Done
646 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
648 # create CR then allow portions of it to be "selectable" (below)
649 self
.cr_fields
= CRFields(initial_cr
)
650 self
.cr
= self
.cr_fields
.cr
652 # "undefined", just set to variable-bit-width int (use exts "max")
653 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
656 self
.namespace
.update(self
.spr
)
657 self
.namespace
.update({'GPR': self
.gpr
,
661 'memassign': self
.memassign
,
664 'SVSTATE': self
.svstate
.spr
,
665 'SVREMAP': self
.spr
['SVREMAP'],
666 'SVSHAPE0': self
.spr
['SVSHAPE0'],
667 'SVSHAPE1': self
.spr
['SVSHAPE1'],
668 'SVSHAPE2': self
.spr
['SVSHAPE2'],
669 'SVSHAPE3': self
.spr
['SVSHAPE3'],
672 'undefined': undefined
,
673 'mode_is_64bit': True,
677 # update pc to requested start point
678 self
.set_pc(initial_pc
)
680 # field-selectable versions of Condition Register
681 self
.crl
= self
.cr_fields
.crl
683 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
685 self
.decoder
= decoder2
.dec
688 def call_trap(self
, trap_addr
, trap_bit
):
689 """calls TRAP and sets up NIA to the new execution location.
690 next instruction will begin at trap_addr.
692 self
.TRAP(trap_addr
, trap_bit
)
693 self
.namespace
['NIA'] = self
.trap_nia
694 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
696 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
697 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
699 TRAP function is callable from inside the pseudocode itself,
700 hence the default arguments. when calling from inside ISACaller
701 it is best to use call_trap()
703 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
704 # store CIA(+4?) in SRR0, set NIA to 0x700
705 # store MSR in SRR1, set MSR to um errr something, have to check spec
706 # store SVSTATE (if enabled) in SVSRR0
707 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
708 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
709 if self
.is_svp64_mode
:
710 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
711 self
.trap_nia
= SelectableInt(trap_addr
, 64)
712 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
714 # set exception bits. TODO: this should, based on the address
715 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
716 # bits appropriately. however it turns out that *for now* in all
717 # cases (all trap_addrs) the exact same thing is needed.
718 self
.msr
[MSRb
.IR
] = 0
719 self
.msr
[MSRb
.DR
] = 0
720 self
.msr
[MSRb
.FE0
] = 0
721 self
.msr
[MSRb
.FE1
] = 0
722 self
.msr
[MSRb
.EE
] = 0
723 self
.msr
[MSRb
.RI
] = 0
724 self
.msr
[MSRb
.SF
] = 1
725 self
.msr
[MSRb
.TM
] = 0
726 self
.msr
[MSRb
.VEC
] = 0
727 self
.msr
[MSRb
.VSX
] = 0
728 self
.msr
[MSRb
.PR
] = 0
729 self
.msr
[MSRb
.FP
] = 0
730 self
.msr
[MSRb
.PMM
] = 0
731 self
.msr
[MSRb
.TEs
] = 0
732 self
.msr
[MSRb
.TEe
] = 0
733 self
.msr
[MSRb
.UND
] = 0
734 self
.msr
[MSRb
.LE
] = 1
736 def memassign(self
, ea
, sz
, val
):
737 self
.mem
.memassign(ea
, sz
, val
)
739 def prep_namespace(self
, formname
, op_fields
):
740 # TODO: get field names from form in decoder*1* (not decoder2)
741 # decoder2 is hand-created, and decoder1.sigform is auto-generated
743 # then "yield" fields only from op_fields rather than hard-coded
745 fields
= self
.decoder
.sigforms
[formname
]
746 log("prep_namespace", formname
, op_fields
)
747 for name
in op_fields
:
749 sig
= getattr(fields
, name
.upper())
751 sig
= getattr(fields
, name
)
753 # these are all opcode fields involved in index-selection of CR,
754 # and need to do "standard" arithmetic. CR[BA+32] for example
755 # would, if using SelectableInt, only be 5-bit.
756 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
757 self
.namespace
[name
] = val
759 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
761 self
.namespace
['XER'] = self
.spr
['XER']
762 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
763 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
765 # add some SVSTATE convenience variables
766 vl
= self
.svstate
.vl
.asint(msb0
=True)
767 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
768 self
.namespace
['VL'] = vl
769 self
.namespace
['srcstep'] = srcstep
771 def handle_carry_(self
, inputs
, outputs
, already_done
):
772 inv_a
= yield self
.dec2
.e
.do
.invert_in
774 inputs
[0] = ~inputs
[0]
776 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
778 imm
= yield self
.dec2
.e
.do
.imm_data
.data
779 inputs
.append(SelectableInt(imm
, 64))
780 assert len(outputs
) >= 1
781 log("outputs", repr(outputs
))
782 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
788 log("gt input", x
, output
)
789 gt
= (gtu(x
, output
))
792 cy
= 1 if any(gts
) else 0
794 if not (1 & already_done
):
795 self
.spr
['XER'][XER_bits
['CA']] = cy
797 log("inputs", already_done
, inputs
)
799 # ARGH... different for OP_ADD... *sigh*...
800 op
= yield self
.dec2
.e
.do
.insn_type
801 if op
== MicrOp
.OP_ADD
.value
:
802 res32
= (output
.value
& (1 << 32)) != 0
803 a32
= (inputs
[0].value
& (1 << 32)) != 0
805 b32
= (inputs
[1].value
& (1 << 32)) != 0
808 cy32
= res32 ^ a32 ^ b32
809 log("CA32 ADD", cy32
)
813 log("input", x
, output
)
814 log(" x[32:64]", x
, x
[32:64])
815 log(" o[32:64]", output
, output
[32:64])
816 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
818 cy32
= 1 if any(gts
) else 0
819 log("CA32", cy32
, gts
)
820 if not (2 & already_done
):
821 self
.spr
['XER'][XER_bits
['CA32']] = cy32
823 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
824 if hasattr(self
.dec2
.e
.do
, "invert_in"):
825 inv_a
= yield self
.dec2
.e
.do
.invert_in
827 inputs
[0] = ~inputs
[0]
829 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
831 imm
= yield self
.dec2
.e
.do
.imm_data
.data
832 inputs
.append(SelectableInt(imm
, 64))
833 assert len(outputs
) >= 1
834 log("handle_overflow", inputs
, outputs
, div_overflow
)
835 if len(inputs
) < 2 and div_overflow
is None:
838 # div overflow is different: it's returned by the pseudo-code
839 # because it's more complex than can be done by analysing the output
840 if div_overflow
is not None:
841 ov
, ov32
= div_overflow
, div_overflow
842 # arithmetic overflow can be done by analysing the input and output
843 elif len(inputs
) >= 2:
847 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
848 output_sgn
= exts(output
.value
, output
.bits
) < 0
849 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
850 output_sgn
!= input_sgn
[0] else 0
853 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
854 output32_sgn
= exts(output
.value
, 32) < 0
855 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
856 output32_sgn
!= input32_sgn
[0] else 0
858 self
.spr
['XER'][XER_bits
['OV']] = ov
859 self
.spr
['XER'][XER_bits
['OV32']] = ov32
860 so
= self
.spr
['XER'][XER_bits
['SO']]
862 self
.spr
['XER'][XER_bits
['SO']] = so
864 def handle_comparison(self
, outputs
, cr_idx
=0):
866 assert isinstance(out
, SelectableInt
), \
867 "out zero not a SelectableInt %s" % repr(outputs
)
868 log("handle_comparison", out
.bits
, hex(out
.value
))
869 # TODO - XXX *processor* in 32-bit mode
870 # https://bugs.libre-soc.org/show_bug.cgi?id=424
872 # o32 = exts(out.value, 32)
873 # print ("handle_comparison exts 32 bit", hex(o32))
874 out
= exts(out
.value
, out
.bits
)
875 log("handle_comparison exts", hex(out
))
876 zero
= SelectableInt(out
== 0, 1)
877 positive
= SelectableInt(out
> 0, 1)
878 negative
= SelectableInt(out
< 0, 1)
879 SO
= self
.spr
['XER'][XER_bits
['SO']]
880 log("handle_comparison SO", SO
)
881 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
882 self
.crl
[cr_idx
].eq(cr_field
)
884 def set_pc(self
, pc_val
):
885 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
886 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
888 def get_next_insn(self
):
892 pc
= self
.pc
.CIA
.value
895 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
897 raise KeyError("no instruction at 0x%x" % pc
)
901 """set up one instruction
903 pc
, insn
= self
.get_next_insn()
904 yield from self
.setup_next_insn(pc
, insn
)
906 def setup_next_insn(self
, pc
, ins
):
907 """set up next instruction
910 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
911 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
913 yield self
.dec2
.sv_rm
.eq(0)
914 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
915 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
916 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
917 yield self
.dec2
.state
.pc
.eq(pc
)
918 if self
.svstate
is not None:
919 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
921 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
923 opcode
= yield self
.dec2
.dec
.opcode_in
924 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
925 pfx
.insn
.value
= opcode
926 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
927 log ("prefix test: opcode:", major
, bin(major
),
928 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
929 self
.is_svp64_mode
= ((major
== 0b000001) and
930 pfx
.insn
[7].value
== 0b1 and
931 pfx
.insn
[9].value
== 0b1)
932 self
.pc
.update_nia(self
.is_svp64_mode
)
933 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
934 self
.namespace
['NIA'] = self
.pc
.NIA
935 self
.namespace
['SVSTATE'] = self
.svstate
.spr
936 if not self
.is_svp64_mode
:
939 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
940 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
941 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
942 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
943 sv_rm
= pfx
.rm
.asint(msb0
=True)
944 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
945 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
946 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
947 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
950 def execute_one(self
):
951 """execute one instruction
953 # get the disassembly code for this instruction
954 if self
.is_svp64_mode
:
955 if not self
.disassembly
:
956 code
= yield from self
.get_assembly_name()
958 code
= self
.disassembly
[self
._pc
+4]
959 log(" svp64 sim-execute", hex(self
._pc
), code
)
961 if not self
.disassembly
:
962 code
= yield from self
.get_assembly_name()
964 code
= self
.disassembly
[self
._pc
]
965 log("sim-execute", hex(self
._pc
), code
)
966 opname
= code
.split(' ')[0]
968 yield from self
.call(opname
) # execute the instruction
969 except MemException
as e
: # check for memory errors
970 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
971 raise e
# ... re-raise
972 # run a Trap but set DAR first
973 print ("memory unaligned exception, DAR", e
.dar
)
974 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
975 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
978 # don't use this except in special circumstances
979 if not self
.respect_pc
:
982 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
984 def get_assembly_name(self
):
985 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
986 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
987 dec_insn
= yield self
.dec2
.e
.do
.insn
988 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
989 asmcode
= yield self
.dec2
.dec
.op
.asmcode
990 int_op
= yield self
.dec2
.dec
.op
.internal_op
991 log("get assembly name asmcode", asmcode
, int_op
,
992 hex(dec_insn
), bin(insn_1_11
))
993 asmop
= insns
.get(asmcode
, None)
995 # sigh reconstruct the assembly instruction name
996 if hasattr(self
.dec2
.e
.do
, "oe"):
997 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
998 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1002 if hasattr(self
.dec2
.e
.do
, "rc"):
1003 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1004 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1008 # grrrr have to special-case MUL op (see DecodeOE)
1009 log("ov %d en %d rc %d en %d op %d" %
1010 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1011 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1016 if not asmop
.endswith("."): # don't add "." to "andis."
1019 if hasattr(self
.dec2
.e
.do
, "lk"):
1020 lk
= yield self
.dec2
.e
.do
.lk
1023 log("int_op", int_op
)
1024 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1025 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1029 spr_msb
= yield from self
.get_spr_msb()
1030 if int_op
== MicrOp
.OP_MFCR
.value
:
1035 # XXX TODO: for whatever weird reason this doesn't work
1036 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1037 if int_op
== MicrOp
.OP_MTCRF
.value
:
1044 def get_spr_msb(self
):
1045 dec_insn
= yield self
.dec2
.e
.do
.insn
1046 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1048 def call(self
, name
):
1049 """call(opcode) - the primary execution point for instructions
1051 self
.last_st_addr
= None # reset the last known store address
1052 self
.last_ld_addr
= None # etc.
1054 name
= name
.strip() # remove spaces if not already done so
1056 log("halted - not executing", name
)
1059 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1060 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1061 asmop
= yield from self
.get_assembly_name()
1062 log("call", name
, asmop
)
1065 int_op
= yield self
.dec2
.dec
.op
.internal_op
1066 spr_msb
= yield from self
.get_spr_msb()
1068 instr_is_privileged
= False
1069 if int_op
in [MicrOp
.OP_ATTN
.value
,
1070 MicrOp
.OP_MFMSR
.value
,
1071 MicrOp
.OP_MTMSR
.value
,
1072 MicrOp
.OP_MTMSRD
.value
,
1074 MicrOp
.OP_RFID
.value
]:
1075 instr_is_privileged
= True
1076 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1077 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1078 instr_is_privileged
= True
1080 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1082 # check MSR priv bit and whether op is privileged: if so, throw trap
1083 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1084 self
.call_trap(0x700, PIb
.PRIV
)
1087 # check halted condition
1092 # check illegal instruction
1094 if name
not in ['mtcrf', 'mtocrf']:
1095 illegal
= name
!= asmop
1097 # sigh deal with setvl not being supported by binutils (.long)
1098 if asmop
.startswith('setvl'):
1102 # and svremap not being supported by binutils (.long)
1103 if asmop
.startswith('svremap'):
1107 # and svshape not being supported by binutils (.long)
1108 if asmop
.startswith('svshape'):
1112 # sigh also deal with ffmadds not being supported by binutils (.long)
1113 if asmop
== 'ffmadds':
1117 # and ffadds not being supported by binutils (.long)
1118 if asmop
== 'ffadds':
1123 print("illegal", name
, asmop
)
1124 self
.call_trap(0x700, PIb
.ILLEG
)
1125 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1126 (name
, asmop
, self
.pc
.CIA
.value
))
1129 # this is for setvl "Vertical" mode: if set true,
1130 # srcstep/dststep is explicitly advanced
1131 self
.allow_next_step_inc
= False
1133 # nop has to be supported, we could let the actual op calculate
1134 # but PowerDecoder has a pattern for nop
1136 self
.update_pc_next()
1139 info
= self
.instrs
[name
]
1140 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1142 # preserve order of register names
1143 input_names
= create_args(list(info
.read_regs
) +
1144 list(info
.uninit_regs
))
1145 log("input names", input_names
)
1147 # get SVP64 entry for the current instruction
1148 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1149 if sv_rm
is not None:
1150 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1152 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1153 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1155 # see if srcstep/dststep need skipping over masked-out predicate bits
1156 if self
.is_svp64_mode
:
1157 yield from self
.svstate_pre_inc()
1158 pre
= yield from self
.update_new_svstate_steps()
1160 self
.svp64_reset_loop()
1162 self
.update_pc_next()
1164 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1165 pred_dst_zero
= self
.pred_dst_zero
1166 pred_src_zero
= self
.pred_src_zero
1167 vl
= self
.svstate
.vl
.asint(msb0
=True)
1169 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1170 if self
.is_svp64_mode
and vl
== 0:
1171 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1172 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1173 self
.namespace
['NIA'])
1177 SVREMAP
= self
.spr
['SVREMAP']
1178 # for when SVREMAP is active, using pre-arranged schedule.
1179 # note: modifying PowerDecoder2 needs to "settle"
1180 remap_en
= SVREMAP
.men
1181 active
= self
.last_op_svshape
and remap_en
!= 0
1182 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1184 if self
.is_svp64_mode
and self
.last_op_svshape
:
1185 # get four SVSHAPEs. here we are hard-coding
1186 SVSHAPE0
= self
.spr
['SVSHAPE0']
1187 SVSHAPE1
= self
.spr
['SVSHAPE1']
1188 SVSHAPE2
= self
.spr
['SVSHAPE2']
1189 SVSHAPE3
= self
.spr
['SVSHAPE3']
1190 # just some convenient debug info
1192 sname
= 'SVSHAPE%d' % i
1193 shape
= self
.spr
[sname
]
1194 log (sname
, bin(shape
.value
))
1195 log (" lims", shape
.lims
)
1196 log (" mode", shape
.mode
)
1197 log (" skip", shape
.skip
)
1199 # set up the list of steps to remap
1200 steps
= [(self
.dec2
.in1_step
, SVREMAP
.mi0
), # RA
1201 (self
.dec2
.in2_step
, SVREMAP
.mi1
), # RB
1202 (self
.dec2
.in3_step
, SVREMAP
.mi2
), # RC
1203 (self
.dec2
.o_step
, SVREMAP
.mo0
), # RT
1204 (self
.dec2
.o2_step
, SVREMAP
.mo1
), # EA
1206 # set up the iterators
1207 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1208 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1209 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1210 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1212 # go through all iterators in lock-step, advance to next remap_idx
1214 for i
, (shape
, remap
) in enumerate(remaps
):
1215 # zero is "disabled"
1216 if shape
.value
== 0x0:
1217 remap_idxs
.append(0)
1218 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1219 step
= dststep
if (i
in [3, 4]) else srcstep
1220 # this is terrible. O(N^2) looking for the match. but hey.
1221 for idx
, remap_idx
in enumerate(remap
):
1224 remap_idxs
.append(remap_idx
)
1227 # now cross-index the required SHAPE for each of 3-in 2-out regs
1228 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1229 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1230 (shape
, remap
) = remaps
[shape_idx
]
1231 remap_idx
= remap_idxs
[shape_idx
]
1232 # zero is "disabled"
1233 if shape
.value
== 0x0:
1235 # now set the actual requested step to the current index
1236 yield dstep
.eq(remap_idx
)
1238 # debug printout info
1239 rremaps
.append((shape
.mode
, i
, rnames
[i
], step
, shape_idx
,
1242 log ("shape remap", x
)
1243 # after that, settle down (combinatorial) to let Vector reg numbers
1244 # work themselves out
1246 remap_active
= yield self
.dec2
.remap_active
1247 log ("remap active", bin(remap_active
))
1249 # main input registers (RT, RA ...)
1251 for name
in input_names
:
1252 # using PowerDecoder2, first, find the decoder index.
1253 # (mapping name RA RB RC RS to in1, in2, in3)
1254 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1256 # doing this is not part of svp64, it's because output
1257 # registers, to be modified, need to be in the namespace.
1258 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1260 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1263 # in case getting the register number is needed, _RA, _RB
1264 regname
= "_" + name
1265 self
.namespace
[regname
] = regnum
1266 if not self
.is_svp64_mode
or not pred_src_zero
:
1267 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1269 reg_val
= self
.fpr(regnum
)
1270 elif name
is not None:
1271 reg_val
= self
.gpr(regnum
)
1273 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1275 inputs
.append(reg_val
)
1276 # arrrrgh, awful hack, to get _RT into namespace
1277 if asmop
== 'setvl':
1279 RT
= yield self
.dec2
.dec
.RT
1280 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1282 # in SVP64 mode for LD/ST work out immediate
1283 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1284 # use info.form to detect
1285 replace_d
= False # update / replace constant in pseudocode
1286 if self
.is_svp64_mode
:
1287 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1288 # bitreverse mode reads SVD (or SVDS - TODO)
1289 # *BUT*... because this is "overloading" of LD operations,
1290 # it gets *STORED* into D (or DS, TODO)
1291 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1292 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1293 imm
= exts(imm
, 11) # sign-extend to integer
1294 log ("bitrev SVD", imm
)
1297 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1298 imm
= exts(imm
, 16) # sign-extend to integer
1299 # get the right step. LD is from srcstep, ST is dststep
1300 op
= yield self
.dec2
.e
.do
.insn_type
1302 if op
== MicrOp
.OP_LOAD
.value
:
1304 log("D-field src", imm
, offsmul
)
1305 elif op
== MicrOp
.OP_STORE
.value
:
1307 log("D-field dst", imm
, offsmul
)
1309 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1310 # manually look up RC, sigh
1311 RC
= yield self
.dec2
.dec
.RC
[0:5]
1313 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1314 "rev", bin(bitrev(offsmul
, vl
)))
1315 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1316 # Unit-Strided LD/ST adds offset*width to immediate
1317 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1318 ldst_len
= yield self
.dec2
.e
.do
.data_len
1319 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1321 # Element-strided multiplies the immediate by element step
1322 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1323 imm
= SelectableInt(imm
* offsmul
, 32)
1325 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1326 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1327 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1328 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1331 self
.namespace
['D'] = imm
1333 # "special" registers
1334 for special
in info
.special_regs
:
1335 if special
in special_sprs
:
1336 inputs
.append(self
.spr
[special
])
1338 inputs
.append(self
.namespace
[special
])
1340 # clear trap (trap) NIA
1341 self
.trap_nia
= None
1343 # execute actual instruction here (finally)
1344 log("inputs", inputs
)
1345 results
= info
.func(self
, *inputs
)
1346 log("results", results
)
1348 # "inject" decorator takes namespace from function locals: we need to
1349 # overwrite NIA being overwritten (sigh)
1350 if self
.trap_nia
is not None:
1351 self
.namespace
['NIA'] = self
.trap_nia
1353 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1355 # check if op was a LD/ST so that debugging can check the
1357 if int_op
in [MicrOp
.OP_STORE
.value
,
1359 self
.last_st_addr
= self
.mem
.last_st_addr
1360 if int_op
in [MicrOp
.OP_LOAD
.value
,
1362 self
.last_ld_addr
= self
.mem
.last_ld_addr
1363 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1364 self
.last_st_addr
, self
.last_ld_addr
)
1366 # detect if CA/CA32 already in outputs (sra*, basically)
1369 output_names
= create_args(info
.write_regs
)
1370 for name
in output_names
:
1376 log("carry already done?", bin(already_done
))
1377 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1378 carry_en
= yield self
.dec2
.e
.do
.output_carry
1382 yield from self
.handle_carry_(inputs
, results
, already_done
)
1384 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1385 # detect if overflow was in return result
1388 for name
, output
in zip(output_names
, results
):
1389 if name
== 'overflow':
1392 if hasattr(self
.dec2
.e
.do
, "oe"):
1393 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1394 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1398 log("internal overflow", overflow
, ov_en
, ov_ok
)
1400 yield from self
.handle_overflow(inputs
, results
, overflow
)
1402 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1404 if not self
.is_svp64_mode
or not pred_dst_zero
:
1405 if hasattr(self
.dec2
.e
.do
, "rc"):
1406 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1408 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1409 self
.handle_comparison(results
, regnum
)
1411 # any modified return results?
1413 for name
, output
in zip(output_names
, results
):
1414 if name
== 'overflow': # ignore, done already (above)
1416 if isinstance(output
, int):
1417 output
= SelectableInt(output
, 256)
1418 if name
in ['CA', 'CA32']:
1420 log("writing %s to XER" % name
, output
)
1421 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1423 log("NOT writing %s to XER" % name
, output
)
1424 elif name
in info
.special_regs
:
1425 log('writing special %s' % name
, output
, special_sprs
)
1426 if name
in special_sprs
:
1427 self
.spr
[name
] = output
1429 self
.namespace
[name
].eq(output
)
1431 log('msr written', hex(self
.msr
.value
))
1433 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1436 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1439 # temporary hack for not having 2nd output
1440 regnum
= yield getattr(self
.decoder
, name
)
1442 if self
.is_svp64_mode
and pred_dst_zero
:
1443 log('zeroing reg %d %s' % (regnum
, str(output
)),
1445 output
= SelectableInt(0, 256)
1451 log('writing %s %s %s' % (ftype
, regnum
, str(output
)),
1453 if output
.bits
> 64:
1454 output
= SelectableInt(output
.value
, 64)
1456 self
.fpr
[regnum
] = output
1458 self
.gpr
[regnum
] = output
1460 # check if it is the SVSTATE.src/dest step that needs incrementing
1461 # this is our Sub-Program-Counter loop from 0 to VL-1
1464 if self
.allow_next_step_inc
:
1465 log("SVSTATE_NEXT: inc requested")
1466 yield from self
.svstate_pre_inc()
1467 pre
= yield from self
.update_new_svstate_steps()
1469 # reset at end of loop including exit Vertical Mode
1470 log ("SVSTATE_NEXT: end of loop, reset")
1471 self
.svp64_reset_loop()
1472 self
.msr
[MSRb
.SVF
] = 0
1475 results
= [SelectableInt(0, 64)]
1476 self
.handle_comparison(results
) # CR0
1478 log ("SVSTATE_NEXT: post-inc")
1479 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1480 vl
= self
.svstate
.vl
.asint(msb0
=True)
1481 end_src
= srcstep
== vl
-1
1482 end_dst
= dststep
== vl
-1
1484 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1486 self
.svstate
.dststep
+= SelectableInt(1, 7)
1487 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1488 # set CR0 (if Rc=1) based on end
1490 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1491 dststep
= self
.svstate
.srcstep
.asint(msb0
=True)
1492 endtest
= 0 if (end_src
or end_dst
) else 1
1493 results
= [SelectableInt(endtest
, 64)]
1494 self
.handle_comparison(results
) # CR0
1495 if end_src
or end_dst
:
1496 # reset at end of loop including exit Vertical Mode
1497 log ("SVSTATE_NEXT: after increments, reset")
1498 self
.svp64_reset_loop()
1499 self
.msr
[MSRb
.SVF
] = 0
1501 elif self
.is_svp64_mode
:
1502 yield from self
.svstate_post_inc()
1504 # XXX only in non-SVP64 mode!
1505 # record state of whether the current operation was an svshape,
1506 # to be able to know if it should apply in the next instruction.
1507 # also (if going to use this instruction) should disable ability
1508 # to interrupt in between. sigh.
1509 self
.last_op_svshape
= asmop
== 'svremap'
1511 self
.update_pc_next()
1513 def SVSTATE_NEXT(self
):
1514 """explicitly moves srcstep/dststep on to next element, for
1515 "Vertical-First" mode. this function is called from
1516 setvl pseudo-code, as a pseudo-op "svstep"
1519 self
.allow_next_step_inc
= True
1521 def svstate_pre_inc(self
):
1522 """check if srcstep/dststep need to skip over masked-out predicate bits
1524 # get SVSTATE VL (oh and print out some debug stuff)
1525 vl
= self
.svstate
.vl
.asint(msb0
=True)
1526 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1527 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1528 sv_a_nz
= yield self
.dec2
.sv_a_nz
1529 fft_mode
= yield self
.dec2
.use_svp64_fft
1530 in1
= yield self
.dec2
.e
.read_reg1
.data
1531 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1532 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1534 # get predicate mask
1535 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1537 pmode
= yield self
.dec2
.rm_dec
.predmode
1538 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1539 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1540 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1541 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1542 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1543 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1544 if pmode
== SVP64PredMode
.INT
.value
:
1545 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1546 if sv_ptype
== SVPtype
.P2
.value
:
1547 srcmask
= get_predint(self
.gpr
, srcpred
)
1548 elif pmode
== SVP64PredMode
.CR
.value
:
1549 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1550 if sv_ptype
== SVPtype
.P2
.value
:
1551 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1552 log (" pmode", pmode
)
1553 log (" reverse", reverse_gear
)
1554 log (" ptype", sv_ptype
)
1555 log (" srcpred", bin(srcpred
))
1556 log (" dstpred", bin(dstpred
))
1557 log (" srcmask", bin(srcmask
))
1558 log (" dstmask", bin(dstmask
))
1559 log (" pred_sz", bin(pred_src_zero
))
1560 log (" pred_dz", bin(pred_dst_zero
))
1562 # okaaay, so here we simply advance srcstep (TODO dststep)
1563 # until the predicate mask has a "1" bit... or we run out of VL
1564 # let srcstep==VL be the indicator to move to next instruction
1565 if not pred_src_zero
:
1566 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1567 log (" skip", bin(1<<srcstep
))
1570 if not pred_dst_zero
:
1571 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1572 log (" skip", bin(1<<dststep
))
1575 # now work out if the relevant mask bits require zeroing
1577 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1579 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1581 # store new srcstep / dststep
1582 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1583 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1584 log (" new srcstep", srcstep
)
1585 log (" new dststep", dststep
)
1587 def update_new_svstate_steps(self
):
1588 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1590 # update SVSTATE with new srcstep
1591 self
.svstate
.srcstep
[0:7] = srcstep
1592 self
.svstate
.dststep
[0:7] = dststep
1593 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1594 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1595 yield Settle() # let decoder update
1596 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1597 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1598 vl
= self
.svstate
.vl
.asint(msb0
=True)
1599 log (" srcstep", srcstep
)
1600 log (" dststep", dststep
)
1603 # check if end reached (we let srcstep overrun, above)
1604 # nothing needs doing (TODO zeroing): just do next instruction
1605 return srcstep
== vl
or dststep
== vl
1607 def svstate_post_inc(self
, vf
=0):
1608 # check if SV "Vertical First" mode is enabled
1609 log (" SV Vertical First", vf
, self
.msr
[MSRb
.SVF
].value
)
1610 if not vf
and self
.msr
[MSRb
.SVF
].value
== 1:
1614 # check if it is the SVSTATE.src/dest step that needs incrementing
1615 # this is our Sub-Program-Counter loop from 0 to VL-1
1616 # XXX twin predication TODO
1617 vl
= self
.svstate
.vl
.asint(msb0
=True)
1618 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1619 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1620 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1621 rm_mode
= yield self
.dec2
.rm_dec
.mode
1622 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1623 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1624 out_vec
= not (yield self
.dec2
.no_out_vec
)
1625 in_vec
= not (yield self
.dec2
.no_in_vec
)
1626 log (" svstate.vl", vl
)
1627 log (" svstate.mvl", mvl
)
1628 log (" svstate.srcstep", srcstep
)
1629 log (" svstate.dststep", dststep
)
1630 log (" mode", rm_mode
)
1631 log (" reverse", reverse_gear
)
1632 log (" out_vec", out_vec
)
1633 log (" in_vec", in_vec
)
1634 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1635 # check if srcstep needs incrementing by one, stop PC advancing
1636 # svp64 loop can end early if the dest is scalar for single-pred
1637 # but for 2-pred both src/dest have to be checked.
1638 # XXX this might not be true! it may just be LD/ST
1639 if sv_ptype
== SVPtype
.P2
.value
:
1640 svp64_is_vector
= (out_vec
or in_vec
)
1642 svp64_is_vector
= out_vec
1643 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1644 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1645 self
.svstate
.dststep
+= SelectableInt(1, 7)
1646 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1647 self
.namespace
['NIA'] = self
.pc
.NIA
1648 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1649 log("end of sub-pc call", self
.namespace
['CIA'],
1650 self
.namespace
['NIA'])
1651 return False # DO NOT allow PC update whilst Sub-PC loop running
1653 # reset loop to zero and update NIA
1654 self
.svp64_reset_loop()
1659 def update_pc_next(self
):
1660 # UPDATE program counter
1661 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1662 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1663 log("end of call", self
.namespace
['CIA'],
1664 self
.namespace
['NIA'],
1665 self
.namespace
['SVSTATE'])
1667 def svp64_reset_loop(self
):
1668 self
.svstate
.srcstep
[0:7] = 0
1669 self
.svstate
.dststep
[0:7] = 0
1670 log (" svstate.srcstep loop end (PC to update)")
1671 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1673 def update_nia(self
):
1674 self
.pc
.update_nia(self
.is_svp64_mode
)
1675 self
.namespace
['NIA'] = self
.pc
.NIA
1678 """Decorator factory.
1680 this decorator will "inject" variables into the function's namespace,
1681 from the *dictionary* in self.namespace. it therefore becomes possible
1682 to make it look like a whole stack of variables which would otherwise
1683 need "self." inserted in front of them (*and* for those variables to be
1684 added to the instance) "appear" in the function.
1686 "self.namespace['SI']" for example becomes accessible as just "SI" but
1687 *only* inside the function, when decorated.
1689 def variable_injector(func
):
1691 def decorator(*args
, **kwargs
):
1693 func_globals
= func
.__globals
__ # Python 2.6+
1694 except AttributeError:
1695 func_globals
= func
.func_globals
# Earlier versions.
1697 context
= args
[0].namespace
# variables to be injected
1698 saved_values
= func_globals
.copy() # Shallow copy of dict.
1699 log("globals before", context
.keys())
1700 func_globals
.update(context
)
1701 result
= func(*args
, **kwargs
)
1702 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1703 log("args[0]", args
[0].namespace
['CIA'],
1704 args
[0].namespace
['NIA'],
1705 args
[0].namespace
['SVSTATE'])
1706 args
[0].namespace
= func_globals
1707 #exec (func.__code__, func_globals)
1710 # func_globals = saved_values # Undo changes.
1716 return variable_injector