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