1ee2b51aa52a2807067565162cfa67b91e3ae1b4
1 # SPDX-License-Identifier: LGPLv3+
2 # Copyright (C) 2020, 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Copyright (C) 2020 Michael Nolan
4 # Funded by NLnet http://nlnet.nl
5 """core of the python-based POWER9 simulator
7 this is part of a cycle-accurate POWER9 simulator. its primary purpose is
8 not speed, it is for both learning and educational purposes, as well as
9 a method of verifying the HDL.
13 * https://bugs.libre-soc.org/show_bug.cgi?id=424
16 from nmigen
.back
.pysim
import Settle
17 from functools
import wraps
19 from openpower
.decoder
.orderedset
import OrderedSet
20 from openpower
.decoder
.selectable_int
import (FieldSelectableInt
, SelectableInt
,
22 from openpower
.decoder
.power_enums
import (spr_dict
, spr_byname
, XER_bits
,
23 insns
, MicrOp
, In1Sel
, In2Sel
, In3Sel
,
24 OutSel
, CROutSel
, LDSTMode
,
25 SVP64RMMode
, SVP64PredMode
,
26 SVP64PredInt
, SVP64PredCR
,
29 from openpower
.decoder
.power_enums
import SVPtype
31 from openpower
.decoder
.helpers
import (exts
, gtu
, ltu
, undefined
, bitrev
)
32 from openpower
.consts
import PIb
, MSRb
# big-endian (PowerISA versions)
33 from openpower
.consts
import SVP64CROffs
34 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
36 from openpower
.decoder
.isa
.radixmmu
import RADIX
37 from openpower
.decoder
.isa
.mem
import Mem
, swap_order
, MemException
38 from openpower
.decoder
.isa
.svshape
import SVSHAPE
40 from openpower
.util
import log
42 from collections
import namedtuple
46 instruction_info
= namedtuple('instruction_info',
47 'func read_regs uninit_regs write_regs ' +
48 'special_regs op_fields form asmregs')
59 # TODO (lkcl): adjust other registers that should be in a particular order
60 # probably CA, CA32, and CR
85 "overflow": 7, # should definitely be last
88 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
91 def create_args(reglist
, extra
=None):
92 retval
= list(OrderedSet(reglist
))
93 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
95 return [extra
] + retval
101 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
104 self
.isacaller
= isacaller
105 self
.svstate
= svstate
106 for i
in range(len(regfile
)):
107 self
[i
] = SelectableInt(regfile
[i
], 64)
109 def __call__(self
, ridx
):
112 def set_form(self
, form
):
115 def getz(self
, rnum
):
116 # rnum = rnum.value # only SelectableInt allowed
117 log("GPR getzero?", rnum
)
119 return SelectableInt(0, 64)
122 def _get_regnum(self
, attr
):
123 getform
= self
.sd
.sigforms
[self
.form
]
124 rnum
= getattr(getform
, attr
)
127 def ___getitem__(self
, attr
):
128 """ XXX currently not used
130 rnum
= self
._get
_regnum
(attr
)
131 log("GPR getitem", attr
, rnum
)
132 return self
.regfile
[rnum
]
134 def dump(self
, printout
=True):
136 for i
in range(len(self
)):
137 res
.append(self
[i
].value
)
139 for i
in range(0, len(res
), 8):
142 s
.append("%08x" % res
[i
+j
])
144 print("reg", "%2d" % i
, s
)
149 def __init__(self
, dec2
, initial_sprs
={}):
152 for key
, v
in initial_sprs
.items():
153 if isinstance(key
, SelectableInt
):
155 key
= special_sprs
.get(key
, key
)
156 if isinstance(key
, int):
159 info
= spr_byname
[key
]
160 if not isinstance(v
, SelectableInt
):
161 v
= SelectableInt(v
, info
.length
)
164 def __getitem__(self
, key
):
166 log("dict", self
.items())
167 # if key in special_sprs get the special spr, otherwise return key
168 if isinstance(key
, SelectableInt
):
170 if isinstance(key
, int):
171 key
= spr_dict
[key
].SPR
172 key
= special_sprs
.get(key
, key
)
173 if key
== 'HSRR0': # HACK!
175 if key
== 'HSRR1': # HACK!
178 res
= dict.__getitem
__(self
, key
)
180 if isinstance(key
, int):
183 info
= spr_byname
[key
]
184 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
185 res
= dict.__getitem
__(self
, key
)
186 log("spr returning", key
, res
)
189 def __setitem__(self
, key
, value
):
190 if isinstance(key
, SelectableInt
):
192 if isinstance(key
, int):
193 key
= spr_dict
[key
].SPR
195 key
= special_sprs
.get(key
, key
)
196 if key
== 'HSRR0': # HACK!
197 self
.__setitem
__('SRR0', value
)
198 if key
== 'HSRR1': # HACK!
199 self
.__setitem
__('SRR1', value
)
200 log("setting spr", key
, value
)
201 dict.__setitem
__(self
, key
, value
)
203 def __call__(self
, ridx
):
206 def dump(self
, printout
=True):
208 keys
= list(self
.keys())
211 sprname
= spr_dict
.get(k
, None)
215 sprname
= sprname
.SPR
216 res
.append((sprname
, self
[k
].value
))
218 for sprname
, value
in res
:
219 print(" ", sprname
, hex(value
))
224 def __init__(self
, pc_init
=0):
225 self
.CIA
= SelectableInt(pc_init
, 64)
226 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
228 def update_nia(self
, is_svp64
):
229 increment
= 8 if is_svp64
else 4
230 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
232 def update(self
, namespace
, is_svp64
):
233 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
235 self
.CIA
= namespace
['NIA'].narrow(64)
236 self
.update_nia(is_svp64
)
237 namespace
['CIA'] = self
.CIA
238 namespace
['NIA'] = self
.NIA
241 # Simple-V: see https://libre-soc.org/openpower/sv
243 def __init__(self
, init
=0):
244 self
.spr
= SelectableInt(init
, 32)
245 # fields of SVSTATE, see https://libre-soc.org/openpower/sv/sprs/
246 self
.maxvl
= FieldSelectableInt(self
.spr
, tuple(range(0,7)))
247 self
.vl
= FieldSelectableInt(self
.spr
, tuple(range(7,14)))
248 self
.srcstep
= FieldSelectableInt(self
.spr
, tuple(range(14,21)))
249 self
.dststep
= FieldSelectableInt(self
.spr
, tuple(range(21,28)))
250 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(28,30)))
251 self
.svstep
= FieldSelectableInt(self
.spr
, tuple(range(30,32)))
256 def __init__(self
, init
=0):
257 self
.spr
= SelectableInt(init
, 24)
258 # SVP64 RM fields: see https://libre-soc.org/openpower/sv/svp64/
259 self
.mmode
= FieldSelectableInt(self
.spr
, [0])
260 self
.mask
= FieldSelectableInt(self
.spr
, tuple(range(1,4)))
261 self
.elwidth
= FieldSelectableInt(self
.spr
, tuple(range(4,6)))
262 self
.ewsrc
= FieldSelectableInt(self
.spr
, tuple(range(6,8)))
263 self
.subvl
= FieldSelectableInt(self
.spr
, tuple(range(8,10)))
264 self
.extra
= FieldSelectableInt(self
.spr
, tuple(range(10,19)))
265 self
.mode
= FieldSelectableInt(self
.spr
, tuple(range(19,24)))
266 # these cover the same extra field, split into parts as EXTRA2
267 self
.extra2
= list(range(4))
268 self
.extra2
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,12)))
269 self
.extra2
[1] = FieldSelectableInt(self
.spr
, tuple(range(12,14)))
270 self
.extra2
[2] = FieldSelectableInt(self
.spr
, tuple(range(14,16)))
271 self
.extra2
[3] = FieldSelectableInt(self
.spr
, tuple(range(16,18)))
272 self
.smask
= FieldSelectableInt(self
.spr
, tuple(range(16,19)))
273 # and here as well, but EXTRA3
274 self
.extra3
= list(range(3))
275 self
.extra3
[0] = FieldSelectableInt(self
.spr
, tuple(range(10,13)))
276 self
.extra3
[1] = FieldSelectableInt(self
.spr
, tuple(range(13,16)))
277 self
.extra3
[2] = FieldSelectableInt(self
.spr
, tuple(range(16,19)))
280 SVP64RM_MMODE_SIZE
= len(SVP64RMFields().mmode
.br
)
281 SVP64RM_MASK_SIZE
= len(SVP64RMFields().mask
.br
)
282 SVP64RM_ELWIDTH_SIZE
= len(SVP64RMFields().elwidth
.br
)
283 SVP64RM_EWSRC_SIZE
= len(SVP64RMFields().ewsrc
.br
)
284 SVP64RM_SUBVL_SIZE
= len(SVP64RMFields().subvl
.br
)
285 SVP64RM_EXTRA2_SPEC_SIZE
= len(SVP64RMFields().extra2
[0].br
)
286 SVP64RM_EXTRA3_SPEC_SIZE
= len(SVP64RMFields().extra3
[0].br
)
287 SVP64RM_SMASK_SIZE
= len(SVP64RMFields().smask
.br
)
288 SVP64RM_MODE_SIZE
= len(SVP64RMFields().mode
.br
)
291 # SVP64 Prefix fields: see https://libre-soc.org/openpower/sv/svp64/
292 class SVP64PrefixFields
:
294 self
.insn
= SelectableInt(0, 32)
295 # 6 bit major opcode EXT001, 2 bits "identifying" (7, 9), 24 SV ReMap
296 self
.major
= FieldSelectableInt(self
.insn
, tuple(range(0,6)))
297 self
.pid
= FieldSelectableInt(self
.insn
, (7, 9)) # must be 0b11
298 rmfields
= [6, 8] + list(range(10,32)) # SVP64 24-bit RM (ReMap)
299 self
.rm
= FieldSelectableInt(self
.insn
, rmfields
)
302 SV64P_MAJOR_SIZE
= len(SVP64PrefixFields().major
.br
)
303 SV64P_PID_SIZE
= len(SVP64PrefixFields().pid
.br
)
304 SV64P_RM_SIZE
= len(SVP64PrefixFields().rm
.br
)
308 # See PowerISA Version 3.0 B Book 1
309 # Section 2.3.1 Condition Register pages 30 - 31
311 LT
= FL
= 0 # negative, less than, floating-point less than
312 GT
= FG
= 1 # positive, greater than, floating-point greater than
313 EQ
= FE
= 2 # equal, floating-point equal
314 SO
= FU
= 3 # summary overflow, floating-point unordered
316 def __init__(self
, init
=0):
317 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
318 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
319 self
.cr
= SelectableInt(init
, 64) # underlying reg
320 # field-selectable versions of Condition Register TODO check bitranges?
323 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
324 _cr
= FieldSelectableInt(self
.cr
, bits
)
327 # decode SVP64 predicate integer to reg number and invert
328 def get_predint(gpr
, mask
):
331 log ("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
332 if mask
== SVP64PredInt
.ALWAYS
.value
:
333 return 0xffff_ffff_ffff_ffff
334 if mask
== SVP64PredInt
.R3_UNARY
.value
:
335 return 1 << (gpr(3).value
& 0b111111)
336 if mask
== SVP64PredInt
.R3
.value
:
338 if mask
== SVP64PredInt
.R3_N
.value
:
340 if mask
== SVP64PredInt
.R10
.value
:
342 if mask
== SVP64PredInt
.R10_N
.value
:
343 return ~
gpr(10).value
344 if mask
== SVP64PredInt
.R30
.value
:
346 if mask
== SVP64PredInt
.R30_N
.value
:
347 return ~
gpr(30).value
349 # decode SVP64 predicate CR to reg number and invert status
350 def _get_predcr(mask
):
351 if mask
== SVP64PredCR
.LT
.value
:
353 if mask
== SVP64PredCR
.GE
.value
:
355 if mask
== SVP64PredCR
.GT
.value
:
357 if mask
== SVP64PredCR
.LE
.value
:
359 if mask
== SVP64PredCR
.EQ
.value
:
361 if mask
== SVP64PredCR
.NE
.value
:
363 if mask
== SVP64PredCR
.SO
.value
:
365 if mask
== SVP64PredCR
.NS
.value
:
368 # read individual CR fields (0..VL-1), extract the required bit
369 # and construct the mask
370 def get_predcr(crl
, mask
, vl
):
371 idx
, noninv
= _get_predcr(mask
)
374 cr
= crl
[i
+SVP64CROffs
.CRPred
]
375 if cr
[idx
].value
== noninv
:
380 # TODO, really should just be using PowerDecoder2
381 def get_pdecode_idx_in(dec2
, name
):
383 in1_sel
= yield op
.in1_sel
384 in2_sel
= yield op
.in2_sel
385 in3_sel
= yield op
.in3_sel
386 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
387 in1
= yield dec2
.e
.read_reg1
.data
388 in2
= yield dec2
.e
.read_reg2
.data
389 in3
= yield dec2
.e
.read_reg3
.data
390 in1_isvec
= yield dec2
.in1_isvec
391 in2_isvec
= yield dec2
.in2_isvec
392 in3_isvec
= yield dec2
.in3_isvec
393 log ("get_pdecode_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
395 log ("get_pdecode_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
397 log ("get_pdecode_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
399 log ("get_pdecode_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.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
)
481 if out_sel
== OutSel
.RT
.value
:
484 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRA
.value
, out
, o_isvec
)
485 if out_sel
== OutSel
.FRA
.value
:
488 log ("get_pdecode_idx_out", out_sel
, OutSel
.FRT
.value
,
489 OutSel
.FRT
.value
, out
, o_isvec
)
490 if out_sel
== OutSel
.FRT
.value
:
492 log ("get_pdecode_idx_out not found", name
, out_sel
, out
, o_isvec
)
496 # TODO, really should just be using PowerDecoder2
497 def get_pdecode_idx_out2(dec2
, name
):
498 # check first if register is activated for write
500 out_sel
= yield op
.out_sel
501 out
= yield dec2
.e
.write_ea
.data
502 o_isvec
= yield dec2
.o2_isvec
503 out_ok
= yield dec2
.e
.write_ea
.ok
504 log ("get_pdecode_idx_out2", name
, out_sel
, out
, out_ok
, o_isvec
)
509 if hasattr(op
, "upd"):
510 # update mode LD/ST uses read-reg A also as an output
512 log ("get_pdecode_idx_out2", upd
, LDSTMode
.update
.value
,
513 out_sel
, OutSel
.RA
.value
,
515 if upd
== LDSTMode
.update
.value
:
518 int_op
= yield dec2
.dec
.op
.internal_op
519 fft_en
= yield dec2
.use_svp64_fft
520 if int_op
== MicrOp
.OP_FP_MADD
.value
and fft_en
:
521 log ("get_pdecode_idx_out2", out_sel
, OutSel
.FRS
.value
,
528 # decoder2 - an instance of power_decoder2
529 # regfile - a list of initial values for the registers
530 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
531 # respect_pc - tracks the program counter. requires initial_insns
532 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
533 initial_mem
=None, initial_msr
=0,
544 self
.bigendian
= bigendian
546 self
.is_svp64_mode
= False
547 self
.respect_pc
= respect_pc
548 if initial_sprs
is None:
550 if initial_mem
is None:
552 if fpregfile
is None:
554 if initial_insns
is None:
556 assert self
.respect_pc
== False, "instructions required to honor pc"
558 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
559 log("ISACaller initial_msr", initial_msr
)
561 # "fake program counter" mode (for unit testing)
565 if isinstance(initial_mem
, tuple):
566 self
.fake_pc
= initial_mem
[0]
567 disasm_start
= self
.fake_pc
569 disasm_start
= initial_pc
571 # disassembly: we need this for now (not given from the decoder)
572 self
.disassembly
= {}
574 for i
, code
in enumerate(disassembly
):
575 self
.disassembly
[i
*4 + disasm_start
] = code
577 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
578 self
.svp64rm
= SVP64RM()
579 if initial_svstate
is None:
581 if isinstance(initial_svstate
, int):
582 initial_svstate
= SVP64State(initial_svstate
)
583 # SVSTATE, MSR and PC
584 self
.svstate
= initial_svstate
585 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
587 # GPR FPR SPR registers
588 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
589 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
590 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
592 # set up 4 dummy SVSHAPEs if they aren't already set up
594 sname
= 'SVSHAPE%d' % i
595 if sname
not in self
.spr
:
596 self
.spr
[sname
] = SVSHAPE(0)
598 # make sure it's an SVSHAPE
599 val
= self
.spr
[sname
].value
600 self
.spr
[sname
] = SVSHAPE(val
)
601 self
.last_op_svshape
= False
604 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
)
605 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
606 # MMU mode, redirect underlying Mem through RADIX
608 self
.mem
= RADIX(self
.mem
, self
)
610 self
.imem
= RADIX(self
.imem
, self
)
613 # FPR (same as GPR except for FP nums)
614 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
615 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
616 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
617 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
619 # 2.3.2 LR (actually SPR #8) -- Done
620 # 2.3.3 CTR (actually SPR #9) -- Done
621 # 2.3.4 TAR (actually SPR #815)
622 # 3.2.2 p45 XER (actually SPR #1) -- Done
623 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
625 # create CR then allow portions of it to be "selectable" (below)
626 self
.cr_fields
= CRFields(initial_cr
)
627 self
.cr
= self
.cr_fields
.cr
629 # "undefined", just set to variable-bit-width int (use exts "max")
630 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
633 self
.namespace
.update(self
.spr
)
634 self
.namespace
.update({'GPR': self
.gpr
,
638 'memassign': self
.memassign
,
641 'SVSTATE': self
.svstate
.spr
,
642 'SVSHAPE0': self
.spr
['SVSHAPE0'],
643 'SVSHAPE1': self
.spr
['SVSHAPE1'],
644 'SVSHAPE2': self
.spr
['SVSHAPE2'],
645 'SVSHAPE3': self
.spr
['SVSHAPE3'],
648 'undefined': undefined
,
649 'mode_is_64bit': True,
653 # update pc to requested start point
654 self
.set_pc(initial_pc
)
656 # field-selectable versions of Condition Register
657 self
.crl
= self
.cr_fields
.crl
659 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
661 self
.decoder
= decoder2
.dec
664 def call_trap(self
, trap_addr
, trap_bit
):
665 """calls TRAP and sets up NIA to the new execution location.
666 next instruction will begin at trap_addr.
668 self
.TRAP(trap_addr
, trap_bit
)
669 self
.namespace
['NIA'] = self
.trap_nia
670 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
672 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
673 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
675 TRAP function is callable from inside the pseudocode itself,
676 hence the default arguments. when calling from inside ISACaller
677 it is best to use call_trap()
679 log("TRAP:", hex(trap_addr
), hex(self
.namespace
['MSR'].value
))
680 # store CIA(+4?) in SRR0, set NIA to 0x700
681 # store MSR in SRR1, set MSR to um errr something, have to check spec
682 # store SVSTATE (if enabled) in SVSRR0
683 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
684 self
.spr
['SRR1'].value
= self
.namespace
['MSR'].value
685 if self
.is_svp64_mode
:
686 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
687 self
.trap_nia
= SelectableInt(trap_addr
, 64)
688 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
690 # set exception bits. TODO: this should, based on the address
691 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
692 # bits appropriately. however it turns out that *for now* in all
693 # cases (all trap_addrs) the exact same thing is needed.
694 self
.msr
[MSRb
.IR
] = 0
695 self
.msr
[MSRb
.DR
] = 0
696 self
.msr
[MSRb
.FE0
] = 0
697 self
.msr
[MSRb
.FE1
] = 0
698 self
.msr
[MSRb
.EE
] = 0
699 self
.msr
[MSRb
.RI
] = 0
700 self
.msr
[MSRb
.SF
] = 1
701 self
.msr
[MSRb
.TM
] = 0
702 self
.msr
[MSRb
.VEC
] = 0
703 self
.msr
[MSRb
.VSX
] = 0
704 self
.msr
[MSRb
.PR
] = 0
705 self
.msr
[MSRb
.FP
] = 0
706 self
.msr
[MSRb
.PMM
] = 0
707 self
.msr
[MSRb
.TEs
] = 0
708 self
.msr
[MSRb
.TEe
] = 0
709 self
.msr
[MSRb
.UND
] = 0
710 self
.msr
[MSRb
.LE
] = 1
712 def memassign(self
, ea
, sz
, val
):
713 self
.mem
.memassign(ea
, sz
, val
)
715 def prep_namespace(self
, formname
, op_fields
):
716 # TODO: get field names from form in decoder*1* (not decoder2)
717 # decoder2 is hand-created, and decoder1.sigform is auto-generated
719 # then "yield" fields only from op_fields rather than hard-coded
721 fields
= self
.decoder
.sigforms
[formname
]
722 for name
in op_fields
:
724 sig
= getattr(fields
, name
.upper())
726 sig
= getattr(fields
, name
)
728 # these are all opcode fields involved in index-selection of CR,
729 # and need to do "standard" arithmetic. CR[BA+32] for example
730 # would, if using SelectableInt, only be 5-bit.
731 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
732 self
.namespace
[name
] = val
734 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
736 self
.namespace
['XER'] = self
.spr
['XER']
737 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
738 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
740 # add some SVSTATE convenience variables
741 vl
= self
.svstate
.vl
.asint(msb0
=True)
742 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
743 self
.namespace
['VL'] = vl
744 self
.namespace
['srcstep'] = srcstep
746 def handle_carry_(self
, inputs
, outputs
, already_done
):
747 inv_a
= yield self
.dec2
.e
.do
.invert_in
749 inputs
[0] = ~inputs
[0]
751 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
753 imm
= yield self
.dec2
.e
.do
.imm_data
.data
754 inputs
.append(SelectableInt(imm
, 64))
755 assert len(outputs
) >= 1
756 log("outputs", repr(outputs
))
757 if isinstance(outputs
, list) or isinstance(outputs
, tuple):
763 log("gt input", x
, output
)
764 gt
= (gtu(x
, output
))
767 cy
= 1 if any(gts
) else 0
769 if not (1 & already_done
):
770 self
.spr
['XER'][XER_bits
['CA']] = cy
772 log("inputs", already_done
, inputs
)
774 # ARGH... different for OP_ADD... *sigh*...
775 op
= yield self
.dec2
.e
.do
.insn_type
776 if op
== MicrOp
.OP_ADD
.value
:
777 res32
= (output
.value
& (1 << 32)) != 0
778 a32
= (inputs
[0].value
& (1 << 32)) != 0
780 b32
= (inputs
[1].value
& (1 << 32)) != 0
783 cy32
= res32 ^ a32 ^ b32
784 log("CA32 ADD", cy32
)
788 log("input", x
, output
)
789 log(" x[32:64]", x
, x
[32:64])
790 log(" o[32:64]", output
, output
[32:64])
791 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
793 cy32
= 1 if any(gts
) else 0
794 log("CA32", cy32
, gts
)
795 if not (2 & already_done
):
796 self
.spr
['XER'][XER_bits
['CA32']] = cy32
798 def handle_overflow(self
, inputs
, outputs
, div_overflow
):
799 if hasattr(self
.dec2
.e
.do
, "invert_in"):
800 inv_a
= yield self
.dec2
.e
.do
.invert_in
802 inputs
[0] = ~inputs
[0]
804 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
806 imm
= yield self
.dec2
.e
.do
.imm_data
.data
807 inputs
.append(SelectableInt(imm
, 64))
808 assert len(outputs
) >= 1
809 log("handle_overflow", inputs
, outputs
, div_overflow
)
810 if len(inputs
) < 2 and div_overflow
is None:
813 # div overflow is different: it's returned by the pseudo-code
814 # because it's more complex than can be done by analysing the output
815 if div_overflow
is not None:
816 ov
, ov32
= div_overflow
, div_overflow
817 # arithmetic overflow can be done by analysing the input and output
818 elif len(inputs
) >= 2:
822 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
823 output_sgn
= exts(output
.value
, output
.bits
) < 0
824 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
825 output_sgn
!= input_sgn
[0] else 0
828 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
829 output32_sgn
= exts(output
.value
, 32) < 0
830 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
831 output32_sgn
!= input32_sgn
[0] else 0
833 self
.spr
['XER'][XER_bits
['OV']] = ov
834 self
.spr
['XER'][XER_bits
['OV32']] = ov32
835 so
= self
.spr
['XER'][XER_bits
['SO']]
837 self
.spr
['XER'][XER_bits
['SO']] = so
839 def handle_comparison(self
, outputs
, cr_idx
=0):
841 assert isinstance(out
, SelectableInt
), \
842 "out zero not a SelectableInt %s" % repr(outputs
)
843 log("handle_comparison", out
.bits
, hex(out
.value
))
844 # TODO - XXX *processor* in 32-bit mode
845 # https://bugs.libre-soc.org/show_bug.cgi?id=424
847 # o32 = exts(out.value, 32)
848 # print ("handle_comparison exts 32 bit", hex(o32))
849 out
= exts(out
.value
, out
.bits
)
850 log("handle_comparison exts", hex(out
))
851 zero
= SelectableInt(out
== 0, 1)
852 positive
= SelectableInt(out
> 0, 1)
853 negative
= SelectableInt(out
< 0, 1)
854 SO
= self
.spr
['XER'][XER_bits
['SO']]
855 log("handle_comparison SO", SO
)
856 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
857 self
.crl
[cr_idx
].eq(cr_field
)
859 def set_pc(self
, pc_val
):
860 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
861 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
863 def get_next_insn(self
):
867 pc
= self
.pc
.CIA
.value
870 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
872 raise KeyError("no instruction at 0x%x" % pc
)
876 """set up one instruction
878 pc
, insn
= self
.get_next_insn()
879 yield from self
.setup_next_insn(pc
, insn
)
881 def setup_next_insn(self
, pc
, ins
):
882 """set up next instruction
885 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
886 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
888 yield self
.dec2
.sv_rm
.eq(0)
889 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
890 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
891 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
892 yield self
.dec2
.state
.pc
.eq(pc
)
893 if self
.svstate
is not None:
894 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
896 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
898 opcode
= yield self
.dec2
.dec
.opcode_in
899 pfx
= SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
900 pfx
.insn
.value
= opcode
901 major
= pfx
.major
.asint(msb0
=True) # MSB0 inversion
902 log ("prefix test: opcode:", major
, bin(major
),
903 pfx
.insn
[7] == 0b1, pfx
.insn
[9] == 0b1)
904 self
.is_svp64_mode
= ((major
== 0b000001) and
905 pfx
.insn
[7].value
== 0b1 and
906 pfx
.insn
[9].value
== 0b1)
907 self
.pc
.update_nia(self
.is_svp64_mode
)
908 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
) # set SVP64 decode
909 self
.namespace
['NIA'] = self
.pc
.NIA
910 self
.namespace
['SVSTATE'] = self
.svstate
.spr
911 if not self
.is_svp64_mode
:
914 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
915 log ("svp64.rm", bin(pfx
.rm
.asint(msb0
=True)))
916 log (" svstate.vl", self
.svstate
.vl
.asint(msb0
=True))
917 log (" svstate.mvl", self
.svstate
.maxvl
.asint(msb0
=True))
918 sv_rm
= pfx
.rm
.asint(msb0
=True)
919 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
920 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
921 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
922 yield self
.dec2
.sv_rm
.eq(sv_rm
) # svp64 prefix
925 def execute_one(self
):
926 """execute one instruction
928 # get the disassembly code for this instruction
929 if self
.is_svp64_mode
:
930 if not self
.disassembly
:
931 code
= yield from self
.get_assembly_name()
933 code
= self
.disassembly
[self
._pc
+4]
934 log(" svp64 sim-execute", hex(self
._pc
), code
)
936 if not self
.disassembly
:
937 code
= yield from self
.get_assembly_name()
939 code
= self
.disassembly
[self
._pc
]
940 log("sim-execute", hex(self
._pc
), code
)
941 opname
= code
.split(' ')[0]
943 yield from self
.call(opname
) # execute the instruction
944 except MemException
as e
: # check for memory errors
945 if e
.args
[0] != 'unaligned': # only doing aligned at the mo
946 raise e
# ... re-raise
947 # run a Trap but set DAR first
948 print ("memory unaligned exception, DAR", e
.dar
)
949 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
950 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
953 # don't use this except in special circumstances
954 if not self
.respect_pc
:
957 log("execute one, CIA NIA", self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
959 def get_assembly_name(self
):
960 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
961 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
962 dec_insn
= yield self
.dec2
.e
.do
.insn
963 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
964 asmcode
= yield self
.dec2
.dec
.op
.asmcode
965 int_op
= yield self
.dec2
.dec
.op
.internal_op
966 log("get assembly name asmcode", asmcode
, int_op
,
967 hex(dec_insn
), bin(insn_1_11
))
968 asmop
= insns
.get(asmcode
, None)
970 # sigh reconstruct the assembly instruction name
971 if hasattr(self
.dec2
.e
.do
, "oe"):
972 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
973 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
977 if hasattr(self
.dec2
.e
.do
, "rc"):
978 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
979 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
983 # grrrr have to special-case MUL op (see DecodeOE)
984 log("ov %d en %d rc %d en %d op %d" %
985 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
986 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
991 if not asmop
.endswith("."): # don't add "." to "andis."
994 if hasattr(self
.dec2
.e
.do
, "lk"):
995 lk
= yield self
.dec2
.e
.do
.lk
998 log("int_op", int_op
)
999 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1000 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1004 spr_msb
= yield from self
.get_spr_msb()
1005 if int_op
== MicrOp
.OP_MFCR
.value
:
1010 # XXX TODO: for whatever weird reason this doesn't work
1011 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1012 if int_op
== MicrOp
.OP_MTCRF
.value
:
1019 def get_spr_msb(self
):
1020 dec_insn
= yield self
.dec2
.e
.do
.insn
1021 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1023 def call(self
, name
):
1024 """call(opcode) - the primary execution point for instructions
1026 self
.last_st_addr
= None # reset the last known store address
1027 self
.last_ld_addr
= None # etc.
1029 name
= name
.strip() # remove spaces if not already done so
1031 log("halted - not executing", name
)
1034 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1035 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1036 asmop
= yield from self
.get_assembly_name()
1037 log("call", name
, asmop
)
1040 int_op
= yield self
.dec2
.dec
.op
.internal_op
1041 spr_msb
= yield from self
.get_spr_msb()
1043 instr_is_privileged
= False
1044 if int_op
in [MicrOp
.OP_ATTN
.value
,
1045 MicrOp
.OP_MFMSR
.value
,
1046 MicrOp
.OP_MTMSR
.value
,
1047 MicrOp
.OP_MTMSRD
.value
,
1049 MicrOp
.OP_RFID
.value
]:
1050 instr_is_privileged
= True
1051 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1052 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1053 instr_is_privileged
= True
1055 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1057 # check MSR priv bit and whether op is privileged: if so, throw trap
1058 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1059 self
.call_trap(0x700, PIb
.PRIV
)
1062 # check halted condition
1067 # check illegal instruction
1069 if name
not in ['mtcrf', 'mtocrf']:
1070 illegal
= name
!= asmop
1072 # sigh deal with setvl not being supported by binutils (.long)
1073 if asmop
.startswith('setvl'):
1077 # and svremap not being supported by binutils (.long)
1078 if asmop
.startswith('svremap'):
1082 # sigh also deal with ffmadds not being supported by binutils (.long)
1083 if asmop
== 'ffmadds':
1088 print("illegal", name
, asmop
)
1089 self
.call_trap(0x700, PIb
.ILLEG
)
1090 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1091 (name
, asmop
, self
.pc
.CIA
.value
))
1094 # nop has to be supported, we could let the actual op calculate
1095 # but PowerDecoder has a pattern for nop
1097 self
.update_pc_next()
1100 info
= self
.instrs
[name
]
1101 yield from self
.prep_namespace(info
.form
, info
.op_fields
)
1103 # preserve order of register names
1104 input_names
= create_args(list(info
.read_regs
) +
1105 list(info
.uninit_regs
))
1108 # get SVP64 entry for the current instruction
1109 sv_rm
= self
.svp64rm
.instrs
.get(name
)
1110 if sv_rm
is not None:
1111 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
1113 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
1114 log ("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
1116 # get SVSTATE VL (oh and print out some debug stuff)
1117 if self
.is_svp64_mode
:
1118 vl
= self
.svstate
.vl
.asint(msb0
=True)
1119 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1120 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1121 sv_a_nz
= yield self
.dec2
.sv_a_nz
1122 fft_mode
= yield self
.dec2
.use_svp64_fft
1123 in1
= yield self
.dec2
.e
.read_reg1
.data
1124 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1125 vl
, srcstep
, dststep
, sv_a_nz
, in1
, fft_mode
)
1127 # get predicate mask
1128 srcmask
= dstmask
= 0xffff_ffff_ffff_ffff
1129 if self
.is_svp64_mode
:
1130 pmode
= yield self
.dec2
.rm_dec
.predmode
1131 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1132 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1133 srcpred
= yield self
.dec2
.rm_dec
.srcpred
1134 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1135 pred_src_zero
= yield self
.dec2
.rm_dec
.pred_sz
1136 pred_dst_zero
= yield self
.dec2
.rm_dec
.pred_dz
1137 if pmode
== SVP64PredMode
.INT
.value
:
1138 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1139 if sv_ptype
== SVPtype
.P2
.value
:
1140 srcmask
= get_predint(self
.gpr
, srcpred
)
1141 elif pmode
== SVP64PredMode
.CR
.value
:
1142 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1143 if sv_ptype
== SVPtype
.P2
.value
:
1144 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1145 log (" pmode", pmode
)
1146 log (" reverse", reverse_gear
)
1147 log (" ptype", sv_ptype
)
1148 log (" srcpred", bin(srcpred
))
1149 log (" dstpred", bin(dstpred
))
1150 log (" srcmask", bin(srcmask
))
1151 log (" dstmask", bin(dstmask
))
1152 log (" pred_sz", bin(pred_src_zero
))
1153 log (" pred_dz", bin(pred_dst_zero
))
1155 # okaaay, so here we simply advance srcstep (TODO dststep)
1156 # until the predicate mask has a "1" bit... or we run out of VL
1157 # let srcstep==VL be the indicator to move to next instruction
1158 if not pred_src_zero
:
1159 while (((1<<srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1160 log (" skip", bin(1<<srcstep
))
1163 if not pred_dst_zero
:
1164 while (((1<<dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1165 log (" skip", bin(1<<dststep
))
1168 # now work out if the relevant mask bits require zeroing
1170 pred_dst_zero
= ((1<<dststep
) & dstmask
) == 0
1172 pred_src_zero
= ((1<<srcstep
) & srcmask
) == 0
1174 # update SVSTATE with new srcstep
1175 self
.svstate
.srcstep
[0:7] = srcstep
1176 self
.svstate
.dststep
[0:7] = dststep
1177 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1178 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.spr
.value
)
1179 yield Settle() # let decoder update
1180 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1181 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1182 log (" srcstep", srcstep
)
1183 log (" dststep", dststep
)
1185 # check if end reached (we let srcstep overrun, above)
1186 # nothing needs doing (TODO zeroing): just do next instruction
1187 if srcstep
== vl
or dststep
== vl
:
1188 self
.svp64_reset_loop()
1189 self
.update_pc_next()
1192 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1193 if self
.is_svp64_mode
and vl
== 0:
1194 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1195 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
1196 self
.namespace
['NIA'])
1199 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1200 # using pre-arranged schedule. all of this is awful but it is a
1201 # start. next job will be to put the proper activation in place
1202 yield self
.dec2
.remap_active
.eq(1 if self
.last_op_svshape
else 0)
1203 if self
.last_op_svshape
:
1204 # get four SVSHAPEs. here we are hard-coding
1205 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1206 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1207 SVSHAPE0
= self
.spr
['SVSHAPE0']
1208 SVSHAPE1
= self
.spr
['SVSHAPE1']
1209 SVSHAPE2
= self
.spr
['SVSHAPE2']
1210 SVSHAPE3
= self
.spr
['SVSHAPE3']
1211 print ("svshape0", bin(SVSHAPE0
.value
))
1212 print (" xdim", SVSHAPE0
.xdimsz
)
1213 print (" ydim", SVSHAPE0
.ydimsz
)
1214 print (" zdim", SVSHAPE0
.zdimsz
)
1215 remaps
= [SVSHAPE0
.get_iterator(),
1216 SVSHAPE1
.get_iterator(),
1217 SVSHAPE2
.get_iterator(),
1218 SVSHAPE3
.get_iterator(),
1221 for i
, remap
in enumerate(remaps
):
1222 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1223 step
= dststep
if (i
== 0) else srcstep
1224 # this is terrible. O(N^2) looking for the match. but hey.
1225 for idx
, remap_idx
in enumerate(remap
):
1229 yield self
.dec2
.o_step
.eq(remap_idx
)
1230 yield self
.dec2
.o2_step
.eq(remap_idx
)
1232 yield self
.dec2
.in1_step
.eq(remap_idx
)
1234 yield self
.dec2
.in2_step
.eq(remap_idx
)
1236 yield self
.dec2
.in3_step
.eq(remap_idx
)
1237 rremaps
.append((i
, idx
, remap_idx
))
1239 print ("shape remap", x
)
1240 # after that, settle down (combinatorial) to let Vector reg numbers
1241 # work themselves out
1243 remap_active
= yield self
.dec2
.remap_active
1244 print ("remap active", remap_active
)
1246 # main input registers (RT, RA ...)
1248 for name
in input_names
:
1249 # using PowerDecoder2, first, find the decoder index.
1250 # (mapping name RA RB RC RS to in1, in2, in3)
1251 regnum
, is_vec
= yield from get_pdecode_idx_in(self
.dec2
, name
)
1253 # doing this is not part of svp64, it's because output
1254 # registers, to be modified, need to be in the namespace.
1255 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
, name
)
1257 regnum
, is_vec
= yield from get_pdecode_idx_out2(self
.dec2
,
1260 # in case getting the register number is needed, _RA, _RB
1261 regname
= "_" + name
1262 self
.namespace
[regname
] = regnum
1263 if not self
.is_svp64_mode
or not pred_src_zero
:
1264 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
1266 reg_val
= self
.fpr(regnum
)
1268 reg_val
= self
.gpr(regnum
)
1270 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
1272 inputs
.append(reg_val
)
1274 # in SVP64 mode for LD/ST work out immediate
1275 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1276 # use info.form to detect
1277 replace_d
= False # update / replace constant in pseudocode
1278 if self
.is_svp64_mode
:
1279 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
1280 # bitreverse mode reads SVD (or SVDS - TODO)
1281 # *BUT*... because this is "overloading" of LD operations,
1282 # it gets *STORED* into D (or DS, TODO)
1283 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1284 imm
= yield self
.dec2
.dec
.fields
.FormSVD
.SVD
[0:11]
1285 imm
= exts(imm
, 11) # sign-extend to integer
1286 print ("bitrev SVD", imm
)
1289 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
1290 imm
= exts(imm
, 16) # sign-extend to integer
1291 # get the right step. LD is from srcstep, ST is dststep
1292 op
= yield self
.dec2
.e
.do
.insn_type
1294 if op
== MicrOp
.OP_LOAD
.value
:
1296 log("D-field src", imm
, offsmul
)
1297 elif op
== MicrOp
.OP_STORE
.value
:
1299 log("D-field dst", imm
, offsmul
)
1301 if ldstmode
== SVP64LDSTmode
.BITREVERSE
.value
:
1302 # manually look up RC, sigh
1303 RC
= yield self
.dec2
.dec
.RC
[0:5]
1305 log ("RC", RC
.value
, "imm", imm
, "offs", bin(offsmul
),
1306 "rev", bin(bitrev(offsmul
, vl
)))
1307 imm
= SelectableInt((imm
* bitrev(offsmul
, vl
)) << RC
.value
, 32)
1308 # Unit-Strided LD/ST adds offset*width to immediate
1309 elif ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
1310 ldst_len
= yield self
.dec2
.e
.do
.data_len
1311 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
1313 # Element-strided multiplies the immediate by element step
1314 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
1315 imm
= SelectableInt(imm
* offsmul
, 32)
1317 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
1318 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
1319 log("LDSTmode", ldstmode
, SVP64LDSTmode
.BITREVERSE
.value
,
1320 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
1323 self
.namespace
['D'] = imm
1325 # "special" registers
1326 for special
in info
.special_regs
:
1327 if special
in special_sprs
:
1328 inputs
.append(self
.spr
[special
])
1330 inputs
.append(self
.namespace
[special
])
1332 # clear trap (trap) NIA
1333 self
.trap_nia
= None
1335 # execute actual instruction here (finally)
1336 log("inputs", inputs
)
1337 results
= info
.func(self
, *inputs
)
1338 log("results", results
)
1340 # "inject" decorator takes namespace from function locals: we need to
1341 # overwrite NIA being overwritten (sigh)
1342 if self
.trap_nia
is not None:
1343 self
.namespace
['NIA'] = self
.trap_nia
1345 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
1347 # check if op was a LD/ST so that debugging can check the
1349 if int_op
in [MicrOp
.OP_STORE
.value
,
1351 self
.last_st_addr
= self
.mem
.last_st_addr
1352 if int_op
in [MicrOp
.OP_LOAD
.value
,
1354 self
.last_ld_addr
= self
.mem
.last_ld_addr
1355 log ("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
1356 self
.last_st_addr
, self
.last_ld_addr
)
1358 # detect if CA/CA32 already in outputs (sra*, basically)
1361 output_names
= create_args(info
.write_regs
)
1362 for name
in output_names
:
1368 log("carry already done?", bin(already_done
))
1369 if hasattr(self
.dec2
.e
.do
, "output_carry"):
1370 carry_en
= yield self
.dec2
.e
.do
.output_carry
1374 yield from self
.handle_carry_(inputs
, results
, already_done
)
1376 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
1377 # detect if overflow was in return result
1380 for name
, output
in zip(output_names
, results
):
1381 if name
== 'overflow':
1384 if hasattr(self
.dec2
.e
.do
, "oe"):
1385 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1386 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1390 log("internal overflow", overflow
, ov_en
, ov_ok
)
1392 yield from self
.handle_overflow(inputs
, results
, overflow
)
1394 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1396 if not self
.is_svp64_mode
or not pred_dst_zero
:
1397 if hasattr(self
.dec2
.e
.do
, "rc"):
1398 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1400 regnum
, is_vec
= yield from get_pdecode_cr_out(self
.dec2
, "CR0")
1401 self
.handle_comparison(results
, regnum
)
1403 # any modified return results?
1405 for name
, output
in zip(output_names
, results
):
1406 if name
== 'overflow': # ignore, done already (above)
1408 if isinstance(output
, int):
1409 output
= SelectableInt(output
, 256)
1410 if name
in ['CA', 'CA32']:
1412 log("writing %s to XER" % name
, output
)
1413 self
.spr
['XER'][XER_bits
[name
]] = output
.value
1415 log("NOT writing %s to XER" % name
, output
)
1416 elif name
in info
.special_regs
:
1417 log('writing special %s' % name
, output
, special_sprs
)
1418 if name
in special_sprs
:
1419 self
.spr
[name
] = output
1421 self
.namespace
[name
].eq(output
)
1423 log('msr written', hex(self
.msr
.value
))
1425 regnum
, is_vec
= yield from get_pdecode_idx_out(self
.dec2
,
1428 regnum
, is_vec
= yield from get_pdecode_idx_out2(
1431 # temporary hack for not having 2nd output
1432 regnum
= yield getattr(self
.decoder
, name
)
1434 if self
.is_svp64_mode
and pred_dst_zero
:
1435 log('zeroing reg %d %s' % (regnum
, str(output
)),
1437 output
= SelectableInt(0, 256)
1443 log('writing %s %s %s' % (regnum
, ftype
, str(output
)),
1445 if output
.bits
> 64:
1446 output
= SelectableInt(output
.value
, 64)
1448 self
.fpr
[regnum
] = output
1450 self
.gpr
[regnum
] = output
1452 # check if it is the SVSTATE.src/dest step that needs incrementing
1453 # this is our Sub-Program-Counter loop from 0 to VL-1
1454 if self
.is_svp64_mode
:
1455 # XXX twin predication TODO
1456 vl
= self
.svstate
.vl
.asint(msb0
=True)
1457 mvl
= self
.svstate
.maxvl
.asint(msb0
=True)
1458 srcstep
= self
.svstate
.srcstep
.asint(msb0
=True)
1459 dststep
= self
.svstate
.dststep
.asint(msb0
=True)
1460 rm_mode
= yield self
.dec2
.rm_dec
.mode
1461 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1462 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1463 out_vec
= not (yield self
.dec2
.no_out_vec
)
1464 in_vec
= not (yield self
.dec2
.no_in_vec
)
1465 log (" svstate.vl", vl
)
1466 log (" svstate.mvl", mvl
)
1467 log (" svstate.srcstep", srcstep
)
1468 log (" svstate.dststep", dststep
)
1469 log (" mode", rm_mode
)
1470 log (" reverse", reverse_gear
)
1471 log (" out_vec", out_vec
)
1472 log (" in_vec", in_vec
)
1473 log (" sv_ptype", sv_ptype
, sv_ptype
== SVPtype
.P2
.value
)
1474 # check if srcstep needs incrementing by one, stop PC advancing
1475 # svp64 loop can end early if the dest is scalar for single-pred
1476 # but for 2-pred both src/dest have to be checked.
1477 # XXX this might not be true! it may just be LD/ST
1478 if sv_ptype
== SVPtype
.P2
.value
:
1479 svp64_is_vector
= (out_vec
or in_vec
)
1481 svp64_is_vector
= out_vec
1482 if svp64_is_vector
and srcstep
!= vl
-1 and dststep
!= vl
-1:
1483 self
.svstate
.srcstep
+= SelectableInt(1, 7)
1484 self
.svstate
.dststep
+= SelectableInt(1, 7)
1485 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
1486 self
.namespace
['NIA'] = self
.pc
.NIA
1487 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1488 log("end of sub-pc call", self
.namespace
['CIA'],
1489 self
.namespace
['NIA'])
1490 return # DO NOT allow PC to update whilst Sub-PC loop running
1491 # reset loop to zero
1492 self
.svp64_reset_loop()
1494 # XXX only in non-SVP64 mode!
1495 # record state of whether the current operation was an svshape,
1496 # to be able to know if it should apply in the next instruction.
1497 # also (if going to use this instruction) should disable ability
1498 # to interrupt in between. sigh.
1499 self
.last_op_svshape
= asmop
== 'svremap'
1501 self
.update_pc_next()
1503 def update_pc_next(self
):
1504 # UPDATE program counter
1505 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1506 self
.svstate
.spr
= self
.namespace
['SVSTATE']
1507 log("end of call", self
.namespace
['CIA'],
1508 self
.namespace
['NIA'],
1509 self
.namespace
['SVSTATE'])
1511 def svp64_reset_loop(self
):
1512 self
.svstate
.srcstep
[0:7] = 0
1513 self
.svstate
.dststep
[0:7] = 0
1514 log (" svstate.srcstep loop end (PC to update)")
1515 self
.pc
.update_nia(self
.is_svp64_mode
)
1516 self
.namespace
['NIA'] = self
.pc
.NIA
1517 self
.namespace
['SVSTATE'] = self
.svstate
.spr
1521 """Decorator factory.
1523 this decorator will "inject" variables into the function's namespace,
1524 from the *dictionary* in self.namespace. it therefore becomes possible
1525 to make it look like a whole stack of variables which would otherwise
1526 need "self." inserted in front of them (*and* for those variables to be
1527 added to the instance) "appear" in the function.
1529 "self.namespace['SI']" for example becomes accessible as just "SI" but
1530 *only* inside the function, when decorated.
1532 def variable_injector(func
):
1534 def decorator(*args
, **kwargs
):
1536 func_globals
= func
.__globals
__ # Python 2.6+
1537 except AttributeError:
1538 func_globals
= func
.func_globals
# Earlier versions.
1540 context
= args
[0].namespace
# variables to be injected
1541 saved_values
= func_globals
.copy() # Shallow copy of dict.
1542 func_globals
.update(context
)
1543 result
= func(*args
, **kwargs
)
1544 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
1545 log("args[0]", args
[0].namespace
['CIA'],
1546 args
[0].namespace
['NIA'],
1547 args
[0].namespace
['SVSTATE'])
1548 args
[0].namespace
= func_globals
1549 #exec (func.__code__, func_globals)
1552 # func_globals = saved_values # Undo changes.
1558 return variable_injector