b3d4d8cc3074efd2c2310448d8ea99c399ff2df3
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
.svstate
import SVP64State
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
87 "overflow": 7, # should definitely be last
90 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
93 def create_args(reglist
, extra
=None):
94 retval
= list(OrderedSet(reglist
))
95 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
97 return [extra
] + retval
103 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
106 self
.isacaller
= isacaller
107 self
.svstate
= svstate
108 for i
in range(len(regfile
)):
109 self
[i
] = SelectableInt(regfile
[i
], 64)
111 def __call__(self
, ridx
):
112 if isinstance(ridx
, SelectableInt
):
116 def set_form(self
, form
):
119 def __setitem__(self
, rnum
, value
):
120 # rnum = rnum.value # only SelectableInt allowed
121 log("GPR setitem", rnum
, value
)
122 if isinstance(rnum
, SelectableInt
):
124 dict.__setitem
__(self
, rnum
, value
)
126 def getz(self
, rnum
):
127 # rnum = rnum.value # only SelectableInt allowed
128 log("GPR getzero?", rnum
)
130 return SelectableInt(0, 64)
133 def _get_regnum(self
, attr
):
134 getform
= self
.sd
.sigforms
[self
.form
]
135 rnum
= getattr(getform
, attr
)
138 def ___getitem__(self
, attr
):
139 """ XXX currently not used
141 rnum
= self
._get
_regnum
(attr
)
142 log("GPR getitem", attr
, rnum
)
143 return self
.regfile
[rnum
]
145 def dump(self
, printout
=True):
147 for i
in range(len(self
)):
148 res
.append(self
[i
].value
)
150 for i
in range(0, len(res
), 8):
153 s
.append("%08x" % res
[i
+j
])
155 print("reg", "%2d" % i
, s
)
160 def __init__(self
, dec2
, initial_sprs
={}):
163 for key
, v
in initial_sprs
.items():
164 if isinstance(key
, SelectableInt
):
166 key
= special_sprs
.get(key
, key
)
167 if isinstance(key
, int):
170 info
= spr_byname
[key
]
171 if not isinstance(v
, SelectableInt
):
172 v
= SelectableInt(v
, info
.length
)
175 def __getitem__(self
, key
):
177 log("dict", self
.items())
178 # if key in special_sprs get the special spr, otherwise return key
179 if isinstance(key
, SelectableInt
):
181 if isinstance(key
, int):
182 key
= spr_dict
[key
].SPR
183 key
= special_sprs
.get(key
, key
)
184 if key
== 'HSRR0': # HACK!
186 if key
== 'HSRR1': # HACK!
189 res
= dict.__getitem
__(self
, key
)
191 if isinstance(key
, int):
194 info
= spr_byname
[key
]
195 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
196 res
= dict.__getitem
__(self
, key
)
197 log("spr returning", key
, res
)
200 def __setitem__(self
, key
, value
):
201 if isinstance(key
, SelectableInt
):
203 if isinstance(key
, int):
204 key
= spr_dict
[key
].SPR
206 key
= special_sprs
.get(key
, key
)
207 if key
== 'HSRR0': # HACK!
208 self
.__setitem
__('SRR0', value
)
209 if key
== 'HSRR1': # HACK!
210 self
.__setitem
__('SRR1', value
)
211 log("setting spr", key
, value
)
212 dict.__setitem
__(self
, key
, value
)
214 def __call__(self
, ridx
):
217 def dump(self
, printout
=True):
219 keys
= list(self
.keys())
222 sprname
= spr_dict
.get(k
, None)
226 sprname
= sprname
.SPR
227 res
.append((sprname
, self
[k
].value
))
229 for sprname
, value
in res
:
230 print(" ", sprname
, hex(value
))
235 def __init__(self
, pc_init
=0):
236 self
.CIA
= SelectableInt(pc_init
, 64)
237 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
239 def update_nia(self
, is_svp64
):
240 increment
= 8 if is_svp64
else 4
241 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
243 def update(self
, namespace
, is_svp64
):
244 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
246 self
.CIA
= namespace
['NIA'].narrow(64)
247 self
.update_nia(is_svp64
)
248 namespace
['CIA'] = self
.CIA
249 namespace
['NIA'] = self
.NIA
254 def __init__(self
, init
=0):
255 self
.spr
= SelectableInt(init
, 24)
256 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
257 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
258 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
259 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
260 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
261 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
262 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
263 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
264 # these cover the same extra field, split into parts as EXTRA2
265 self
.extra2
= list(range(4))
266 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
267 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
268 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
269 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
270 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
271 # and here as well, but EXTRA3
272 self
.extra3
= list(range(3))
273 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
274 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
275 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
278 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
279 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
280 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
281 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
282 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
283 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
284 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
285 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
286 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
289 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
290 class SVP64PrefixFields
:
292 self
.insn
= SelectableInt(0, 32)
293 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
294 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
295 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
296 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
297 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
300 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
301 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
302 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
306 # See PowerISA Version 3.0 B Book 1
307 # Section 2.3.1 Condition Register pages 30 - 31
309 LT
= FL
= 0 # negative, less than, floating-point less than
310 GT
= FG
= 1 # positive, greater than, floating-point greater than
311 EQ
= FE
= 2 # equal, floating-point equal
312 SO
= FU
= 3 # summary overflow, floating-point unordered
314 def __init__(self
, init
=0):
315 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
316 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
317 self
.cr
= SelectableInt(init
, 64) # underlying reg
318 # field-selectable versions of Condition Register TODO check bitranges?
321 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
322 _cr
= FieldSelectableInt(self
.cr
, bits
)
325 # decode SVP64 predicate integer to reg number and invert
326 def get_predint(gpr
, mask
):
329 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
330 if mask
== SVP64PredInt
.ALWAYS
.value
:
331 return 0xffff_ffff_ffff_ffff
332 if mask
== SVP64PredInt
.R3_UNARY
.value
:
333 return 1 << (gpr(3).value
& 0b111111)
334 if mask
== SVP64PredInt
.R3
.value
:
336 if mask
== SVP64PredInt
.R3_N
.value
:
338 if mask
== SVP64PredInt
.R10
.value
:
340 if mask
== SVP64PredInt
.R10_N
.value
:
341 return ~
gpr(10).value
342 if mask
== SVP64PredInt
.R30
.value
:
344 if mask
== SVP64PredInt
.R30_N
.value
:
345 return ~
gpr(30).value
347 # decode SVP64 predicate CR to reg number and invert status
348 def _get_predcr(mask
):
349 if mask
== SVP64PredCR
.LT
.value
:
351 if mask
== SVP64PredCR
.GE
.value
:
353 if mask
== SVP64PredCR
.GT
.value
:
355 if mask
== SVP64PredCR
.LE
.value
:
357 if mask
== SVP64PredCR
.EQ
.value
:
359 if mask
== SVP64PredCR
.NE
.value
:
361 if mask
== SVP64PredCR
.SO
.value
:
363 if mask
== SVP64PredCR
.NS
.value
:
366 # read individual CR fields (0..VL-1), extract the required bit
367 # and construct the mask
368 def get_predcr(crl
, mask
, vl
):
369 idx
, noninv
= _get_predcr(mask
)
372 cr
= crl
[i
+SVP64CROffs
.CRPred
]
373 if cr
[idx
].value
== noninv
:
378 # TODO, really should just be using PowerDecoder2
379 def get_pdecode_idx_in(dec2
, name
):
381 in1_sel
= yield op
.in1_sel
382 in2_sel
= yield op
.in2_sel
383 in3_sel
= yield op
.in3_sel
384 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
385 in1
= yield dec2
.e
.read_reg1
.data
386 in2
= yield dec2
.e
.read_reg2
.data
387 in3
= yield dec2
.e
.read_reg3
.data
388 in1_isvec
= yield dec2
.in1_isvec
389 in2_isvec
= yield dec2
.in2_isvec
390 in3_isvec
= yield dec2
.in3_isvec
391 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
393 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
395 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
397 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
399 log ("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
401 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
403 # identify which regnames map to in1/2/3
405 if (in1_sel
== In1Sel
.RA
.value
or
406 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
407 return in1
, in1_isvec
408 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
409 return in1
, in1_isvec
411 if in2_sel
== In2Sel
.RB
.value
:
412 return in2
, in2_isvec
413 if in3_sel
== In3Sel
.RB
.value
:
414 return in3
, in3_isvec
415 # XXX TODO, RC doesn't exist yet!
417 assert False, "RC does not exist yet"
419 if in1_sel
== In1Sel
.RS
.value
:
420 return in1
, in1_isvec
421 if in2_sel
== In2Sel
.RS
.value
:
422 return in2
, in2_isvec
423 if in3_sel
== In3Sel
.RS
.value
:
424 return in3
, in3_isvec
426 if in1_sel
== In1Sel
.FRA
.value
:
427 return in1
, in1_isvec
429 if in2_sel
== In2Sel
.FRB
.value
:
430 return in2
, in2_isvec
432 if in3_sel
== In3Sel
.FRC
.value
:
433 return in3
, in3_isvec
435 if in1_sel
== In1Sel
.FRS
.value
:
436 return in1
, in1_isvec
437 if in3_sel
== In3Sel
.FRS
.value
:
438 return in3
, in3_isvec
442 # TODO, really should just be using PowerDecoder2
443 def get_pdecode_cr_out(dec2
, name
):
445 out_sel
= yield op
.cr_out
446 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
447 sv_cr_out
= yield op
.sv_cr_out
448 spec
= yield dec2
.crout_svdec
.spec
449 sv_override
= yield dec2
.dec_cr_out
.sv_override
450 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
451 out
= yield dec2
.e
.write_cr
.data
452 o_isvec
= yield dec2
.o_isvec
453 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
454 log (" sv_cr_out", sv_cr_out
)
455 log (" cr_bf", out_bitfield
)
457 log (" override", sv_override
)
458 # identify which regnames map to out / o2
460 if out_sel
== CROutSel
.CR0
.value
:
462 log ("get_pdecode_cr_out not found", name
)
466 # TODO, really should just be using PowerDecoder2
467 def get_pdecode_idx_out(dec2
, name
):
469 out_sel
= yield op
.out_sel
470 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
471 out
= yield dec2
.e
.write_reg
.data
472 o_isvec
= yield dec2
.o_isvec
473 # identify which regnames map to out / o2
475 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
476 if out_sel
== OutSel
.RA
.value
:
479 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
480 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
482 if out_sel
== OutSel
.RT
.value
:
485 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
486 if out_sel
== OutSel
.FRA
.value
:
489 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
490 OutSel
.FRT
.value
, out
, o_isvec
)
491 if out_sel
== OutSel
.FRT
.value
:
493 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
497 # TODO, really should just be using PowerDecoder2
498 def get_pdecode_idx_out2(dec2
, name
):
499 # check first if register is activated for write
501 out_sel
= yield op
.out_sel
502 out
= yield dec2
.e
.write_ea
.data
503 o_isvec
= yield dec2
.o2_isvec
504 out_ok
= yield dec2
.e
.write_ea
.ok
505 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
510 if hasattr(op
, "upd"):
511 # update mode LD/ST uses read-reg A also as an output
513 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
514 out_sel
, OutSel
.RA
.value
,
516 if upd
== LDSTMode
.update
.value
:
519 int_op
= yield dec2
.dec
.op
.internal_op
520 fft_en
= yield dec2
.use_svp64_fft
521 #if int_op == MicrOp.OP_FP_MADD.value and fft_en:
523 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
530 # decoder2 - an instance of power_decoder2
531 # regfile - a list of initial values for the registers
532 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
533 # respect_pc - tracks the program counter. requires initial_insns
534 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
535 initial_mem
=None, initial_msr
=0,
546 self
.bigendian
= bigendian
548 self
.is_svp64_mode
= False
549 self
.respect_pc
= respect_pc
550 if initial_sprs
is None:
552 if initial_mem
is None:
554 if fpregfile
is None:
556 if initial_insns
is None:
558 assert self
.respect_pc
== False, "instructions required to honor pc"
560 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
561 log("ISACaller initial_msr", initial_msr
)
563 # "fake program counter" mode (for unit testing)
567 if isinstance(initial_mem
, tuple):
568 self
.fake_pc
= initial_mem
[0]
569 disasm_start
= self
.fake_pc
571 disasm_start
= initial_pc
573 # disassembly: we need this for now (not given from the decoder)
574 self
.disassembly
= {}
576 for i
, code
in enumerate(disassembly
):
577 self
.disassembly
[i
*4 + disasm_start
] = code
579 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
580 self
.svp64rm
= SVP64RM()
581 if initial_svstate
is None:
583 if isinstance(initial_svstate
, int):
584 initial_svstate
= SVP64State(initial_svstate
)
585 # SVSTATE, MSR and PC
586 self
.svstate
= initial_svstate
587 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
589 # GPR FPR SPR registers
590 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
591 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
592 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
594 # set up 4 dummy SVSHAPEs if they aren't already set up
596 sname
= 'SVSHAPE%d' % i
597 if sname
not in self
.spr
:
598 self
.spr
[sname
] = SVSHAPE(0)
600 # make sure it's an SVSHAPE
601 val
= self
.spr
[sname
].value
602 self
.spr
[sname
] = SVSHAPE(val
)
603 self
.last_op_svshape
= False
606 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
607 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
608 # MMU mode, redirect underlying Mem through RADIX
610 self
.mem
= RADIX(self
.mem
, self
)
612 self
.imem
= RADIX(self
.imem
, self
)
615 # FPR (same as GPR except for FP nums)
616 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
617 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
618 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
619 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
621 # 2.3.2 LR (actually SPR #8) -- Done
622 # 2.3.3 CTR (actually SPR #9) -- Done
623 # 2.3.4 TAR (actually SPR #815)
624 # 3.2.2 p45 XER (actually SPR #1) -- Done
625 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
627 # create CR then allow portions of it to be "selectable" (below)
628 self
.cr_fields
= CRFields(initial_cr
)
629 self
.cr
= self
.cr_fields
.cr
631 # "undefined", just set to variable-bit-width int (use exts "max")
632 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
635 self
.namespace
.update(self
.spr
)
636 self
.namespace
.update({'GPR': self
.gpr
,
640 'memassign': self
.memassign
,
643 'SVSTATE': self
.svstate
,
644 'SVSHAPE0': self
.spr
['SVSHAPE0'],
645 'SVSHAPE1': self
.spr
['SVSHAPE1'],
646 'SVSHAPE2': self
.spr
['SVSHAPE2'],
647 'SVSHAPE3': self
.spr
['SVSHAPE3'],
650 'undefined': undefined
,
651 'mode_is_64bit': True,
655 # update pc to requested start point
656 self
.set_pc(initial_pc
)
658 # field-selectable versions of Condition Register
659 self
.crl
= self
.cr_fields
.crl
661 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
663 self
.decoder
= decoder2
.dec
666 def call_trap(self
, trap_addr
, trap_bit
):
667 """calls TRAP and sets up NIA to the new execution location.
668 next instruction will begin at trap_addr.
670 self
.TRAP(trap_addr
, trap_bit
)
671 self
.namespace
['NIA'] = self
.trap_nia
672 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
674 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
675 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
677 TRAP function is callable from inside the pseudocode itself,
678 hence the default arguments. when calling from inside ISACaller
679 it is best to use call_trap()
681 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
682 # store CIA(+4?) in SRR0, set NIA to 0x700
683 # store MSR in SRR1, set MSR to um errr something, have to check spec
684 # store SVSTATE (if enabled) in SVSRR0
685 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
686 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
687 if self
.is_svp64_mode
:
688 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
689 self
.trap_nia
= SelectableInt(trap_addr
, 64)
690 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
692 # set exception bits. TODO: this should, based on the address
693 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
694 # bits appropriately. however it turns out that *for now* in all
695 # cases (all trap_addrs) the exact same thing is needed.
696 self
.msr
[MSRb
.IR
] = 0
697 self
.msr
[MSRb
.DR
] = 0
698 self
.msr
[MSRb
.FE0
] = 0
699 self
.msr
[MSRb
.FE1
] = 0
700 self
.msr
[MSRb
.EE
] = 0
701 self
.msr
[MSRb
.RI
] = 0
702 self
.msr
[MSRb
.SF
] = 1
703 self
.msr
[MSRb
.TM
] = 0
704 self
.msr
[MSRb
.VEC
] = 0
705 self
.msr
[MSRb
.VSX
] = 0
706 self
.msr
[MSRb
.PR
] = 0
707 self
.msr
[MSRb
.FP
] = 0
708 self
.msr
[MSRb
.PMM
] = 0
709 self
.msr
[MSRb
.TEs
] = 0
710 self
.msr
[MSRb
.TEe
] = 0
711 self
.msr
[MSRb
.UND
] = 0
712 self
.msr
[MSRb
.LE
] = 1
714 def memassign(self
, ea
, sz
, val
):
715 self
.mem
.memassign(ea
, sz
, val
)
717 def prep_namespace(self
, formname
, op_fields
):
718 # TODO: get field names from form in decoder*1* (not decoder2)
719 # decoder2 is hand-created, and decoder1.sigform is auto-generated
721 # then "yield" fields only from op_fields rather than hard-coded
723 fields
= self
.decoder
.sigforms
[formname
]
724 log("prep_namespace", formname
, op_fields
)
725 for name
in op_fields
:
727 sig
= getattr(fields
, name
.upper())
729 sig
= getattr(fields
, name
)
731 # these are all opcode fields involved in index-selection of CR,
732 # and need to do "standard" arithmetic. CR[BA+32] for example
733 # would, if using SelectableInt, only be 5-bit.
734 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
735 self
.namespace
[name
] = val
737 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
739 self
.namespace
['XER'] = self
.spr
['XER']
740 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
741 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
743 # add some SVSTATE convenience variables
745 srcstep
= self
.svstate
.srcstep
746 self
.namespace
['VL'] = vl
747 self
.namespace
['srcstep'] = srcstep
749 def handle_carry_(self
, inputs
, outputs
, already_done
):
750 inv_a
= yield self
.dec2
.e
.do
.invert_in
752 inputs
[0] = ~inputs
[0]
754 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
756 imm
= yield self
.dec2
.e
.do
.imm_data
.data
757 inputs
.append(SelectableInt(imm
, 64))
758 assert len(outputs
) >= 1
759 log("outputs", repr(outputs
))
760 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
766 log("gt input", x
, output
)
767 gt
= (gtu(x
, output
))
770 cy
= 1 if any(gts
) else 0
772 if not (1 & already_done
):
773 self
.spr
['XER'][XER_bits
['CA']] = cy
775 log("inputs", already_done
, inputs
)
777 # ARGH... different for OP_ADD... *sigh*...
778 op
= yield self
.dec2
.e
.do
.insn_type
779 if op
== MicrOp
.OP_ADD
.value
:
780 res32
= (output
.value
& (1 << 32)) != 0
781 a32
= (inputs
[0].value
& (1 << 32)) != 0
783 b32
= (inputs
[1].value
& (1 << 32)) != 0
786 cy32
= res32 ^ a32 ^ b32
787 log("CA32 ADD", cy32
)
791 log("input", x
, output
)
792 log(" x[32:64]", x
, x
[32:64])
793 log(" o[32:64]", output
, output
[32:64])
794 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
796 cy32
= 1 if any(gts
) else 0
797 log("CA32", cy32
, gts
)
798 if not (2 & already_done
):
799 self
.spr
['XER'][XER_bits
['CA32']] = cy32
801 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
802 if hasattr(self
.dec2
.e
.do
, "invert_in"):
803 inv_a
= yield self
.dec2
.e
.do
.invert_in
805 inputs
[0] = ~inputs
[0]
807 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
809 imm
= yield self
.dec2
.e
.do
.imm_data
.data
810 inputs
.append(SelectableInt(imm
, 64))
811 assert len(outputs
) >= 1
812 log("handle_overflow", inputs
, outputs
, div_overflow
)
813 if len(inputs
) < 2 and div_overflow
is None:
816 # div overflow is different: it's returned by the pseudo-code
817 # because it's more complex than can be done by analysing the output
818 if div_overflow
is not None:
819 ov
, ov32
= div_overflow
, div_overflow
820 # arithmetic overflow can be done by analysing the input and output
821 elif len(inputs
) >= 2:
825 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
826 output_sgn
= exts(output
.value
, output
.bits
) < 0
827 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
828 output_sgn
!= input_sgn
[0] else 0
831 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
832 output32_sgn
= exts(output
.value
, 32) < 0
833 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
834 output32_sgn
!= input32_sgn
[0] else 0
836 self
.spr
['XER'][XER_bits
['OV']] = ov
837 self
.spr
['XER'][XER_bits
['OV32']] = ov32
838 so
= self
.spr
['XER'][XER_bits
['SO']]
840 self
.spr
['XER'][XER_bits
['SO']] = so
842 def handle_comparison(self
, outputs
, cr_idx
=0):
844 assert isinstance(out
, SelectableInt
), \
845 "out zero not a SelectableInt %s" % repr(outputs
)
846 log("handle_comparison", out
.bits
, hex(out
.value
))
847 # TODO - XXX *processor* in 32-bit mode
848 # https://bugs.libre-soc.org/show_bug.cgi?id=424
850 # o32 = exts(out.value, 32)
851 # print ("handle_comparison exts 32 bit", hex(o32))
852 out
= exts(out
.value
, out
.bits
)
853 log("handle_comparison exts", hex(out
))
854 zero
= SelectableInt(out
== 0, 1)
855 positive
= SelectableInt(out
> 0, 1)
856 negative
= SelectableInt(out
< 0, 1)
857 SO
= self
.spr
['XER'][XER_bits
['SO']]
858 log("handle_comparison SO", SO
)
859 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
860 self
.crl
[cr_idx
].eq(cr_field
)
862 def set_pc(self
, pc_val
):
863 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
864 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
866 def get_next_insn(self
):
870 pc
= self
.pc
.CIA
.value
873 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
875 raise KeyError("no instruction at 0x%x" % pc
)
879 """set up one instruction
881 pc
, insn
= self
.get_next_insn()
882 yield from self
.setup_next_insn(pc
, insn
)
884 def setup_next_insn(self
, pc
, ins
):
885 """set up next instruction
888 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
889 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
891 yield self
.dec2
.sv_rm
.eq(0)
892 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
893 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
894 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
895 yield self
.dec2
.state
.pc
.eq(pc
)
896 if self
.svstate
is not None:
897 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
899 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
901 opcode
= yield self
.dec2
.dec
.opcode_in
902 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
903 pfx
.insn
.value
= opcode
904 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
905 log ("prefix test: opcode:", major
, bin(major
),
906 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
907 self
.is_svp64_mode
= ((major
== 0b000001) and
908 pfx
.insn
[7].value
== 0b1 and
909 pfx
.insn
[9].value
== 0b1)
910 self
.pc
.update_nia(self
.is_svp64_mode
)
911 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
912 self
.namespace
['NIA'] = self
.pc
.NIA
913 self
.namespace
['SVSTATE'] = self
.svstate
914 if not self
.is_svp64_mode
:
917 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
918 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
919 log (" svstate.vl", self
.svstate
.vl
)
920 log (" svstate.mvl", self
.svstate
.maxvl
)
921 sv_rm
= pfx
.rm
.asint(msb0
=True)
922 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
923 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
924 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
925 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
928 def execute_one(self
):
929 """execute one instruction
931 # get the disassembly code for this instruction
932 if self
.is_svp64_mode
:
933 if not self
.disassembly
:
934 code
= yield from self
.get_assembly_name()
936 code
= self
.disassembly
[self
._pc
+4]
937 log(" svp64 sim-execute", hex(self
._pc
), code
)
939 if not self
.disassembly
:
940 code
= yield from self
.get_assembly_name()
942 code
= self
.disassembly
[self
._pc
]
943 log("sim-execute", hex(self
._pc
), code
)
944 opname
= code
.split(' ')[0]
946 yield from self
.call(opname
) # execute the instruction
947 except MemException
as e
: # check for memory errors
948 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
949 raise e
# ... re-raise
950 # run a Trap but set DAR first
951 print ("memory unaligned exception, DAR", e
.dar
)
952 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
953 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
956 # don't use this except in special circumstances
957 if not self
.respect_pc
:
960 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
962 def get_assembly_name(self
):
963 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
964 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
965 dec_insn
= yield self
.dec2
.e
.do
.insn
966 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
967 asmcode
= yield self
.dec2
.dec
.op
.asmcode
968 int_op
= yield self
.dec2
.dec
.op
.internal_op
969 log("get assembly name asmcode", asmcode
, int_op
,
970 hex(dec_insn
), bin(insn_1_11
))
971 asmop
= insns
.get(asmcode
, None)
973 # sigh reconstruct the assembly instruction name
974 if hasattr(self
.dec2
.e
.do
, "oe"):
975 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
976 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
980 if hasattr(self
.dec2
.e
.do
, "rc"):
981 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
982 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
986 # grrrr have to special-case MUL op (see DecodeOE)
987 log("ov %d en %d rc %d en %d op %d" %
988 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
989 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
994 if not asmop
.endswith("."): # don't add "." to "andis."
997 if hasattr(self
.dec2
.e
.do
, "lk"):
998 lk
= yield self
.dec2
.e
.do
.lk
1001 log("int_op", int_op
)
1002 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1003 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1007 spr_msb
= yield from self
.get_spr_msb()
1008 if int_op
== MicrOp
.OP_MFCR
.value
:
1013 # XXX TODO: for whatever weird reason this doesn't work
1014 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1015 if int_op
== MicrOp
.OP_MTCRF
.value
:
1022 def get_remap_indices(self
):
1023 # go through all iterators in lock-step, advance to next remap_idx
1024 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1025 # get four SVSHAPEs. here we are hard-coding
1026 SVSHAPE0
= self
.spr
['SVSHAPE0']
1027 SVSHAPE1
= self
.spr
['SVSHAPE1']
1028 SVSHAPE2
= self
.spr
['SVSHAPE2']
1029 SVSHAPE3
= self
.spr
['SVSHAPE3']
1030 # set up the iterators
1031 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1032 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1033 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1034 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1037 self
.remap_loopends
= [0] * 4
1038 self
.remap_idxs
= [0] * 4
1040 for i
, (shape
, remap
) in enumerate(remaps
):
1041 # zero is "disabled"
1042 if shape
.value
== 0x0:
1043 self
.remap_idxs
[i
] = 0
1044 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1045 step
= dststep
if (i
in [3, 4]) else srcstep
1046 # this is terrible. O(N^2) looking for the match. but hey.
1047 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1050 self
.remap_idxs
[i
] = remap_idx
1051 self
.remap_loopends
[i
] = loopends
1052 dbg
.append((i
, step
, remap_idx
, loopends
))
1053 for (i
, step
, remap_idx
, loopends
) in dbg
:
1054 log ("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1057 def get_spr_msb(self
):
1058 dec_insn
= yield self
.dec2
.e
.do
.insn
1059 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1061 def call(self
, name
):
1062 """call(opcode) - the primary execution point for instructions
1064 self
.last_st_addr
= None # reset the last known store address
1065 self
.last_ld_addr
= None # etc.
1067 ins_name
= name
.strip() # remove spaces if not already done so
1069 log("halted - not executing", ins_name
)
1072 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1073 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1074 asmop
= yield from self
.get_assembly_name()
1075 log("call", ins_name
, asmop
)
1078 int_op
= yield self
.dec2
.dec
.op
.internal_op
1079 spr_msb
= yield from self
.get_spr_msb()
1081 instr_is_privileged
= False
1082 if int_op
in [MicrOp
.OP_ATTN
.value
,
1083 MicrOp
.OP_MFMSR
.value
,
1084 MicrOp
.OP_MTMSR
.value
,
1085 MicrOp
.OP_MTMSRD
.value
,
1087 MicrOp
.OP_RFID
.value
]:
1088 instr_is_privileged
= True
1089 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1090 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1091 instr_is_privileged
= True
1093 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1095 # check MSR priv bit and whether op is privileged: if so, throw trap
1096 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1097 self
.call_trap(0x700, PIb
.PRIV
)
1100 # check halted condition
1101 if ins_name
== 'attn':
1105 # check illegal instruction
1107 if ins_name
not in ['mtcrf', 'mtocrf']:
1108 illegal
= ins_name
!= asmop
1110 # sigh deal with setvl not being supported by binutils (.long)
1111 if asmop
.startswith('setvl'):
1115 # and svremap not being supported by binutils (.long)
1116 if asmop
.startswith('svremap'):
1118 ins_name
= 'svremap'
1120 # and svshape not being supported by binutils (.long)
1121 if asmop
.startswith('svshape'):
1123 ins_name
= 'svshape'
1126 if asmop
== 'fsins':
1129 if asmop
== 'fcoss':
1133 # sigh also deal with ffmadds not being supported by binutils (.long)
1134 if asmop
== 'ffmadds':
1136 ins_name
= 'ffmadds'
1138 # and fdmadds not being supported by binutils (.long)
1139 if asmop
== 'fdmadds':
1141 ins_name
= 'fdmadds'
1143 # and ffadds not being supported by binutils (.long)
1144 if asmop
== 'ffadds':
1149 print("illegal", ins_name
, asmop
)
1150 self
.call_trap(0x700, PIb
.ILLEG
)
1151 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1152 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1155 # this is for setvl "Vertical" mode: if set true,
1156 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1157 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1158 self
.allow_next_step_inc
= False
1159 self
.svstate_next_mode
= 0
1161 # nop has to be supported, we could let the actual op calculate
1162 # but PowerDecoder has a pattern for nop
1163 if ins_name
is 'nop':
1164 self
.update_pc_next()
1167 info
= self
.instrs
[ins_name
]
1168 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1170 # preserve order of register names
1171 input_names
= create_args(list(info
.read_regs
) +
1172 list(info
.uninit_regs
))
1173 log("input names", input_names
)
1175 # get SVP64 entry for the current instruction
1176 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
1177 if sv_rm
is not None:
1178 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1180 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1181 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1183 # see if srcstep/dststep need skipping over masked-out predicate bits
1184 if (self
.is_svp64_mode
or ins_name
== 'setvl' or
1185 ins_name
.startswith("sv")):
1186 yield from self
.svstate_pre_inc()
1187 if self
.is_svp64_mode
:
1188 pre
= yield from self
.update_new_svstate_steps()
1190 self
.svp64_reset_loop()
1192 self
.update_pc_next()
1194 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1195 pred_dst_zero
= self
.pred_dst_zero
1196 pred_src_zero
= self
.pred_src_zero
1197 vl
= self
.svstate
.vl
1199 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1200 if self
.is_svp64_mode
and vl
== 0:
1201 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1202 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1203 self
.namespace
['NIA'])
1206 # for when SVREMAP is active, using pre-arranged schedule.
1207 # note: modifying PowerDecoder2 needs to "settle"
1208 remap_en
= self
.svstate
.SVme
1209 persist
= self
.svstate
.RMpst
1210 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
1211 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
1213 if persist
or self
.last_op_svshape
:
1214 remaps
= self
.get_remap_indices()
1215 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
1216 # just some convenient debug info
1218 sname
= 'SVSHAPE%d' % i
1219 shape
= self
.spr
[sname
]
1220 log (sname
, bin(shape
.value
))
1221 log (" lims", shape
.lims
)
1222 log (" mode", shape
.mode
)
1223 log (" skip", shape
.skip
)
1225 # set up the list of steps to remap
1226 mi0
= self
.svstate
.mi0
1227 mi1
= self
.svstate
.mi1
1228 mi2
= self
.svstate
.mi2
1229 mo0
= self
.svstate
.mo0
1230 mo1
= self
.svstate
.mo1
1231 steps
= [(self
.dec2
.in1_step
, mi0
), # RA
1232 (self
.dec2
.in2_step
, mi1
), # RB
1233 (self
.dec2
.in3_step
, mi2
), # RC
1234 (self
.dec2
.o_step
, mo0
), # RT
1235 (self
.dec2
.o2_step
, mo1
), # EA
1237 remap_idxs
= self
.remap_idxs
1239 # now cross-index the required SHAPE for each of 3-in 2-out regs
1240 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
1241 for i
, (dstep
, shape_idx
) in enumerate(steps
):
1242 (shape
, remap
) = remaps
[shape_idx
]
1243 remap_idx
= remap_idxs
[shape_idx
]
1244 # zero is "disabled"
1245 if shape
.value
== 0x0:
1247 # now set the actual requested step to the current index
1248 yield dstep
.eq(remap_idx
)
1250 # debug printout info
1251 rremaps
.append((shape
.mode
, i
, rnames
[i
], shape_idx
,
1254 log ("shape remap", x
)
1255 # after that, settle down (combinatorial) to let Vector reg numbers
1256 # work themselves out
1258 remap_active
= yield self
.dec2
.remap_active
1259 log ("remap active", bin(remap_active
))
1261 # main input registers (RT, RA ...)
1263 for name
in input_names
:
1264 # using PowerDecoder2, first, find the decoder index.
1265 # (mapping name RA RB RC RS to in1, in2, in3)
1266 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1268 # doing this is not part of svp64, it's because output
1269 # registers, to be modified, need to be in the namespace.
1270 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1272 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1275 # in case getting the register number is needed, _RA, _RB
1276 regname
= "_" + name
1277 self
.namespace
[regname
] = regnum
1278 if not self
.is_svp64_mode
or not pred_src_zero
:
1279 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1281 reg_val
= self
.fpr(regnum
)
1282 elif name
is not None:
1283 reg_val
= self
.gpr(regnum
)
1285 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1287 inputs
.append(reg_val
)
1288 # arrrrgh, awful hack, to get _RT into namespace
1289 if ins_name
== 'setvl':
1291 RT
= yield self
.dec2
.dec
.RT
1292 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1294 # in SVP64 mode for LD/ST work out immediate
1295 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1296 # use info.form to detect
1297 replace_d
= False # update / replace constant in pseudocode
1298 if self
.is_svp64_mode
:
1299 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1300 # bitreverse mode reads SVD (or SVDS - TODO)
1301 # *BUT*... because this is "overloading" of LD operations,
1302 # it gets *STORED* into D (or DS, TODO)
1303 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1304 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1305 imm
= exts(imm
, 11) # sign-extend to integer
1306 log ("bitrev SVD", imm
)
1309 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1310 imm
= exts(imm
, 16) # sign-extend to integer
1311 # get the right step. LD is from srcstep, ST is dststep
1312 op
= yield self
.dec2
.e
.do
.insn_type
1314 if op
== MicrOp
.OP_LOAD
.value
:
1316 log("D-field src", imm
, offsmul
)
1317 elif op
== MicrOp
.OP_STORE
.value
:
1319 log("D-field dst", imm
, offsmul
)
1321 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1322 # manually look up RC, sigh
1323 RC
= yield self
.dec2
.dec
.RC
[0:5]
1325 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1326 "rev", bin(bitrev(offsmul
, vl
)))
1327 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1328 # Unit-Strided LD/ST adds offset*width to immediate
1329 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1330 ldst_len
= yield self
.dec2
.e
.do
.data_len
1331 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1333 # Element-strided multiplies the immediate by element step
1334 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1335 imm
= SelectableInt(imm
* offsmul
, 32)
1337 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1338 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1339 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1340 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1343 self
.namespace
['D'] = imm
1345 # "special" registers
1346 for special
in info
.special_regs
:
1347 if special
in special_sprs
:
1348 inputs
.append(self
.spr
[special
])
1350 inputs
.append(self
.namespace
[special
])
1352 # clear trap (trap) NIA
1353 self
.trap_nia
= None
1355 # execute actual instruction here (finally)
1356 log("inputs", inputs
)
1357 results
= info
.func(self
, *inputs
)
1358 log("results", results
)
1360 # "inject" decorator takes namespace from function locals: we need to
1361 # overwrite NIA being overwritten (sigh)
1362 if self
.trap_nia
is not None:
1363 self
.namespace
['NIA'] = self
.trap_nia
1365 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1367 # check if op was a LD/ST so that debugging can check the
1369 if int_op
in [MicrOp
.OP_STORE
.value
,
1371 self
.last_st_addr
= self
.mem
.last_st_addr
1372 if int_op
in [MicrOp
.OP_LOAD
.value
,
1374 self
.last_ld_addr
= self
.mem
.last_ld_addr
1375 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1376 self
.last_st_addr
, self
.last_ld_addr
)
1378 # detect if CA/CA32 already in outputs (sra*, basically)
1381 output_names
= create_args(info
.write_regs
)
1382 for name
in output_names
:
1388 log("carry already done?", bin(already_done
))
1389 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1390 carry_en
= yield self
.dec2
.e
.do
.output_carry
1394 yield from self
.handle_carry_(inputs
, results
, already_done
)
1396 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1397 # detect if overflow was in return result
1400 for name
, output
in zip(output_names
, results
):
1401 if name
== 'overflow':
1404 if hasattr(self
.dec2
.e
.do
, "oe"):
1405 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1406 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1410 log("internal overflow", overflow
, ov_en
, ov_ok
)
1412 yield from self
.handle_overflow(inputs
, results
, overflow
)
1414 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1416 if not self
.is_svp64_mode
or not pred_dst_zero
:
1417 if hasattr(self
.dec2
.e
.do
, "rc"):
1418 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1420 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1421 self
.handle_comparison(results
, regnum
)
1423 # any modified return results?
1425 for name
, output
in zip(output_names
, results
):
1426 if name
== 'overflow': # ignore, done already (above)
1428 if isinstance(output
, int):
1429 output
= SelectableInt(output
, 256)
1430 if name
in ['CA', 'CA32']:
1432 log("writing %s to XER" % name
, output
)
1433 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1435 log("NOT writing %s to XER" % name
, output
)
1436 elif name
in info
.special_regs
:
1437 log('writing special %s' % name
, output
, special_sprs
)
1438 if name
in special_sprs
:
1439 self
.spr
[name
] = output
1441 self
.namespace
[name
].eq(output
)
1443 log('msr written', hex(self
.msr
.value
))
1445 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1448 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1451 # temporary hack for not having 2nd output
1452 regnum
= yield getattr(self
.decoder
, name
)
1454 if self
.is_svp64_mode
and pred_dst_zero
:
1455 log('zeroing reg %d %s' % (regnum
, str(output
)),
1457 output
= SelectableInt(0, 256)
1463 log('writing %s %s %s' % (ftype
, regnum
, str(output
)),
1465 if output
.bits
> 64:
1466 output
= SelectableInt(output
.value
, 64)
1468 self
.fpr
[regnum
] = output
1470 self
.gpr
[regnum
] = output
1472 # check if it is the SVSTATE.src/dest step that needs incrementing
1473 # this is our Sub-Program-Counter loop from 0 to VL-1
1476 if self
.allow_next_step_inc
:
1477 log("SVSTATE_NEXT: inc requested, mode", self
.svstate_next_mode
)
1478 yield from self
.svstate_pre_inc()
1479 pre
= yield from self
.update_new_svstate_steps()
1481 # reset at end of loop including exit Vertical Mode
1482 log ("SVSTATE_NEXT: end of loop, reset")
1483 self
.svp64_reset_loop()
1484 self
.svstate
.vfirst
= 0
1487 results
= [SelectableInt(0, 64)]
1488 self
.handle_comparison(results
) # CR0
1490 log ("SVSTATE_NEXT: post-inc")
1491 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1492 remaps
= self
.get_remap_indices()
1493 remap_idxs
= self
.remap_idxs
1494 vl
= self
.svstate
.vl
1495 end_src
= srcstep
== vl
-1
1496 end_dst
= dststep
== vl
-1
1498 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1500 self
.svstate
.dststep
+= SelectableInt(1, 7)
1501 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1502 # set CR0 (if Rc=1) based on end
1504 srcstep
= self
.svstate
.srcstep
1505 dststep
= self
.svstate
.srcstep
1506 endtest
= 1 if (end_src
or end_dst
) else 0
1507 #results = [SelectableInt(endtest, 64)]
1508 #self.handle_comparison(results) # CR0
1510 # see if svstep was requested, if so, which SVSTATE
1512 if self
.svstate_next_mode
> 0:
1513 shape_idx
= self
.svstate_next_mode
.value
-1
1514 endings
= self
.remap_loopends
[shape_idx
]
1515 cr_field
= SelectableInt((~endings
)<<1 | endtest
, 4)
1516 print ("svstep Rc=1, CR0", cr_field
)
1517 self
.crl
[0].eq(cr_field
) # CR0
1518 if end_src
or end_dst
:
1519 # reset at end of loop including exit Vertical Mode
1520 log ("SVSTATE_NEXT: after increments, reset")
1521 self
.svp64_reset_loop()
1522 self
.svstate
.vfirst
= 0
1524 elif self
.is_svp64_mode
:
1525 yield from self
.svstate_post_inc()
1527 # XXX only in non-SVP64 mode!
1528 # record state of whether the current operation was an svshape,
1529 # to be able to know if it should apply in the next instruction.
1530 # also (if going to use this instruction) should disable ability
1531 # to interrupt in between. sigh.
1532 self
.last_op_svshape
= asmop
== 'svremap'
1534 self
.update_pc_next()
1536 def SVSTATE_NEXT(self
, mode
):
1537 """explicitly moves srcstep/dststep on to next element, for
1538 "Vertical-First" mode. this function is called from
1539 setvl pseudo-code, as a pseudo-op "svstep"
1541 log("SVSTATE_NEXT mode", mode
)
1542 self
.allow_next_step_inc
= True
1543 self
.svstate_next_mode
= mode
1544 if self
.svstate_next_mode
> 0:
1545 shape_idx
= self
.svstate_next_mode
.value
-1
1546 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
1547 return SelectableInt(0, 7)
1549 def svstate_pre_inc(self
):
1550 """check if srcstep/dststep need to skip over masked-out predicate bits
1552 # get SVSTATE VL (oh and print out some debug stuff)
1553 vl
= self
.svstate
.vl
1554 srcstep
= self
.svstate
.srcstep
1555 dststep
= self
.svstate
.dststep
1556 sv_a_nz
= yield self
.dec2
.sv_a_nz
1557 fft_mode
= yield self
.dec2
.use_svp64_fft
1558 in1
= yield self
.dec2
.e
.read_reg1
.data
1559 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1560 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1562 # get predicate mask
1563 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1565 pmode
= yield self
.dec2
.rm_dec
.predmode
1566 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1567 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1568 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1569 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1570 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1571 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1572 if pmode
== SVP64PredMode
.INT
.value
:
1573 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1574 if sv_ptype
== SVPtype
.P2
.value
:
1575 srcmask
= get_predint(self
.gpr
, srcpred
)
1576 elif pmode
== SVP64PredMode
.CR
.value
:
1577 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1578 if sv_ptype
== SVPtype
.P2
.value
:
1579 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1580 log (" pmode", pmode
)
1581 log (" reverse", reverse_gear
)
1582 log (" ptype", sv_ptype
)
1583 log (" srcpred", bin(srcpred
))
1584 log (" dstpred", bin(dstpred
))
1585 log (" srcmask", bin(srcmask
))
1586 log (" dstmask", bin(dstmask
))
1587 log (" pred_sz", bin(pred_src_zero
))
1588 log (" pred_dz", bin(pred_dst_zero
))
1590 # okaaay, so here we simply advance srcstep (TODO dststep)
1591 # until the predicate mask has a "1" bit... or we run out of VL
1592 # let srcstep==VL be the indicator to move to next instruction
1593 if not pred_src_zero
:
1594 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1595 log (" skip", bin(1<<srcstep
))
1598 if not pred_dst_zero
:
1599 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1600 log (" skip", bin(1<<dststep
))
1603 # now work out if the relevant mask bits require zeroing
1605 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1607 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1609 # store new srcstep / dststep
1610 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1611 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1612 log (" new srcstep", srcstep
)
1613 log (" new dststep", dststep
)
1615 def update_new_svstate_steps(self
):
1616 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1618 # update SVSTATE with new srcstep
1619 self
.svstate
.srcstep
= srcstep
1620 self
.svstate
.dststep
= dststep
1621 self
.namespace
['SVSTATE'] = self
.svstate
1622 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1623 yield Settle() # let decoder update
1624 srcstep
= self
.svstate
.srcstep
1625 dststep
= self
.svstate
.dststep
1626 vl
= self
.svstate
.vl
1627 log (" srcstep", srcstep
)
1628 log (" dststep", dststep
)
1631 # check if end reached (we let srcstep overrun, above)
1632 # nothing needs doing (TODO zeroing): just do next instruction
1633 return srcstep
== vl
or dststep
== vl
1635 def svstate_post_inc(self
, vf
=0):
1636 # check if SV "Vertical First" mode is enabled
1637 vfirst
= self
.svstate
.vfirst
1638 log (" SV Vertical First", vf
, vfirst
)
1639 if not vf
and vfirst
== 1:
1643 # check if it is the SVSTATE.src/dest step that needs incrementing
1644 # this is our Sub-Program-Counter loop from 0 to VL-1
1645 # XXX twin predication TODO
1646 vl
= self
.svstate
.vl
1647 mvl
= self
.svstate
.maxvl
1648 srcstep
= self
.svstate
.srcstep
1649 dststep
= self
.svstate
.dststep
1650 rm_mode
= yield self
.dec2
.rm_dec
.mode
1651 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1652 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1653 out_vec
= not (yield self
.dec2
.no_out_vec
)
1654 in_vec
= not (yield self
.dec2
.no_in_vec
)
1655 log (" svstate.vl", vl
)
1656 log (" svstate.mvl", mvl
)
1657 log (" svstate.srcstep", srcstep
)
1658 log (" svstate.dststep", dststep
)
1659 log (" mode", rm_mode
)
1660 log (" reverse", reverse_gear
)
1661 log (" out_vec", out_vec
)
1662 log (" in_vec", in_vec
)
1663 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1664 # check if srcstep needs incrementing by one, stop PC advancing
1665 # svp64 loop can end early if the dest is scalar for single-pred
1666 # but for 2-pred both src/dest have to be checked.
1667 # XXX this might not be true! it may just be LD/ST
1668 if sv_ptype
== SVPtype
.P2
.value
:
1669 svp64_is_vector
= (out_vec
or in_vec
)
1671 svp64_is_vector
= out_vec
1672 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1673 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1674 self
.svstate
.dststep
+= SelectableInt(1, 7)
1675 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1676 self
.namespace
['NIA'] = self
.pc
.NIA
1677 self
.namespace
['SVSTATE'] = self
.svstate
1678 log("end of sub-pc call", self
.namespace
['CIA'],
1679 self
.namespace
['NIA'])
1680 return False # DO NOT allow PC update whilst Sub-PC loop running
1682 # reset loop to zero and update NIA
1683 self
.svp64_reset_loop()
1688 def update_pc_next(self
):
1689 # UPDATE program counter
1690 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1691 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1692 log("end of call", self
.namespace
['CIA'],
1693 self
.namespace
['NIA'],
1694 self
.namespace
['SVSTATE'])
1696 def svp64_reset_loop(self
):
1697 self
.svstate
.srcstep
= 0
1698 self
.svstate
.dststep
= 0
1699 log (" svstate.srcstep loop end (PC to update)")
1700 self
.namespace
['SVSTATE'] = self
.svstate
1702 def update_nia(self
):
1703 self
.pc
.update_nia(self
.is_svp64_mode
)
1704 self
.namespace
['NIA'] = self
.pc
.NIA
1707 """Decorator factory.
1709 this decorator will "inject" variables into the function's namespace,
1710 from the *dictionary* in self.namespace. it therefore becomes possible
1711 to make it look like a whole stack of variables which would otherwise
1712 need "self." inserted in front of them (*and* for those variables to be
1713 added to the instance) "appear" in the function.
1715 "self.namespace['SI']" for example becomes accessible as just "SI" but
1716 *only* inside the function, when decorated.
1718 def variable_injector(func
):
1720 def decorator(*args
, **kwargs
):
1722 func_globals
= func
.__globals
__ # Python 2.6+
1723 except AttributeError:
1724 func_globals
= func
.func_globals
# Earlier versions.
1726 context
= args
[0].namespace
# variables to be injected
1727 saved_values
= func_globals
.copy() # Shallow copy of dict.
1728 log("globals before", context
.keys())
1729 func_globals
.update(context
)
1730 result
= func(*args
, **kwargs
)
1731 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1732 log("args[0]", args
[0].namespace
['CIA'],
1733 args
[0].namespace
['NIA'],
1734 args
[0].namespace
['SVSTATE'])
1735 args
[0].namespace
= func_globals
1736 #exec (func.__code__, func_globals)
1739 # func_globals = saved_values # Undo changes.
1745 return variable_injector