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