another code-morph working towards getting the predicate-skipping
[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 self.srcstep_skip = False
671 self.srcmask = srcmask
672 self.pred_src_zero = pred_src_zero
673 self.new_ssubstep = ssubstep
674 log(" new ssubstep", ssubstep)
675 if ssubstart:
676 # until the predicate mask has a "1" bit... or we run out of VL
677 # let srcstep==VL be the indicator to move to next instruction
678 if not pred_src_zero:
679 self.srcstep_skip = True
680
681 self.skip_src()
682
683 self.dststep_skip = False
684 self.dstmask = dstmask
685 self.pred_dst_zero = pred_dst_zero
686 self.new_dsubstep = dsubstep
687 log(" new dsubstep", dsubstep)
688 if dsubstart:
689 # same for dststep
690 if not pred_dst_zero:
691 self.dststep_skip = True
692
693 self.skip_dst()
694
695 def skip_src(self):
696
697 srcstep = self.svstate.srcstep
698 srcmask = self.srcmask
699 pred_src_zero = self.pred_src_zero
700 vl = self.svstate.vl
701 # srcstep-skipping opportunity identified
702 if self.srcstep_skip:
703 while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl):
704 log(" sskip", bin(1 << srcstep))
705 srcstep += 1
706
707 # now work out if the relevant mask bits require zeroing
708 if pred_src_zero:
709 pred_src_zero = ((1 << srcstep) & srcmask) == 0
710
711 # store new srcstep / dststep
712 self.new_srcstep = srcstep
713 self.pred_src_zero = pred_src_zero
714 log(" new srcstep", srcstep)
715
716 def skip_dst(self):
717 # dststep-skipping opportunity identified
718 dststep = self.svstate.dststep
719 dstmask = self.dstmask
720 pred_dst_zero = self.pred_dst_zero
721 vl = self.svstate.vl
722 if self.dststep_skip:
723 while (((1 << dststep) & dstmask) == 0) and (dststep != vl):
724 log(" dskip", bin(1 << dststep))
725 dststep += 1
726
727 # now work out if the relevant mask bits require zeroing
728 if pred_dst_zero:
729 pred_dst_zero = ((1 << dststep) & dstmask) == 0
730
731 # store new srcstep / dststep
732 self.new_dststep = dststep
733 self.pred_dst_zero = pred_dst_zero
734 log(" new dststep", dststep)
735
736
737 class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
738 # decoder2 - an instance of power_decoder2
739 # regfile - a list of initial values for the registers
740 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
741 # respect_pc - tracks the program counter. requires initial_insns
742 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
743 initial_mem=None, initial_msr=0,
744 initial_svstate=0,
745 initial_insns=None,
746 fpregfile=None,
747 respect_pc=False,
748 disassembly=None,
749 initial_pc=0,
750 bigendian=False,
751 mmu=False,
752 icachemmu=False):
753
754 self.bigendian = bigendian
755 self.halted = False
756 self.is_svp64_mode = False
757 self.respect_pc = respect_pc
758 if initial_sprs is None:
759 initial_sprs = {}
760 if initial_mem is None:
761 initial_mem = {}
762 if fpregfile is None:
763 fpregfile = [0] * 32
764 if initial_insns is None:
765 initial_insns = {}
766 assert self.respect_pc == False, "instructions required to honor pc"
767
768 log("ISACaller insns", respect_pc, initial_insns, disassembly)
769 log("ISACaller initial_msr", initial_msr)
770
771 # "fake program counter" mode (for unit testing)
772 self.fake_pc = 0
773 disasm_start = 0
774 if not respect_pc:
775 if isinstance(initial_mem, tuple):
776 self.fake_pc = initial_mem[0]
777 disasm_start = self.fake_pc
778 else:
779 disasm_start = initial_pc
780
781 # disassembly: we need this for now (not given from the decoder)
782 self.disassembly = {}
783 if disassembly:
784 for i, code in enumerate(disassembly):
785 self.disassembly[i*4 + disasm_start] = code
786
787 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
788 self.svp64rm = SVP64RM()
789 if initial_svstate is None:
790 initial_svstate = 0
791 if isinstance(initial_svstate, int):
792 initial_svstate = SVP64State(initial_svstate)
793 # SVSTATE, MSR and PC
794 StepLoop.__init__(self, initial_svstate)
795 self.msr = SelectableInt(initial_msr, 64) # underlying reg
796 self.pc = PC()
797 # GPR FPR SPR registers
798 initial_sprs = deepcopy(initial_sprs) # so as not to get modified
799 self.gpr = GPR(decoder2, self, self.svstate, regfile)
800 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
801 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
802
803 # set up 4 dummy SVSHAPEs if they aren't already set up
804 for i in range(4):
805 sname = 'SVSHAPE%d' % i
806 if sname not in self.spr:
807 val = 0
808 else:
809 val = self.spr[sname].value
810 # make sure it's an SVSHAPE
811 self.spr[sname] = SVSHAPE(val, self.gpr)
812 self.last_op_svshape = False
813
814 # "raw" memory
815 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
816 self.mem.log_fancy(kind=LogKind.InstrInOuts)
817 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
818 # MMU mode, redirect underlying Mem through RADIX
819 if mmu:
820 self.mem = RADIX(self.mem, self)
821 if icachemmu:
822 self.imem = RADIX(self.imem, self)
823
824 # TODO, needed here:
825 # FPR (same as GPR except for FP nums)
826 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
827 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
828 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
829 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
830 # -- Done
831 # 2.3.2 LR (actually SPR #8) -- Done
832 # 2.3.3 CTR (actually SPR #9) -- Done
833 # 2.3.4 TAR (actually SPR #815)
834 # 3.2.2 p45 XER (actually SPR #1) -- Done
835 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
836
837 # create CR then allow portions of it to be "selectable" (below)
838 self.cr_fields = CRFields(initial_cr)
839 self.cr = self.cr_fields.cr
840
841 # "undefined", just set to variable-bit-width int (use exts "max")
842 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
843
844 self.namespace = {}
845 self.namespace.update(self.spr)
846 self.namespace.update({'GPR': self.gpr,
847 'FPR': self.fpr,
848 'MEM': self.mem,
849 'SPR': self.spr,
850 'memassign': self.memassign,
851 'NIA': self.pc.NIA,
852 'CIA': self.pc.CIA,
853 'SVSTATE': self.svstate,
854 'SVSHAPE0': self.spr['SVSHAPE0'],
855 'SVSHAPE1': self.spr['SVSHAPE1'],
856 'SVSHAPE2': self.spr['SVSHAPE2'],
857 'SVSHAPE3': self.spr['SVSHAPE3'],
858 'CR': self.cr,
859 'MSR': self.msr,
860 'undefined': undefined,
861 'mode_is_64bit': True,
862 'SO': XER_bits['SO'],
863 'XLEN': 64 # elwidth overrides, later
864 })
865
866 # update pc to requested start point
867 self.set_pc(initial_pc)
868
869 # field-selectable versions of Condition Register
870 self.crl = self.cr_fields.crl
871 for i in range(8):
872 self.namespace["CR%d" % i] = self.crl[i]
873
874 self.decoder = decoder2.dec
875 self.dec2 = decoder2
876
877 super().__init__(XLEN=self.namespace["XLEN"])
878
879 @property
880 def XLEN(self):
881 return self.namespace["XLEN"]
882
883 def call_trap(self, trap_addr, trap_bit):
884 """calls TRAP and sets up NIA to the new execution location.
885 next instruction will begin at trap_addr.
886 """
887 self.TRAP(trap_addr, trap_bit)
888 self.namespace['NIA'] = self.trap_nia
889 self.pc.update(self.namespace, self.is_svp64_mode)
890
891 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
892 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
893
894 TRAP function is callable from inside the pseudocode itself,
895 hence the default arguments. when calling from inside ISACaller
896 it is best to use call_trap()
897 """
898 # https://bugs.libre-soc.org/show_bug.cgi?id=859
899 kaivb = self.spr['KAIVB'].value
900 msr = self.namespace['MSR'].value
901 log("TRAP:", hex(trap_addr), hex(msr), "kaivb", hex(kaivb))
902 # store CIA(+4?) in SRR0, set NIA to 0x700
903 # store MSR in SRR1, set MSR to um errr something, have to check spec
904 # store SVSTATE (if enabled) in SVSRR0
905 self.spr['SRR0'].value = self.pc.CIA.value
906 self.spr['SRR1'].value = msr
907 if self.is_svp64_mode:
908 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
909 self.trap_nia = SelectableInt(trap_addr | (kaivb&~0x1fff), 64)
910 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
911
912 # set exception bits. TODO: this should, based on the address
913 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
914 # bits appropriately. however it turns out that *for now* in all
915 # cases (all trap_addrs) the exact same thing is needed.
916 self.msr[MSRb.IR] = 0
917 self.msr[MSRb.DR] = 0
918 self.msr[MSRb.FE0] = 0
919 self.msr[MSRb.FE1] = 0
920 self.msr[MSRb.EE] = 0
921 self.msr[MSRb.RI] = 0
922 self.msr[MSRb.SF] = 1
923 self.msr[MSRb.TM] = 0
924 self.msr[MSRb.VEC] = 0
925 self.msr[MSRb.VSX] = 0
926 self.msr[MSRb.PR] = 0
927 self.msr[MSRb.FP] = 0
928 self.msr[MSRb.PMM] = 0
929 self.msr[MSRb.TEs] = 0
930 self.msr[MSRb.TEe] = 0
931 self.msr[MSRb.UND] = 0
932 self.msr[MSRb.LE] = 1
933
934 def memassign(self, ea, sz, val):
935 self.mem.memassign(ea, sz, val)
936
937 def prep_namespace(self, insn_name, formname, op_fields):
938 # TODO: get field names from form in decoder*1* (not decoder2)
939 # decoder2 is hand-created, and decoder1.sigform is auto-generated
940 # from spec
941 # then "yield" fields only from op_fields rather than hard-coded
942 # list, here.
943 fields = self.decoder.sigforms[formname]
944 log("prep_namespace", formname, op_fields, insn_name)
945 for name in op_fields:
946 # CR immediates. deal with separately. needs modifying
947 # pseudocode
948 if self.is_svp64_mode and name in ['BI']: # TODO, more CRs
949 # BI is a 5-bit, must reconstruct the value
950 regnum, is_vec = yield from get_pdecode_cr_in(self.dec2, name)
951 sig = getattr(fields, name)
952 val = yield sig
953 # low 2 LSBs (CR field selector) remain same, CR num extended
954 assert regnum <= 7, "sigh, TODO, 128 CR fields"
955 val = (val & 0b11) | (regnum << 2)
956 else:
957 sig = getattr(fields, name)
958 val = yield sig
959 # these are all opcode fields involved in index-selection of CR,
960 # and need to do "standard" arithmetic. CR[BA+32] for example
961 # would, if using SelectableInt, only be 5-bit.
962 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
963 self.namespace[name] = val
964 else:
965 self.namespace[name] = SelectableInt(val, sig.width)
966
967 self.namespace['XER'] = self.spr['XER']
968 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
969 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
970
971 # add some SVSTATE convenience variables
972 vl = self.svstate.vl
973 srcstep = self.svstate.srcstep
974 self.namespace['VL'] = vl
975 self.namespace['srcstep'] = srcstep
976
977 # sv.bc* need some extra fields
978 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
979 # blegh grab bits manually
980 mode = yield self.dec2.rm_dec.rm_in.mode
981 bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0
982 bc_vli = (mode & SVP64MODE.BC_VLI) != 0
983 bc_snz = (mode & SVP64MODE.BC_SNZ) != 0
984 bc_vsb = yield self.dec2.rm_dec.bc_vsb
985 bc_lru = yield self.dec2.rm_dec.bc_lru
986 bc_gate = yield self.dec2.rm_dec.bc_gate
987 sz = yield self.dec2.rm_dec.pred_sz
988 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
989 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
990 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
991 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
992 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
993 self.namespace['sz'] = SelectableInt(sz, 1)
994 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
995
996 def handle_carry_(self, inputs, outputs, already_done):
997 inv_a = yield self.dec2.e.do.invert_in
998 if inv_a:
999 inputs[0] = ~inputs[0]
1000
1001 imm_ok = yield self.dec2.e.do.imm_data.ok
1002 if imm_ok:
1003 imm = yield self.dec2.e.do.imm_data.data
1004 inputs.append(SelectableInt(imm, 64))
1005 assert len(outputs) >= 1
1006 log("outputs", repr(outputs))
1007 if isinstance(outputs, list) or isinstance(outputs, tuple):
1008 output = outputs[0]
1009 else:
1010 output = outputs
1011 gts = []
1012 for x in inputs:
1013 log("gt input", x, output)
1014 gt = (gtu(x, output))
1015 gts.append(gt)
1016 log(gts)
1017 cy = 1 if any(gts) else 0
1018 log("CA", cy, gts)
1019 if not (1 & already_done):
1020 self.spr['XER'][XER_bits['CA']] = cy
1021
1022 log("inputs", already_done, inputs)
1023 # 32 bit carry
1024 # ARGH... different for OP_ADD... *sigh*...
1025 op = yield self.dec2.e.do.insn_type
1026 if op == MicrOp.OP_ADD.value:
1027 res32 = (output.value & (1 << 32)) != 0
1028 a32 = (inputs[0].value & (1 << 32)) != 0
1029 if len(inputs) >= 2:
1030 b32 = (inputs[1].value & (1 << 32)) != 0
1031 else:
1032 b32 = False
1033 cy32 = res32 ^ a32 ^ b32
1034 log("CA32 ADD", cy32)
1035 else:
1036 gts = []
1037 for x in inputs:
1038 log("input", x, output)
1039 log(" x[32:64]", x, x[32:64])
1040 log(" o[32:64]", output, output[32:64])
1041 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
1042 gts.append(gt)
1043 cy32 = 1 if any(gts) else 0
1044 log("CA32", cy32, gts)
1045 if not (2 & already_done):
1046 self.spr['XER'][XER_bits['CA32']] = cy32
1047
1048 def handle_overflow(self, inputs, outputs, div_overflow):
1049 if hasattr(self.dec2.e.do, "invert_in"):
1050 inv_a = yield self.dec2.e.do.invert_in
1051 if inv_a:
1052 inputs[0] = ~inputs[0]
1053
1054 imm_ok = yield self.dec2.e.do.imm_data.ok
1055 if imm_ok:
1056 imm = yield self.dec2.e.do.imm_data.data
1057 inputs.append(SelectableInt(imm, 64))
1058 assert len(outputs) >= 1
1059 log("handle_overflow", inputs, outputs, div_overflow)
1060 if len(inputs) < 2 and div_overflow is None:
1061 return
1062
1063 # div overflow is different: it's returned by the pseudo-code
1064 # because it's more complex than can be done by analysing the output
1065 if div_overflow is not None:
1066 ov, ov32 = div_overflow, div_overflow
1067 # arithmetic overflow can be done by analysing the input and output
1068 elif len(inputs) >= 2:
1069 output = outputs[0]
1070
1071 # OV (64-bit)
1072 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
1073 output_sgn = exts(output.value, output.bits) < 0
1074 ov = 1 if input_sgn[0] == input_sgn[1] and \
1075 output_sgn != input_sgn[0] else 0
1076
1077 # OV (32-bit)
1078 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
1079 output32_sgn = exts(output.value, 32) < 0
1080 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
1081 output32_sgn != input32_sgn[0] else 0
1082
1083 # now update XER OV/OV32/SO
1084 so = self.spr['XER'][XER_bits['SO']]
1085 new_so = so | ov # sticky overflow ORs in old with new
1086 self.spr['XER'][XER_bits['OV']] = ov
1087 self.spr['XER'][XER_bits['OV32']] = ov32
1088 self.spr['XER'][XER_bits['SO']] = new_so
1089 log(" set overflow", ov, ov32, so, new_so)
1090
1091 def handle_comparison(self, outputs, cr_idx=0, overflow=None, no_so=False):
1092 out = outputs[0]
1093 assert isinstance(out, SelectableInt), \
1094 "out zero not a SelectableInt %s" % repr(outputs)
1095 log("handle_comparison", out.bits, hex(out.value))
1096 # TODO - XXX *processor* in 32-bit mode
1097 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1098 # if is_32bit:
1099 # o32 = exts(out.value, 32)
1100 # print ("handle_comparison exts 32 bit", hex(o32))
1101 out = exts(out.value, out.bits)
1102 log("handle_comparison exts", hex(out))
1103 # create the three main CR flags, EQ GT LT
1104 zero = SelectableInt(out == 0, 1)
1105 positive = SelectableInt(out > 0, 1)
1106 negative = SelectableInt(out < 0, 1)
1107 # get (or not) XER.SO. for setvl this is important *not* to read SO
1108 if no_so:
1109 SO = SelectableInt(1, 0)
1110 else:
1111 SO = self.spr['XER'][XER_bits['SO']]
1112 log("handle_comparison SO overflow", SO, overflow)
1113 # alternative overflow checking (setvl mainly at the moment)
1114 if overflow is not None and overflow == 1:
1115 SO = SelectableInt(1, 1)
1116 # create the four CR field values and set the required CR field
1117 cr_field = selectconcat(negative, positive, zero, SO)
1118 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
1119 self.crl[cr_idx].eq(cr_field)
1120
1121 def set_pc(self, pc_val):
1122 self.namespace['NIA'] = SelectableInt(pc_val, 64)
1123 self.pc.update(self.namespace, self.is_svp64_mode)
1124
1125 def get_next_insn(self):
1126 """check instruction
1127 """
1128 if self.respect_pc:
1129 pc = self.pc.CIA.value
1130 else:
1131 pc = self.fake_pc
1132 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
1133 if ins is None:
1134 raise KeyError("no instruction at 0x%x" % pc)
1135 return pc, ins
1136
1137 def setup_one(self):
1138 """set up one instruction
1139 """
1140 pc, insn = self.get_next_insn()
1141 yield from self.setup_next_insn(pc, insn)
1142
1143 def setup_next_insn(self, pc, ins):
1144 """set up next instruction
1145 """
1146 self._pc = pc
1147 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
1148 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
1149
1150 yield self.dec2.sv_rm.eq(0)
1151 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
1152 yield self.dec2.dec.bigendian.eq(self.bigendian)
1153 yield self.dec2.state.msr.eq(self.msr.value)
1154 yield self.dec2.state.pc.eq(pc)
1155 if self.svstate is not None:
1156 yield self.dec2.state.svstate.eq(self.svstate.value)
1157
1158 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1159 yield Settle()
1160 opcode = yield self.dec2.dec.opcode_in
1161 opcode = SelectableInt(value=opcode, bits=32)
1162 pfx = SVP64Instruction.Prefix(opcode)
1163 log("prefix test: opcode:", pfx.po, bin(pfx.po), pfx.id)
1164 self.is_svp64_mode = bool((pfx.po == 0b000001) and (pfx.id == 0b11))
1165 self.pc.update_nia(self.is_svp64_mode)
1166 # set SVP64 decode
1167 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
1168 self.namespace['NIA'] = self.pc.NIA
1169 self.namespace['SVSTATE'] = self.svstate
1170 if not self.is_svp64_mode:
1171 return
1172
1173 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1174 log("svp64.rm", bin(pfx.rm))
1175 log(" svstate.vl", self.svstate.vl)
1176 log(" svstate.mvl", self.svstate.maxvl)
1177 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
1178 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
1179 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
1180 yield self.dec2.sv_rm.eq(int(pfx.rm)) # svp64 prefix
1181 yield Settle()
1182
1183 def execute_one(self):
1184 """execute one instruction
1185 """
1186 # get the disassembly code for this instruction
1187 if self.is_svp64_mode:
1188 if not self.disassembly:
1189 code = yield from self.get_assembly_name()
1190 else:
1191 code = self.disassembly[self._pc+4]
1192 log(" svp64 sim-execute", hex(self._pc), code)
1193 else:
1194 if not self.disassembly:
1195 code = yield from self.get_assembly_name()
1196 else:
1197 code = self.disassembly[self._pc]
1198 log("sim-execute", hex(self._pc), code)
1199 opname = code.split(' ')[0]
1200 try:
1201 yield from self.call(opname) # execute the instruction
1202 except MemException as e: # check for memory errors
1203 if e.args[0] == 'unaligned': # alignment error
1204 # run a Trap but set DAR first
1205 print("memory unaligned exception, DAR", e.dar)
1206 self.spr['DAR'] = SelectableInt(e.dar, 64)
1207 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1208 return
1209 elif e.args[0] == 'invalid': # invalid
1210 # run a Trap but set DAR first
1211 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1212 if e.mode == 'EXECUTE':
1213 # XXX TODO: must set a few bits in SRR1,
1214 # see microwatt loadstore1.vhdl
1215 # if m_in.segerr = '0' then
1216 # v.srr1(47 - 33) := m_in.invalid;
1217 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1218 # v.srr1(47 - 44) := m_in.badtree;
1219 # v.srr1(47 - 45) := m_in.rc_error;
1220 # v.intr_vec := 16#400#;
1221 # else
1222 # v.intr_vec := 16#480#;
1223 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1224 else:
1225 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1226 return
1227 # not supported yet:
1228 raise e # ... re-raise
1229
1230 # don't use this except in special circumstances
1231 if not self.respect_pc:
1232 self.fake_pc += 4
1233
1234 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1235 hex(self.pc.NIA.value))
1236
1237 def get_assembly_name(self):
1238 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1239 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1240 dec_insn = yield self.dec2.e.do.insn
1241 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1242 asmcode = yield self.dec2.dec.op.asmcode
1243 int_op = yield self.dec2.dec.op.internal_op
1244 log("get assembly name asmcode", asmcode, int_op,
1245 hex(dec_insn), bin(insn_1_11))
1246 asmop = insns.get(asmcode, None)
1247
1248 # sigh reconstruct the assembly instruction name
1249 if hasattr(self.dec2.e.do, "oe"):
1250 ov_en = yield self.dec2.e.do.oe.oe
1251 ov_ok = yield self.dec2.e.do.oe.ok
1252 else:
1253 ov_en = False
1254 ov_ok = False
1255 if hasattr(self.dec2.e.do, "rc"):
1256 rc_en = yield self.dec2.e.do.rc.rc
1257 rc_ok = yield self.dec2.e.do.rc.ok
1258 else:
1259 rc_en = False
1260 rc_ok = False
1261 # grrrr have to special-case MUL op (see DecodeOE)
1262 log("ov %d en %d rc %d en %d op %d" %
1263 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1264 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1265 log("mul op")
1266 if rc_en & rc_ok:
1267 asmop += "."
1268 else:
1269 if not asmop.endswith("."): # don't add "." to "andis."
1270 if rc_en & rc_ok:
1271 asmop += "."
1272 if hasattr(self.dec2.e.do, "lk"):
1273 lk = yield self.dec2.e.do.lk
1274 if lk:
1275 asmop += "l"
1276 log("int_op", int_op)
1277 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1278 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1279 log("AA", AA)
1280 if AA:
1281 asmop += "a"
1282 spr_msb = yield from self.get_spr_msb()
1283 if int_op == MicrOp.OP_MFCR.value:
1284 if spr_msb:
1285 asmop = 'mfocrf'
1286 else:
1287 asmop = 'mfcr'
1288 # XXX TODO: for whatever weird reason this doesn't work
1289 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1290 if int_op == MicrOp.OP_MTCRF.value:
1291 if spr_msb:
1292 asmop = 'mtocrf'
1293 else:
1294 asmop = 'mtcrf'
1295 return asmop
1296
1297 def get_remap_indices(self):
1298 """WARNING, this function stores remap_idxs and remap_loopends
1299 in the class for later use. this to avoid problems with yield
1300 """
1301 # go through all iterators in lock-step, advance to next remap_idx
1302 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1303 # get four SVSHAPEs. here we are hard-coding
1304 SVSHAPE0 = self.spr['SVSHAPE0']
1305 SVSHAPE1 = self.spr['SVSHAPE1']
1306 SVSHAPE2 = self.spr['SVSHAPE2']
1307 SVSHAPE3 = self.spr['SVSHAPE3']
1308 # set up the iterators
1309 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1310 (SVSHAPE1, SVSHAPE1.get_iterator()),
1311 (SVSHAPE2, SVSHAPE2.get_iterator()),
1312 (SVSHAPE3, SVSHAPE3.get_iterator()),
1313 ]
1314
1315 self.remap_loopends = [0] * 4
1316 self.remap_idxs = [0, 1, 2, 3]
1317 dbg = []
1318 for i, (shape, remap) in enumerate(remaps):
1319 # zero is "disabled"
1320 if shape.value == 0x0:
1321 self.remap_idxs[i] = 0
1322 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1323 step = dststep if (i in [3, 4]) else srcstep
1324 # this is terrible. O(N^2) looking for the match. but hey.
1325 for idx, (remap_idx, loopends) in enumerate(remap):
1326 if idx == step:
1327 break
1328 self.remap_idxs[i] = remap_idx
1329 self.remap_loopends[i] = loopends
1330 dbg.append((i, step, remap_idx, loopends))
1331 for (i, step, remap_idx, loopends) in dbg:
1332 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1333 return remaps
1334
1335 def get_spr_msb(self):
1336 dec_insn = yield self.dec2.e.do.insn
1337 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1338
1339 def call(self, name):
1340 """call(opcode) - the primary execution point for instructions
1341 """
1342 self.last_st_addr = None # reset the last known store address
1343 self.last_ld_addr = None # etc.
1344
1345 ins_name = name.strip() # remove spaces if not already done so
1346 if self.halted:
1347 log("halted - not executing", ins_name)
1348 return
1349
1350 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1351 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1352 asmop = yield from self.get_assembly_name()
1353 log("call", ins_name, asmop)
1354
1355 # sv.setvl is *not* a loop-function. sigh
1356 log("is_svp64_mode", self.is_svp64_mode, asmop)
1357
1358 # check privileged
1359 int_op = yield self.dec2.dec.op.internal_op
1360 spr_msb = yield from self.get_spr_msb()
1361
1362 instr_is_privileged = False
1363 if int_op in [MicrOp.OP_ATTN.value,
1364 MicrOp.OP_MFMSR.value,
1365 MicrOp.OP_MTMSR.value,
1366 MicrOp.OP_MTMSRD.value,
1367 # TODO: OP_TLBIE
1368 MicrOp.OP_RFID.value]:
1369 instr_is_privileged = True
1370 if int_op in [MicrOp.OP_MFSPR.value,
1371 MicrOp.OP_MTSPR.value] and spr_msb:
1372 instr_is_privileged = True
1373
1374 log("is priv", instr_is_privileged, hex(self.msr.value),
1375 self.msr[MSRb.PR])
1376 # check MSR priv bit and whether op is privileged: if so, throw trap
1377 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1378 self.call_trap(0x700, PIb.PRIV)
1379 return
1380
1381 # check halted condition
1382 if ins_name == 'attn':
1383 self.halted = True
1384 return
1385
1386 # check illegal instruction
1387 illegal = False
1388 if ins_name not in ['mtcrf', 'mtocrf']:
1389 illegal = ins_name != asmop
1390
1391 # list of instructions not being supported by binutils (.long)
1392 dotstrp = asmop[:-1] if asmop[-1] == '.' else asmop
1393 if dotstrp in [*FPTRANS_INSNS,
1394 'ffmadds', 'fdmadds', 'ffadds',
1395 'mins', 'maxs', 'minu', 'maxu',
1396 'setvl', 'svindex', 'svremap', 'svstep',
1397 'svshape', 'svshape2',
1398 'grev', 'ternlogi', 'bmask', 'cprop',
1399 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1400 'fmvis', 'fishmv',
1401 ]:
1402 illegal = False
1403 ins_name = dotstrp
1404
1405 # branch-conditional redirects to sv.bc
1406 if asmop.startswith('bc') and self.is_svp64_mode:
1407 ins_name = 'sv.%s' % ins_name
1408
1409 log(" post-processed name", dotstrp, ins_name, asmop)
1410
1411 # illegal instructions call TRAP at 0x700
1412 if illegal:
1413 print("illegal", ins_name, asmop)
1414 self.call_trap(0x700, PIb.ILLEG)
1415 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1416 (ins_name, asmop, self.pc.CIA.value))
1417 return
1418
1419 # this is for setvl "Vertical" mode: if set true,
1420 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1421 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1422 self.allow_next_step_inc = False
1423 self.svstate_next_mode = 0
1424
1425 # nop has to be supported, we could let the actual op calculate
1426 # but PowerDecoder has a pattern for nop
1427 if ins_name == 'nop':
1428 self.update_pc_next()
1429 return
1430
1431 # look up instruction in ISA.instrs, prepare namespace
1432 info = self.instrs[ins_name]
1433 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1434
1435 # preserve order of register names
1436 input_names = create_args(list(info.read_regs) +
1437 list(info.uninit_regs))
1438 log("input names", input_names)
1439
1440 # get SVP64 entry for the current instruction
1441 sv_rm = self.svp64rm.instrs.get(ins_name)
1442 if sv_rm is not None:
1443 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1444 else:
1445 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1446 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1447
1448 # see if srcstep/dststep need skipping over masked-out predicate bits
1449 if (self.is_svp64_mode or ins_name in ['setvl', 'svremap', 'svstate']):
1450 yield from self.svstate_pre_inc()
1451 if self.is_svp64_mode:
1452 pre = yield from self.update_new_svstate_steps()
1453 if pre:
1454 self.svp64_reset_loop()
1455 self.update_nia()
1456 self.update_pc_next()
1457 return
1458 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1459 pred_dst_zero = self.pred_dst_zero
1460 pred_src_zero = self.pred_src_zero
1461 vl = self.svstate.vl
1462 subvl = yield self.dec2.rm_dec.rm_in.subvl
1463
1464 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1465 if self.is_svp64_mode and vl == 0:
1466 self.pc.update(self.namespace, self.is_svp64_mode)
1467 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1468 self.namespace['NIA'], kind=LogKind.InstrInOuts)
1469 return
1470
1471 # for when SVREMAP is active, using pre-arranged schedule.
1472 # note: modifying PowerDecoder2 needs to "settle"
1473 remap_en = self.svstate.SVme
1474 persist = self.svstate.RMpst
1475 active = (persist or self.last_op_svshape) and remap_en != 0
1476 if self.is_svp64_mode:
1477 yield self.dec2.remap_active.eq(remap_en if active else 0)
1478 yield Settle()
1479 if persist or self.last_op_svshape:
1480 remaps = self.get_remap_indices()
1481 if self.is_svp64_mode and (persist or self.last_op_svshape):
1482 yield from self.remap_set_steps(remaps)
1483 # after that, settle down (combinatorial) to let Vector reg numbers
1484 # work themselves out
1485 yield Settle()
1486 if self.is_svp64_mode:
1487 remap_active = yield self.dec2.remap_active
1488 else:
1489 remap_active = False
1490 log("remap active", bin(remap_active))
1491
1492 # main input registers (RT, RA ...)
1493 inputs = []
1494 for name in input_names:
1495 log("name", name)
1496 regval = (yield from self.get_input(name))
1497 log("regval", regval)
1498 inputs.append(regval)
1499
1500 # arrrrgh, awful hack, to get _RT into namespace
1501 if ins_name in ['setvl', 'svstep']:
1502 regname = "_RT"
1503 RT = yield self.dec2.dec.RT
1504 self.namespace[regname] = SelectableInt(RT, 5)
1505 if RT == 0:
1506 self.namespace["RT"] = SelectableInt(0, 5)
1507 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1508 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1509
1510 # in SVP64 mode for LD/ST work out immediate
1511 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1512 # use info.form to detect
1513 if self.is_svp64_mode:
1514 yield from self.check_replace_d(info, remap_active)
1515
1516 # "special" registers
1517 for special in info.special_regs:
1518 if special in special_sprs:
1519 inputs.append(self.spr[special])
1520 else:
1521 inputs.append(self.namespace[special])
1522
1523 # clear trap (trap) NIA
1524 self.trap_nia = None
1525
1526 # check if this was an sv.bc* and create an indicator that
1527 # this is the last check to be made as a loop. combined with
1528 # the ALL/ANY mode we can early-exit
1529 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
1530 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
1531 # XXX TODO - pack/unpack here
1532 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
1533 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
1534
1535 # execute actual instruction here (finally)
1536 log("inputs", inputs)
1537 results = info.func(self, *inputs)
1538 log("results", results)
1539
1540 # "inject" decorator takes namespace from function locals: we need to
1541 # overwrite NIA being overwritten (sigh)
1542 if self.trap_nia is not None:
1543 self.namespace['NIA'] = self.trap_nia
1544
1545 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1546
1547 # check if op was a LD/ST so that debugging can check the
1548 # address
1549 if int_op in [MicrOp.OP_STORE.value,
1550 ]:
1551 self.last_st_addr = self.mem.last_st_addr
1552 if int_op in [MicrOp.OP_LOAD.value,
1553 ]:
1554 self.last_ld_addr = self.mem.last_ld_addr
1555 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1556 self.last_st_addr, self.last_ld_addr)
1557
1558 # detect if CA/CA32 already in outputs (sra*, basically)
1559 already_done = 0
1560 if info.write_regs:
1561 output_names = create_args(info.write_regs)
1562 for name in output_names:
1563 if name == 'CA':
1564 already_done |= 1
1565 if name == 'CA32':
1566 already_done |= 2
1567
1568 log("carry already done?", bin(already_done))
1569 if hasattr(self.dec2.e.do, "output_carry"):
1570 carry_en = yield self.dec2.e.do.output_carry
1571 else:
1572 carry_en = False
1573 if carry_en:
1574 yield from self.handle_carry_(inputs, results, already_done)
1575
1576 # check if one of the regs was named "overflow"
1577 overflow = None
1578 if info.write_regs:
1579 for name, output in zip(output_names, results):
1580 if name == 'overflow':
1581 overflow = output
1582
1583 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1584 # detect if overflow was in return result
1585 if hasattr(self.dec2.e.do, "oe"):
1586 ov_en = yield self.dec2.e.do.oe.oe
1587 ov_ok = yield self.dec2.e.do.oe.ok
1588 else:
1589 ov_en = False
1590 ov_ok = False
1591 log("internal overflow", ins_name, overflow, "en?", ov_en, ov_ok)
1592 if ov_en & ov_ok:
1593 yield from self.handle_overflow(inputs, results, overflow)
1594
1595 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1596 rc_en = False
1597 if not self.is_svp64_mode or not pred_dst_zero:
1598 if hasattr(self.dec2.e.do, "rc"):
1599 rc_en = yield self.dec2.e.do.rc.rc
1600 if rc_en and ins_name not in ['svstep']:
1601 if ins_name.startswith("f"):
1602 rc_reg = "CR1" # not calculated correctly yet (not FP compares)
1603 else:
1604 rc_reg = "CR0"
1605 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, rc_reg)
1606 cmps = results
1607 # hang on... for `setvl` actually you want to test SVSTATE.VL
1608 is_setvl = ins_name == 'setvl'
1609 if is_setvl:
1610 vl = results[0].vl
1611 cmps = (SelectableInt(vl, 64), overflow,)
1612 else:
1613 overflow = None # do not override overflow except in setvl
1614 self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
1615
1616 # any modified return results?
1617 if info.write_regs:
1618 for name, output in zip(output_names, results):
1619 yield from self.check_write(info, name, output, carry_en)
1620
1621 nia_update = (yield from self.check_step_increment(results, rc_en,
1622 asmop, ins_name))
1623 if nia_update:
1624 self.update_pc_next()
1625
1626 def check_replace_d(self, info, remap_active):
1627 replace_d = False # update / replace constant in pseudocode
1628 ldstmode = yield self.dec2.rm_dec.ldstmode
1629 vl = self.svstate.vl
1630 subvl = yield self.dec2.rm_dec.rm_in.subvl
1631 srcstep, dststep = self.new_srcstep, self.new_dststep
1632 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1633 if info.form == 'DS':
1634 # DS-Form, multiply by 4 then knock 2 bits off after
1635 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1636 else:
1637 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1638 imm = exts(imm, 16) # sign-extend to integer
1639 # get the right step. LD is from srcstep, ST is dststep
1640 op = yield self.dec2.e.do.insn_type
1641 offsmul = 0
1642 if op == MicrOp.OP_LOAD.value:
1643 if remap_active:
1644 offsmul = yield self.dec2.in1_step
1645 log("D-field REMAP src", imm, offsmul)
1646 else:
1647 offsmul = (srcstep * (subvl+1)) + ssubstep
1648 log("D-field src", imm, offsmul)
1649 elif op == MicrOp.OP_STORE.value:
1650 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1651 offsmul = (dststep * (subvl+1)) + dsubstep
1652 log("D-field dst", imm, offsmul)
1653 # Unit-Strided LD/ST adds offset*width to immediate
1654 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1655 ldst_len = yield self.dec2.e.do.data_len
1656 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1657 replace_d = True
1658 # Element-strided multiplies the immediate by element step
1659 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1660 imm = SelectableInt(imm * offsmul, 32)
1661 replace_d = True
1662 if replace_d:
1663 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1664 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1665 log("LDSTmode", SVP64LDSTmode(ldstmode),
1666 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1667 # new replacement D... errr.. DS
1668 if replace_d:
1669 if info.form == 'DS':
1670 # TODO: assert 2 LSBs are zero?
1671 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1672 imm.value = imm.value >> 2
1673 self.namespace['DS'] = imm
1674 else:
1675 self.namespace['D'] = imm
1676
1677 def get_input(self, name):
1678 # using PowerDecoder2, first, find the decoder index.
1679 # (mapping name RA RB RC RS to in1, in2, in3)
1680 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1681 if regnum is None:
1682 # doing this is not part of svp64, it's because output
1683 # registers, to be modified, need to be in the namespace.
1684 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1685 if regnum is None:
1686 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1687
1688 # in case getting the register number is needed, _RA, _RB
1689 regname = "_" + name
1690 self.namespace[regname] = regnum
1691 if not self.is_svp64_mode or not self.pred_src_zero:
1692 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1693 if name in fregs:
1694 reg_val = SelectableInt(self.fpr(regnum))
1695 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1696 elif name is not None:
1697 reg_val = SelectableInt(self.gpr(regnum))
1698 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1699 else:
1700 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1701 reg_val = 0
1702 return reg_val
1703
1704 def remap_set_steps(self, remaps):
1705 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1706 they work in concert with PowerDecoder2 at the moment,
1707 there is no HDL implementation of REMAP. therefore this
1708 function, because ISACaller still uses PowerDecoder2,
1709 will *explicitly* write the dec2.XX_step values. this has
1710 to get sorted out.
1711 """
1712 # just some convenient debug info
1713 for i in range(4):
1714 sname = 'SVSHAPE%d' % i
1715 shape = self.spr[sname]
1716 log(sname, bin(shape.value))
1717 log(" lims", shape.lims)
1718 log(" mode", shape.mode)
1719 log(" skip", shape.skip)
1720
1721 # set up the list of steps to remap
1722 mi0 = self.svstate.mi0
1723 mi1 = self.svstate.mi1
1724 mi2 = self.svstate.mi2
1725 mo0 = self.svstate.mo0
1726 mo1 = self.svstate.mo1
1727 steps = [(self.dec2.in1_step, mi0), # RA
1728 (self.dec2.in2_step, mi1), # RB
1729 (self.dec2.in3_step, mi2), # RC
1730 (self.dec2.o_step, mo0), # RT
1731 (self.dec2.o2_step, mo1), # EA
1732 ]
1733 remap_idxs = self.remap_idxs
1734 rremaps = []
1735 # now cross-index the required SHAPE for each of 3-in 2-out regs
1736 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1737 for i, (dstep, shape_idx) in enumerate(steps):
1738 (shape, remap) = remaps[shape_idx]
1739 remap_idx = remap_idxs[shape_idx]
1740 # zero is "disabled"
1741 if shape.value == 0x0:
1742 continue
1743 # now set the actual requested step to the current index
1744 yield dstep.eq(remap_idx)
1745
1746 # debug printout info
1747 rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
1748 for x in rremaps:
1749 log("shape remap", x)
1750
1751 def check_write(self, info, name, output, carry_en):
1752 if name == 'overflow': # ignore, done already (above)
1753 return
1754 if isinstance(output, int):
1755 output = SelectableInt(output, 256)
1756 if name in ['CA', 'CA32']:
1757 if carry_en:
1758 log("writing %s to XER" % name, output)
1759 log("write XER %s 0x%x" % (name, output.value))
1760 self.spr['XER'][XER_bits[name]] = output.value
1761 else:
1762 log("NOT writing %s to XER" % name, output)
1763 elif name in info.special_regs:
1764 log('writing special %s' % name, output, special_sprs)
1765 log("write reg %s 0x%x" % (name, output.value))
1766 if name in special_sprs:
1767 self.spr[name] = output
1768 else:
1769 self.namespace[name].eq(output)
1770 if name == 'MSR':
1771 log('msr written', hex(self.msr.value))
1772 else:
1773 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1774 if regnum is None:
1775 regnum, is_vec = yield from get_pdecode_idx_out2(
1776 self.dec2, name)
1777 if regnum is None:
1778 # temporary hack for not having 2nd output
1779 regnum = yield getattr(self.decoder, name)
1780 is_vec = False
1781 if self.is_svp64_mode and self.pred_dst_zero:
1782 log('zeroing reg %d %s' % (regnum, str(output)),
1783 is_vec)
1784 output = SelectableInt(0, 256)
1785 else:
1786 if name in fregs:
1787 reg_prefix = 'f'
1788 else:
1789 reg_prefix = 'r'
1790 log("write reg %s%d %0xx" % (reg_prefix, regnum, output.value))
1791 if output.bits > 64:
1792 output = SelectableInt(output.value, 64)
1793 if name in fregs:
1794 self.fpr[regnum] = output
1795 else:
1796 self.gpr[regnum] = output
1797
1798 def check_step_increment(self, results, rc_en, asmop, ins_name):
1799 # check if it is the SVSTATE.src/dest step that needs incrementing
1800 # this is our Sub-Program-Counter loop from 0 to VL-1
1801 pre = False
1802 post = False
1803 nia_update = True
1804 if self.allow_next_step_inc:
1805 log("SVSTATE_NEXT: inc requested, mode",
1806 self.svstate_next_mode, self.allow_next_step_inc)
1807 yield from self.svstate_pre_inc()
1808 pre = yield from self.update_new_svstate_steps()
1809 if pre:
1810 # reset at end of loop including exit Vertical Mode
1811 log("SVSTATE_NEXT: end of loop, reset")
1812 self.svp64_reset_loop()
1813 self.svstate.vfirst = 0
1814 self.update_nia()
1815 if not rc_en:
1816 return True
1817 results = [SelectableInt(0, 64)]
1818 self.handle_comparison(results) # CR0
1819 return True
1820 if self.allow_next_step_inc == 2:
1821 log("SVSTATE_NEXT: read")
1822 nia_update = (yield from self.svstate_post_inc(ins_name))
1823 else:
1824 log("SVSTATE_NEXT: post-inc")
1825 # use actual src/dst-step here to check end, do NOT
1826 # use bit-reversed version
1827 srcstep, dststep = self.new_srcstep, self.new_dststep
1828 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1829 remaps = self.get_remap_indices()
1830 remap_idxs = self.remap_idxs
1831 vl = self.svstate.vl
1832 subvl = yield self.dec2.rm_dec.rm_in.subvl
1833 end_src = srcstep == vl-1
1834 end_dst = dststep == vl-1
1835 if self.allow_next_step_inc != 2:
1836 yield from self.advance_svstate_steps(end_src, end_dst)
1837 #self.namespace['SVSTATE'] = self.svstate.spr
1838 # set CR0 (if Rc=1) based on end
1839 if rc_en:
1840 endtest = 1 if (end_src or end_dst) else 0
1841 #results = [SelectableInt(endtest, 64)]
1842 # self.handle_comparison(results) # CR0
1843
1844 # see if svstep was requested, if so, which SVSTATE
1845 endings = 0b111
1846 if self.svstate_next_mode > 0:
1847 shape_idx = self.svstate_next_mode.value-1
1848 endings = self.remap_loopends[shape_idx]
1849 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
1850 log("svstep Rc=1, CR0", cr_field)
1851 self.crl[0].eq(cr_field) # CR0
1852 if end_src or end_dst:
1853 # reset at end of loop including exit Vertical Mode
1854 log("SVSTATE_NEXT: after increments, reset")
1855 self.svp64_reset_loop()
1856 self.svstate.vfirst = 0
1857 return nia_update
1858
1859 if self.is_svp64_mode:
1860 return (yield from self.svstate_post_inc(ins_name))
1861
1862 # XXX only in non-SVP64 mode!
1863 # record state of whether the current operation was an svshape,
1864 # OR svindex!
1865 # to be able to know if it should apply in the next instruction.
1866 # also (if going to use this instruction) should disable ability
1867 # to interrupt in between. sigh.
1868 self.last_op_svshape = asmop in ['svremap', 'svindex', 'svshape2']
1869
1870 return True
1871
1872 def SVSTATE_NEXT(self, mode, submode):
1873 """explicitly moves srcstep/dststep on to next element, for
1874 "Vertical-First" mode. this function is called from
1875 setvl pseudo-code, as a pseudo-op "svstep"
1876
1877 WARNING: this function uses information that was created EARLIER
1878 due to it being in the middle of a yield, but this function is
1879 *NOT* called from yield (it's called from compiled pseudocode).
1880 """
1881 self.allow_next_step_inc = submode.value + 1
1882 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
1883 self.svstate_next_mode = mode
1884 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
1885 shape_idx = self.svstate_next_mode.value-1
1886 return SelectableInt(self.remap_idxs[shape_idx], 7)
1887 if self.svstate_next_mode == 5:
1888 self.svstate_next_mode = 0
1889 return SelectableInt(self.svstate.srcstep, 7)
1890 if self.svstate_next_mode == 6:
1891 self.svstate_next_mode = 0
1892 return SelectableInt(self.svstate.dststep, 7)
1893 return SelectableInt(0, 7)
1894
1895 def get_src_dststeps(self):
1896 """gets srcstep, dststep, and ssubstep, dsubstep
1897 """
1898 return (self.new_srcstep, self.new_dststep,
1899 self.new_ssubstep, self.new_dsubstep)
1900
1901 def update_new_svstate_steps(self):
1902 # note, do not get the bit-reversed srcstep here!
1903 srcstep, dststep = self.new_srcstep, self.new_dststep
1904 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1905
1906 # update SVSTATE with new srcstep
1907 self.svstate.srcstep = srcstep
1908 self.svstate.dststep = dststep
1909 self.svstate.ssubstep = ssubstep
1910 self.svstate.dsubstep = dsubstep
1911 self.namespace['SVSTATE'] = self.svstate
1912 yield self.dec2.state.svstate.eq(self.svstate.value)
1913 yield Settle() # let decoder update
1914 srcstep = self.svstate.srcstep
1915 dststep = self.svstate.dststep
1916 ssubstep = self.svstate.ssubstep
1917 dsubstep = self.svstate.dsubstep
1918 pack = self.svstate.pack
1919 unpack = self.svstate.unpack
1920 vl = self.svstate.vl
1921 subvl = yield self.dec2.rm_dec.rm_in.subvl
1922 log(" srcstep", srcstep)
1923 log(" dststep", dststep)
1924 log(" pack", pack)
1925 log(" unpack", unpack)
1926 log(" ssubstep", ssubstep)
1927 log(" dsubstep", dsubstep)
1928 log(" vl", vl)
1929 log(" subvl", subvl)
1930
1931 # check if end reached (we let srcstep overrun, above)
1932 # nothing needs doing (TODO zeroing): just do next instruction
1933 return ((ssubstep == subvl and srcstep == vl) or
1934 (dsubstep == subvl and dststep == vl))
1935
1936 def svstate_post_inc(self, insn_name, vf=0):
1937 # check if SV "Vertical First" mode is enabled
1938 vfirst = self.svstate.vfirst
1939 log(" SV Vertical First", vf, vfirst)
1940 if not vf and vfirst == 1:
1941 self.update_nia()
1942 return True
1943
1944 # check if it is the SVSTATE.src/dest step that needs incrementing
1945 # this is our Sub-Program-Counter loop from 0 to VL-1
1946 # XXX twin predication TODO
1947 vl = self.svstate.vl
1948 subvl = yield self.dec2.rm_dec.rm_in.subvl
1949 mvl = self.svstate.maxvl
1950 srcstep = self.svstate.srcstep
1951 dststep = self.svstate.dststep
1952 ssubstep = self.svstate.ssubstep
1953 dsubstep = self.svstate.dsubstep
1954 pack = self.svstate.pack
1955 unpack = self.svstate.unpack
1956 rm_mode = yield self.dec2.rm_dec.mode
1957 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1958 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1959 out_vec = not (yield self.dec2.no_out_vec)
1960 in_vec = not (yield self.dec2.no_in_vec)
1961 log(" svstate.vl", vl)
1962 log(" svstate.mvl", mvl)
1963 log(" rm.subvl", subvl)
1964 log(" svstate.srcstep", srcstep)
1965 log(" svstate.dststep", dststep)
1966 log(" svstate.ssubstep", ssubstep)
1967 log(" svstate.dsubstep", dsubstep)
1968 log(" svstate.pack", pack)
1969 log(" svstate.unpack", unpack)
1970 log(" mode", rm_mode)
1971 log(" reverse", reverse_gear)
1972 log(" out_vec", out_vec)
1973 log(" in_vec", in_vec)
1974 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1975 # check if this was an sv.bc* and if so did it succeed
1976 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1977 end_loop = self.namespace['end_loop']
1978 log("branch %s end_loop" % insn_name, end_loop)
1979 if end_loop.value:
1980 self.svp64_reset_loop()
1981 self.update_pc_next()
1982 return False
1983 # check if srcstep needs incrementing by one, stop PC advancing
1984 # but for 2-pred both src/dest have to be checked.
1985 # XXX this might not be true! it may just be LD/ST
1986 if sv_ptype == SVPtype.P2.value:
1987 svp64_is_vector = (out_vec or in_vec)
1988 else:
1989 svp64_is_vector = out_vec
1990 # loops end at the first "hit" (source or dest)
1991 end_src = srcstep == vl-1
1992 end_dst = dststep == vl-1
1993 loopend = ((end_src and ssubstep == subvl) or
1994 (end_dst and dsubstep == subvl))
1995 log("loopend", loopend, end_src, end_dst,
1996 ssubstep == subvl, dsubstep == subvl)
1997 if not svp64_is_vector or loopend:
1998 # reset loop to zero and update NIA
1999 self.svp64_reset_loop()
2000 self.update_nia()
2001
2002 return True
2003
2004 # still looping, advance and update NIA
2005 yield from self.advance_svstate_steps(end_src, end_dst)
2006 self.namespace['SVSTATE'] = self.svstate
2007
2008 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2009 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2010 # this way we keep repeating the same instruction (with new steps)
2011 self.pc.NIA.value = self.pc.CIA.value
2012 self.namespace['NIA'] = self.pc.NIA
2013 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
2014 return False # DO NOT allow PC update whilst Sub-PC loop running
2015
2016 def update_pc_next(self):
2017 # UPDATE program counter
2018 self.pc.update(self.namespace, self.is_svp64_mode)
2019 #self.svstate.spr = self.namespace['SVSTATE']
2020 log("end of call", self.namespace['CIA'],
2021 self.namespace['NIA'],
2022 self.namespace['SVSTATE'])
2023
2024 def svp64_reset_loop(self):
2025 self.svstate.srcstep = 0
2026 self.svstate.dststep = 0
2027 self.svstate.ssubstep = 0
2028 self.svstate.dsubstep = 0
2029 log(" svstate.srcstep loop end (PC to update)")
2030 self.namespace['SVSTATE'] = self.svstate
2031
2032 def update_nia(self):
2033 self.pc.update_nia(self.is_svp64_mode)
2034 self.namespace['NIA'] = self.pc.NIA
2035
2036
2037 def inject():
2038 """Decorator factory.
2039
2040 this decorator will "inject" variables into the function's namespace,
2041 from the *dictionary* in self.namespace. it therefore becomes possible
2042 to make it look like a whole stack of variables which would otherwise
2043 need "self." inserted in front of them (*and* for those variables to be
2044 added to the instance) "appear" in the function.
2045
2046 "self.namespace['SI']" for example becomes accessible as just "SI" but
2047 *only* inside the function, when decorated.
2048 """
2049 def variable_injector(func):
2050 @wraps(func)
2051 def decorator(*args, **kwargs):
2052 try:
2053 func_globals = func.__globals__ # Python 2.6+
2054 except AttributeError:
2055 func_globals = func.func_globals # Earlier versions.
2056
2057 context = args[0].namespace # variables to be injected
2058 saved_values = func_globals.copy() # Shallow copy of dict.
2059 log("globals before", context.keys())
2060 func_globals.update(context)
2061 result = func(*args, **kwargs)
2062 log("globals after", func_globals['CIA'], func_globals['NIA'])
2063 log("args[0]", args[0].namespace['CIA'],
2064 args[0].namespace['NIA'],
2065 args[0].namespace['SVSTATE'])
2066 if 'end_loop' in func_globals:
2067 log("args[0] end_loop", func_globals['end_loop'])
2068 args[0].namespace = func_globals
2069 #exec (func.__code__, func_globals)
2070
2071 # finally:
2072 # func_globals = saved_values # Undo changes.
2073
2074 return result
2075
2076 return decorator
2077
2078 return variable_injector