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