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