code-morph in StepLoop work towards splitting into iterators
[openpower-isa.git] / src / openpower / decoder / isa / caller.py
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
6
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.
10
11 related bugs:
12
13 * https://bugs.libre-soc.org/show_bug.cgi?id=424
14 """
15
16 import re
17 from nmigen.sim import Settle, Delay
18 from functools import wraps
19 from copy import copy, deepcopy
20 from openpower.decoder.orderedset import OrderedSet
21 from openpower.decoder.selectable_int import (
22 FieldSelectableInt,
23 SelectableInt,
24 selectconcat,
25 )
26 from openpower.decoder.power_insn import SVP64Instruction
27 from openpower.decoder.power_enums import (spr_dict, spr_byname, XER_bits,
28 insns, MicrOp,
29 In1Sel, In2Sel, In3Sel,
30 OutSel, CRInSel, CROutSel, LDSTMode,
31 SVP64RMMode, SVP64PredMode,
32 SVP64PredInt, SVP64PredCR,
33 SVP64LDSTmode, FPTRANS_INSNS)
34
35 from openpower.decoder.power_enums import SVPtype
36
37 from openpower.decoder.helpers import (exts, gtu, ltu, undefined,
38 ISACallerHelper, ISAFPHelpers)
39 from openpower.consts import PIb, MSRb # big-endian (PowerISA versions)
40 from openpower.consts import (SVP64MODE,
41 SVP64CROffs,
42 )
43 from openpower.decoder.power_svp64 import SVP64RM, decode_extra
44
45 from openpower.decoder.isa.radixmmu import RADIX
46 from openpower.decoder.isa.mem import Mem, swap_order, MemException
47 from openpower.decoder.isa.svshape import SVSHAPE
48 from openpower.decoder.isa.svstate import SVP64State
49
50
51 from openpower.util import LogKind, log
52
53 from collections import namedtuple
54 import math
55 import sys
56
57 instruction_info = namedtuple('instruction_info',
58 'func read_regs uninit_regs write_regs ' +
59 'special_regs op_fields form asmregs')
60
61 special_sprs = {
62 'LR': 8,
63 'CTR': 9,
64 'TAR': 815,
65 'XER': 1,
66 'VRSAVE': 256}
67
68
69 REG_SORT_ORDER = {
70 # TODO (lkcl): adjust other registers that should be in a particular order
71 # probably CA, CA32, and CR
72 "FRT": 0,
73 "FRA": 0,
74 "FRB": 0,
75 "FRC": 0,
76 "FRS": 0,
77 "RT": 0,
78 "RA": 0,
79 "RB": 0,
80 "RC": 0,
81 "RS": 0,
82 "BI": 0,
83 "CR": 0,
84 "LR": 0,
85 "CTR": 0,
86 "TAR": 0,
87 "MSR": 0,
88 "SVSTATE": 0,
89 "SVSHAPE0": 0,
90 "SVSHAPE1": 0,
91 "SVSHAPE2": 0,
92 "SVSHAPE3": 0,
93
94 "CA": 0,
95 "CA32": 0,
96
97 "overflow": 7, # should definitely be last
98 }
99
100 fregs = ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
101
102
103 def create_args(reglist, extra=None):
104 retval = list(OrderedSet(reglist))
105 retval.sort(key=lambda reg: REG_SORT_ORDER.get(reg, 0))
106 if extra is not None:
107 return [extra] + retval
108 return retval
109
110
111 class GPR(dict):
112 def __init__(self, decoder, isacaller, svstate, regfile):
113 dict.__init__(self)
114 self.sd = decoder
115 self.isacaller = isacaller
116 self.svstate = svstate
117 for i in range(len(regfile)):
118 self[i] = SelectableInt(regfile[i], 64)
119
120 def __call__(self, ridx):
121 if isinstance(ridx, SelectableInt):
122 ridx = ridx.value
123 return self[ridx]
124
125 def set_form(self, form):
126 self.form = form
127
128 def __setitem__(self, rnum, value):
129 # rnum = rnum.value # only SelectableInt allowed
130 log("GPR setitem", rnum, value)
131 if isinstance(rnum, SelectableInt):
132 rnum = rnum.value
133 dict.__setitem__(self, rnum, value)
134
135 def getz(self, rnum):
136 # rnum = rnum.value # only SelectableInt allowed
137 log("GPR getzero?", rnum)
138 if rnum == 0:
139 return SelectableInt(0, 64)
140 return self[rnum]
141
142 def _get_regnum(self, attr):
143 getform = self.sd.sigforms[self.form]
144 rnum = getattr(getform, attr)
145 return rnum
146
147 def ___getitem__(self, attr):
148 """ XXX currently not used
149 """
150 rnum = self._get_regnum(attr)
151 log("GPR getitem", attr, rnum)
152 return self.regfile[rnum]
153
154 def dump(self, printout=True):
155 res = []
156 for i in range(len(self)):
157 res.append(self[i].value)
158 if printout:
159 for i in range(0, len(res), 8):
160 s = []
161 for j in range(8):
162 s.append("%08x" % res[i+j])
163 s = ' '.join(s)
164 print("reg", "%2d" % i, s)
165 return res
166
167
168 class SPR(dict):
169 def __init__(self, dec2, initial_sprs={}):
170 self.sd = dec2
171 dict.__init__(self)
172 for key, v in initial_sprs.items():
173 if isinstance(key, SelectableInt):
174 key = key.value
175 key = special_sprs.get(key, key)
176 if isinstance(key, int):
177 info = spr_dict[key]
178 else:
179 info = spr_byname[key]
180 if not isinstance(v, SelectableInt):
181 v = SelectableInt(v, info.length)
182 self[key] = v
183
184 def __getitem__(self, key):
185 log("get spr", key)
186 log("dict", self.items())
187 # if key in special_sprs get the special spr, otherwise return key
188 if isinstance(key, SelectableInt):
189 key = key.value
190 if isinstance(key, int):
191 key = spr_dict[key].SPR
192 key = special_sprs.get(key, key)
193 if key == 'HSRR0': # HACK!
194 key = 'SRR0'
195 if key == 'HSRR1': # HACK!
196 key = 'SRR1'
197 if key in self:
198 res = dict.__getitem__(self, key)
199 else:
200 if isinstance(key, int):
201 info = spr_dict[key]
202 else:
203 info = spr_byname[key]
204 dict.__setitem__(self, key, SelectableInt(0, info.length))
205 res = dict.__getitem__(self, key)
206 log("spr returning", key, res)
207 return res
208
209 def __setitem__(self, key, value):
210 if isinstance(key, SelectableInt):
211 key = key.value
212 if isinstance(key, int):
213 key = spr_dict[key].SPR
214 log("spr key", key)
215 key = special_sprs.get(key, key)
216 if key == 'HSRR0': # HACK!
217 self.__setitem__('SRR0', value)
218 if key == 'HSRR1': # HACK!
219 self.__setitem__('SRR1', value)
220 log("setting spr", key, value)
221 dict.__setitem__(self, key, value)
222
223 def __call__(self, ridx):
224 return self[ridx]
225
226 def dump(self, printout=True):
227 res = []
228 keys = list(self.keys())
229 # keys.sort()
230 for k in keys:
231 sprname = spr_dict.get(k, None)
232 if sprname is None:
233 sprname = k
234 else:
235 sprname = sprname.SPR
236 res.append((sprname, self[k].value))
237 if printout:
238 for sprname, value in res:
239 print(" ", sprname, hex(value))
240 return res
241
242
243 class PC:
244 def __init__(self, pc_init=0):
245 self.CIA = SelectableInt(pc_init, 64)
246 self.NIA = self.CIA + SelectableInt(4, 64) # only true for v3.0B!
247
248 def update_nia(self, is_svp64):
249 increment = 8 if is_svp64 else 4
250 self.NIA = self.CIA + SelectableInt(increment, 64)
251
252 def update(self, namespace, is_svp64):
253 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
254 """
255 self.CIA = namespace['NIA'].narrow(64)
256 self.update_nia(is_svp64)
257 namespace['CIA'] = self.CIA
258 namespace['NIA'] = self.NIA
259
260
261 # CR register fields
262 # See PowerISA Version 3.0 B Book 1
263 # Section 2.3.1 Condition Register pages 30 - 31
264 class CRFields:
265 LT = FL = 0 # negative, less than, floating-point less than
266 GT = FG = 1 # positive, greater than, floating-point greater than
267 EQ = FE = 2 # equal, floating-point equal
268 SO = FU = 3 # summary overflow, floating-point unordered
269
270 def __init__(self, init=0):
271 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
272 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
273 self.cr = SelectableInt(init, 64) # underlying reg
274 # field-selectable versions of Condition Register TODO check bitranges?
275 self.crl = []
276 for i in range(8):
277 bits = tuple(range(i*4+32, (i+1)*4+32))
278 _cr = FieldSelectableInt(self.cr, bits)
279 self.crl.append(_cr)
280
281 # decode SVP64 predicate integer to reg number and invert
282
283
284 def get_predint(gpr, mask):
285 r10 = gpr(10)
286 r30 = gpr(30)
287 log("get_predint", mask, SVP64PredInt.ALWAYS.value)
288 if mask == SVP64PredInt.ALWAYS.value:
289 return 0xffff_ffff_ffff_ffff # 64 bits of 1
290 if mask == SVP64PredInt.R3_UNARY.value:
291 return 1 << (gpr(3).value & 0b111111)
292 if mask == SVP64PredInt.R3.value:
293 return gpr(3).value
294 if mask == SVP64PredInt.R3_N.value:
295 return ~gpr(3).value
296 if mask == SVP64PredInt.R10.value:
297 return gpr(10).value
298 if mask == SVP64PredInt.R10_N.value:
299 return ~gpr(10).value
300 if mask == SVP64PredInt.R30.value:
301 return gpr(30).value
302 if mask == SVP64PredInt.R30_N.value:
303 return ~gpr(30).value
304
305 # decode SVP64 predicate CR to reg number and invert status
306
307
308 def _get_predcr(mask):
309 if mask == SVP64PredCR.LT.value:
310 return 0, 1
311 if mask == SVP64PredCR.GE.value:
312 return 0, 0
313 if mask == SVP64PredCR.GT.value:
314 return 1, 1
315 if mask == SVP64PredCR.LE.value:
316 return 1, 0
317 if mask == SVP64PredCR.EQ.value:
318 return 2, 1
319 if mask == SVP64PredCR.NE.value:
320 return 2, 0
321 if mask == SVP64PredCR.SO.value:
322 return 3, 1
323 if mask == SVP64PredCR.NS.value:
324 return 3, 0
325
326 # read individual CR fields (0..VL-1), extract the required bit
327 # and construct the mask
328
329
330 def get_predcr(crl, mask, vl):
331 idx, noninv = _get_predcr(mask)
332 mask = 0
333 for i in range(vl):
334 cr = crl[i+SVP64CROffs.CRPred]
335 if cr[idx].value == noninv:
336 mask |= (1 << i)
337 return mask
338
339
340 # TODO, really should just be using PowerDecoder2
341 def get_pdecode_idx_in(dec2, name):
342 op = dec2.dec.op
343 in1_sel = yield op.in1_sel
344 in2_sel = yield op.in2_sel
345 in3_sel = yield op.in3_sel
346 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
347 in1 = yield dec2.e.read_reg1.data
348 in2 = yield dec2.e.read_reg2.data
349 in3 = yield dec2.e.read_reg3.data
350 in1_isvec = yield dec2.in1_isvec
351 in2_isvec = yield dec2.in2_isvec
352 in3_isvec = yield dec2.in3_isvec
353 log("get_pdecode_idx_in in1", name, in1_sel, In1Sel.RA.value,
354 in1, in1_isvec)
355 log("get_pdecode_idx_in in2", name, in2_sel, In2Sel.RB.value,
356 in2, in2_isvec)
357 log("get_pdecode_idx_in in3", name, in3_sel, In3Sel.RS.value,
358 in3, in3_isvec)
359 log("get_pdecode_idx_in FRS in3", name, in3_sel, In3Sel.FRS.value,
360 in3, in3_isvec)
361 log("get_pdecode_idx_in FRB in2", name, in2_sel, In2Sel.FRB.value,
362 in2, in2_isvec)
363 log("get_pdecode_idx_in FRC in3", name, in3_sel, In3Sel.FRC.value,
364 in3, in3_isvec)
365 # identify which regnames map to in1/2/3
366 if name == 'RA' or name == 'RA_OR_ZERO':
367 if (in1_sel == In1Sel.RA.value or
368 (in1_sel == In1Sel.RA_OR_ZERO.value and in1 != 0)):
369 return in1, in1_isvec
370 if in1_sel == In1Sel.RA_OR_ZERO.value:
371 return in1, in1_isvec
372 elif name == 'RB':
373 if in2_sel == In2Sel.RB.value:
374 return in2, in2_isvec
375 if in3_sel == In3Sel.RB.value:
376 return in3, in3_isvec
377 # XXX TODO, RC doesn't exist yet!
378 elif name == 'RC':
379 assert False, "RC does not exist yet"
380 elif name == 'RS':
381 if in1_sel == In1Sel.RS.value:
382 return in1, in1_isvec
383 if in2_sel == In2Sel.RS.value:
384 return in2, in2_isvec
385 if in3_sel == In3Sel.RS.value:
386 return in3, in3_isvec
387 elif name == 'FRA':
388 if in1_sel == In1Sel.FRA.value:
389 return in1, in1_isvec
390 elif name == 'FRB':
391 if in2_sel == In2Sel.FRB.value:
392 return in2, in2_isvec
393 elif name == 'FRC':
394 if in3_sel == In3Sel.FRC.value:
395 return in3, in3_isvec
396 elif name == 'FRS':
397 if in1_sel == In1Sel.FRS.value:
398 return in1, in1_isvec
399 if in3_sel == In3Sel.FRS.value:
400 return in3, in3_isvec
401 return None, False
402
403
404 # TODO, really should just be using PowerDecoder2
405 def get_pdecode_cr_in(dec2, name):
406 op = dec2.dec.op
407 in_sel = yield op.cr_in
408 in_bitfield = yield dec2.dec_cr_in.cr_bitfield.data
409 sv_cr_in = yield op.sv_cr_in
410 spec = yield dec2.crin_svdec.spec
411 sv_override = yield dec2.dec_cr_in.sv_override
412 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
413 in1 = yield dec2.e.read_cr1.data
414 cr_isvec = yield dec2.cr_in_isvec
415 log("get_pdecode_cr_in", in_sel, CROutSel.CR0.value, in1, cr_isvec)
416 log(" sv_cr_in", sv_cr_in)
417 log(" cr_bf", in_bitfield)
418 log(" spec", spec)
419 log(" override", sv_override)
420 # identify which regnames map to in / o2
421 if name == 'BI':
422 if in_sel == CRInSel.BI.value:
423 return in1, cr_isvec
424 log("get_pdecode_cr_in not found", name)
425 return None, False
426
427
428 # TODO, really should just be using PowerDecoder2
429 def get_pdecode_cr_out(dec2, name):
430 op = dec2.dec.op
431 out_sel = yield op.cr_out
432 out_bitfield = yield dec2.dec_cr_out.cr_bitfield.data
433 sv_cr_out = yield op.sv_cr_out
434 spec = yield dec2.crout_svdec.spec
435 sv_override = yield dec2.dec_cr_out.sv_override
436 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
437 out = yield dec2.e.write_cr.data
438 o_isvec = yield dec2.o_isvec
439 log("get_pdecode_cr_out", out_sel, CROutSel.CR0.value, out, o_isvec)
440 log(" sv_cr_out", sv_cr_out)
441 log(" cr_bf", out_bitfield)
442 log(" spec", spec)
443 log(" override", sv_override)
444 # identify which regnames map to out / o2
445 if name == 'CR0':
446 if out_sel == CROutSel.CR0.value:
447 return out, o_isvec
448 if name == 'CR1': # these are not actually calculated correctly
449 if out_sel == CROutSel.CR1.value:
450 return out, o_isvec
451 log("get_pdecode_cr_out not found", name)
452 return None, False
453
454
455 # TODO, really should just be using PowerDecoder2
456 def get_pdecode_idx_out(dec2, name):
457 op = dec2.dec.op
458 out_sel = yield op.out_sel
459 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
460 out = yield dec2.e.write_reg.data
461 o_isvec = yield dec2.o_isvec
462 # identify which regnames map to out / o2
463 if name == 'RA':
464 log("get_pdecode_idx_out", out_sel, OutSel.RA.value, out, o_isvec)
465 if out_sel == OutSel.RA.value:
466 return out, o_isvec
467 elif name == 'RT':
468 log("get_pdecode_idx_out", out_sel, OutSel.RT.value,
469 OutSel.RT_OR_ZERO.value, out, o_isvec,
470 dec2.dec.RT)
471 if out_sel == OutSel.RT.value:
472 return out, o_isvec
473 if out_sel == OutSel.RT_OR_ZERO.value and out != 0:
474 return out, o_isvec
475 elif name == 'RT_OR_ZERO':
476 log("get_pdecode_idx_out", out_sel, OutSel.RT.value,
477 OutSel.RT_OR_ZERO.value, out, o_isvec,
478 dec2.dec.RT)
479 if out_sel == OutSel.RT_OR_ZERO.value:
480 return out, o_isvec
481 elif name == 'FRA':
482 log("get_pdecode_idx_out", out_sel, OutSel.FRA.value, out, o_isvec)
483 if out_sel == OutSel.FRA.value:
484 return out, o_isvec
485 elif name == 'FRT':
486 log("get_pdecode_idx_out", out_sel, OutSel.FRT.value,
487 OutSel.FRT.value, out, o_isvec)
488 if out_sel == OutSel.FRT.value:
489 return out, o_isvec
490 log("get_pdecode_idx_out not found", name, out_sel, out, o_isvec)
491 return None, False
492
493
494 # TODO, really should just be using PowerDecoder2
495 def get_pdecode_idx_out2(dec2, name):
496 # check first if register is activated for write
497 op = dec2.dec.op
498 out_sel = yield op.out_sel
499 out = yield dec2.e.write_ea.data
500 o_isvec = yield dec2.o2_isvec
501 out_ok = yield dec2.e.write_ea.ok
502 log("get_pdecode_idx_out2", name, out_sel, out, out_ok, o_isvec)
503 if not out_ok:
504 return None, False
505
506 if name == 'RA':
507 if hasattr(op, "upd"):
508 # update mode LD/ST uses read-reg A also as an output
509 upd = yield op.upd
510 log("get_pdecode_idx_out2", upd, LDSTMode.update.value,
511 out_sel, OutSel.RA.value,
512 out, o_isvec)
513 if upd == LDSTMode.update.value:
514 return out, o_isvec
515 if name == 'FRS':
516 int_op = yield dec2.dec.op.internal_op
517 fft_en = yield dec2.use_svp64_fft
518 # if int_op == MicrOp.OP_FP_MADD.value and fft_en:
519 if fft_en:
520 log("get_pdecode_idx_out2", out_sel, OutSel.FRS.value,
521 out, o_isvec)
522 return out, o_isvec
523 return None, False
524
525
526 class StepLoop:
527 """deals with svstate looping.
528 """
529
530 def __init__(self, svstate):
531 self.svstate = svstate
532 #self.src_it = self.src_iterator()
533 #self.dst_it = self.dst_iterator()
534
535 def src_iterator(self):
536 """source-stepping iterator
537 """
538 end_src = self.end_src
539 subvl = self.subvl
540 pack = self.svstate.pack
541 unpack = self.svstate.unpack
542 ssubstep = self.svstate.ssubstep
543 end_ssub = ssubstep == subvl
544 log(" pack/unpack/subvl", pack, unpack, subvl,
545 "end", end_src,
546 "sub", end_ssub)
547 # first source step
548 srcstep = self.svstate.srcstep
549 if pack:
550 # pack advances subvl in *outer* loop
551 if end_src:
552 if not end_ssub:
553 self.svstate.ssubstep += SelectableInt(1, 2)
554 self.svstate.srcstep = SelectableInt(0, 7) # reset
555 else:
556 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
557 else:
558 # advance subvl in *inner* loop
559 if end_ssub:
560 if not end_src:
561 self.svstate.srcstep += SelectableInt(1, 7)
562 self.svstate.ssubstep = SelectableInt(0, 2) # reset
563 else:
564 self.svstate.ssubstep += SelectableInt(1, 2) # advance ssubstep
565
566 log(" advance src", self.svstate.srcstep, self.svstate.ssubstep)
567
568 def dst_iterator(self):
569 """dest step iterator
570 """
571 end_dst = self.end_dst
572 subvl = self.subvl
573 pack = self.svstate.pack
574 unpack = self.svstate.unpack
575 dsubstep = self.svstate.dsubstep
576 end_dsub = dsubstep == subvl
577 log(" pack/unpack/subvl", pack, unpack, subvl,
578 "end", end_dst,
579 "sub", end_dsub)
580 # now dest step
581 if unpack:
582 # unpack advances subvl in *outer* loop
583 if end_dst:
584 if not end_dsub:
585 self.svstate.dsubstep += SelectableInt(1, 2)
586 self.svstate.dststep = SelectableInt(0, 7) # reset
587 else:
588 self.svstate.dststep += SelectableInt(1, 7) # advance dststep
589 else:
590 # advance subvl in *inner* loop
591 if end_dsub:
592 if not end_dst:
593 self.svstate.dststep += SelectableInt(1, 7)
594 self.svstate.dsubstep = SelectableInt(0, 2) # reset
595 else:
596 self.svstate.dsubstep += SelectableInt(1, 2) # advance ssubstep
597 log(" advance dst", self.svstate.dststep, self.svstate.dsubstep)
598
599 def advance_svstate_steps(self, end_src=False, end_dst=False):
600 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
601 TODO when Pack/Unpack is set, substep becomes the *outer* loop
602 """
603 self.subvl = yield self.dec2.rm_dec.rm_in.subvl
604 self.end_src = end_src
605 self.end_dst = end_dst
606 self.src_iterator()
607 self.dst_iterator()
608
609 def svstate_pre_inc(self):
610 """check if srcstep/dststep need to skip over masked-out predicate bits
611 note that this is not supposed to do anything to substep,
612 it is purely for skipping masked-out bits
613 """
614 # get SVSTATE VL (oh and print out some debug stuff)
615 # yield Delay(1e-10) # make changes visible
616 vl = self.svstate.vl
617 subvl = yield self.dec2.rm_dec.rm_in.subvl
618 srcstep = self.svstate.srcstep
619 dststep = self.svstate.dststep
620 ssubstep = self.svstate.ssubstep
621 dsubstep = self.svstate.dsubstep
622 pack = self.svstate.pack
623 unpack = self.svstate.unpack
624 sv_a_nz = yield self.dec2.sv_a_nz
625 fft_mode = yield self.dec2.use_svp64_fft
626 in1 = yield self.dec2.e.read_reg1.data
627 log("SVP64: VL, subvl, srcstep, dststep, ssubstep, dsybstep, sv_a_nz, "
628 "in1 fft, svp64",
629 vl, subvl, srcstep, dststep, ssubstep, dsubstep,
630 sv_a_nz, in1, fft_mode,
631 self.is_svp64_mode)
632
633 # get predicate mask (all 64 bits)
634 srcmask = dstmask = 0xffff_ffff_ffff_ffff
635
636 pmode = yield self.dec2.rm_dec.predmode
637 reverse_gear = yield self.dec2.rm_dec.reverse_gear
638 sv_ptype = yield self.dec2.dec.op.SV_Ptype
639 srcpred = yield self.dec2.rm_dec.srcpred
640 dstpred = yield self.dec2.rm_dec.dstpred
641 pred_src_zero = yield self.dec2.rm_dec.pred_sz
642 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
643 if pmode == SVP64PredMode.INT.value:
644 srcmask = dstmask = get_predint(self.gpr, dstpred)
645 if sv_ptype == SVPtype.P2.value:
646 srcmask = get_predint(self.gpr, srcpred)
647 elif pmode == SVP64PredMode.CR.value:
648 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
649 if sv_ptype == SVPtype.P2.value:
650 srcmask = get_predcr(self.crl, srcpred, vl)
651 # work out if the ssubsteps are completed
652 ssubstart = ssubstep == 0
653 dsubstart = dsubstep == 0
654 log(" pmode", pmode)
655 log(" pack/unpack", pack, unpack)
656 log(" reverse", reverse_gear)
657 log(" ptype", sv_ptype)
658 log(" srcpred", bin(srcpred))
659 log(" dstpred", bin(dstpred))
660 log(" srcmask", bin(srcmask))
661 log(" dstmask", bin(dstmask))
662 log(" pred_sz", bin(pred_src_zero))
663 log(" pred_dz", bin(pred_dst_zero))
664 log(" ssubstart", ssubstart)
665 log(" dsubstart", dsubstart)
666
667 # okaaay, so here we simply advance srcstep (TODO dststep)
668 # this can ONLY be done at the beginning of the "for" loop
669 # (this is all actually a FSM so it's hell to keep track sigh)
670 srcstep_skip = False
671 if ssubstart:
672 # until the predicate mask has a "1" bit... or we run out of VL
673 # let srcstep==VL be the indicator to move to next instruction
674 if not pred_src_zero:
675 srcstep_skip = True
676
677 # srcstep-skipping opportunity identified
678 if srcstep_skip:
679 while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl):
680 log(" sskip", bin(1 << srcstep))
681 srcstep += 1
682
683 dststep_skip = False
684 if dsubstart:
685 # same for dststep
686 if not pred_dst_zero:
687 dststep_skip = True
688
689 # dststep-skipping opportunity identified
690 if dststep_skip:
691 while (((1 << dststep) & dstmask) == 0) and (dststep != vl):
692 log(" dskip", bin(1 << dststep))
693 dststep += 1
694
695 # now work out if the relevant mask bits require zeroing
696 if pred_dst_zero:
697 pred_dst_zero = ((1 << dststep) & dstmask) == 0
698 if pred_src_zero:
699 pred_src_zero = ((1 << srcstep) & srcmask) == 0
700
701 # store new srcstep / dststep
702 self.new_srcstep, self.new_dststep = (srcstep, dststep)
703 self.new_ssubstep, self.new_dsubstep = (ssubstep, dsubstep)
704 self.pred_dst_zero, self.pred_src_zero = (pred_dst_zero, pred_src_zero)
705 log(" new srcstep", srcstep)
706 log(" new dststep", dststep)
707 log(" new ssubstep", ssubstep)
708 log(" new dsubstep", dsubstep)
709
710
711 class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
712 # decoder2 - an instance of power_decoder2
713 # regfile - a list of initial values for the registers
714 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
715 # respect_pc - tracks the program counter. requires initial_insns
716 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
717 initial_mem=None, initial_msr=0,
718 initial_svstate=0,
719 initial_insns=None,
720 fpregfile=None,
721 respect_pc=False,
722 disassembly=None,
723 initial_pc=0,
724 bigendian=False,
725 mmu=False,
726 icachemmu=False):
727
728 self.bigendian = bigendian
729 self.halted = False
730 self.is_svp64_mode = False
731 self.respect_pc = respect_pc
732 if initial_sprs is None:
733 initial_sprs = {}
734 if initial_mem is None:
735 initial_mem = {}
736 if fpregfile is None:
737 fpregfile = [0] * 32
738 if initial_insns is None:
739 initial_insns = {}
740 assert self.respect_pc == False, "instructions required to honor pc"
741
742 log("ISACaller insns", respect_pc, initial_insns, disassembly)
743 log("ISACaller initial_msr", initial_msr)
744
745 # "fake program counter" mode (for unit testing)
746 self.fake_pc = 0
747 disasm_start = 0
748 if not respect_pc:
749 if isinstance(initial_mem, tuple):
750 self.fake_pc = initial_mem[0]
751 disasm_start = self.fake_pc
752 else:
753 disasm_start = initial_pc
754
755 # disassembly: we need this for now (not given from the decoder)
756 self.disassembly = {}
757 if disassembly:
758 for i, code in enumerate(disassembly):
759 self.disassembly[i*4 + disasm_start] = code
760
761 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
762 self.svp64rm = SVP64RM()
763 if initial_svstate is None:
764 initial_svstate = 0
765 if isinstance(initial_svstate, int):
766 initial_svstate = SVP64State(initial_svstate)
767 # SVSTATE, MSR and PC
768 StepLoop.__init__(self, initial_svstate)
769 self.msr = SelectableInt(initial_msr, 64) # underlying reg
770 self.pc = PC()
771 # GPR FPR SPR registers
772 initial_sprs = deepcopy(initial_sprs) # so as not to get modified
773 self.gpr = GPR(decoder2, self, self.svstate, regfile)
774 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
775 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
776
777 # set up 4 dummy SVSHAPEs if they aren't already set up
778 for i in range(4):
779 sname = 'SVSHAPE%d' % i
780 if sname not in self.spr:
781 val = 0
782 else:
783 val = self.spr[sname].value
784 # make sure it's an SVSHAPE
785 self.spr[sname] = SVSHAPE(val, self.gpr)
786 self.last_op_svshape = False
787
788 # "raw" memory
789 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
790 self.mem.log_fancy(kind=LogKind.InstrInOuts)
791 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
792 # MMU mode, redirect underlying Mem through RADIX
793 if mmu:
794 self.mem = RADIX(self.mem, self)
795 if icachemmu:
796 self.imem = RADIX(self.imem, self)
797
798 # TODO, needed here:
799 # FPR (same as GPR except for FP nums)
800 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
801 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
802 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
803 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
804 # -- Done
805 # 2.3.2 LR (actually SPR #8) -- Done
806 # 2.3.3 CTR (actually SPR #9) -- Done
807 # 2.3.4 TAR (actually SPR #815)
808 # 3.2.2 p45 XER (actually SPR #1) -- Done
809 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
810
811 # create CR then allow portions of it to be "selectable" (below)
812 self.cr_fields = CRFields(initial_cr)
813 self.cr = self.cr_fields.cr
814
815 # "undefined", just set to variable-bit-width int (use exts "max")
816 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
817
818 self.namespace = {}
819 self.namespace.update(self.spr)
820 self.namespace.update({'GPR': self.gpr,
821 'FPR': self.fpr,
822 'MEM': self.mem,
823 'SPR': self.spr,
824 'memassign': self.memassign,
825 'NIA': self.pc.NIA,
826 'CIA': self.pc.CIA,
827 'SVSTATE': self.svstate,
828 'SVSHAPE0': self.spr['SVSHAPE0'],
829 'SVSHAPE1': self.spr['SVSHAPE1'],
830 'SVSHAPE2': self.spr['SVSHAPE2'],
831 'SVSHAPE3': self.spr['SVSHAPE3'],
832 'CR': self.cr,
833 'MSR': self.msr,
834 'undefined': undefined,
835 'mode_is_64bit': True,
836 'SO': XER_bits['SO'],
837 'XLEN': 64 # elwidth overrides, later
838 })
839
840 # update pc to requested start point
841 self.set_pc(initial_pc)
842
843 # field-selectable versions of Condition Register
844 self.crl = self.cr_fields.crl
845 for i in range(8):
846 self.namespace["CR%d" % i] = self.crl[i]
847
848 self.decoder = decoder2.dec
849 self.dec2 = decoder2
850
851 super().__init__(XLEN=self.namespace["XLEN"])
852
853 @property
854 def XLEN(self):
855 return self.namespace["XLEN"]
856
857 def call_trap(self, trap_addr, trap_bit):
858 """calls TRAP and sets up NIA to the new execution location.
859 next instruction will begin at trap_addr.
860 """
861 self.TRAP(trap_addr, trap_bit)
862 self.namespace['NIA'] = self.trap_nia
863 self.pc.update(self.namespace, self.is_svp64_mode)
864
865 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
866 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
867
868 TRAP function is callable from inside the pseudocode itself,
869 hence the default arguments. when calling from inside ISACaller
870 it is best to use call_trap()
871 """
872 # https://bugs.libre-soc.org/show_bug.cgi?id=859
873 kaivb = self.spr['KAIVB'].value
874 msr = self.namespace['MSR'].value
875 log("TRAP:", hex(trap_addr), hex(msr), "kaivb", hex(kaivb))
876 # store CIA(+4?) in SRR0, set NIA to 0x700
877 # store MSR in SRR1, set MSR to um errr something, have to check spec
878 # store SVSTATE (if enabled) in SVSRR0
879 self.spr['SRR0'].value = self.pc.CIA.value
880 self.spr['SRR1'].value = msr
881 if self.is_svp64_mode:
882 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
883 self.trap_nia = SelectableInt(trap_addr | (kaivb&~0x1fff), 64)
884 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
885
886 # set exception bits. TODO: this should, based on the address
887 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
888 # bits appropriately. however it turns out that *for now* in all
889 # cases (all trap_addrs) the exact same thing is needed.
890 self.msr[MSRb.IR] = 0
891 self.msr[MSRb.DR] = 0
892 self.msr[MSRb.FE0] = 0
893 self.msr[MSRb.FE1] = 0
894 self.msr[MSRb.EE] = 0
895 self.msr[MSRb.RI] = 0
896 self.msr[MSRb.SF] = 1
897 self.msr[MSRb.TM] = 0
898 self.msr[MSRb.VEC] = 0
899 self.msr[MSRb.VSX] = 0
900 self.msr[MSRb.PR] = 0
901 self.msr[MSRb.FP] = 0
902 self.msr[MSRb.PMM] = 0
903 self.msr[MSRb.TEs] = 0
904 self.msr[MSRb.TEe] = 0
905 self.msr[MSRb.UND] = 0
906 self.msr[MSRb.LE] = 1
907
908 def memassign(self, ea, sz, val):
909 self.mem.memassign(ea, sz, val)
910
911 def prep_namespace(self, insn_name, formname, op_fields):
912 # TODO: get field names from form in decoder*1* (not decoder2)
913 # decoder2 is hand-created, and decoder1.sigform is auto-generated
914 # from spec
915 # then "yield" fields only from op_fields rather than hard-coded
916 # list, here.
917 fields = self.decoder.sigforms[formname]
918 log("prep_namespace", formname, op_fields, insn_name)
919 for name in op_fields:
920 # CR immediates. deal with separately. needs modifying
921 # pseudocode
922 if self.is_svp64_mode and name in ['BI']: # TODO, more CRs
923 # BI is a 5-bit, must reconstruct the value
924 regnum, is_vec = yield from get_pdecode_cr_in(self.dec2, name)
925 sig = getattr(fields, name)
926 val = yield sig
927 # low 2 LSBs (CR field selector) remain same, CR num extended
928 assert regnum <= 7, "sigh, TODO, 128 CR fields"
929 val = (val & 0b11) | (regnum << 2)
930 else:
931 sig = getattr(fields, name)
932 val = yield sig
933 # these are all opcode fields involved in index-selection of CR,
934 # and need to do "standard" arithmetic. CR[BA+32] for example
935 # would, if using SelectableInt, only be 5-bit.
936 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
937 self.namespace[name] = val
938 else:
939 self.namespace[name] = SelectableInt(val, sig.width)
940
941 self.namespace['XER'] = self.spr['XER']
942 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
943 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
944
945 # add some SVSTATE convenience variables
946 vl = self.svstate.vl
947 srcstep = self.svstate.srcstep
948 self.namespace['VL'] = vl
949 self.namespace['srcstep'] = srcstep
950
951 # sv.bc* need some extra fields
952 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
953 # blegh grab bits manually
954 mode = yield self.dec2.rm_dec.rm_in.mode
955 bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0
956 bc_vli = (mode & SVP64MODE.BC_VLI) != 0
957 bc_snz = (mode & SVP64MODE.BC_SNZ) != 0
958 bc_vsb = yield self.dec2.rm_dec.bc_vsb
959 bc_lru = yield self.dec2.rm_dec.bc_lru
960 bc_gate = yield self.dec2.rm_dec.bc_gate
961 sz = yield self.dec2.rm_dec.pred_sz
962 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
963 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
964 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
965 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
966 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
967 self.namespace['sz'] = SelectableInt(sz, 1)
968 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
969
970 def handle_carry_(self, inputs, outputs, already_done):
971 inv_a = yield self.dec2.e.do.invert_in
972 if inv_a:
973 inputs[0] = ~inputs[0]
974
975 imm_ok = yield self.dec2.e.do.imm_data.ok
976 if imm_ok:
977 imm = yield self.dec2.e.do.imm_data.data
978 inputs.append(SelectableInt(imm, 64))
979 assert len(outputs) >= 1
980 log("outputs", repr(outputs))
981 if isinstance(outputs, list) or isinstance(outputs, tuple):
982 output = outputs[0]
983 else:
984 output = outputs
985 gts = []
986 for x in inputs:
987 log("gt input", x, output)
988 gt = (gtu(x, output))
989 gts.append(gt)
990 log(gts)
991 cy = 1 if any(gts) else 0
992 log("CA", cy, gts)
993 if not (1 & already_done):
994 self.spr['XER'][XER_bits['CA']] = cy
995
996 log("inputs", already_done, inputs)
997 # 32 bit carry
998 # ARGH... different for OP_ADD... *sigh*...
999 op = yield self.dec2.e.do.insn_type
1000 if op == MicrOp.OP_ADD.value:
1001 res32 = (output.value & (1 << 32)) != 0
1002 a32 = (inputs[0].value & (1 << 32)) != 0
1003 if len(inputs) >= 2:
1004 b32 = (inputs[1].value & (1 << 32)) != 0
1005 else:
1006 b32 = False
1007 cy32 = res32 ^ a32 ^ b32
1008 log("CA32 ADD", cy32)
1009 else:
1010 gts = []
1011 for x in inputs:
1012 log("input", x, output)
1013 log(" x[32:64]", x, x[32:64])
1014 log(" o[32:64]", output, output[32:64])
1015 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
1016 gts.append(gt)
1017 cy32 = 1 if any(gts) else 0
1018 log("CA32", cy32, gts)
1019 if not (2 & already_done):
1020 self.spr['XER'][XER_bits['CA32']] = cy32
1021
1022 def handle_overflow(self, inputs, outputs, div_overflow):
1023 if hasattr(self.dec2.e.do, "invert_in"):
1024 inv_a = yield self.dec2.e.do.invert_in
1025 if inv_a:
1026 inputs[0] = ~inputs[0]
1027
1028 imm_ok = yield self.dec2.e.do.imm_data.ok
1029 if imm_ok:
1030 imm = yield self.dec2.e.do.imm_data.data
1031 inputs.append(SelectableInt(imm, 64))
1032 assert len(outputs) >= 1
1033 log("handle_overflow", inputs, outputs, div_overflow)
1034 if len(inputs) < 2 and div_overflow is None:
1035 return
1036
1037 # div overflow is different: it's returned by the pseudo-code
1038 # because it's more complex than can be done by analysing the output
1039 if div_overflow is not None:
1040 ov, ov32 = div_overflow, div_overflow
1041 # arithmetic overflow can be done by analysing the input and output
1042 elif len(inputs) >= 2:
1043 output = outputs[0]
1044
1045 # OV (64-bit)
1046 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
1047 output_sgn = exts(output.value, output.bits) < 0
1048 ov = 1 if input_sgn[0] == input_sgn[1] and \
1049 output_sgn != input_sgn[0] else 0
1050
1051 # OV (32-bit)
1052 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
1053 output32_sgn = exts(output.value, 32) < 0
1054 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
1055 output32_sgn != input32_sgn[0] else 0
1056
1057 # now update XER OV/OV32/SO
1058 so = self.spr['XER'][XER_bits['SO']]
1059 new_so = so | ov # sticky overflow ORs in old with new
1060 self.spr['XER'][XER_bits['OV']] = ov
1061 self.spr['XER'][XER_bits['OV32']] = ov32
1062 self.spr['XER'][XER_bits['SO']] = new_so
1063 log(" set overflow", ov, ov32, so, new_so)
1064
1065 def handle_comparison(self, outputs, cr_idx=0, overflow=None, no_so=False):
1066 out = outputs[0]
1067 assert isinstance(out, SelectableInt), \
1068 "out zero not a SelectableInt %s" % repr(outputs)
1069 log("handle_comparison", out.bits, hex(out.value))
1070 # TODO - XXX *processor* in 32-bit mode
1071 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1072 # if is_32bit:
1073 # o32 = exts(out.value, 32)
1074 # print ("handle_comparison exts 32 bit", hex(o32))
1075 out = exts(out.value, out.bits)
1076 log("handle_comparison exts", hex(out))
1077 # create the three main CR flags, EQ GT LT
1078 zero = SelectableInt(out == 0, 1)
1079 positive = SelectableInt(out > 0, 1)
1080 negative = SelectableInt(out < 0, 1)
1081 # get (or not) XER.SO. for setvl this is important *not* to read SO
1082 if no_so:
1083 SO = SelectableInt(1, 0)
1084 else:
1085 SO = self.spr['XER'][XER_bits['SO']]
1086 log("handle_comparison SO overflow", SO, overflow)
1087 # alternative overflow checking (setvl mainly at the moment)
1088 if overflow is not None and overflow == 1:
1089 SO = SelectableInt(1, 1)
1090 # create the four CR field values and set the required CR field
1091 cr_field = selectconcat(negative, positive, zero, SO)
1092 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
1093 self.crl[cr_idx].eq(cr_field)
1094
1095 def set_pc(self, pc_val):
1096 self.namespace['NIA'] = SelectableInt(pc_val, 64)
1097 self.pc.update(self.namespace, self.is_svp64_mode)
1098
1099 def get_next_insn(self):
1100 """check instruction
1101 """
1102 if self.respect_pc:
1103 pc = self.pc.CIA.value
1104 else:
1105 pc = self.fake_pc
1106 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
1107 if ins is None:
1108 raise KeyError("no instruction at 0x%x" % pc)
1109 return pc, ins
1110
1111 def setup_one(self):
1112 """set up one instruction
1113 """
1114 pc, insn = self.get_next_insn()
1115 yield from self.setup_next_insn(pc, insn)
1116
1117 def setup_next_insn(self, pc, ins):
1118 """set up next instruction
1119 """
1120 self._pc = pc
1121 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
1122 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
1123
1124 yield self.dec2.sv_rm.eq(0)
1125 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
1126 yield self.dec2.dec.bigendian.eq(self.bigendian)
1127 yield self.dec2.state.msr.eq(self.msr.value)
1128 yield self.dec2.state.pc.eq(pc)
1129 if self.svstate is not None:
1130 yield self.dec2.state.svstate.eq(self.svstate.value)
1131
1132 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1133 yield Settle()
1134 opcode = yield self.dec2.dec.opcode_in
1135 opcode = SelectableInt(value=opcode, bits=32)
1136 pfx = SVP64Instruction.Prefix(opcode)
1137 log("prefix test: opcode:", pfx.po, bin(pfx.po), pfx.id)
1138 self.is_svp64_mode = bool((pfx.po == 0b000001) and (pfx.id == 0b11))
1139 self.pc.update_nia(self.is_svp64_mode)
1140 # set SVP64 decode
1141 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
1142 self.namespace['NIA'] = self.pc.NIA
1143 self.namespace['SVSTATE'] = self.svstate
1144 if not self.is_svp64_mode:
1145 return
1146
1147 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1148 log("svp64.rm", bin(pfx.rm))
1149 log(" svstate.vl", self.svstate.vl)
1150 log(" svstate.mvl", self.svstate.maxvl)
1151 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
1152 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
1153 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
1154 yield self.dec2.sv_rm.eq(int(pfx.rm)) # svp64 prefix
1155 yield Settle()
1156
1157 def execute_one(self):
1158 """execute one instruction
1159 """
1160 # get the disassembly code for this instruction
1161 if self.is_svp64_mode:
1162 if not self.disassembly:
1163 code = yield from self.get_assembly_name()
1164 else:
1165 code = self.disassembly[self._pc+4]
1166 log(" svp64 sim-execute", hex(self._pc), code)
1167 else:
1168 if not self.disassembly:
1169 code = yield from self.get_assembly_name()
1170 else:
1171 code = self.disassembly[self._pc]
1172 log("sim-execute", hex(self._pc), code)
1173 opname = code.split(' ')[0]
1174 try:
1175 yield from self.call(opname) # execute the instruction
1176 except MemException as e: # check for memory errors
1177 if e.args[0] == 'unaligned': # alignment error
1178 # run a Trap but set DAR first
1179 print("memory unaligned exception, DAR", e.dar)
1180 self.spr['DAR'] = SelectableInt(e.dar, 64)
1181 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1182 return
1183 elif e.args[0] == 'invalid': # invalid
1184 # run a Trap but set DAR first
1185 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1186 if e.mode == 'EXECUTE':
1187 # XXX TODO: must set a few bits in SRR1,
1188 # see microwatt loadstore1.vhdl
1189 # if m_in.segerr = '0' then
1190 # v.srr1(47 - 33) := m_in.invalid;
1191 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1192 # v.srr1(47 - 44) := m_in.badtree;
1193 # v.srr1(47 - 45) := m_in.rc_error;
1194 # v.intr_vec := 16#400#;
1195 # else
1196 # v.intr_vec := 16#480#;
1197 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1198 else:
1199 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1200 return
1201 # not supported yet:
1202 raise e # ... re-raise
1203
1204 # don't use this except in special circumstances
1205 if not self.respect_pc:
1206 self.fake_pc += 4
1207
1208 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1209 hex(self.pc.NIA.value))
1210
1211 def get_assembly_name(self):
1212 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1213 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1214 dec_insn = yield self.dec2.e.do.insn
1215 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1216 asmcode = yield self.dec2.dec.op.asmcode
1217 int_op = yield self.dec2.dec.op.internal_op
1218 log("get assembly name asmcode", asmcode, int_op,
1219 hex(dec_insn), bin(insn_1_11))
1220 asmop = insns.get(asmcode, None)
1221
1222 # sigh reconstruct the assembly instruction name
1223 if hasattr(self.dec2.e.do, "oe"):
1224 ov_en = yield self.dec2.e.do.oe.oe
1225 ov_ok = yield self.dec2.e.do.oe.ok
1226 else:
1227 ov_en = False
1228 ov_ok = False
1229 if hasattr(self.dec2.e.do, "rc"):
1230 rc_en = yield self.dec2.e.do.rc.rc
1231 rc_ok = yield self.dec2.e.do.rc.ok
1232 else:
1233 rc_en = False
1234 rc_ok = False
1235 # grrrr have to special-case MUL op (see DecodeOE)
1236 log("ov %d en %d rc %d en %d op %d" %
1237 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1238 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1239 log("mul op")
1240 if rc_en & rc_ok:
1241 asmop += "."
1242 else:
1243 if not asmop.endswith("."): # don't add "." to "andis."
1244 if rc_en & rc_ok:
1245 asmop += "."
1246 if hasattr(self.dec2.e.do, "lk"):
1247 lk = yield self.dec2.e.do.lk
1248 if lk:
1249 asmop += "l"
1250 log("int_op", int_op)
1251 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1252 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1253 log("AA", AA)
1254 if AA:
1255 asmop += "a"
1256 spr_msb = yield from self.get_spr_msb()
1257 if int_op == MicrOp.OP_MFCR.value:
1258 if spr_msb:
1259 asmop = 'mfocrf'
1260 else:
1261 asmop = 'mfcr'
1262 # XXX TODO: for whatever weird reason this doesn't work
1263 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1264 if int_op == MicrOp.OP_MTCRF.value:
1265 if spr_msb:
1266 asmop = 'mtocrf'
1267 else:
1268 asmop = 'mtcrf'
1269 return asmop
1270
1271 def get_remap_indices(self):
1272 """WARNING, this function stores remap_idxs and remap_loopends
1273 in the class for later use. this to avoid problems with yield
1274 """
1275 # go through all iterators in lock-step, advance to next remap_idx
1276 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1277 # get four SVSHAPEs. here we are hard-coding
1278 SVSHAPE0 = self.spr['SVSHAPE0']
1279 SVSHAPE1 = self.spr['SVSHAPE1']
1280 SVSHAPE2 = self.spr['SVSHAPE2']
1281 SVSHAPE3 = self.spr['SVSHAPE3']
1282 # set up the iterators
1283 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1284 (SVSHAPE1, SVSHAPE1.get_iterator()),
1285 (SVSHAPE2, SVSHAPE2.get_iterator()),
1286 (SVSHAPE3, SVSHAPE3.get_iterator()),
1287 ]
1288
1289 self.remap_loopends = [0] * 4
1290 self.remap_idxs = [0, 1, 2, 3]
1291 dbg = []
1292 for i, (shape, remap) in enumerate(remaps):
1293 # zero is "disabled"
1294 if shape.value == 0x0:
1295 self.remap_idxs[i] = 0
1296 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1297 step = dststep if (i in [3, 4]) else srcstep
1298 # this is terrible. O(N^2) looking for the match. but hey.
1299 for idx, (remap_idx, loopends) in enumerate(remap):
1300 if idx == step:
1301 break
1302 self.remap_idxs[i] = remap_idx
1303 self.remap_loopends[i] = loopends
1304 dbg.append((i, step, remap_idx, loopends))
1305 for (i, step, remap_idx, loopends) in dbg:
1306 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1307 return remaps
1308
1309 def get_spr_msb(self):
1310 dec_insn = yield self.dec2.e.do.insn
1311 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1312
1313 def call(self, name):
1314 """call(opcode) - the primary execution point for instructions
1315 """
1316 self.last_st_addr = None # reset the last known store address
1317 self.last_ld_addr = None # etc.
1318
1319 ins_name = name.strip() # remove spaces if not already done so
1320 if self.halted:
1321 log("halted - not executing", ins_name)
1322 return
1323
1324 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1325 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1326 asmop = yield from self.get_assembly_name()
1327 log("call", ins_name, asmop)
1328
1329 # sv.setvl is *not* a loop-function. sigh
1330 log("is_svp64_mode", self.is_svp64_mode, asmop)
1331
1332 # check privileged
1333 int_op = yield self.dec2.dec.op.internal_op
1334 spr_msb = yield from self.get_spr_msb()
1335
1336 instr_is_privileged = False
1337 if int_op in [MicrOp.OP_ATTN.value,
1338 MicrOp.OP_MFMSR.value,
1339 MicrOp.OP_MTMSR.value,
1340 MicrOp.OP_MTMSRD.value,
1341 # TODO: OP_TLBIE
1342 MicrOp.OP_RFID.value]:
1343 instr_is_privileged = True
1344 if int_op in [MicrOp.OP_MFSPR.value,
1345 MicrOp.OP_MTSPR.value] and spr_msb:
1346 instr_is_privileged = True
1347
1348 log("is priv", instr_is_privileged, hex(self.msr.value),
1349 self.msr[MSRb.PR])
1350 # check MSR priv bit and whether op is privileged: if so, throw trap
1351 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1352 self.call_trap(0x700, PIb.PRIV)
1353 return
1354
1355 # check halted condition
1356 if ins_name == 'attn':
1357 self.halted = True
1358 return
1359
1360 # check illegal instruction
1361 illegal = False
1362 if ins_name not in ['mtcrf', 'mtocrf']:
1363 illegal = ins_name != asmop
1364
1365 # list of instructions not being supported by binutils (.long)
1366 dotstrp = asmop[:-1] if asmop[-1] == '.' else asmop
1367 if dotstrp in [*FPTRANS_INSNS,
1368 'ffmadds', 'fdmadds', 'ffadds',
1369 'mins', 'maxs', 'minu', 'maxu',
1370 'setvl', 'svindex', 'svremap', 'svstep',
1371 'svshape', 'svshape2',
1372 'grev', 'ternlogi', 'bmask', 'cprop',
1373 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1374 'fmvis', 'fishmv',
1375 ]:
1376 illegal = False
1377 ins_name = dotstrp
1378
1379 # branch-conditional redirects to sv.bc
1380 if asmop.startswith('bc') and self.is_svp64_mode:
1381 ins_name = 'sv.%s' % ins_name
1382
1383 log(" post-processed name", dotstrp, ins_name, asmop)
1384
1385 # illegal instructions call TRAP at 0x700
1386 if illegal:
1387 print("illegal", ins_name, asmop)
1388 self.call_trap(0x700, PIb.ILLEG)
1389 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1390 (ins_name, asmop, self.pc.CIA.value))
1391 return
1392
1393 # this is for setvl "Vertical" mode: if set true,
1394 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1395 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1396 self.allow_next_step_inc = False
1397 self.svstate_next_mode = 0
1398
1399 # nop has to be supported, we could let the actual op calculate
1400 # but PowerDecoder has a pattern for nop
1401 if ins_name == 'nop':
1402 self.update_pc_next()
1403 return
1404
1405 # look up instruction in ISA.instrs, prepare namespace
1406 info = self.instrs[ins_name]
1407 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1408
1409 # preserve order of register names
1410 input_names = create_args(list(info.read_regs) +
1411 list(info.uninit_regs))
1412 log("input names", input_names)
1413
1414 # get SVP64 entry for the current instruction
1415 sv_rm = self.svp64rm.instrs.get(ins_name)
1416 if sv_rm is not None:
1417 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1418 else:
1419 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1420 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1421
1422 # see if srcstep/dststep need skipping over masked-out predicate bits
1423 if (self.is_svp64_mode or ins_name in ['setvl', 'svremap', 'svstate']):
1424 yield from self.svstate_pre_inc()
1425 if self.is_svp64_mode:
1426 pre = yield from self.update_new_svstate_steps()
1427 if pre:
1428 self.svp64_reset_loop()
1429 self.update_nia()
1430 self.update_pc_next()
1431 return
1432 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1433 pred_dst_zero = self.pred_dst_zero
1434 pred_src_zero = self.pred_src_zero
1435 vl = self.svstate.vl
1436 subvl = yield self.dec2.rm_dec.rm_in.subvl
1437
1438 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1439 if self.is_svp64_mode and vl == 0:
1440 self.pc.update(self.namespace, self.is_svp64_mode)
1441 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1442 self.namespace['NIA'], kind=LogKind.InstrInOuts)
1443 return
1444
1445 # for when SVREMAP is active, using pre-arranged schedule.
1446 # note: modifying PowerDecoder2 needs to "settle"
1447 remap_en = self.svstate.SVme
1448 persist = self.svstate.RMpst
1449 active = (persist or self.last_op_svshape) and remap_en != 0
1450 if self.is_svp64_mode:
1451 yield self.dec2.remap_active.eq(remap_en if active else 0)
1452 yield Settle()
1453 if persist or self.last_op_svshape:
1454 remaps = self.get_remap_indices()
1455 if self.is_svp64_mode and (persist or self.last_op_svshape):
1456 yield from self.remap_set_steps(remaps)
1457 # after that, settle down (combinatorial) to let Vector reg numbers
1458 # work themselves out
1459 yield Settle()
1460 if self.is_svp64_mode:
1461 remap_active = yield self.dec2.remap_active
1462 else:
1463 remap_active = False
1464 log("remap active", bin(remap_active))
1465
1466 # main input registers (RT, RA ...)
1467 inputs = []
1468 for name in input_names:
1469 log("name", name)
1470 regval = (yield from self.get_input(name))
1471 log("regval", regval)
1472 inputs.append(regval)
1473
1474 # arrrrgh, awful hack, to get _RT into namespace
1475 if ins_name in ['setvl', 'svstep']:
1476 regname = "_RT"
1477 RT = yield self.dec2.dec.RT
1478 self.namespace[regname] = SelectableInt(RT, 5)
1479 if RT == 0:
1480 self.namespace["RT"] = SelectableInt(0, 5)
1481 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1482 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1483
1484 # in SVP64 mode for LD/ST work out immediate
1485 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1486 # use info.form to detect
1487 if self.is_svp64_mode:
1488 yield from self.check_replace_d(info, remap_active)
1489
1490 # "special" registers
1491 for special in info.special_regs:
1492 if special in special_sprs:
1493 inputs.append(self.spr[special])
1494 else:
1495 inputs.append(self.namespace[special])
1496
1497 # clear trap (trap) NIA
1498 self.trap_nia = None
1499
1500 # check if this was an sv.bc* and create an indicator that
1501 # this is the last check to be made as a loop. combined with
1502 # the ALL/ANY mode we can early-exit
1503 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
1504 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
1505 # XXX TODO - pack/unpack here
1506 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
1507 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
1508
1509 # execute actual instruction here (finally)
1510 log("inputs", inputs)
1511 results = info.func(self, *inputs)
1512 log("results", results)
1513
1514 # "inject" decorator takes namespace from function locals: we need to
1515 # overwrite NIA being overwritten (sigh)
1516 if self.trap_nia is not None:
1517 self.namespace['NIA'] = self.trap_nia
1518
1519 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1520
1521 # check if op was a LD/ST so that debugging can check the
1522 # address
1523 if int_op in [MicrOp.OP_STORE.value,
1524 ]:
1525 self.last_st_addr = self.mem.last_st_addr
1526 if int_op in [MicrOp.OP_LOAD.value,
1527 ]:
1528 self.last_ld_addr = self.mem.last_ld_addr
1529 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1530 self.last_st_addr, self.last_ld_addr)
1531
1532 # detect if CA/CA32 already in outputs (sra*, basically)
1533 already_done = 0
1534 if info.write_regs:
1535 output_names = create_args(info.write_regs)
1536 for name in output_names:
1537 if name == 'CA':
1538 already_done |= 1
1539 if name == 'CA32':
1540 already_done |= 2
1541
1542 log("carry already done?", bin(already_done))
1543 if hasattr(self.dec2.e.do, "output_carry"):
1544 carry_en = yield self.dec2.e.do.output_carry
1545 else:
1546 carry_en = False
1547 if carry_en:
1548 yield from self.handle_carry_(inputs, results, already_done)
1549
1550 # check if one of the regs was named "overflow"
1551 overflow = None
1552 if info.write_regs:
1553 for name, output in zip(output_names, results):
1554 if name == 'overflow':
1555 overflow = output
1556
1557 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1558 # detect if overflow was in return result
1559 if hasattr(self.dec2.e.do, "oe"):
1560 ov_en = yield self.dec2.e.do.oe.oe
1561 ov_ok = yield self.dec2.e.do.oe.ok
1562 else:
1563 ov_en = False
1564 ov_ok = False
1565 log("internal overflow", ins_name, overflow, "en?", ov_en, ov_ok)
1566 if ov_en & ov_ok:
1567 yield from self.handle_overflow(inputs, results, overflow)
1568
1569 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1570 rc_en = False
1571 if not self.is_svp64_mode or not pred_dst_zero:
1572 if hasattr(self.dec2.e.do, "rc"):
1573 rc_en = yield self.dec2.e.do.rc.rc
1574 if rc_en and ins_name not in ['svstep']:
1575 if ins_name.startswith("f"):
1576 rc_reg = "CR1" # not calculated correctly yet (not FP compares)
1577 else:
1578 rc_reg = "CR0"
1579 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, rc_reg)
1580 cmps = results
1581 # hang on... for `setvl` actually you want to test SVSTATE.VL
1582 is_setvl = ins_name == 'setvl'
1583 if is_setvl:
1584 vl = results[0].vl
1585 cmps = (SelectableInt(vl, 64), overflow,)
1586 else:
1587 overflow = None # do not override overflow except in setvl
1588 self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
1589
1590 # any modified return results?
1591 if info.write_regs:
1592 for name, output in zip(output_names, results):
1593 yield from self.check_write(info, name, output, carry_en)
1594
1595 nia_update = (yield from self.check_step_increment(results, rc_en,
1596 asmop, ins_name))
1597 if nia_update:
1598 self.update_pc_next()
1599
1600 def check_replace_d(self, info, remap_active):
1601 replace_d = False # update / replace constant in pseudocode
1602 ldstmode = yield self.dec2.rm_dec.ldstmode
1603 vl = self.svstate.vl
1604 subvl = yield self.dec2.rm_dec.rm_in.subvl
1605 srcstep, dststep = self.new_srcstep, self.new_dststep
1606 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1607 if info.form == 'DS':
1608 # DS-Form, multiply by 4 then knock 2 bits off after
1609 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1610 else:
1611 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1612 imm = exts(imm, 16) # sign-extend to integer
1613 # get the right step. LD is from srcstep, ST is dststep
1614 op = yield self.dec2.e.do.insn_type
1615 offsmul = 0
1616 if op == MicrOp.OP_LOAD.value:
1617 if remap_active:
1618 offsmul = yield self.dec2.in1_step
1619 log("D-field REMAP src", imm, offsmul)
1620 else:
1621 offsmul = (srcstep * (subvl+1)) + ssubstep
1622 log("D-field src", imm, offsmul)
1623 elif op == MicrOp.OP_STORE.value:
1624 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1625 offsmul = (dststep * (subvl+1)) + dsubstep
1626 log("D-field dst", imm, offsmul)
1627 # Unit-Strided LD/ST adds offset*width to immediate
1628 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1629 ldst_len = yield self.dec2.e.do.data_len
1630 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1631 replace_d = True
1632 # Element-strided multiplies the immediate by element step
1633 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1634 imm = SelectableInt(imm * offsmul, 32)
1635 replace_d = True
1636 if replace_d:
1637 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1638 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1639 log("LDSTmode", SVP64LDSTmode(ldstmode),
1640 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1641 # new replacement D... errr.. DS
1642 if replace_d:
1643 if info.form == 'DS':
1644 # TODO: assert 2 LSBs are zero?
1645 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1646 imm.value = imm.value >> 2
1647 self.namespace['DS'] = imm
1648 else:
1649 self.namespace['D'] = imm
1650
1651 def get_input(self, name):
1652 # using PowerDecoder2, first, find the decoder index.
1653 # (mapping name RA RB RC RS to in1, in2, in3)
1654 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1655 if regnum is None:
1656 # doing this is not part of svp64, it's because output
1657 # registers, to be modified, need to be in the namespace.
1658 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1659 if regnum is None:
1660 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1661
1662 # in case getting the register number is needed, _RA, _RB
1663 regname = "_" + name
1664 self.namespace[regname] = regnum
1665 if not self.is_svp64_mode or not self.pred_src_zero:
1666 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1667 if name in fregs:
1668 reg_val = SelectableInt(self.fpr(regnum))
1669 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1670 elif name is not None:
1671 reg_val = SelectableInt(self.gpr(regnum))
1672 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1673 else:
1674 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1675 reg_val = 0
1676 return reg_val
1677
1678 def remap_set_steps(self, remaps):
1679 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1680 they work in concert with PowerDecoder2 at the moment,
1681 there is no HDL implementation of REMAP. therefore this
1682 function, because ISACaller still uses PowerDecoder2,
1683 will *explicitly* write the dec2.XX_step values. this has
1684 to get sorted out.
1685 """
1686 # just some convenient debug info
1687 for i in range(4):
1688 sname = 'SVSHAPE%d' % i
1689 shape = self.spr[sname]
1690 log(sname, bin(shape.value))
1691 log(" lims", shape.lims)
1692 log(" mode", shape.mode)
1693 log(" skip", shape.skip)
1694
1695 # set up the list of steps to remap
1696 mi0 = self.svstate.mi0
1697 mi1 = self.svstate.mi1
1698 mi2 = self.svstate.mi2
1699 mo0 = self.svstate.mo0
1700 mo1 = self.svstate.mo1
1701 steps = [(self.dec2.in1_step, mi0), # RA
1702 (self.dec2.in2_step, mi1), # RB
1703 (self.dec2.in3_step, mi2), # RC
1704 (self.dec2.o_step, mo0), # RT
1705 (self.dec2.o2_step, mo1), # EA
1706 ]
1707 remap_idxs = self.remap_idxs
1708 rremaps = []
1709 # now cross-index the required SHAPE for each of 3-in 2-out regs
1710 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1711 for i, (dstep, shape_idx) in enumerate(steps):
1712 (shape, remap) = remaps[shape_idx]
1713 remap_idx = remap_idxs[shape_idx]
1714 # zero is "disabled"
1715 if shape.value == 0x0:
1716 continue
1717 # now set the actual requested step to the current index
1718 yield dstep.eq(remap_idx)
1719
1720 # debug printout info
1721 rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
1722 for x in rremaps:
1723 log("shape remap", x)
1724
1725 def check_write(self, info, name, output, carry_en):
1726 if name == 'overflow': # ignore, done already (above)
1727 return
1728 if isinstance(output, int):
1729 output = SelectableInt(output, 256)
1730 if name in ['CA', 'CA32']:
1731 if carry_en:
1732 log("writing %s to XER" % name, output)
1733 log("write XER %s 0x%x" % (name, output.value))
1734 self.spr['XER'][XER_bits[name]] = output.value
1735 else:
1736 log("NOT writing %s to XER" % name, output)
1737 elif name in info.special_regs:
1738 log('writing special %s' % name, output, special_sprs)
1739 log("write reg %s 0x%x" % (name, output.value))
1740 if name in special_sprs:
1741 self.spr[name] = output
1742 else:
1743 self.namespace[name].eq(output)
1744 if name == 'MSR':
1745 log('msr written', hex(self.msr.value))
1746 else:
1747 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1748 if regnum is None:
1749 regnum, is_vec = yield from get_pdecode_idx_out2(
1750 self.dec2, name)
1751 if regnum is None:
1752 # temporary hack for not having 2nd output
1753 regnum = yield getattr(self.decoder, name)
1754 is_vec = False
1755 if self.is_svp64_mode and self.pred_dst_zero:
1756 log('zeroing reg %d %s' % (regnum, str(output)),
1757 is_vec)
1758 output = SelectableInt(0, 256)
1759 else:
1760 if name in fregs:
1761 reg_prefix = 'f'
1762 else:
1763 reg_prefix = 'r'
1764 log("write reg %s%d %0xx" % (reg_prefix, regnum, output.value))
1765 if output.bits > 64:
1766 output = SelectableInt(output.value, 64)
1767 if name in fregs:
1768 self.fpr[regnum] = output
1769 else:
1770 self.gpr[regnum] = output
1771
1772 def check_step_increment(self, results, rc_en, asmop, ins_name):
1773 # check if it is the SVSTATE.src/dest step that needs incrementing
1774 # this is our Sub-Program-Counter loop from 0 to VL-1
1775 pre = False
1776 post = False
1777 nia_update = True
1778 if self.allow_next_step_inc:
1779 log("SVSTATE_NEXT: inc requested, mode",
1780 self.svstate_next_mode, self.allow_next_step_inc)
1781 yield from self.svstate_pre_inc()
1782 pre = yield from self.update_new_svstate_steps()
1783 if pre:
1784 # reset at end of loop including exit Vertical Mode
1785 log("SVSTATE_NEXT: end of loop, reset")
1786 self.svp64_reset_loop()
1787 self.svstate.vfirst = 0
1788 self.update_nia()
1789 if not rc_en:
1790 return True
1791 results = [SelectableInt(0, 64)]
1792 self.handle_comparison(results) # CR0
1793 return True
1794 if self.allow_next_step_inc == 2:
1795 log("SVSTATE_NEXT: read")
1796 nia_update = (yield from self.svstate_post_inc(ins_name))
1797 else:
1798 log("SVSTATE_NEXT: post-inc")
1799 # use actual src/dst-step here to check end, do NOT
1800 # use bit-reversed version
1801 srcstep, dststep = self.new_srcstep, self.new_dststep
1802 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1803 remaps = self.get_remap_indices()
1804 remap_idxs = self.remap_idxs
1805 vl = self.svstate.vl
1806 subvl = yield self.dec2.rm_dec.rm_in.subvl
1807 end_src = srcstep == vl-1
1808 end_dst = dststep == vl-1
1809 if self.allow_next_step_inc != 2:
1810 yield from self.advance_svstate_steps(end_src, end_dst)
1811 #self.namespace['SVSTATE'] = self.svstate.spr
1812 # set CR0 (if Rc=1) based on end
1813 if rc_en:
1814 endtest = 1 if (end_src or end_dst) else 0
1815 #results = [SelectableInt(endtest, 64)]
1816 # self.handle_comparison(results) # CR0
1817
1818 # see if svstep was requested, if so, which SVSTATE
1819 endings = 0b111
1820 if self.svstate_next_mode > 0:
1821 shape_idx = self.svstate_next_mode.value-1
1822 endings = self.remap_loopends[shape_idx]
1823 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
1824 log("svstep Rc=1, CR0", cr_field)
1825 self.crl[0].eq(cr_field) # CR0
1826 if end_src or end_dst:
1827 # reset at end of loop including exit Vertical Mode
1828 log("SVSTATE_NEXT: after increments, reset")
1829 self.svp64_reset_loop()
1830 self.svstate.vfirst = 0
1831 return nia_update
1832
1833 if self.is_svp64_mode:
1834 return (yield from self.svstate_post_inc(ins_name))
1835
1836 # XXX only in non-SVP64 mode!
1837 # record state of whether the current operation was an svshape,
1838 # OR svindex!
1839 # to be able to know if it should apply in the next instruction.
1840 # also (if going to use this instruction) should disable ability
1841 # to interrupt in between. sigh.
1842 self.last_op_svshape = asmop in ['svremap', 'svindex', 'svshape2']
1843
1844 return True
1845
1846 def SVSTATE_NEXT(self, mode, submode):
1847 """explicitly moves srcstep/dststep on to next element, for
1848 "Vertical-First" mode. this function is called from
1849 setvl pseudo-code, as a pseudo-op "svstep"
1850
1851 WARNING: this function uses information that was created EARLIER
1852 due to it being in the middle of a yield, but this function is
1853 *NOT* called from yield (it's called from compiled pseudocode).
1854 """
1855 self.allow_next_step_inc = submode.value + 1
1856 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
1857 self.svstate_next_mode = mode
1858 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
1859 shape_idx = self.svstate_next_mode.value-1
1860 return SelectableInt(self.remap_idxs[shape_idx], 7)
1861 if self.svstate_next_mode == 5:
1862 self.svstate_next_mode = 0
1863 return SelectableInt(self.svstate.srcstep, 7)
1864 if self.svstate_next_mode == 6:
1865 self.svstate_next_mode = 0
1866 return SelectableInt(self.svstate.dststep, 7)
1867 return SelectableInt(0, 7)
1868
1869 def get_src_dststeps(self):
1870 """gets srcstep, dststep, and ssubstep, dsubstep
1871 """
1872 return (self.new_srcstep, self.new_dststep,
1873 self.new_ssubstep, self.new_dsubstep)
1874
1875 def update_new_svstate_steps(self):
1876 # note, do not get the bit-reversed srcstep here!
1877 srcstep, dststep = self.new_srcstep, self.new_dststep
1878 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1879
1880 # update SVSTATE with new srcstep
1881 self.svstate.srcstep = srcstep
1882 self.svstate.dststep = dststep
1883 self.svstate.ssubstep = ssubstep
1884 self.svstate.dsubstep = dsubstep
1885 self.namespace['SVSTATE'] = self.svstate
1886 yield self.dec2.state.svstate.eq(self.svstate.value)
1887 yield Settle() # let decoder update
1888 srcstep = self.svstate.srcstep
1889 dststep = self.svstate.dststep
1890 ssubstep = self.svstate.ssubstep
1891 dsubstep = self.svstate.dsubstep
1892 pack = self.svstate.pack
1893 unpack = self.svstate.unpack
1894 vl = self.svstate.vl
1895 subvl = yield self.dec2.rm_dec.rm_in.subvl
1896 log(" srcstep", srcstep)
1897 log(" dststep", dststep)
1898 log(" pack", pack)
1899 log(" unpack", unpack)
1900 log(" ssubstep", ssubstep)
1901 log(" dsubstep", dsubstep)
1902 log(" vl", vl)
1903 log(" subvl", subvl)
1904
1905 # check if end reached (we let srcstep overrun, above)
1906 # nothing needs doing (TODO zeroing): just do next instruction
1907 return ((ssubstep == subvl and srcstep == vl) or
1908 (dsubstep == subvl and dststep == vl))
1909
1910 def svstate_post_inc(self, insn_name, vf=0):
1911 # check if SV "Vertical First" mode is enabled
1912 vfirst = self.svstate.vfirst
1913 log(" SV Vertical First", vf, vfirst)
1914 if not vf and vfirst == 1:
1915 self.update_nia()
1916 return True
1917
1918 # check if it is the SVSTATE.src/dest step that needs incrementing
1919 # this is our Sub-Program-Counter loop from 0 to VL-1
1920 # XXX twin predication TODO
1921 vl = self.svstate.vl
1922 subvl = yield self.dec2.rm_dec.rm_in.subvl
1923 mvl = self.svstate.maxvl
1924 srcstep = self.svstate.srcstep
1925 dststep = self.svstate.dststep
1926 ssubstep = self.svstate.ssubstep
1927 dsubstep = self.svstate.dsubstep
1928 pack = self.svstate.pack
1929 unpack = self.svstate.unpack
1930 rm_mode = yield self.dec2.rm_dec.mode
1931 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1932 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1933 out_vec = not (yield self.dec2.no_out_vec)
1934 in_vec = not (yield self.dec2.no_in_vec)
1935 log(" svstate.vl", vl)
1936 log(" svstate.mvl", mvl)
1937 log(" rm.subvl", subvl)
1938 log(" svstate.srcstep", srcstep)
1939 log(" svstate.dststep", dststep)
1940 log(" svstate.ssubstep", ssubstep)
1941 log(" svstate.dsubstep", dsubstep)
1942 log(" svstate.pack", pack)
1943 log(" svstate.unpack", unpack)
1944 log(" mode", rm_mode)
1945 log(" reverse", reverse_gear)
1946 log(" out_vec", out_vec)
1947 log(" in_vec", in_vec)
1948 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1949 # check if this was an sv.bc* and if so did it succeed
1950 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1951 end_loop = self.namespace['end_loop']
1952 log("branch %s end_loop" % insn_name, end_loop)
1953 if end_loop.value:
1954 self.svp64_reset_loop()
1955 self.update_pc_next()
1956 return False
1957 # check if srcstep needs incrementing by one, stop PC advancing
1958 # but for 2-pred both src/dest have to be checked.
1959 # XXX this might not be true! it may just be LD/ST
1960 if sv_ptype == SVPtype.P2.value:
1961 svp64_is_vector = (out_vec or in_vec)
1962 else:
1963 svp64_is_vector = out_vec
1964 # loops end at the first "hit" (source or dest)
1965 end_src = srcstep == vl-1
1966 end_dst = dststep == vl-1
1967 loopend = ((end_src and ssubstep == subvl) or
1968 (end_dst and dsubstep == subvl))
1969 log("loopend", loopend, end_src, end_dst,
1970 ssubstep == subvl, dsubstep == subvl)
1971 if not svp64_is_vector or loopend:
1972 # reset loop to zero and update NIA
1973 self.svp64_reset_loop()
1974 self.update_nia()
1975
1976 return True
1977
1978 # still looping, advance and update NIA
1979 yield from self.advance_svstate_steps(end_src, end_dst)
1980 self.namespace['SVSTATE'] = self.svstate
1981
1982 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1983 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1984 # this way we keep repeating the same instruction (with new steps)
1985 self.pc.NIA.value = self.pc.CIA.value
1986 self.namespace['NIA'] = self.pc.NIA
1987 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
1988 return False # DO NOT allow PC update whilst Sub-PC loop running
1989
1990 def update_pc_next(self):
1991 # UPDATE program counter
1992 self.pc.update(self.namespace, self.is_svp64_mode)
1993 #self.svstate.spr = self.namespace['SVSTATE']
1994 log("end of call", self.namespace['CIA'],
1995 self.namespace['NIA'],
1996 self.namespace['SVSTATE'])
1997
1998 def svp64_reset_loop(self):
1999 self.svstate.srcstep = 0
2000 self.svstate.dststep = 0
2001 self.svstate.ssubstep = 0
2002 self.svstate.dsubstep = 0
2003 log(" svstate.srcstep loop end (PC to update)")
2004 self.namespace['SVSTATE'] = self.svstate
2005
2006 def update_nia(self):
2007 self.pc.update_nia(self.is_svp64_mode)
2008 self.namespace['NIA'] = self.pc.NIA
2009
2010
2011 def inject():
2012 """Decorator factory.
2013
2014 this decorator will "inject" variables into the function's namespace,
2015 from the *dictionary* in self.namespace. it therefore becomes possible
2016 to make it look like a whole stack of variables which would otherwise
2017 need "self." inserted in front of them (*and* for those variables to be
2018 added to the instance) "appear" in the function.
2019
2020 "self.namespace['SI']" for example becomes accessible as just "SI" but
2021 *only* inside the function, when decorated.
2022 """
2023 def variable_injector(func):
2024 @wraps(func)
2025 def decorator(*args, **kwargs):
2026 try:
2027 func_globals = func.__globals__ # Python 2.6+
2028 except AttributeError:
2029 func_globals = func.func_globals # Earlier versions.
2030
2031 context = args[0].namespace # variables to be injected
2032 saved_values = func_globals.copy() # Shallow copy of dict.
2033 log("globals before", context.keys())
2034 func_globals.update(context)
2035 result = func(*args, **kwargs)
2036 log("globals after", func_globals['CIA'], func_globals['NIA'])
2037 log("args[0]", args[0].namespace['CIA'],
2038 args[0].namespace['NIA'],
2039 args[0].namespace['SVSTATE'])
2040 if 'end_loop' in func_globals:
2041 log("args[0] end_loop", func_globals['end_loop'])
2042 args[0].namespace = func_globals
2043 #exec (func.__code__, func_globals)
2044
2045 # finally:
2046 # func_globals = saved_values # Undo changes.
2047
2048 return result
2049
2050 return decorator
2051
2052 return variable_injector