1 # SPDX-License-Identifier: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020 Michael Nolan
4 # Funded by NLnet http://nlnet.nl
5 """core of the python-based POWER9 simulator
7 this is part of a cycle-accurate POWER9 simulator. its primary purpose is
8 not speed, it is for both learning and educational purposes, as well as
9 a method of verifying the HDL.
13 * https://bugs.libre-soc.org/show_bug.cgi?id=424
16 from nmigen
.back
.pysim
import Settle
17 from functools
import wraps
19 from openpower
.decoder
.orderedset
import OrderedSet
20 from openpower
.decoder
.selectable_int
import (FieldSelectableInt
, SelectableInt
,
22 from openpower
.decoder
.power_enums
import (spr_dict
, spr_byname
, XER_bits
,
23 insns
, MicrOp
, In1Sel
, In2Sel
, In3Sel
,
24 OutSel
, CROutSel
, LDSTMode
,
25 SVP64RMMode
, SVP64PredMode
,
26 SVP64PredInt
, SVP64PredCR
,
29 from openpower
.decoder
.power_enums
import SVPtype
31 from openpower
.decoder
.helpers
import (exts
, gtu
, ltu
, undefined
, bitrev
)
32 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
33 from openpower
.consts
import SVP64CROffs
34 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
36 from openpower
.decoder
.isa
.radixmmu
import RADIX
37 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
38 from openpower
.decoder
.isa
.svshape
import SVSHAPE
40 from openpower
.util
import log
42 from collections
import namedtuple
46 instruction_info
= namedtuple('instruction_info',
47 'func read_regs uninit_regs write_regs ' +
48 'special_regs op_fields form asmregs')
59 # TODO (lkcl): adjust other registers that should be in a particular order
60 # probably CA, CA32, and CR
86 "overflow": 7, # should definitely be last
89 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
92 def create_args(reglist
, extra
=None):
93 retval
= list(OrderedSet(reglist
))
94 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
96 return [extra
] + retval
102 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
105 self
.isacaller
= isacaller
106 self
.svstate
= svstate
107 for i
in range(len(regfile
)):
108 self
[i
] = SelectableInt(regfile
[i
], 64)
110 def __call__(self
, ridx
):
111 if isinstance(ridx
, SelectableInt
):
115 def set_form(self
, form
):
118 def __setitem__(self
, rnum
, value
):
119 # rnum = rnum.value # only SelectableInt allowed
120 log("GPR setitem", rnum
, value
)
121 if isinstance(rnum
, SelectableInt
):
123 dict.__setitem
__(self
, rnum
, value
)
125 def getz(self
, rnum
):
126 # rnum = rnum.value # only SelectableInt allowed
127 log("GPR getzero?", rnum
)
129 return SelectableInt(0, 64)
132 def _get_regnum(self
, attr
):
133 getform
= self
.sd
.sigforms
[self
.form
]
134 rnum
= getattr(getform
, attr
)
137 def ___getitem__(self
, attr
):
138 """ XXX currently not used
140 rnum
= self
._get
_regnum
(attr
)
141 log("GPR getitem", attr
, rnum
)
142 return self
.regfile
[rnum
]
144 def dump(self
, printout
=True):
146 for i
in range(len(self
)):
147 res
.append(self
[i
].value
)
149 for i
in range(0, len(res
), 8):
152 s
.append("%08x" % res
[i
+j
])
154 print("reg", "%2d" % i
, s
)
159 def __init__(self
, dec2
, initial_sprs
={}):
162 for key
, v
in initial_sprs
.items():
163 if isinstance(key
, SelectableInt
):
165 key
= special_sprs
.get(key
, key
)
166 if isinstance(key
, int):
169 info
= spr_byname
[key
]
170 if not isinstance(v
, SelectableInt
):
171 v
= SelectableInt(v
, info
.length
)
174 def __getitem__(self
, key
):
176 log("dict", self
.items())
177 # if key in special_sprs get the special spr, otherwise return key
178 if isinstance(key
, SelectableInt
):
180 if isinstance(key
, int):
181 key
= spr_dict
[key
].SPR
182 key
= special_sprs
.get(key
, key
)
183 if key
== 'HSRR0': # HACK!
185 if key
== 'HSRR1': # HACK!
188 res
= dict.__getitem
__(self
, key
)
190 if isinstance(key
, int):
193 info
= spr_byname
[key
]
194 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
195 res
= dict.__getitem
__(self
, key
)
196 log("spr returning", key
, res
)
199 def __setitem__(self
, key
, value
):
200 if isinstance(key
, SelectableInt
):
202 if isinstance(key
, int):
203 key
= spr_dict
[key
].SPR
205 key
= special_sprs
.get(key
, key
)
206 if key
== 'HSRR0': # HACK!
207 self
.__setitem
__('SRR0', value
)
208 if key
== 'HSRR1': # HACK!
209 self
.__setitem
__('SRR1', value
)
210 log("setting spr", key
, value
)
211 dict.__setitem
__(self
, key
, value
)
213 def __call__(self
, ridx
):
216 def dump(self
, printout
=True):
218 keys
= list(self
.keys())
221 sprname
= spr_dict
.get(k
, None)
225 sprname
= sprname
.SPR
226 res
.append((sprname
, self
[k
].value
))
228 for sprname
, value
in res
:
229 print(" ", sprname
, hex(value
))
234 def __init__(self
, pc_init
=0):
235 self
.CIA
= SelectableInt(pc_init
, 64)
236 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
238 def update_nia(self
, is_svp64
):
239 increment
= 8 if is_svp64
else 4
240 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
242 def update(self
, namespace
, is_svp64
):
243 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
245 self
.CIA
= namespace
['NIA'].narrow(64)
246 self
.update_nia(is_svp64
)
247 namespace
['CIA'] = self
.CIA
248 namespace
['NIA'] = self
.NIA
251 # Simple-V: see https://libre-soc.org/openpower/sv
253 def __init__(self
, init
=0):
254 self
.spr
= SelectableInt(init
, 32)
255 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
256 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
257 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
258 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
259 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
260 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
261 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
266 def __init__(self
, init
=0):
267 self
.spr
= SelectableInt(init
, 24)
268 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
269 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
270 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
271 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
272 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
273 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
274 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
275 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
276 # these cover the same extra field, split into parts as EXTRA2
277 self
.extra2
= list(range(4))
278 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
279 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
280 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
281 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
282 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
283 # and here as well, but EXTRA3
284 self
.extra3
= list(range(3))
285 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
286 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
287 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
290 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
291 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
292 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
293 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
294 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
295 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
296 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
297 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
298 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
301 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
302 class SVP64PrefixFields
:
304 self
.insn
= SelectableInt(0, 32)
305 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
306 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
307 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
308 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
309 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
312 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
313 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
314 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
318 # See PowerISA Version 3.0 B Book 1
319 # Section 2.3.1 Condition Register pages 30 - 31
321 LT
= FL
= 0 # negative, less than, floating-point less than
322 GT
= FG
= 1 # positive, greater than, floating-point greater than
323 EQ
= FE
= 2 # equal, floating-point equal
324 SO
= FU
= 3 # summary overflow, floating-point unordered
326 def __init__(self
, init
=0):
327 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
328 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
329 self
.cr
= SelectableInt(init
, 64) # underlying reg
330 # field-selectable versions of Condition Register TODO check bitranges?
333 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
334 _cr
= FieldSelectableInt(self
.cr
, bits
)
337 # decode SVP64 predicate integer to reg number and invert
338 def get_predint(gpr
, mask
):
341 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
342 if mask
== SVP64PredInt
.ALWAYS
.value
:
343 return 0xffff_ffff_ffff_ffff
344 if mask
== SVP64PredInt
.R3_UNARY
.value
:
345 return 1 << (gpr(3).value
& 0b111111)
346 if mask
== SVP64PredInt
.R3
.value
:
348 if mask
== SVP64PredInt
.R3_N
.value
:
350 if mask
== SVP64PredInt
.R10
.value
:
352 if mask
== SVP64PredInt
.R10_N
.value
:
353 return ~
gpr(10).value
354 if mask
== SVP64PredInt
.R30
.value
:
356 if mask
== SVP64PredInt
.R30_N
.value
:
357 return ~
gpr(30).value
359 # decode SVP64 predicate CR to reg number and invert status
360 def _get_predcr(mask
):
361 if mask
== SVP64PredCR
.LT
.value
:
363 if mask
== SVP64PredCR
.GE
.value
:
365 if mask
== SVP64PredCR
.GT
.value
:
367 if mask
== SVP64PredCR
.LE
.value
:
369 if mask
== SVP64PredCR
.EQ
.value
:
371 if mask
== SVP64PredCR
.NE
.value
:
373 if mask
== SVP64PredCR
.SO
.value
:
375 if mask
== SVP64PredCR
.NS
.value
:
378 # read individual CR fields (0..VL-1), extract the required bit
379 # and construct the mask
380 def get_predcr(crl
, mask
, vl
):
381 idx
, noninv
= _get_predcr(mask
)
384 cr
= crl
[i
+SVP64CROffs
.CRPred
]
385 if cr
[idx
].value
== noninv
:
390 # TODO, really should just be using PowerDecoder2
391 def get_pdecode_idx_in(dec2
, name
):
393 in1_sel
= yield op
.in1_sel
394 in2_sel
= yield op
.in2_sel
395 in3_sel
= yield op
.in3_sel
396 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
397 in1
= yield dec2
.e
.read_reg1
.data
398 in2
= yield dec2
.e
.read_reg2
.data
399 in3
= yield dec2
.e
.read_reg3
.data
400 in1_isvec
= yield dec2
.in1_isvec
401 in2_isvec
= yield dec2
.in2_isvec
402 in3_isvec
= yield dec2
.in3_isvec
403 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
405 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
407 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
409 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
411 log ("get_pdecode_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
413 log ("get_pdecode_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
415 # identify which regnames map to in1/2/3
417 if (in1_sel
== In1Sel
.RA
.value
or
418 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
419 return in1
, in1_isvec
420 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
421 return in1
, in1_isvec
423 if in2_sel
== In2Sel
.RB
.value
:
424 return in2
, in2_isvec
425 if in3_sel
== In3Sel
.RB
.value
:
426 return in3
, in3_isvec
427 # XXX TODO, RC doesn't exist yet!
429 assert False, "RC does not exist yet"
431 if in1_sel
== In1Sel
.RS
.value
:
432 return in1
, in1_isvec
433 if in2_sel
== In2Sel
.RS
.value
:
434 return in2
, in2_isvec
435 if in3_sel
== In3Sel
.RS
.value
:
436 return in3
, in3_isvec
438 if in1_sel
== In1Sel
.FRA
.value
:
439 return in1
, in1_isvec
441 if in2_sel
== In2Sel
.FRB
.value
:
442 return in2
, in2_isvec
444 if in3_sel
== In3Sel
.FRC
.value
:
445 return in3
, in3_isvec
447 if in1_sel
== In1Sel
.FRS
.value
:
448 return in1
, in1_isvec
449 if in3_sel
== In3Sel
.FRS
.value
:
450 return in3
, in3_isvec
454 # TODO, really should just be using PowerDecoder2
455 def get_pdecode_cr_out(dec2
, name
):
457 out_sel
= yield op
.cr_out
458 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
459 sv_cr_out
= yield op
.sv_cr_out
460 spec
= yield dec2
.crout_svdec
.spec
461 sv_override
= yield dec2
.dec_cr_out
.sv_override
462 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
463 out
= yield dec2
.e
.write_cr
.data
464 o_isvec
= yield dec2
.o_isvec
465 log ("get_pdecode_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
466 log (" sv_cr_out", sv_cr_out
)
467 log (" cr_bf", out_bitfield
)
469 log (" override", sv_override
)
470 # identify which regnames map to out / o2
472 if out_sel
== CROutSel
.CR0
.value
:
474 log ("get_pdecode_cr_out not found", name
)
478 # TODO, really should just be using PowerDecoder2
479 def get_pdecode_idx_out(dec2
, name
):
481 out_sel
= yield op
.out_sel
482 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
483 out
= yield dec2
.e
.write_reg
.data
484 o_isvec
= yield dec2
.o_isvec
485 # identify which regnames map to out / o2
487 log ("get_pdecode_idx_out", out_sel
, OutSel
.RA
.value
, out
, o_isvec
)
488 if out_sel
== OutSel
.RA
.value
:
491 log ("get_pdecode_idx_out", out_sel
, OutSel
.RT
.value
,
492 OutSel
.RT_OR_ZERO
.value
, out
, o_isvec
,
494 if out_sel
== OutSel
.RT
.value
:
497 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
498 if out_sel
== OutSel
.FRA
.value
:
501 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
502 OutSel
.FRT
.value
, out
, o_isvec
)
503 if out_sel
== OutSel
.FRT
.value
:
505 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
509 # TODO, really should just be using PowerDecoder2
510 def get_pdecode_idx_out2(dec2
, name
):
511 # check first if register is activated for write
513 out_sel
= yield op
.out_sel
514 out
= yield dec2
.e
.write_ea
.data
515 o_isvec
= yield dec2
.o2_isvec
516 out_ok
= yield dec2
.e
.write_ea
.ok
517 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
522 if hasattr(op
, "upd"):
523 # update mode LD/ST uses read-reg A also as an output
525 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
526 out_sel
, OutSel
.RA
.value
,
528 if upd
== LDSTMode
.update
.value
:
531 int_op
= yield dec2
.dec
.op
.internal_op
532 fft_en
= yield dec2
.use_svp64_fft
533 #if int_op == MicrOp.OP_FP_MADD.value and fft_en:
535 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
542 # decoder2 - an instance of power_decoder2
543 # regfile - a list of initial values for the registers
544 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
545 # respect_pc - tracks the program counter. requires initial_insns
546 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
547 initial_mem
=None, initial_msr
=0,
558 self
.bigendian
= bigendian
560 self
.is_svp64_mode
= False
561 self
.respect_pc
= respect_pc
562 if initial_sprs
is None:
564 if initial_mem
is None:
566 if fpregfile
is None:
568 if initial_insns
is None:
570 assert self
.respect_pc
== False, "instructions required to honor pc"
572 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
573 log("ISACaller initial_msr", initial_msr
)
575 # "fake program counter" mode (for unit testing)
579 if isinstance(initial_mem
, tuple):
580 self
.fake_pc
= initial_mem
[0]
581 disasm_start
= self
.fake_pc
583 disasm_start
= initial_pc
585 # disassembly: we need this for now (not given from the decoder)
586 self
.disassembly
= {}
588 for i
, code
in enumerate(disassembly
):
589 self
.disassembly
[i
*4 + disasm_start
] = code
591 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
592 self
.svp64rm
= SVP64RM()
593 if initial_svstate
is None:
595 if isinstance(initial_svstate
, int):
596 initial_svstate
= SVP64State(initial_svstate
)
597 # SVSTATE, MSR and PC
598 self
.svstate
= initial_svstate
599 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
601 # GPR FPR SPR registers
602 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
603 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
604 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
606 # set up 4 dummy SVSHAPEs if they aren't already set up
608 sname
= 'SVSHAPE%d' % i
609 if sname
not in self
.spr
:
610 self
.spr
[sname
] = SVSHAPE(0)
612 # make sure it's an SVSHAPE
613 val
= self
.spr
[sname
].value
614 self
.spr
[sname
] = SVSHAPE(val
)
615 self
.last_op_svshape
= False
618 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
619 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
620 # MMU mode, redirect underlying Mem through RADIX
622 self
.mem
= RADIX(self
.mem
, self
)
624 self
.imem
= RADIX(self
.imem
, self
)
627 # FPR (same as GPR except for FP nums)
628 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
629 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
630 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
631 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
633 # 2.3.2 LR (actually SPR #8) -- Done
634 # 2.3.3 CTR (actually SPR #9) -- Done
635 # 2.3.4 TAR (actually SPR #815)
636 # 3.2.2 p45 XER (actually SPR #1) -- Done
637 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
639 # create CR then allow portions of it to be "selectable" (below)
640 self
.cr_fields
= CRFields(initial_cr
)
641 self
.cr
= self
.cr_fields
.cr
643 # "undefined", just set to variable-bit-width int (use exts "max")
644 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
647 self
.namespace
.update(self
.spr
)
648 self
.namespace
.update({'GPR': self
.gpr
,
652 'memassign': self
.memassign
,
655 'SVSTATE': self
.svstate
.spr
,
656 'SVSHAPE0': self
.spr
['SVSHAPE0'],
657 'SVSHAPE1': self
.spr
['SVSHAPE1'],
658 'SVSHAPE2': self
.spr
['SVSHAPE2'],
659 'SVSHAPE3': self
.spr
['SVSHAPE3'],
662 'undefined': undefined
,
663 'mode_is_64bit': True,
667 # update pc to requested start point
668 self
.set_pc(initial_pc
)
670 # field-selectable versions of Condition Register
671 self
.crl
= self
.cr_fields
.crl
673 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
675 self
.decoder
= decoder2
.dec
678 def call_trap(self
, trap_addr
, trap_bit
):
679 """calls TRAP and sets up NIA to the new execution location.
680 next instruction will begin at trap_addr.
682 self
.TRAP(trap_addr
, trap_bit
)
683 self
.namespace
['NIA'] = self
.trap_nia
684 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
686 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
687 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
689 TRAP function is callable from inside the pseudocode itself,
690 hence the default arguments. when calling from inside ISACaller
691 it is best to use call_trap()
693 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
694 # store CIA(+4?) in SRR0, set NIA to 0x700
695 # store MSR in SRR1, set MSR to um errr something, have to check spec
696 # store SVSTATE (if enabled) in SVSRR0
697 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
698 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
699 if self
.is_svp64_mode
:
700 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
701 self
.trap_nia
= SelectableInt(trap_addr
, 64)
702 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
704 # set exception bits. TODO: this should, based on the address
705 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
706 # bits appropriately. however it turns out that *for now* in all
707 # cases (all trap_addrs) the exact same thing is needed.
708 self
.msr
[MSRb
.IR
] = 0
709 self
.msr
[MSRb
.DR
] = 0
710 self
.msr
[MSRb
.FE0
] = 0
711 self
.msr
[MSRb
.FE1
] = 0
712 self
.msr
[MSRb
.EE
] = 0
713 self
.msr
[MSRb
.RI
] = 0
714 self
.msr
[MSRb
.SF
] = 1
715 self
.msr
[MSRb
.TM
] = 0
716 self
.msr
[MSRb
.VEC
] = 0
717 self
.msr
[MSRb
.VSX
] = 0
718 self
.msr
[MSRb
.PR
] = 0
719 self
.msr
[MSRb
.FP
] = 0
720 self
.msr
[MSRb
.PMM
] = 0
721 self
.msr
[MSRb
.TEs
] = 0
722 self
.msr
[MSRb
.TEe
] = 0
723 self
.msr
[MSRb
.UND
] = 0
724 self
.msr
[MSRb
.LE
] = 1
726 def memassign(self
, ea
, sz
, val
):
727 self
.mem
.memassign(ea
, sz
, val
)
729 def prep_namespace(self
, formname
, op_fields
):
730 # TODO: get field names from form in decoder*1* (not decoder2)
731 # decoder2 is hand-created, and decoder1.sigform is auto-generated
733 # then "yield" fields only from op_fields rather than hard-coded
735 fields
= self
.decoder
.sigforms
[formname
]
736 for name
in op_fields
:
738 sig
= getattr(fields
, name
.upper())
740 sig
= getattr(fields
, name
)
742 # these are all opcode fields involved in index-selection of CR,
743 # and need to do "standard" arithmetic. CR[BA+32] for example
744 # would, if using SelectableInt, only be 5-bit.
745 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
746 self
.namespace
[name
] = val
748 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
750 self
.namespace
['XER'] = self
.spr
['XER']
751 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
752 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
754 # add some SVSTATE convenience variables
755 vl
= self
.svstate
.vl
.asint(msb0
=True)
756 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
757 self
.namespace
['VL'] = vl
758 self
.namespace
['srcstep'] = srcstep
760 def handle_carry_(self
, inputs
, outputs
, already_done
):
761 inv_a
= yield self
.dec2
.e
.do
.invert_in
763 inputs
[0] = ~inputs
[0]
765 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
767 imm
= yield self
.dec2
.e
.do
.imm_data
.data
768 inputs
.append(SelectableInt(imm
, 64))
769 assert len(outputs
) >= 1
770 log("outputs", repr(outputs
))
771 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
777 log("gt input", x
, output
)
778 gt
= (gtu(x
, output
))
781 cy
= 1 if any(gts
) else 0
783 if not (1 & already_done
):
784 self
.spr
['XER'][XER_bits
['CA']] = cy
786 log("inputs", already_done
, inputs
)
788 # ARGH... different for OP_ADD... *sigh*...
789 op
= yield self
.dec2
.e
.do
.insn_type
790 if op
== MicrOp
.OP_ADD
.value
:
791 res32
= (output
.value
& (1 << 32)) != 0
792 a32
= (inputs
[0].value
& (1 << 32)) != 0
794 b32
= (inputs
[1].value
& (1 << 32)) != 0
797 cy32
= res32 ^ a32 ^ b32
798 log("CA32 ADD", cy32
)
802 log("input", x
, output
)
803 log(" x[32:64]", x
, x
[32:64])
804 log(" o[32:64]", output
, output
[32:64])
805 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
807 cy32
= 1 if any(gts
) else 0
808 log("CA32", cy32
, gts
)
809 if not (2 & already_done
):
810 self
.spr
['XER'][XER_bits
['CA32']] = cy32
812 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
813 if hasattr(self
.dec2
.e
.do
, "invert_in"):
814 inv_a
= yield self
.dec2
.e
.do
.invert_in
816 inputs
[0] = ~inputs
[0]
818 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
820 imm
= yield self
.dec2
.e
.do
.imm_data
.data
821 inputs
.append(SelectableInt(imm
, 64))
822 assert len(outputs
) >= 1
823 log("handle_overflow", inputs
, outputs
, div_overflow
)
824 if len(inputs
) < 2 and div_overflow
is None:
827 # div overflow is different: it's returned by the pseudo-code
828 # because it's more complex than can be done by analysing the output
829 if div_overflow
is not None:
830 ov
, ov32
= div_overflow
, div_overflow
831 # arithmetic overflow can be done by analysing the input and output
832 elif len(inputs
) >= 2:
836 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
837 output_sgn
= exts(output
.value
, output
.bits
) < 0
838 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
839 output_sgn
!= input_sgn
[0] else 0
842 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
843 output32_sgn
= exts(output
.value
, 32) < 0
844 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
845 output32_sgn
!= input32_sgn
[0] else 0
847 self
.spr
['XER'][XER_bits
['OV']] = ov
848 self
.spr
['XER'][XER_bits
['OV32']] = ov32
849 so
= self
.spr
['XER'][XER_bits
['SO']]
851 self
.spr
['XER'][XER_bits
['SO']] = so
853 def handle_comparison(self
, outputs
, cr_idx
=0):
855 assert isinstance(out
, SelectableInt
), \
856 "out zero not a SelectableInt %s" % repr(outputs
)
857 log("handle_comparison", out
.bits
, hex(out
.value
))
858 # TODO - XXX *processor* in 32-bit mode
859 # https://bugs.libre-soc.org/show_bug.cgi?id=424
861 # o32 = exts(out.value, 32)
862 # print ("handle_comparison exts 32 bit", hex(o32))
863 out
= exts(out
.value
, out
.bits
)
864 log("handle_comparison exts", hex(out
))
865 zero
= SelectableInt(out
== 0, 1)
866 positive
= SelectableInt(out
> 0, 1)
867 negative
= SelectableInt(out
< 0, 1)
868 SO
= self
.spr
['XER'][XER_bits
['SO']]
869 log("handle_comparison SO", SO
)
870 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
871 self
.crl
[cr_idx
].eq(cr_field
)
873 def set_pc(self
, pc_val
):
874 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
875 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
877 def get_next_insn(self
):
881 pc
= self
.pc
.CIA
.value
884 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
886 raise KeyError("no instruction at 0x%x" % pc
)
890 """set up one instruction
892 pc
, insn
= self
.get_next_insn()
893 yield from self
.setup_next_insn(pc
, insn
)
895 def setup_next_insn(self
, pc
, ins
):
896 """set up next instruction
899 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
900 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
902 yield self
.dec2
.sv_rm
.eq(0)
903 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
904 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
905 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
906 yield self
.dec2
.state
.pc
.eq(pc
)
907 if self
.svstate
is not None:
908 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
910 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
912 opcode
= yield self
.dec2
.dec
.opcode_in
913 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
914 pfx
.insn
.value
= opcode
915 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
916 log ("prefix test: opcode:", major
, bin(major
),
917 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
918 self
.is_svp64_mode
= ((major
== 0b000001) and
919 pfx
.insn
[7].value
== 0b1 and
920 pfx
.insn
[9].value
== 0b1)
921 self
.pc
.update_nia(self
.is_svp64_mode
)
922 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
923 self
.namespace
['NIA'] = self
.pc
.NIA
924 self
.namespace
['SVSTATE'] = self
.svstate
.spr
925 if not self
.is_svp64_mode
:
928 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
929 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
930 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
931 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
932 sv_rm
= pfx
.rm
.asint(msb0
=True)
933 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
934 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
935 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
936 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
939 def execute_one(self
):
940 """execute one instruction
942 # get the disassembly code for this instruction
943 if self
.is_svp64_mode
:
944 if not self
.disassembly
:
945 code
= yield from self
.get_assembly_name()
947 code
= self
.disassembly
[self
._pc
+4]
948 log(" svp64 sim-execute", hex(self
._pc
), code
)
950 if not self
.disassembly
:
951 code
= yield from self
.get_assembly_name()
953 code
= self
.disassembly
[self
._pc
]
954 log("sim-execute", hex(self
._pc
), code
)
955 opname
= code
.split(' ')[0]
957 yield from self
.call(opname
) # execute the instruction
958 except MemException
as e
: # check for memory errors
959 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
960 raise e
# ... re-raise
961 # run a Trap but set DAR first
962 print ("memory unaligned exception, DAR", e
.dar
)
963 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
964 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
967 # don't use this except in special circumstances
968 if not self
.respect_pc
:
971 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
973 def get_assembly_name(self
):
974 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
975 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
976 dec_insn
= yield self
.dec2
.e
.do
.insn
977 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
978 asmcode
= yield self
.dec2
.dec
.op
.asmcode
979 int_op
= yield self
.dec2
.dec
.op
.internal_op
980 log("get assembly name asmcode", asmcode
, int_op
,
981 hex(dec_insn
), bin(insn_1_11
))
982 asmop
= insns
.get(asmcode
, None)
984 # sigh reconstruct the assembly instruction name
985 if hasattr(self
.dec2
.e
.do
, "oe"):
986 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
987 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
991 if hasattr(self
.dec2
.e
.do
, "rc"):
992 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
993 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
997 # grrrr have to special-case MUL op (see DecodeOE)
998 log("ov %d en %d rc %d en %d op %d" %
999 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1000 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1005 if not asmop
.endswith("."): # don't add "." to "andis."
1008 if hasattr(self
.dec2
.e
.do
, "lk"):
1009 lk
= yield self
.dec2
.e
.do
.lk
1012 log("int_op", int_op
)
1013 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1014 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1018 spr_msb
= yield from self
.get_spr_msb()
1019 if int_op
== MicrOp
.OP_MFCR
.value
:
1024 # XXX TODO: for whatever weird reason this doesn't work
1025 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1026 if int_op
== MicrOp
.OP_MTCRF
.value
:
1033 def get_spr_msb(self
):
1034 dec_insn
= yield self
.dec2
.e
.do
.insn
1035 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1037 def call(self
, name
):
1038 """call(opcode) - the primary execution point for instructions
1040 self
.last_st_addr
= None # reset the last known store address
1041 self
.last_ld_addr
= None # etc.
1043 name
= name
.strip() # remove spaces if not already done so
1045 log("halted - not executing", name
)
1048 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1049 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1050 asmop
= yield from self
.get_assembly_name()
1051 log("call", name
, asmop
)
1054 int_op
= yield self
.dec2
.dec
.op
.internal_op
1055 spr_msb
= yield from self
.get_spr_msb()
1057 instr_is_privileged
= False
1058 if int_op
in [MicrOp
.OP_ATTN
.value
,
1059 MicrOp
.OP_MFMSR
.value
,
1060 MicrOp
.OP_MTMSR
.value
,
1061 MicrOp
.OP_MTMSRD
.value
,
1063 MicrOp
.OP_RFID
.value
]:
1064 instr_is_privileged
= True
1065 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1066 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1067 instr_is_privileged
= True
1069 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1071 # check MSR priv bit and whether op is privileged: if so, throw trap
1072 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1073 self
.call_trap(0x700, PIb
.PRIV
)
1076 # check halted condition
1081 # check illegal instruction
1083 if name
not in ['mtcrf', 'mtocrf']:
1084 illegal
= name
!= asmop
1086 # sigh deal with setvl not being supported by binutils (.long)
1087 if asmop
.startswith('setvl'):
1091 # and svshape not being supported by binutils (.long)
1092 if asmop
.startswith('svshape'):
1096 # sigh also deal with ffmadds not being supported by binutils (.long)
1097 if asmop
== 'ffmadds':
1101 # and ffadds not being supported by binutils (.long)
1102 if asmop
== 'ffadds':
1107 print("illegal", name
, asmop
)
1108 self
.call_trap(0x700, PIb
.ILLEG
)
1109 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1110 (name
, asmop
, self
.pc
.CIA
.value
))
1113 # this is for setvl "Vertical" mode: if set true,
1114 # srcstep/dststep is explicitly advanced
1115 self
.allow_next_step_inc
= False
1117 # nop has to be supported, we could let the actual op calculate
1118 # but PowerDecoder has a pattern for nop
1120 self
.update_pc_next()
1123 info
= self
.instrs
[name
]
1124 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1126 # preserve order of register names
1127 input_names
= create_args(list(info
.read_regs
) +
1128 list(info
.uninit_regs
))
1131 # get SVP64 entry for the current instruction
1132 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1133 if sv_rm
is not None:
1134 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1136 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1137 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1139 # see if srcstep/dststep need skipping over masked-out predicate bits
1140 if self
.is_svp64_mode
:
1141 yield from self
.svstate_pre_inc()
1142 pre
= yield from self
.update_new_svstate_steps()
1144 self
.svp64_reset_loop()
1146 self
.update_pc_next()
1148 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1149 pred_dst_zero
= self
.pred_dst_zero
1150 pred_src_zero
= self
.pred_src_zero
1151 vl
= self
.svstate
.vl
.asint(msb0
=True)
1153 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1154 if self
.is_svp64_mode
and vl
== 0:
1155 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1156 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1157 self
.namespace
['NIA'])
1160 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1161 # using pre-arranged schedule. all of this is awful but it is a
1162 # start. next job will be to put the proper activation in place
1163 yield self
.dec2
.remap_active
.eq(1 if self
.last_op_svshape
else 0)
1165 if self
.is_svp64_mode
and self
.last_op_svshape
:
1166 # get four SVSHAPEs. here we are hard-coding
1167 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1168 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1169 SVSHAPE0
= self
.spr
['SVSHAPE0']
1170 SVSHAPE1
= self
.spr
['SVSHAPE1']
1171 SVSHAPE2
= self
.spr
['SVSHAPE2']
1172 SVSHAPE3
= self
.spr
['SVSHAPE3']
1174 sname
= 'SVSHAPE%d' % i
1175 shape
= self
.spr
[sname
]
1176 print (sname
, bin(shape
.value
))
1177 print (" lims", shape
.lims
)
1178 print (" mode", shape
.mode
)
1179 print (" skip", shape
.skip
)
1181 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1182 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1183 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1184 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1187 for i
, (shape
, remap
) in enumerate(remaps
):
1188 # zero is "disabled"
1189 if shape
.value
== 0x0:
1191 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1192 if shape
.mode
== 0b00: # multiply mode
1193 step
= dststep
if (i
== 0) else srcstep
1194 if shape
.mode
== 0b01: # FFT butterfly mode
1195 step
= srcstep
# XXX HACK - for now only use srcstep
1196 # this is terrible. O(N^2) looking for the match. but hey.
1197 for idx
, remap_idx
in enumerate(remap
):
1201 if shape
.mode
== 0b00:
1203 yield self
.dec2
.o_step
.eq(remap_idx
) # RT
1204 yield self
.dec2
.o2_step
.eq(remap_idx
) # EA
1206 yield self
.dec2
.in1_step
.eq(remap_idx
) # RA
1208 yield self
.dec2
.in3_step
.eq(remap_idx
) # RB
1210 yield self
.dec2
.in2_step
.eq(remap_idx
) # RC
1211 # FFT butterfly mode
1212 if shape
.mode
== 0b01:
1214 yield self
.dec2
.o_step
.eq(remap_idx
) # RT
1215 yield self
.dec2
.in2_step
.eq(remap_idx
) # RB
1217 yield self
.dec2
.in1_step
.eq(remap_idx
) # RA
1218 yield self
.dec2
.o2_step
.eq(remap_idx
) # EA (FRS)
1220 yield self
.dec2
.in3_step
.eq(remap_idx
) # RC
1223 rremaps
.append((shape
.mode
, i
, idx
, remap_idx
)) # debug printing
1225 print ("shape remap", x
)
1226 # after that, settle down (combinatorial) to let Vector reg numbers
1227 # work themselves out
1229 remap_active
= yield self
.dec2
.remap_active
1230 print ("remap active", remap_active
)
1232 # main input registers (RT, RA ...)
1234 for name
in input_names
:
1235 # using PowerDecoder2, first, find the decoder index.
1236 # (mapping name RA RB RC RS to in1, in2, in3)
1237 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1239 # doing this is not part of svp64, it's because output
1240 # registers, to be modified, need to be in the namespace.
1241 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1243 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1246 # in case getting the register number is needed, _RA, _RB
1247 regname
= "_" + name
1248 self
.namespace
[regname
] = regnum
1249 if not self
.is_svp64_mode
or not pred_src_zero
:
1250 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1252 reg_val
= self
.fpr(regnum
)
1253 elif name
is not None:
1254 reg_val
= self
.gpr(regnum
)
1256 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1258 inputs
.append(reg_val
)
1259 # arrrrgh, awful hack, to get _RT into namespace
1260 if asmop
== 'setvl':
1262 RT
= yield self
.dec2
.dec
.RT
1263 self
.namespace
[regname
] = SelectableInt(RT
, 5)
1265 # in SVP64 mode for LD/ST work out immediate
1266 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1267 # use info.form to detect
1268 replace_d
= False # update / replace constant in pseudocode
1269 if self
.is_svp64_mode
:
1270 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1271 # bitreverse mode reads SVD (or SVDS - TODO)
1272 # *BUT*... because this is "overloading" of LD operations,
1273 # it gets *STORED* into D (or DS, TODO)
1274 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1275 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1276 imm
= exts(imm
, 11) # sign-extend to integer
1277 print ("bitrev SVD", imm
)
1280 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1281 imm
= exts(imm
, 16) # sign-extend to integer
1282 # get the right step. LD is from srcstep, ST is dststep
1283 op
= yield self
.dec2
.e
.do
.insn_type
1285 if op
== MicrOp
.OP_LOAD
.value
:
1287 log("D-field src", imm
, offsmul
)
1288 elif op
== MicrOp
.OP_STORE
.value
:
1290 log("D-field dst", imm
, offsmul
)
1292 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1293 # manually look up RC, sigh
1294 RC
= yield self
.dec2
.dec
.RC
[0:5]
1296 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1297 "rev", bin(bitrev(offsmul
, vl
)))
1298 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1299 # Unit-Strided LD/ST adds offset*width to immediate
1300 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1301 ldst_len
= yield self
.dec2
.e
.do
.data_len
1302 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1304 # Element-strided multiplies the immediate by element step
1305 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1306 imm
= SelectableInt(imm
* offsmul
, 32)
1308 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1309 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1310 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1311 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1314 self
.namespace
['D'] = imm
1316 # "special" registers
1317 for special
in info
.special_regs
:
1318 if special
in special_sprs
:
1319 inputs
.append(self
.spr
[special
])
1321 inputs
.append(self
.namespace
[special
])
1323 # clear trap (trap) NIA
1324 self
.trap_nia
= None
1326 # execute actual instruction here (finally)
1327 log("inputs", inputs
)
1328 results
= info
.func(self
, *inputs
)
1329 log("results", results
)
1331 # "inject" decorator takes namespace from function locals: we need to
1332 # overwrite NIA being overwritten (sigh)
1333 if self
.trap_nia
is not None:
1334 self
.namespace
['NIA'] = self
.trap_nia
1336 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1338 # check if op was a LD/ST so that debugging can check the
1340 if int_op
in [MicrOp
.OP_STORE
.value
,
1342 self
.last_st_addr
= self
.mem
.last_st_addr
1343 if int_op
in [MicrOp
.OP_LOAD
.value
,
1345 self
.last_ld_addr
= self
.mem
.last_ld_addr
1346 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1347 self
.last_st_addr
, self
.last_ld_addr
)
1349 # detect if CA/CA32 already in outputs (sra*, basically)
1352 output_names
= create_args(info
.write_regs
)
1353 for name
in output_names
:
1359 log("carry already done?", bin(already_done
))
1360 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1361 carry_en
= yield self
.dec2
.e
.do
.output_carry
1365 yield from self
.handle_carry_(inputs
, results
, already_done
)
1367 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1368 # detect if overflow was in return result
1371 for name
, output
in zip(output_names
, results
):
1372 if name
== 'overflow':
1375 if hasattr(self
.dec2
.e
.do
, "oe"):
1376 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1377 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1381 log("internal overflow", overflow
, ov_en
, ov_ok
)
1383 yield from self
.handle_overflow(inputs
, results
, overflow
)
1385 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1387 if not self
.is_svp64_mode
or not pred_dst_zero
:
1388 if hasattr(self
.dec2
.e
.do
, "rc"):
1389 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1391 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1392 self
.handle_comparison(results
, regnum
)
1394 # any modified return results?
1396 for name
, output
in zip(output_names
, results
):
1397 if name
== 'overflow': # ignore, done already (above)
1399 if isinstance(output
, int):
1400 output
= SelectableInt(output
, 256)
1401 if name
in ['CA', 'CA32']:
1403 log("writing %s to XER" % name
, output
)
1404 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1406 log("NOT writing %s to XER" % name
, output
)
1407 elif name
in info
.special_regs
:
1408 log('writing special %s' % name
, output
, special_sprs
)
1409 if name
in special_sprs
:
1410 self
.spr
[name
] = output
1412 self
.namespace
[name
].eq(output
)
1414 log('msr written', hex(self
.msr
.value
))
1416 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1419 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1422 # temporary hack for not having 2nd output
1423 regnum
= yield getattr(self
.decoder
, name
)
1425 if self
.is_svp64_mode
and pred_dst_zero
:
1426 log('zeroing reg %d %s' % (regnum
, str(output
)),
1428 output
= SelectableInt(0, 256)
1434 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1436 if output
.bits
> 64:
1437 output
= SelectableInt(output
.value
, 64)
1439 self
.fpr
[regnum
] = output
1441 self
.gpr
[regnum
] = output
1443 # check if it is the SVSTATE.src/dest step that needs incrementing
1444 # this is our Sub-Program-Counter loop from 0 to VL-1
1447 if self
.allow_next_step_inc
:
1448 log("SVSTATE_NEXT: inc requested")
1449 yield from self
.svstate_pre_inc()
1450 pre
= yield from self
.update_new_svstate_steps()
1452 # reset at end of loop including exit Vertical Mode
1453 log ("SVSTATE_NEXT: end of loop, reset")
1454 self
.svp64_reset_loop()
1455 self
.msr
[MSRb
.SVF
] = 0
1458 results
= [SelectableInt(0, 64)]
1459 self
.handle_comparison(results
) # CR0
1461 log ("SVSTATE_NEXT: post-inc")
1462 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1463 vl
= self
.svstate
.vl
.asint(msb0
=True)
1464 end_src
= srcstep
== vl
-1
1465 end_dst
= dststep
== vl
-1
1467 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1469 self
.svstate
.dststep
+= SelectableInt(1, 7)
1470 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1471 # set CR0 (if Rc=1) based on end
1473 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1474 dststep
= self
.svstate
.srcstep
.asint(msb0
=True)
1475 endtest
= 0 if (end_src
or end_dst
) else 1
1476 results
= [SelectableInt(endtest
, 64)]
1477 self
.handle_comparison(results
) # CR0
1478 if end_src
or end_dst
:
1479 # reset at end of loop including exit Vertical Mode
1480 log ("SVSTATE_NEXT: after increments, reset")
1481 self
.svp64_reset_loop()
1482 self
.msr
[MSRb
.SVF
] = 0
1484 elif self
.is_svp64_mode
:
1485 yield from self
.svstate_post_inc()
1487 # XXX only in non-SVP64 mode!
1488 # record state of whether the current operation was an svshape,
1489 # to be able to know if it should apply in the next instruction.
1490 # also (if going to use this instruction) should disable ability
1491 # to interrupt in between. sigh.
1492 self
.last_op_svshape
= asmop
== 'svshape'
1494 self
.update_pc_next()
1496 def SVSTATE_NEXT(self
):
1497 """explicitly moves srcstep/dststep on to next element, for
1498 "Vertical-First" mode. this function is called from
1499 setvl pseudo-code, as a pseudo-op "svstep"
1502 self
.allow_next_step_inc
= True
1504 def svstate_pre_inc(self
):
1505 """check if srcstep/dststep need to skip over masked-out predicate bits
1507 # get SVSTATE VL (oh and print out some debug stuff)
1508 vl
= self
.svstate
.vl
.asint(msb0
=True)
1509 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1510 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1511 sv_a_nz
= yield self
.dec2
.sv_a_nz
1512 fft_mode
= yield self
.dec2
.use_svp64_fft
1513 in1
= yield self
.dec2
.e
.read_reg1
.data
1514 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1515 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1517 # get predicate mask
1518 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1520 pmode
= yield self
.dec2
.rm_dec
.predmode
1521 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1522 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1523 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1524 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1525 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1526 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1527 if pmode
== SVP64PredMode
.INT
.value
:
1528 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1529 if sv_ptype
== SVPtype
.P2
.value
:
1530 srcmask
= get_predint(self
.gpr
, srcpred
)
1531 elif pmode
== SVP64PredMode
.CR
.value
:
1532 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1533 if sv_ptype
== SVPtype
.P2
.value
:
1534 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1535 log (" pmode", pmode
)
1536 log (" reverse", reverse_gear
)
1537 log (" ptype", sv_ptype
)
1538 log (" srcpred", bin(srcpred
))
1539 log (" dstpred", bin(dstpred
))
1540 log (" srcmask", bin(srcmask
))
1541 log (" dstmask", bin(dstmask
))
1542 log (" pred_sz", bin(pred_src_zero
))
1543 log (" pred_dz", bin(pred_dst_zero
))
1545 # okaaay, so here we simply advance srcstep (TODO dststep)
1546 # until the predicate mask has a "1" bit... or we run out of VL
1547 # let srcstep==VL be the indicator to move to next instruction
1548 if not pred_src_zero
:
1549 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1550 log (" skip", bin(1<<srcstep
))
1553 if not pred_dst_zero
:
1554 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1555 log (" skip", bin(1<<dststep
))
1558 # now work out if the relevant mask bits require zeroing
1560 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1562 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1564 # store new srcstep / dststep
1565 self
.new_srcstep
, self
.new_dststep
= srcstep
, dststep
1566 self
.pred_dst_zero
, self
.pred_src_zero
= pred_dst_zero
, pred_src_zero
1567 log (" new srcstep", srcstep
)
1568 log (" new dststep", dststep
)
1570 def update_new_svstate_steps(self
):
1571 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
1573 # update SVSTATE with new srcstep
1574 self
.svstate
.srcstep
[0:7] = srcstep
1575 self
.svstate
.dststep
[0:7] = dststep
1576 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1577 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1578 yield Settle() # let decoder update
1579 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1580 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1581 vl
= self
.svstate
.vl
.asint(msb0
=True)
1582 log (" srcstep", srcstep
)
1583 log (" dststep", dststep
)
1585 # check if end reached (we let srcstep overrun, above)
1586 # nothing needs doing (TODO zeroing): just do next instruction
1587 return srcstep
== vl
or dststep
== vl
1589 def svstate_post_inc(self
, vf
=0):
1590 # check if SV "Vertical First" mode is enabled
1591 log (" SV Vertical First", vf
, self
.msr
[MSRb
.SVF
].value
)
1592 if not vf
and self
.msr
[MSRb
.SVF
].value
== 1:
1596 # check if it is the SVSTATE.src/dest step that needs incrementing
1597 # this is our Sub-Program-Counter loop from 0 to VL-1
1598 # XXX twin predication TODO
1599 vl
= self
.svstate
.vl
.asint(msb0
=True)
1600 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1601 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1602 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1603 rm_mode
= yield self
.dec2
.rm_dec
.mode
1604 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1605 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1606 out_vec
= not (yield self
.dec2
.no_out_vec
)
1607 in_vec
= not (yield self
.dec2
.no_in_vec
)
1608 log (" svstate.vl", vl
)
1609 log (" svstate.mvl", mvl
)
1610 log (" svstate.srcstep", srcstep
)
1611 log (" svstate.dststep", dststep
)
1612 log (" mode", rm_mode
)
1613 log (" reverse", reverse_gear
)
1614 log (" out_vec", out_vec
)
1615 log (" in_vec", in_vec
)
1616 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1617 # check if srcstep needs incrementing by one, stop PC advancing
1618 # svp64 loop can end early if the dest is scalar for single-pred
1619 # but for 2-pred both src/dest have to be checked.
1620 # XXX this might not be true! it may just be LD/ST
1621 if sv_ptype
== SVPtype
.P2
.value
:
1622 svp64_is_vector
= (out_vec
or in_vec
)
1624 svp64_is_vector
= out_vec
1625 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1626 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1627 self
.svstate
.dststep
+= SelectableInt(1, 7)
1628 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1629 self
.namespace
['NIA'] = self
.pc
.NIA
1630 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1631 log("end of sub-pc call", self
.namespace
['CIA'],
1632 self
.namespace
['NIA'])
1633 return False # DO NOT allow PC update whilst Sub-PC loop running
1635 # reset loop to zero and update NIA
1636 self
.svp64_reset_loop()
1641 def update_pc_next(self
):
1642 # UPDATE program counter
1643 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1644 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1645 log("end of call", self
.namespace
['CIA'],
1646 self
.namespace
['NIA'],
1647 self
.namespace
['SVSTATE'])
1649 def svp64_reset_loop(self
):
1650 self
.svstate
.srcstep
[0:7] = 0
1651 self
.svstate
.dststep
[0:7] = 0
1652 log (" svstate.srcstep loop end (PC to update)")
1653 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1655 def update_nia(self
):
1656 self
.pc
.update_nia(self
.is_svp64_mode
)
1657 self
.namespace
['NIA'] = self
.pc
.NIA
1660 """Decorator factory.
1662 this decorator will "inject" variables into the function's namespace,
1663 from the *dictionary* in self.namespace. it therefore becomes possible
1664 to make it look like a whole stack of variables which would otherwise
1665 need "self." inserted in front of them (*and* for those variables to be
1666 added to the instance) "appear" in the function.
1668 "self.namespace['SI']" for example becomes accessible as just "SI" but
1669 *only* inside the function, when decorated.
1671 def variable_injector(func
):
1673 def decorator(*args
, **kwargs
):
1675 func_globals
= func
.__globals
__ # Python 2.6+
1676 except AttributeError:
1677 func_globals
= func
.func_globals
# Earlier versions.
1679 context
= args
[0].namespace
# variables to be injected
1680 saved_values
= func_globals
.copy() # Shallow copy of dict.
1681 func_globals
.update(context
)
1682 result
= func(*args
, **kwargs
)
1683 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1684 log("args[0]", args
[0].namespace
['CIA'],
1685 args
[0].namespace
['NIA'],
1686 args
[0].namespace
['SVSTATE'])
1687 args
[0].namespace
= func_globals
1688 #exec (func.__code__, func_globals)
1691 # func_globals = saved_values # Undo changes.
1697 return variable_injector