add MemMMap class
[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, MemMMap, 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 use_mmap_mem=False):
1153
1154 # trace log file for model output. if None do nothing
1155 self.insnlog = insnlog
1156 self.insnlog_is_file = hasattr(insnlog, "write")
1157 if not self.insnlog_is_file and self.insnlog:
1158 self.insnlog = open(self.insnlog, "w")
1159
1160 self.bigendian = bigendian
1161 self.halted = False
1162 self.is_svp64_mode = False
1163 self.respect_pc = respect_pc
1164 if initial_sprs is None:
1165 initial_sprs = {}
1166 if initial_mem is None:
1167 initial_mem = {}
1168 if fpregfile is None:
1169 fpregfile = [0] * 32
1170 if initial_insns is None:
1171 initial_insns = {}
1172 assert self.respect_pc == False, "instructions required to honor pc"
1173
1174 log("ISACaller insns", respect_pc, initial_insns, disassembly)
1175 log("ISACaller initial_msr", initial_msr)
1176
1177 # "fake program counter" mode (for unit testing)
1178 self.fake_pc = 0
1179 disasm_start = 0
1180 if not respect_pc:
1181 if isinstance(initial_mem, tuple):
1182 self.fake_pc = initial_mem[0]
1183 disasm_start = self.fake_pc
1184 else:
1185 disasm_start = initial_pc
1186
1187 # disassembly: we need this for now (not given from the decoder)
1188 self.disassembly = {}
1189 if disassembly:
1190 for i, code in enumerate(disassembly):
1191 self.disassembly[i*4 + disasm_start] = code
1192
1193 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
1194 self.svp64rm = SVP64RM()
1195 if initial_svstate is None:
1196 initial_svstate = 0
1197 if isinstance(initial_svstate, int):
1198 initial_svstate = SVP64State(initial_svstate)
1199 # SVSTATE, MSR and PC
1200 StepLoop.__init__(self, initial_svstate)
1201 self.msr = SelectableInt(initial_msr, 64) # underlying reg
1202 self.pc = PC()
1203 # GPR FPR SPR registers
1204 initial_sprs = deepcopy(initial_sprs) # so as not to get modified
1205 self.gpr = GPR(decoder2, self, self.svstate, regfile)
1206 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
1207 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
1208
1209 # set up 4 dummy SVSHAPEs if they aren't already set up
1210 for i in range(4):
1211 sname = 'SVSHAPE%d' % i
1212 val = self.spr.get(sname, 0)
1213 # make sure it's an SVSHAPE
1214 self.spr[sname] = SVSHAPE(val, self.gpr)
1215 self.last_op_svshape = False
1216
1217 # "raw" memory
1218 if use_mmap_mem:
1219 self.mem = MemMMap(row_bytes=8,
1220 initial_mem=initial_mem,
1221 misaligned_ok=True)
1222 self.imem = self.mem
1223 self.mem.initialize(row_bytes=4, initial_mem=initial_insns)
1224 self.mem.log_fancy(kind=LogKind.InstrInOuts)
1225 else:
1226 self.mem = Mem(row_bytes=8, initial_mem=initial_mem,
1227 misaligned_ok=True)
1228 self.mem.log_fancy(kind=LogKind.InstrInOuts)
1229 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
1230 # MMU mode, redirect underlying Mem through RADIX
1231 if mmu:
1232 self.mem = RADIX(self.mem, self)
1233 if icachemmu:
1234 self.imem = RADIX(self.imem, self)
1235
1236 # TODO, needed here:
1237 # FPR (same as GPR except for FP nums)
1238 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1239 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1240 self.fpscr = FPSCRState(initial_fpscr)
1241
1242 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1243 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1244 # -- Done
1245 # 2.3.2 LR (actually SPR #8) -- Done
1246 # 2.3.3 CTR (actually SPR #9) -- Done
1247 # 2.3.4 TAR (actually SPR #815)
1248 # 3.2.2 p45 XER (actually SPR #1) -- Done
1249 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1250
1251 # create CR then allow portions of it to be "selectable" (below)
1252 self.cr_fields = CRFields(initial_cr)
1253 self.cr = self.cr_fields.cr
1254 self.cr_backup = 0 # sigh, dreadful hack: for fail-first (VLi)
1255
1256 # "undefined", just set to variable-bit-width int (use exts "max")
1257 # self.undefined = SelectableInt(0, EFFECTIVELY_UNLIMITED)
1258
1259 self.namespace = {}
1260 self.namespace.update(self.spr)
1261 self.namespace.update({'GPR': self.gpr,
1262 'FPR': self.fpr,
1263 'MEM': self.mem,
1264 'SPR': self.spr,
1265 'memassign': self.memassign,
1266 'NIA': self.pc.NIA,
1267 'CIA': self.pc.CIA,
1268 'SVSTATE': self.svstate,
1269 'SVSHAPE0': self.spr['SVSHAPE0'],
1270 'SVSHAPE1': self.spr['SVSHAPE1'],
1271 'SVSHAPE2': self.spr['SVSHAPE2'],
1272 'SVSHAPE3': self.spr['SVSHAPE3'],
1273 'CR': self.cr,
1274 'MSR': self.msr,
1275 'FPSCR': self.fpscr,
1276 'undefined': undefined,
1277 'mode_is_64bit': True,
1278 'SO': XER_bits['SO'],
1279 'XLEN': 64 # elwidth overrides
1280 })
1281
1282 for name in BFP_FLAG_NAMES:
1283 setattr(self, name, 0)
1284
1285 # update pc to requested start point
1286 self.set_pc(initial_pc)
1287
1288 # field-selectable versions of Condition Register
1289 self.crl = self.cr_fields.crl
1290 for i in range(8):
1291 self.namespace["CR%d" % i] = self.crl[i]
1292
1293 self.decoder = decoder2.dec
1294 self.dec2 = decoder2
1295
1296 super().__init__(XLEN=self.namespace["XLEN"], FPSCR=self.fpscr)
1297
1298 def trace(self, out):
1299 if self.insnlog is None: return
1300 self.insnlog.write(out)
1301
1302 @property
1303 def XLEN(self):
1304 return self.namespace["XLEN"]
1305
1306 @property
1307 def FPSCR(self):
1308 return self.fpscr
1309
1310 def call_trap(self, trap_addr, trap_bit):
1311 """calls TRAP and sets up NIA to the new execution location.
1312 next instruction will begin at trap_addr.
1313 """
1314 self.TRAP(trap_addr, trap_bit)
1315 self.namespace['NIA'] = self.trap_nia
1316 self.pc.update(self.namespace, self.is_svp64_mode)
1317
1318 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
1319 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1320
1321 TRAP function is callable from inside the pseudocode itself,
1322 hence the default arguments. when calling from inside ISACaller
1323 it is best to use call_trap()
1324 """
1325 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1326 kaivb = self.spr['KAIVB'].value
1327 msr = self.namespace['MSR'].value
1328 log("TRAP:", hex(trap_addr), hex(msr), "kaivb", hex(kaivb))
1329 # store CIA(+4?) in SRR0, set NIA to 0x700
1330 # store MSR in SRR1, set MSR to um errr something, have to check spec
1331 # store SVSTATE (if enabled) in SVSRR0
1332 self.spr['SRR0'].value = self.pc.CIA.value
1333 self.spr['SRR1'].value = msr
1334 if self.is_svp64_mode:
1335 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
1336 self.trap_nia = SelectableInt(trap_addr | (kaivb & ~0x1fff), 64)
1337 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
1338
1339 # set exception bits. TODO: this should, based on the address
1340 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1341 # bits appropriately. however it turns out that *for now* in all
1342 # cases (all trap_addrs) the exact same thing is needed.
1343 self.msr[MSRb.IR] = 0
1344 self.msr[MSRb.DR] = 0
1345 self.msr[MSRb.FE0] = 0
1346 self.msr[MSRb.FE1] = 0
1347 self.msr[MSRb.EE] = 0
1348 self.msr[MSRb.RI] = 0
1349 self.msr[MSRb.SF] = 1
1350 self.msr[MSRb.TM] = 0
1351 self.msr[MSRb.VEC] = 0
1352 self.msr[MSRb.VSX] = 0
1353 self.msr[MSRb.PR] = 0
1354 self.msr[MSRb.FP] = 0
1355 self.msr[MSRb.PMM] = 0
1356 self.msr[MSRb.TEs] = 0
1357 self.msr[MSRb.TEe] = 0
1358 self.msr[MSRb.UND] = 0
1359 self.msr[MSRb.LE] = 1
1360
1361 def memassign(self, ea, sz, val):
1362 self.mem.memassign(ea, sz, val)
1363
1364 def prep_namespace(self, insn_name, formname, op_fields, xlen):
1365 # TODO: get field names from form in decoder*1* (not decoder2)
1366 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1367 # from spec
1368 # then "yield" fields only from op_fields rather than hard-coded
1369 # list, here.
1370 fields = self.decoder.sigforms[formname]
1371 log("prep_namespace", formname, op_fields, insn_name)
1372 for name in op_fields:
1373 # CR immediates. deal with separately. needs modifying
1374 # pseudocode
1375 if self.is_svp64_mode and name in ['BI']: # TODO, more CRs
1376 # BI is a 5-bit, must reconstruct the value
1377 regnum, is_vec = yield from get_cr_in(self.dec2, name)
1378 sig = getattr(fields, name)
1379 val = yield sig
1380 # low 2 LSBs (CR field selector) remain same, CR num extended
1381 assert regnum <= 7, "sigh, TODO, 128 CR fields"
1382 val = (val & 0b11) | (regnum << 2)
1383 elif self.is_svp64_mode and name in ['BF']: # TODO, more CRs
1384 regnum, is_vec = yield from get_cr_out(self.dec2, "BF")
1385 log('hack %s' % name, regnum, is_vec)
1386 val = regnum
1387 else:
1388 sig = getattr(fields, name)
1389 val = yield sig
1390 # these are all opcode fields involved in index-selection of CR,
1391 # and need to do "standard" arithmetic. CR[BA+32] for example
1392 # would, if using SelectableInt, only be 5-bit.
1393 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1394 self.namespace[name] = val
1395 else:
1396 self.namespace[name] = SelectableInt(val, sig.width)
1397
1398 self.namespace['XER'] = self.spr['XER']
1399 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
1400 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
1401 self.namespace['OV'] = self.spr['XER'][XER_bits['OV']].value
1402 self.namespace['OV32'] = self.spr['XER'][XER_bits['OV32']].value
1403 self.namespace['XLEN'] = xlen
1404
1405 # add some SVSTATE convenience variables
1406 vl = self.svstate.vl
1407 srcstep = self.svstate.srcstep
1408 self.namespace['VL'] = vl
1409 self.namespace['srcstep'] = srcstep
1410
1411 # take a copy of the CR field value: if non-VLi fail-first fails
1412 # this is because the pseudocode writes *directly* to CR. sigh
1413 self.cr_backup = self.cr.value
1414
1415 # sv.bc* need some extra fields
1416 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1417 # blegh grab bits manually
1418 mode = yield self.dec2.rm_dec.rm_in.mode
1419 # convert to SelectableInt before test
1420 mode = SelectableInt(mode, 5)
1421 bc_vlset = mode[SVP64MODEb.BC_VLSET] != 0
1422 bc_vli = mode[SVP64MODEb.BC_VLI] != 0
1423 bc_snz = mode[SVP64MODEb.BC_SNZ] != 0
1424 bc_vsb = yield self.dec2.rm_dec.bc_vsb
1425 bc_lru = yield self.dec2.rm_dec.bc_lru
1426 bc_gate = yield self.dec2.rm_dec.bc_gate
1427 sz = yield self.dec2.rm_dec.pred_sz
1428 self.namespace['mode'] = SelectableInt(mode, 5)
1429 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
1430 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
1431 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
1432 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
1433 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
1434 self.namespace['sz'] = SelectableInt(sz, 1)
1435 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
1436
1437 def get_kludged_op_add_ca_ov(self, inputs, inp_ca_ov):
1438 """ this was not at all necessary to do. this function massively
1439 duplicates - in a laborious and complex fashion - the contents of
1440 the CSV files that were extracted two years ago from microwatt's
1441 source code. A-inversion is the "inv A" column, output inversion
1442 is the "inv out" column, carry-in equal to 0 or 1 or CA is the
1443 "cry in" column
1444
1445 all of that information is available in
1446 self.instrs[ins_name].op_fields
1447 where info is usually assigned to self.instrs[ins_name]
1448
1449 https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=openpower/isatables/minor_31.csv;hb=HEAD
1450
1451 the immediate constants are *also* decoded correctly and placed
1452 usually by DecodeIn2Imm into operand2, as part of power_decoder2.py
1453 """
1454 def ca(a, b, ca_in, width):
1455 mask = (1 << width) - 1
1456 y = (a & mask) + (b & mask) + ca_in
1457 return y >> width
1458
1459 asmcode = yield self.dec2.dec.op.asmcode
1460 insn = insns.get(asmcode)
1461 SI = yield self.dec2.dec.SI
1462 SI &= 0xFFFF
1463 CA, OV = inp_ca_ov
1464 inputs = [i.value for i in inputs]
1465 if SI & 0x8000:
1466 SI -= 0x10000
1467 if insn in ("add", "addo", "addc", "addco"):
1468 a = inputs[0]
1469 b = inputs[1]
1470 ca_in = 0
1471 elif insn == "addic" or insn == "addic.":
1472 a = inputs[0]
1473 b = SI
1474 ca_in = 0
1475 elif insn in ("subf", "subfo", "subfc", "subfco"):
1476 a = ~inputs[0]
1477 b = inputs[1]
1478 ca_in = 1
1479 elif insn == "subfic":
1480 a = ~inputs[0]
1481 b = SI
1482 ca_in = 1
1483 elif insn == "adde" or insn == "addeo":
1484 a = inputs[0]
1485 b = inputs[1]
1486 ca_in = CA
1487 elif insn == "subfe" or insn == "subfeo":
1488 a = ~inputs[0]
1489 b = inputs[1]
1490 ca_in = CA
1491 elif insn == "addme" or insn == "addmeo":
1492 a = inputs[0]
1493 b = ~0
1494 ca_in = CA
1495 elif insn == "addze" or insn == "addzeo":
1496 a = inputs[0]
1497 b = 0
1498 ca_in = CA
1499 elif insn == "subfme" or insn == "subfmeo":
1500 a = ~inputs[0]
1501 b = ~0
1502 ca_in = CA
1503 elif insn == "subfze" or insn == "subfzeo":
1504 a = ~inputs[0]
1505 b = 0
1506 ca_in = CA
1507 elif insn == "addex":
1508 # CA[32] aren't actually written, just generate so we have
1509 # something to return
1510 ca64 = ov64 = ca(inputs[0], inputs[1], OV, 64)
1511 ca32 = ov32 = ca(inputs[0], inputs[1], OV, 32)
1512 return ca64, ca32, ov64, ov32
1513 elif insn == "neg" or insn == "nego":
1514 a = ~inputs[0]
1515 b = 0
1516 ca_in = 1
1517 else:
1518 raise NotImplementedError(
1519 "op_add kludge unimplemented instruction: ", asmcode, insn)
1520
1521 ca64 = ca(a, b, ca_in, 64)
1522 ca32 = ca(a, b, ca_in, 32)
1523 ov64 = ca64 != ca(a, b, ca_in, 63)
1524 ov32 = ca32 != ca(a, b, ca_in, 31)
1525 return ca64, ca32, ov64, ov32
1526
1527 def handle_carry_(self, inputs, output, ca, ca32, inp_ca_ov):
1528 op = yield self.dec2.e.do.insn_type
1529 if op == MicrOp.OP_ADD.value and ca is None and ca32 is None:
1530 retval = yield from self.get_kludged_op_add_ca_ov(
1531 inputs, inp_ca_ov)
1532 ca, ca32, ov, ov32 = retval
1533 asmcode = yield self.dec2.dec.op.asmcode
1534 if insns.get(asmcode) == 'addex':
1535 # TODO: if 32-bit mode, set ov to ov32
1536 self.spr['XER'][XER_bits['OV']] = ov
1537 self.spr['XER'][XER_bits['OV32']] = ov32
1538 else:
1539 # TODO: if 32-bit mode, set ca to ca32
1540 self.spr['XER'][XER_bits['CA']] = ca
1541 self.spr['XER'][XER_bits['CA32']] = ca32
1542 return
1543 inv_a = yield self.dec2.e.do.invert_in
1544 if inv_a:
1545 inputs[0] = ~inputs[0]
1546
1547 imm_ok = yield self.dec2.e.do.imm_data.ok
1548 if imm_ok:
1549 imm = yield self.dec2.e.do.imm_data.data
1550 inputs.append(SelectableInt(imm, 64))
1551 gts = []
1552 for x in inputs:
1553 log("gt input", x, output)
1554 gt = (gtu(x, output))
1555 gts.append(gt)
1556 log(gts)
1557 cy = 1 if any(gts) else 0
1558 log("CA", cy, gts)
1559 if ca is None: # already written
1560 self.spr['XER'][XER_bits['CA']] = cy
1561
1562 # 32 bit carry
1563 # ARGH... different for OP_ADD... *sigh*...
1564 op = yield self.dec2.e.do.insn_type
1565 if op == MicrOp.OP_ADD.value:
1566 res32 = (output.value & (1 << 32)) != 0
1567 a32 = (inputs[0].value & (1 << 32)) != 0
1568 if len(inputs) >= 2:
1569 b32 = (inputs[1].value & (1 << 32)) != 0
1570 else:
1571 b32 = False
1572 cy32 = res32 ^ a32 ^ b32
1573 log("CA32 ADD", cy32)
1574 else:
1575 gts = []
1576 for x in inputs:
1577 log("input", x, output)
1578 log(" x[32:64]", x, x[32:64])
1579 log(" o[32:64]", output, output[32:64])
1580 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
1581 gts.append(gt)
1582 cy32 = 1 if any(gts) else 0
1583 log("CA32", cy32, gts)
1584 if ca32 is None: # already written
1585 self.spr['XER'][XER_bits['CA32']] = cy32
1586
1587 def handle_overflow(self, inputs, output, div_overflow, inp_ca_ov):
1588 op = yield self.dec2.e.do.insn_type
1589 if op == MicrOp.OP_ADD.value:
1590 retval = yield from self.get_kludged_op_add_ca_ov(
1591 inputs, inp_ca_ov)
1592 ca, ca32, ov, ov32 = retval
1593 # TODO: if 32-bit mode, set ov to ov32
1594 self.spr['XER'][XER_bits['OV']] = ov
1595 self.spr['XER'][XER_bits['OV32']] = ov32
1596 self.spr['XER'][XER_bits['SO']] |= ov
1597 return
1598 if hasattr(self.dec2.e.do, "invert_in"):
1599 inv_a = yield self.dec2.e.do.invert_in
1600 if inv_a:
1601 inputs[0] = ~inputs[0]
1602
1603 imm_ok = yield self.dec2.e.do.imm_data.ok
1604 if imm_ok:
1605 imm = yield self.dec2.e.do.imm_data.data
1606 inputs.append(SelectableInt(imm, 64))
1607 log("handle_overflow", inputs, output, div_overflow)
1608 if len(inputs) < 2 and div_overflow is None:
1609 return
1610
1611 # div overflow is different: it's returned by the pseudo-code
1612 # because it's more complex than can be done by analysing the output
1613 if div_overflow is not None:
1614 ov, ov32 = div_overflow, div_overflow
1615 # arithmetic overflow can be done by analysing the input and output
1616 elif len(inputs) >= 2:
1617 # OV (64-bit)
1618 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
1619 output_sgn = exts(output.value, output.bits) < 0
1620 ov = 1 if input_sgn[0] == input_sgn[1] and \
1621 output_sgn != input_sgn[0] else 0
1622
1623 # OV (32-bit)
1624 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
1625 output32_sgn = exts(output.value, 32) < 0
1626 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
1627 output32_sgn != input32_sgn[0] else 0
1628
1629 # now update XER OV/OV32/SO
1630 so = self.spr['XER'][XER_bits['SO']]
1631 new_so = so | ov # sticky overflow ORs in old with new
1632 self.spr['XER'][XER_bits['OV']] = ov
1633 self.spr['XER'][XER_bits['OV32']] = ov32
1634 self.spr['XER'][XER_bits['SO']] = new_so
1635 log(" set overflow", ov, ov32, so, new_so)
1636
1637 def handle_comparison(self, out, cr_idx=0, overflow=None, no_so=False):
1638 assert isinstance(out, SelectableInt), \
1639 "out zero not a SelectableInt %s" % repr(outputs)
1640 log("handle_comparison", out.bits, hex(out.value))
1641 # TODO - XXX *processor* in 32-bit mode
1642 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1643 # if is_32bit:
1644 # o32 = exts(out.value, 32)
1645 # print ("handle_comparison exts 32 bit", hex(o32))
1646 out = exts(out.value, out.bits)
1647 log("handle_comparison exts", hex(out))
1648 # create the three main CR flags, EQ GT LT
1649 zero = SelectableInt(out == 0, 1)
1650 positive = SelectableInt(out > 0, 1)
1651 negative = SelectableInt(out < 0, 1)
1652 # get (or not) XER.SO. for setvl this is important *not* to read SO
1653 if no_so:
1654 SO = SelectableInt(1, 0)
1655 else:
1656 SO = self.spr['XER'][XER_bits['SO']]
1657 log("handle_comparison SO", SO.value,
1658 "overflow", overflow,
1659 "zero", zero.value,
1660 "+ve", positive.value,
1661 "-ve", negative.value)
1662 # alternative overflow checking (setvl mainly at the moment)
1663 if overflow is not None and overflow == 1:
1664 SO = SelectableInt(1, 1)
1665 # create the four CR field values and set the required CR field
1666 cr_field = selectconcat(negative, positive, zero, SO)
1667 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
1668 self.crl[cr_idx].eq(cr_field)
1669
1670 def set_pc(self, pc_val):
1671 self.namespace['NIA'] = SelectableInt(pc_val, 64)
1672 self.pc.update(self.namespace, self.is_svp64_mode)
1673
1674 def get_next_insn(self):
1675 """check instruction
1676 """
1677 if self.respect_pc:
1678 pc = self.pc.CIA.value
1679 else:
1680 pc = self.fake_pc
1681 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
1682 if ins is None:
1683 raise KeyError("no instruction at 0x%x" % pc)
1684 return pc, ins
1685
1686 def setup_one(self):
1687 """set up one instruction
1688 """
1689 pc, insn = self.get_next_insn()
1690 yield from self.setup_next_insn(pc, insn)
1691
1692 # cache since it's really slow to construct
1693 __PREFIX_CACHE = SVP64Instruction.Prefix(SelectableInt(value=0, bits=32))
1694
1695 def __decode_prefix(self, opcode):
1696 pfx = self.__PREFIX_CACHE
1697 pfx.storage.eq(opcode)
1698 return pfx
1699
1700 def setup_next_insn(self, pc, ins):
1701 """set up next instruction
1702 """
1703 self._pc = pc
1704 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
1705 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
1706
1707 yield self.dec2.sv_rm.eq(0)
1708 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
1709 yield self.dec2.dec.bigendian.eq(self.bigendian)
1710 yield self.dec2.state.msr.eq(self.msr.value)
1711 yield self.dec2.state.pc.eq(pc)
1712 if self.svstate is not None:
1713 yield self.dec2.state.svstate.eq(self.svstate.value)
1714
1715 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1716 yield Settle()
1717 opcode = yield self.dec2.dec.opcode_in
1718 opcode = SelectableInt(value=opcode, bits=32)
1719 pfx = self.__decode_prefix(opcode)
1720 log("prefix test: opcode:", pfx.PO, bin(pfx.PO), pfx.id)
1721 self.is_svp64_mode = bool((pfx.PO == 0b000001) and (pfx.id == 0b11))
1722 self.pc.update_nia(self.is_svp64_mode)
1723 # set SVP64 decode
1724 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
1725 self.namespace['NIA'] = self.pc.NIA
1726 self.namespace['SVSTATE'] = self.svstate
1727 if not self.is_svp64_mode:
1728 return
1729
1730 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1731 log("svp64.rm", bin(pfx.rm))
1732 log(" svstate.vl", self.svstate.vl)
1733 log(" svstate.mvl", self.svstate.maxvl)
1734 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
1735 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
1736 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
1737 yield self.dec2.sv_rm.eq(int(pfx.rm)) # svp64 prefix
1738 yield Settle()
1739
1740 def execute_one(self):
1741 """execute one instruction
1742 """
1743 # get the disassembly code for this instruction
1744 if not self.disassembly:
1745 code = yield from self.get_assembly_name()
1746 else:
1747 offs, dbg = 0, ""
1748 if self.is_svp64_mode:
1749 offs, dbg = 4, "svp64 "
1750 code = self.disassembly[self._pc+offs]
1751 log(" %s sim-execute" % dbg, hex(self._pc), code)
1752 opname = code.split(' ')[0]
1753 try:
1754 yield from self.call(opname) # execute the instruction
1755 except MemException as e: # check for memory errors
1756 if e.args[0] == 'unaligned': # alignment error
1757 # run a Trap but set DAR first
1758 print("memory unaligned exception, DAR", e.dar, repr(e))
1759 self.spr['DAR'] = SelectableInt(e.dar, 64)
1760 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1761 return
1762 elif e.args[0] == 'invalid': # invalid
1763 # run a Trap but set DAR first
1764 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1765 if e.mode == 'EXECUTE':
1766 # XXX TODO: must set a few bits in SRR1,
1767 # see microwatt loadstore1.vhdl
1768 # if m_in.segerr = '0' then
1769 # v.srr1(47 - 33) := m_in.invalid;
1770 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1771 # v.srr1(47 - 44) := m_in.badtree;
1772 # v.srr1(47 - 45) := m_in.rc_error;
1773 # v.intr_vec := 16#400#;
1774 # else
1775 # v.intr_vec := 16#480#;
1776 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1777 else:
1778 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1779 return
1780 # not supported yet:
1781 raise e # ... re-raise
1782
1783 # append to the trace log file
1784 self.trace(" # %s\n" % code)
1785
1786 log("gprs after code", code)
1787 self.gpr.dump()
1788 crs = []
1789 for i in range(len(self.crl)):
1790 crs.append(bin(self.crl[i].asint()))
1791 log("crs", " ".join(crs))
1792 log("vl,maxvl", self.svstate.vl, self.svstate.maxvl)
1793
1794 # don't use this except in special circumstances
1795 if not self.respect_pc:
1796 self.fake_pc += 4
1797
1798 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1799 hex(self.pc.NIA.value))
1800
1801 def get_assembly_name(self):
1802 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1803 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1804 dec_insn = yield self.dec2.e.do.insn
1805 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1806 asmcode = yield self.dec2.dec.op.asmcode
1807 int_op = yield self.dec2.dec.op.internal_op
1808 log("get assembly name asmcode", asmcode, int_op,
1809 hex(dec_insn), bin(insn_1_11))
1810 asmop = insns.get(asmcode, None)
1811
1812 # sigh reconstruct the assembly instruction name
1813 if hasattr(self.dec2.e.do, "oe"):
1814 ov_en = yield self.dec2.e.do.oe.oe
1815 ov_ok = yield self.dec2.e.do.oe.ok
1816 else:
1817 ov_en = False
1818 ov_ok = False
1819 if hasattr(self.dec2.e.do, "rc"):
1820 rc_en = yield self.dec2.e.do.rc.rc
1821 rc_ok = yield self.dec2.e.do.rc.ok
1822 else:
1823 rc_en = False
1824 rc_ok = False
1825 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1826 RC1 = yield self.dec2.rm_dec.RC1
1827 if RC1:
1828 rc_en = False
1829 rc_ok = False
1830 # grrrr have to special-case MUL op (see DecodeOE)
1831 log("ov %d en %d rc %d en %d op %d" %
1832 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1833 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1834 log("mul op")
1835 if rc_en & rc_ok:
1836 asmop += "."
1837 else:
1838 if not asmop.endswith("."): # don't add "." to "andis."
1839 if rc_en & rc_ok:
1840 asmop += "."
1841 if hasattr(self.dec2.e.do, "lk"):
1842 lk = yield self.dec2.e.do.lk
1843 if lk:
1844 asmop += "l"
1845 log("int_op", int_op)
1846 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1847 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1848 log("AA", AA)
1849 if AA:
1850 asmop += "a"
1851 spr_msb = yield from self.get_spr_msb()
1852 if int_op == MicrOp.OP_MFCR.value:
1853 if spr_msb:
1854 asmop = 'mfocrf'
1855 else:
1856 asmop = 'mfcr'
1857 # XXX TODO: for whatever weird reason this doesn't work
1858 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1859 if int_op == MicrOp.OP_MTCRF.value:
1860 if spr_msb:
1861 asmop = 'mtocrf'
1862 else:
1863 asmop = 'mtcrf'
1864 return asmop
1865
1866 def reset_remaps(self):
1867 self.remap_loopends = [0] * 4
1868 self.remap_idxs = [0, 1, 2, 3]
1869
1870 def get_remap_indices(self):
1871 """WARNING, this function stores remap_idxs and remap_loopends
1872 in the class for later use. this to avoid problems with yield
1873 """
1874 # go through all iterators in lock-step, advance to next remap_idx
1875 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1876 # get four SVSHAPEs. here we are hard-coding
1877 self.reset_remaps()
1878 SVSHAPE0 = self.spr['SVSHAPE0']
1879 SVSHAPE1 = self.spr['SVSHAPE1']
1880 SVSHAPE2 = self.spr['SVSHAPE2']
1881 SVSHAPE3 = self.spr['SVSHAPE3']
1882 # set up the iterators
1883 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1884 (SVSHAPE1, SVSHAPE1.get_iterator()),
1885 (SVSHAPE2, SVSHAPE2.get_iterator()),
1886 (SVSHAPE3, SVSHAPE3.get_iterator()),
1887 ]
1888
1889 dbg = []
1890 for i, (shape, remap) in enumerate(remaps):
1891 # zero is "disabled"
1892 if shape.value == 0x0:
1893 self.remap_idxs[i] = 0
1894 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1895 step = dststep if (i in [3, 4]) else srcstep
1896 # this is terrible. O(N^2) looking for the match. but hey.
1897 for idx, (remap_idx, loopends) in enumerate(remap):
1898 if idx == step:
1899 break
1900 self.remap_idxs[i] = remap_idx
1901 self.remap_loopends[i] = loopends
1902 dbg.append((i, step, remap_idx, loopends))
1903 for (i, step, remap_idx, loopends) in dbg:
1904 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1905 return remaps
1906
1907 def get_spr_msb(self):
1908 dec_insn = yield self.dec2.e.do.insn
1909 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1910
1911 def call(self, name):
1912 """call(opcode) - the primary execution point for instructions
1913 """
1914 self.last_st_addr = None # reset the last known store address
1915 self.last_ld_addr = None # etc.
1916
1917 ins_name = name.strip() # remove spaces if not already done so
1918 if self.halted:
1919 log("halted - not executing", ins_name)
1920 return
1921
1922 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1923 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1924 asmop = yield from self.get_assembly_name()
1925 log("call", ins_name, asmop)
1926
1927 # sv.setvl is *not* a loop-function. sigh
1928 log("is_svp64_mode", self.is_svp64_mode, asmop)
1929
1930 # check privileged
1931 int_op = yield self.dec2.dec.op.internal_op
1932 spr_msb = yield from self.get_spr_msb()
1933
1934 instr_is_privileged = False
1935 if int_op in [MicrOp.OP_ATTN.value,
1936 MicrOp.OP_MFMSR.value,
1937 MicrOp.OP_MTMSR.value,
1938 MicrOp.OP_MTMSRD.value,
1939 # TODO: OP_TLBIE
1940 MicrOp.OP_RFID.value]:
1941 instr_is_privileged = True
1942 if int_op in [MicrOp.OP_MFSPR.value,
1943 MicrOp.OP_MTSPR.value] and spr_msb:
1944 instr_is_privileged = True
1945
1946 log("is priv", instr_is_privileged, hex(self.msr.value),
1947 self.msr[MSRb.PR])
1948 # check MSR priv bit and whether op is privileged: if so, throw trap
1949 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1950 self.call_trap(0x700, PIb.PRIV)
1951 return
1952
1953 # check halted condition
1954 if ins_name == 'attn':
1955 self.halted = True
1956 return
1957
1958 # check illegal instruction
1959 illegal = False
1960 if ins_name not in ['mtcrf', 'mtocrf']:
1961 illegal = ins_name != asmop
1962
1963 # list of instructions not being supported by binutils (.long)
1964 dotstrp = asmop[:-1] if asmop[-1] == '.' else asmop
1965 if dotstrp in [*FPTRANS_INSNS,
1966 *LDST_UPDATE_INSNS,
1967 'ffmadds', 'fdmadds', 'ffadds',
1968 'minmax',
1969 "brh", "brw", "brd",
1970 'setvl', 'svindex', 'svremap', 'svstep',
1971 'svshape', 'svshape2',
1972 'ternlogi', 'bmask', 'cprop',
1973 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1974 'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
1975 "dsld", "dsrd", "maddedus",
1976 "sadd", "saddw", "sadduw",
1977 "cffpr", "cffpro",
1978 "mffpr", "mffprs",
1979 "ctfpr", "ctfprs",
1980 "mtfpr", "mtfprs",
1981 "maddsubrs", "maddrs", "msubrs",
1982 "cfuged", "cntlzdm", "cnttzdm", "pdepd", "pextd",
1983 "setbc", "setbcr", "setnbc", "setnbcr",
1984 ]:
1985 illegal = False
1986 ins_name = dotstrp
1987
1988 # branch-conditional redirects to sv.bc
1989 if asmop.startswith('bc') and self.is_svp64_mode:
1990 ins_name = 'sv.%s' % ins_name
1991
1992 # ld-immediate-with-pi mode redirects to ld-with-postinc
1993 ldst_imm_postinc = False
1994 if 'u' in ins_name and self.is_svp64_mode:
1995 ldst_pi = yield self.dec2.rm_dec.ldst_postinc
1996 if ldst_pi:
1997 ins_name = ins_name.replace("u", "up")
1998 ldst_imm_postinc = True
1999 log(" enable ld/st postinc", ins_name)
2000
2001 log(" post-processed name", dotstrp, ins_name, asmop)
2002
2003 # illegal instructions call TRAP at 0x700
2004 if illegal:
2005 print("illegal", ins_name, asmop)
2006 self.call_trap(0x700, PIb.ILLEG)
2007 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
2008 (ins_name, asmop, self.pc.CIA.value))
2009 return
2010
2011 # this is for setvl "Vertical" mode: if set true,
2012 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
2013 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
2014 self.allow_next_step_inc = False
2015 self.svstate_next_mode = 0
2016
2017 # nop has to be supported, we could let the actual op calculate
2018 # but PowerDecoder has a pattern for nop
2019 if ins_name == 'nop':
2020 self.update_pc_next()
2021 return
2022
2023 # get elwidths, defaults to 64
2024 xlen = 64
2025 ew_src = 64
2026 ew_dst = 64
2027 if self.is_svp64_mode:
2028 ew_src = yield self.dec2.rm_dec.ew_src
2029 ew_dst = yield self.dec2.rm_dec.ew_dst
2030 ew_src = 8 << (3-int(ew_src)) # convert to bitlength
2031 ew_dst = 8 << (3-int(ew_dst)) # convert to bitlength
2032 xlen = max(ew_src, ew_dst)
2033 log("elwdith", ew_src, ew_dst)
2034 log("XLEN:", self.is_svp64_mode, xlen)
2035
2036 # look up instruction in ISA.instrs, prepare namespace
2037 if ins_name == 'pcdec': # grrrr yes there are others ("stbcx." etc.)
2038 info = self.instrs[ins_name+"."]
2039 elif asmop[-1] == '.' and asmop in self.instrs:
2040 info = self.instrs[asmop]
2041 else:
2042 info = self.instrs[ins_name]
2043 yield from self.prep_namespace(ins_name, info.form, info.op_fields,
2044 xlen)
2045
2046 # preserve order of register names
2047 input_names = create_args(list(info.read_regs) +
2048 list(info.uninit_regs))
2049 log("input names", input_names)
2050
2051 # get SVP64 entry for the current instruction
2052 sv_rm = self.svp64rm.instrs.get(ins_name)
2053 if sv_rm is not None:
2054 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
2055 else:
2056 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
2057 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
2058
2059 # see if srcstep/dststep need skipping over masked-out predicate bits
2060 # svstep also needs advancement because it calls SVSTATE_NEXT.
2061 # bit the remaps get computed just after pre_inc moves them on
2062 # with remap_set_steps substituting for PowerDecider2 not doing it,
2063 # and SVSTATE_NEXT not being able to.use yield, the preinc on
2064 # svstep is necessary for now.
2065 self.reset_remaps()
2066 if (self.is_svp64_mode or ins_name in ['svstep']):
2067 yield from self.svstate_pre_inc()
2068 if self.is_svp64_mode:
2069 pre = yield from self.update_new_svstate_steps()
2070 if pre:
2071 self.svp64_reset_loop()
2072 self.update_nia()
2073 self.update_pc_next()
2074 return
2075 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
2076 pred_dst_zero = self.pred_dst_zero
2077 pred_src_zero = self.pred_src_zero
2078 vl = self.svstate.vl
2079 subvl = yield self.dec2.rm_dec.rm_in.subvl
2080
2081 # VL=0 in SVP64 mode means "do nothing: skip instruction"
2082 if self.is_svp64_mode and vl == 0:
2083 self.pc.update(self.namespace, self.is_svp64_mode)
2084 log("SVP64: VL=0, end of call", self.namespace['CIA'],
2085 self.namespace['NIA'], kind=LogKind.InstrInOuts)
2086 return
2087
2088 # for when SVREMAP is active, using pre-arranged schedule.
2089 # note: modifying PowerDecoder2 needs to "settle"
2090 remap_en = self.svstate.SVme
2091 persist = self.svstate.RMpst
2092 active = (persist or self.last_op_svshape) and remap_en != 0
2093 if self.is_svp64_mode:
2094 yield self.dec2.remap_active.eq(remap_en if active else 0)
2095 yield Settle()
2096 if persist or self.last_op_svshape:
2097 remaps = self.get_remap_indices()
2098 if self.is_svp64_mode and (persist or self.last_op_svshape):
2099 yield from self.remap_set_steps(remaps)
2100 # after that, settle down (combinatorial) to let Vector reg numbers
2101 # work themselves out
2102 yield Settle()
2103 if self.is_svp64_mode:
2104 remap_active = yield self.dec2.remap_active
2105 else:
2106 remap_active = False
2107 log("remap active", bin(remap_active))
2108
2109 # main input registers (RT, RA ...)
2110 inputs = []
2111 for name in input_names:
2112 regval = (yield from self.get_input(name, ew_src))
2113 log("regval name", name, regval)
2114 inputs.append(regval)
2115
2116 # arrrrgh, awful hack, to get _RT into namespace
2117 if ins_name in ['setvl', 'svstep']:
2118 regname = "_RT"
2119 RT = yield self.dec2.dec.RT
2120 self.namespace[regname] = SelectableInt(RT, 5)
2121 if RT == 0:
2122 self.namespace["RT"] = SelectableInt(0, 5)
2123 regnum, is_vec = yield from get_idx_out(self.dec2, "RT")
2124 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
2125
2126 # in SVP64 mode for LD/ST work out immediate
2127 # XXX TODO: replace_ds for DS-Form rather than D-Form.
2128 # use info.form to detect
2129 if self.is_svp64_mode and not ldst_imm_postinc:
2130 yield from self.check_replace_d(info, remap_active)
2131
2132 # "special" registers
2133 for special in info.special_regs:
2134 if special in special_sprs:
2135 inputs.append(self.spr[special])
2136 else:
2137 inputs.append(self.namespace[special])
2138
2139 # clear trap (trap) NIA
2140 self.trap_nia = None
2141
2142 # check if this was an sv.bc* and create an indicator that
2143 # this is the last check to be made as a loop. combined with
2144 # the ALL/ANY mode we can early-exit
2145 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
2146 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
2147 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
2148 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
2149
2150 inp_ca_ov = (self.spr['XER'][XER_bits['CA']].value,
2151 self.spr['XER'][XER_bits['OV']].value)
2152
2153 # execute actual instruction here (finally)
2154 log("inputs", inputs)
2155 results = info.func(self, *inputs)
2156 output_names = create_args(info.write_regs)
2157 outs = {}
2158 for out, n in zip(results or [], output_names):
2159 outs[n] = out
2160 log("results", outs)
2161
2162 # "inject" decorator takes namespace from function locals: we need to
2163 # overwrite NIA being overwritten (sigh)
2164 if self.trap_nia is not None:
2165 self.namespace['NIA'] = self.trap_nia
2166
2167 log("after func", self.namespace['CIA'], self.namespace['NIA'])
2168
2169 # check if op was a LD/ST so that debugging can check the
2170 # address
2171 if int_op in [MicrOp.OP_STORE.value,
2172 ]:
2173 self.last_st_addr = self.mem.last_st_addr
2174 if int_op in [MicrOp.OP_LOAD.value,
2175 ]:
2176 self.last_ld_addr = self.mem.last_ld_addr
2177 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
2178 self.last_st_addr, self.last_ld_addr)
2179
2180 # detect if CA/CA32 already in outputs (sra*, basically)
2181 ca = outs.get("CA")
2182 ca32 = outs.get("CA32")
2183
2184 log("carry already done?", ca, ca32, output_names)
2185 # soc test_pipe_caller tests don't have output_carry
2186 has_output_carry = hasattr(self.dec2.e.do, "output_carry")
2187 carry_en = has_output_carry and (yield self.dec2.e.do.output_carry)
2188 if carry_en:
2189 yield from self.handle_carry_(
2190 inputs, results[0], ca, ca32, inp_ca_ov=inp_ca_ov)
2191
2192 # get output named "overflow" and "CR0"
2193 overflow = outs.get('overflow')
2194 cr0 = outs.get('CR0')
2195 cr1 = outs.get('CR1')
2196
2197 # soc test_pipe_caller tests don't have oe
2198 has_oe = hasattr(self.dec2.e.do, "oe")
2199 # yeah just no. not in parallel processing
2200 if has_oe and not self.is_svp64_mode:
2201 # detect if overflow was in return result
2202 ov_en = yield self.dec2.e.do.oe.oe
2203 ov_ok = yield self.dec2.e.do.oe.ok
2204 log("internal overflow", ins_name, overflow, "en?", ov_en, ov_ok)
2205 if ov_en & ov_ok:
2206 yield from self.handle_overflow(
2207 inputs, results[0], overflow, inp_ca_ov=inp_ca_ov)
2208
2209 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
2210 rc_en = False
2211 if not self.is_svp64_mode or not pred_dst_zero:
2212 if hasattr(self.dec2.e.do, "rc"):
2213 rc_en = yield self.dec2.e.do.rc.rc
2214 # don't do Rc=1 for svstep it is handled explicitly.
2215 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
2216 # to write directly to CR0 instead of in ISACaller. hooyahh.
2217 if rc_en and ins_name not in ['svstep']:
2218 yield from self.do_rc_ov(
2219 ins_name, results[0], overflow, cr0, cr1, output_names)
2220
2221 # check failfirst
2222 ffirst_hit = False, False
2223 if self.is_svp64_mode:
2224 sv_mode = yield self.dec2.rm_dec.sv_mode
2225 is_cr = sv_mode == SVMode.CROP.value
2226 chk = rc_en or is_cr
2227 ffirst_hit = (yield from self.check_ffirst(info, chk, srcstep))
2228
2229 # check if a FP Exception occurred. TODO for DD-FFirst, check VLi
2230 # and raise the exception *after* if VLi=1 but if VLi=0 then
2231 # truncate and make the exception "disappear".
2232 if self.FPSCR.FEX and (self.msr[MSRb.FE0] or self.msr[MSRb.FE1]):
2233 self.call_trap(0x700, PIb.FP)
2234 return
2235
2236 # any modified return results?
2237 yield from self.do_outregs_nia(asmop, ins_name, info, outs,
2238 carry_en, rc_en, ffirst_hit, ew_dst)
2239
2240 def check_ffirst(self, info, rc_en, srcstep):
2241 """fail-first mode: checks a bit of Rc Vector, truncates VL
2242 """
2243 rm_mode = yield self.dec2.rm_dec.mode
2244 ff_inv = yield self.dec2.rm_dec.inv
2245 cr_bit = yield self.dec2.rm_dec.cr_sel
2246 RC1 = yield self.dec2.rm_dec.RC1
2247 vli_ = yield self.dec2.rm_dec.vli # VL inclusive if truncated
2248 log(" ff rm_mode", rc_en, rm_mode, SVP64RMMode.FFIRST.value)
2249 log(" inv", ff_inv)
2250 log(" RC1", RC1)
2251 log(" vli", vli_)
2252 log(" cr_bit", cr_bit)
2253 log(" rc_en", rc_en)
2254 if not rc_en or rm_mode != SVP64RMMode.FFIRST.value:
2255 return False, False
2256 # get the CR vevtor, do BO-test
2257 crf = "CR0"
2258 log("asmregs", info.asmregs[0], info.write_regs)
2259 if 'CR' in info.write_regs and 'BF' in info.asmregs[0]:
2260 crf = 'BF'
2261 regnum, is_vec = yield from get_cr_out(self.dec2, crf)
2262 crtest = self.crl[regnum]
2263 ffirst_hit = crtest[cr_bit] != ff_inv
2264 log("cr test", crf, regnum, int(crtest), crtest, cr_bit, ff_inv)
2265 log("cr test?", ffirst_hit)
2266 if not ffirst_hit:
2267 return False, False
2268 # Fail-first activated, truncate VL
2269 vli = SelectableInt(int(vli_), 7)
2270 self.svstate.vl = srcstep + vli
2271 yield self.dec2.state.svstate.eq(self.svstate.value)
2272 yield Settle() # let decoder update
2273 return True, vli_
2274
2275 def do_rc_ov(self, ins_name, result, overflow, cr0, cr1, output_names):
2276 cr_out = yield self.dec2.op.cr_out
2277 if cr_out == CROutSel.CR1.value:
2278 rc_reg = "CR1"
2279 else:
2280 rc_reg = "CR0"
2281 regnum, is_vec = yield from get_cr_out(self.dec2, rc_reg)
2282 # hang on... for `setvl` actually you want to test SVSTATE.VL
2283 is_setvl = ins_name in ('svstep', 'setvl')
2284 if is_setvl:
2285 result = SelectableInt(result.vl, 64)
2286 #else:
2287 # overflow = None # do not override overflow except in setvl
2288
2289 if rc_reg == "CR1":
2290 if cr1 is None:
2291 cr1 = int(self.FPSCR.FX) << 3
2292 cr1 |= int(self.FPSCR.FEX) << 2
2293 cr1 |= int(self.FPSCR.VX) << 1
2294 cr1 |= int(self.FPSCR.OX)
2295 log("default fp cr1", cr1)
2296 else:
2297 log("explicit cr1", cr1)
2298 self.crl[regnum].eq(cr1)
2299 elif cr0 is None:
2300 # if there was not an explicit CR0 in the pseudocode,
2301 # do implicit Rc=1
2302 self.handle_comparison(result, regnum, overflow, no_so=is_setvl)
2303 else:
2304 # otherwise we just blat CR0 into the required regnum
2305 log("explicit rc0", cr0)
2306 self.crl[regnum].eq(cr0)
2307
2308 def do_outregs_nia(self, asmop, ins_name, info, outs,
2309 ca_en, rc_en, ffirst_hit, ew_dst):
2310 ffirst_hit, vli = ffirst_hit
2311 # write out any regs for this instruction, but only if fail-first is ok
2312 # XXX TODO: allow CR-vector to be written out even if ffirst fails
2313 if not ffirst_hit or vli:
2314 for name, output in outs.items():
2315 yield from self.check_write(info, name, output, ca_en, ew_dst)
2316 # restore the CR value on non-VLI failfirst (from sv.cmp and others
2317 # which write directly to CR in the pseudocode (gah, what a mess)
2318 # if ffirst_hit and not vli:
2319 # self.cr.value = self.cr_backup
2320
2321 if ffirst_hit:
2322 self.svp64_reset_loop()
2323 nia_update = True
2324 else:
2325 # check advancement of src/dst/sub-steps and if PC needs updating
2326 nia_update = (yield from self.check_step_increment(rc_en,
2327 asmop, ins_name))
2328 if nia_update:
2329 self.update_pc_next()
2330
2331 def check_replace_d(self, info, remap_active):
2332 replace_d = False # update / replace constant in pseudocode
2333 ldstmode = yield self.dec2.rm_dec.ldstmode
2334 vl = self.svstate.vl
2335 subvl = yield self.dec2.rm_dec.rm_in.subvl
2336 srcstep, dststep = self.new_srcstep, self.new_dststep
2337 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
2338 if info.form == 'DS':
2339 # DS-Form, multiply by 4 then knock 2 bits off after
2340 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
2341 else:
2342 imm = yield self.dec2.dec.fields.FormD.D[0:16]
2343 imm = exts(imm, 16) # sign-extend to integer
2344 # get the right step. LD is from srcstep, ST is dststep
2345 op = yield self.dec2.e.do.insn_type
2346 offsmul = 0
2347 if op == MicrOp.OP_LOAD.value:
2348 if remap_active:
2349 offsmul = yield self.dec2.in1_step
2350 log("D-field REMAP src", imm, offsmul, ldstmode)
2351 else:
2352 offsmul = (srcstep * (subvl+1)) + ssubstep
2353 log("D-field src", imm, offsmul, ldstmode)
2354 elif op == MicrOp.OP_STORE.value:
2355 # XXX NOTE! no bit-reversed STORE! this should not ever be used
2356 offsmul = (dststep * (subvl+1)) + dsubstep
2357 log("D-field dst", imm, offsmul, ldstmode)
2358 # Unit-Strided LD/ST adds offset*width to immediate
2359 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
2360 ldst_len = yield self.dec2.e.do.data_len
2361 imm = SelectableInt(imm + offsmul * ldst_len, 32)
2362 replace_d = True
2363 # Element-strided multiplies the immediate by element step
2364 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
2365 imm = SelectableInt(imm * offsmul, 32)
2366 replace_d = True
2367 if replace_d:
2368 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
2369 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
2370 log("LDSTmode", SVP64LDSTmode(ldstmode),
2371 offsmul, imm, ldst_ra_vec, ldst_imz_in)
2372 # new replacement D... errr.. DS
2373 if replace_d:
2374 if info.form == 'DS':
2375 # TODO: assert 2 LSBs are zero?
2376 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
2377 imm.value = imm.value >> 2
2378 self.namespace['DS'] = imm
2379 else:
2380 self.namespace['D'] = imm
2381
2382 def get_input(self, name, ew_src):
2383 # using PowerDecoder2, first, find the decoder index.
2384 # (mapping name RA RB RC RS to in1, in2, in3)
2385 regnum, is_vec = yield from get_idx_in(self.dec2, name, True)
2386 if regnum is None:
2387 # doing this is not part of svp64, it's because output
2388 # registers, to be modified, need to be in the namespace.
2389 regnum, is_vec = yield from get_idx_out(self.dec2, name, True)
2390 if regnum is None:
2391 regnum, is_vec = yield from get_idx_out2(self.dec2, name, True)
2392
2393 if isinstance(regnum, tuple):
2394 (regnum, base, offs) = regnum
2395 else:
2396 base, offs = regnum, 0 # temporary HACK
2397
2398 # in case getting the register number is needed, _RA, _RB
2399 # (HACK: only in straight non-svp64-mode for now, or elwidth == 64)
2400 regname = "_" + name
2401 if not self.is_svp64_mode or ew_src == 64:
2402 self.namespace[regname] = regnum
2403 elif regname in self.namespace:
2404 del self.namespace[regname]
2405
2406 if not self.is_svp64_mode or not self.pred_src_zero:
2407 log('reading reg %s %s' % (name, str(regnum)), is_vec)
2408 if name in fregs:
2409 reg_val = SelectableInt(self.fpr(base, is_vec, offs, ew_src))
2410 log("read reg %d/%d: 0x%x" % (base, offs, reg_val.value),
2411 kind=LogKind.InstrInOuts)
2412 self.trace("r:FPR:%d:%d:%d " % (base, offs, ew_src))
2413 elif name is not None:
2414 reg_val = SelectableInt(self.gpr(base, is_vec, offs, ew_src))
2415 self.trace("r:GPR:%d:%d:%d " % (base, offs, ew_src))
2416 log("read reg %d/%d: 0x%x" % (base, offs, reg_val.value),
2417 kind=LogKind.InstrInOuts)
2418 else:
2419 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
2420 reg_val = SelectableInt(0, ew_src)
2421 return reg_val
2422
2423 def remap_set_steps(self, remaps):
2424 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
2425 they work in concert with PowerDecoder2 at the moment,
2426 there is no HDL implementation of REMAP. therefore this
2427 function, because ISACaller still uses PowerDecoder2,
2428 will *explicitly* write the dec2.XX_step values. this has
2429 to get sorted out.
2430 """
2431 # just some convenient debug info
2432 for i in range(4):
2433 sname = 'SVSHAPE%d' % i
2434 shape = self.spr[sname]
2435 log(sname, bin(shape.value))
2436 log(" lims", shape.lims)
2437 log(" mode", shape.mode)
2438 log(" skip", shape.skip)
2439
2440 # set up the list of steps to remap
2441 mi0 = self.svstate.mi0
2442 mi1 = self.svstate.mi1
2443 mi2 = self.svstate.mi2
2444 mo0 = self.svstate.mo0
2445 mo1 = self.svstate.mo1
2446 steps = [[self.dec2.in1_step, mi0], # RA
2447 [self.dec2.in2_step, mi1], # RB
2448 [self.dec2.in3_step, mi2], # RC
2449 [self.dec2.o_step, mo0], # RT
2450 [self.dec2.o2_step, mo1], # EA
2451 ]
2452 if False: # TODO
2453 rnames = ['RA', 'RB', 'RC', 'RT', 'RS']
2454 for i, reg in enumerate(rnames):
2455 idx = yield from get_idx_map(self.dec2, reg)
2456 if idx is None:
2457 idx = yield from get_idx_map(self.dec2, "F"+reg)
2458 if idx == 1: # RA
2459 steps[i][0] = self.dec2.in1_step
2460 elif idx == 2: # RB
2461 steps[i][0] = self.dec2.in2_step
2462 elif idx == 3: # RC
2463 steps[i][0] = self.dec2.in3_step
2464 log("remap step", i, reg, idx, steps[i][1])
2465 remap_idxs = self.remap_idxs
2466 rremaps = []
2467 # now cross-index the required SHAPE for each of 3-in 2-out regs
2468 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
2469 for i, (dstep, shape_idx) in enumerate(steps):
2470 (shape, remap) = remaps[shape_idx]
2471 remap_idx = remap_idxs[shape_idx]
2472 # zero is "disabled"
2473 if shape.value == 0x0:
2474 continue
2475 # now set the actual requested step to the current index
2476 if dstep is not None:
2477 yield dstep.eq(remap_idx)
2478
2479 # debug printout info
2480 rremaps.append((shape.mode, hex(shape.value), dstep,
2481 i, rnames[i], shape_idx, remap_idx))
2482 for x in rremaps:
2483 log("shape remap", x)
2484
2485 def check_write(self, info, name, output, carry_en, ew_dst):
2486 if name == 'overflow': # ignore, done already (above)
2487 return
2488 if name == 'CR0': # ignore, done already (above)
2489 return
2490 if isinstance(output, int):
2491 output = SelectableInt(output, EFFECTIVELY_UNLIMITED)
2492 # write FPSCR
2493 if name in ['FPSCR', ]:
2494 log("write FPSCR 0x%x" % (output.value))
2495 self.FPSCR.eq(output)
2496 return
2497 # write carry flags
2498 if name in ['CA', 'CA32']:
2499 if carry_en:
2500 log("writing %s to XER" % name, output)
2501 log("write XER %s 0x%x" % (name, output.value))
2502 self.spr['XER'][XER_bits[name]] = output.value
2503 else:
2504 log("NOT writing %s to XER" % name, output)
2505 return
2506 # write special SPRs
2507 if name in info.special_regs:
2508 log('writing special %s' % name, output, special_sprs)
2509 log("write reg %s 0x%x" % (name, output.value),
2510 kind=LogKind.InstrInOuts)
2511 if name in special_sprs:
2512 self.spr[name] = output
2513 else:
2514 self.namespace[name].eq(output)
2515 if name == 'MSR':
2516 log('msr written', hex(self.msr.value))
2517 return
2518 # find out1/out2 PR/FPR
2519 regnum, is_vec = yield from get_idx_out(self.dec2, name, True)
2520 if regnum is None:
2521 regnum, is_vec = yield from get_idx_out2(self.dec2, name, True)
2522 if regnum is None:
2523 # temporary hack for not having 2nd output
2524 regnum = yield getattr(self.decoder, name)
2525 is_vec = False
2526 # convenient debug prefix
2527 if name in fregs:
2528 reg_prefix = 'f'
2529 else:
2530 reg_prefix = 'r'
2531 # check zeroing due to predicate bit being zero
2532 if self.is_svp64_mode and self.pred_dst_zero:
2533 log('zeroing reg %s %s' % (str(regnum), str(output)), is_vec)
2534 output = SelectableInt(0, EFFECTIVELY_UNLIMITED)
2535 log("write reg %s%s 0x%x ew %d" % (reg_prefix, str(regnum),
2536 output.value, ew_dst),
2537 kind=LogKind.InstrInOuts)
2538 # zero-extend tov64 bit begore storing (should use EXT oh well)
2539 if output.bits > 64:
2540 output = SelectableInt(output.value, 64)
2541 rnum, base, offset = regnum
2542 if name in fregs:
2543 self.fpr.write(regnum, output, is_vec, ew_dst)
2544 self.trace("w:FPR:%d:%d:%d " % (rnum, offset, ew_dst))
2545 else:
2546 self.gpr.write(regnum, output, is_vec, ew_dst)
2547 self.trace("w:GPR:%d:%d:%d " % (rnum, offset, ew_dst))
2548
2549 def check_step_increment(self, rc_en, asmop, ins_name):
2550 # check if it is the SVSTATE.src/dest step that needs incrementing
2551 # this is our Sub-Program-Counter loop from 0 to VL-1
2552 if not self.allow_next_step_inc:
2553 if self.is_svp64_mode:
2554 return (yield from self.svstate_post_inc(ins_name))
2555
2556 # XXX only in non-SVP64 mode!
2557 # record state of whether the current operation was an svshape,
2558 # OR svindex!
2559 # to be able to know if it should apply in the next instruction.
2560 # also (if going to use this instruction) should disable ability
2561 # to interrupt in between. sigh.
2562 self.last_op_svshape = asmop in ['svremap', 'svindex',
2563 'svshape2']
2564 return True
2565
2566 pre = False
2567 post = False
2568 nia_update = True
2569 log("SVSTATE_NEXT: inc requested, mode",
2570 self.svstate_next_mode, self.allow_next_step_inc)
2571 yield from self.svstate_pre_inc()
2572 pre = yield from self.update_new_svstate_steps()
2573 if pre:
2574 # reset at end of loop including exit Vertical Mode
2575 log("SVSTATE_NEXT: end of loop, reset")
2576 self.svp64_reset_loop()
2577 self.svstate.vfirst = 0
2578 self.update_nia()
2579 if not rc_en:
2580 return True
2581 self.handle_comparison(SelectableInt(0, 64)) # CR0
2582 return True
2583 if self.allow_next_step_inc == 2:
2584 log("SVSTATE_NEXT: read")
2585 nia_update = (yield from self.svstate_post_inc(ins_name))
2586 else:
2587 log("SVSTATE_NEXT: post-inc")
2588 # use actual (cached) src/dst-step here to check end
2589 remaps = self.get_remap_indices()
2590 remap_idxs = self.remap_idxs
2591 vl = self.svstate.vl
2592 subvl = yield self.dec2.rm_dec.rm_in.subvl
2593 if self.allow_next_step_inc != 2:
2594 yield from self.advance_svstate_steps()
2595 #self.namespace['SVSTATE'] = self.svstate.spr
2596 # set CR0 (if Rc=1) based on end
2597 endtest = 1 if self.at_loopend() else 0
2598 if rc_en:
2599 #results = [SelectableInt(endtest, 64)]
2600 # self.handle_comparison(results) # CR0
2601
2602 # see if svstep was requested, if so, which SVSTATE
2603 endings = 0b111
2604 if self.svstate_next_mode > 0:
2605 shape_idx = self.svstate_next_mode.value-1
2606 endings = self.remap_loopends[shape_idx]
2607 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
2608 log("svstep Rc=1, CR0", cr_field, endtest)
2609 self.crl[0].eq(cr_field) # CR0
2610 if endtest:
2611 # reset at end of loop including exit Vertical Mode
2612 log("SVSTATE_NEXT: after increments, reset")
2613 self.svp64_reset_loop()
2614 self.svstate.vfirst = 0
2615 return nia_update
2616
2617 def SVSTATE_NEXT(self, mode, submode):
2618 """explicitly moves srcstep/dststep on to next element, for
2619 "Vertical-First" mode. this function is called from
2620 setvl pseudo-code, as a pseudo-op "svstep"
2621
2622 WARNING: this function uses information that was created EARLIER
2623 due to it being in the middle of a yield, but this function is
2624 *NOT* called from yield (it's called from compiled pseudocode).
2625 """
2626 self.allow_next_step_inc = submode.value + 1
2627 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
2628 self.svstate_next_mode = mode
2629 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
2630 shape_idx = self.svstate_next_mode.value-1
2631 return SelectableInt(self.remap_idxs[shape_idx], 7)
2632 if self.svstate_next_mode == 5:
2633 self.svstate_next_mode = 0
2634 return SelectableInt(self.svstate.srcstep, 7)
2635 if self.svstate_next_mode == 6:
2636 self.svstate_next_mode = 0
2637 return SelectableInt(self.svstate.dststep, 7)
2638 if self.svstate_next_mode == 7:
2639 self.svstate_next_mode = 0
2640 return SelectableInt(self.svstate.ssubstep, 7)
2641 if self.svstate_next_mode == 8:
2642 self.svstate_next_mode = 0
2643 return SelectableInt(self.svstate.dsubstep, 7)
2644 return SelectableInt(0, 7)
2645
2646 def get_src_dststeps(self):
2647 """gets srcstep, dststep, and ssubstep, dsubstep
2648 """
2649 return (self.new_srcstep, self.new_dststep,
2650 self.new_ssubstep, self.new_dsubstep)
2651
2652 def update_svstate_namespace(self, overwrite_svstate=True):
2653 if overwrite_svstate:
2654 # note, do not get the bit-reversed srcstep here!
2655 srcstep, dststep = self.new_srcstep, self.new_dststep
2656 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
2657
2658 # update SVSTATE with new srcstep
2659 self.svstate.srcstep = srcstep
2660 self.svstate.dststep = dststep
2661 self.svstate.ssubstep = ssubstep
2662 self.svstate.dsubstep = dsubstep
2663 self.namespace['SVSTATE'] = self.svstate
2664 yield self.dec2.state.svstate.eq(self.svstate.value)
2665 yield Settle() # let decoder update
2666
2667 def update_new_svstate_steps(self, overwrite_svstate=True):
2668 yield from self.update_svstate_namespace(overwrite_svstate)
2669 srcstep = self.svstate.srcstep
2670 dststep = self.svstate.dststep
2671 ssubstep = self.svstate.ssubstep
2672 dsubstep = self.svstate.dsubstep
2673 pack = self.svstate.pack
2674 unpack = self.svstate.unpack
2675 vl = self.svstate.vl
2676 sv_mode = yield self.dec2.rm_dec.sv_mode
2677 subvl = yield self.dec2.rm_dec.rm_in.subvl
2678 rm_mode = yield self.dec2.rm_dec.mode
2679 ff_inv = yield self.dec2.rm_dec.inv
2680 cr_bit = yield self.dec2.rm_dec.cr_sel
2681 log(" srcstep", srcstep)
2682 log(" dststep", dststep)
2683 log(" pack", pack)
2684 log(" unpack", unpack)
2685 log(" ssubstep", ssubstep)
2686 log(" dsubstep", dsubstep)
2687 log(" vl", vl)
2688 log(" subvl", subvl)
2689 log(" rm_mode", rm_mode)
2690 log(" sv_mode", sv_mode)
2691 log(" inv", ff_inv)
2692 log(" cr_bit", cr_bit)
2693
2694 # check if end reached (we let srcstep overrun, above)
2695 # nothing needs doing (TODO zeroing): just do next instruction
2696 if self.loopend:
2697 return True
2698 return ((ssubstep == subvl and srcstep == vl) or
2699 (dsubstep == subvl and dststep == vl))
2700
2701 def svstate_post_inc(self, insn_name, vf=0):
2702 # check if SV "Vertical First" mode is enabled
2703 vfirst = self.svstate.vfirst
2704 log(" SV Vertical First", vf, vfirst)
2705 if not vf and vfirst == 1:
2706 self.update_nia()
2707 return True
2708
2709 # check if it is the SVSTATE.src/dest step that needs incrementing
2710 # this is our Sub-Program-Counter loop from 0 to VL-1
2711 # XXX twin predication TODO
2712 vl = self.svstate.vl
2713 subvl = yield self.dec2.rm_dec.rm_in.subvl
2714 mvl = self.svstate.maxvl
2715 srcstep = self.svstate.srcstep
2716 dststep = self.svstate.dststep
2717 ssubstep = self.svstate.ssubstep
2718 dsubstep = self.svstate.dsubstep
2719 pack = self.svstate.pack
2720 unpack = self.svstate.unpack
2721 rm_mode = yield self.dec2.rm_dec.mode
2722 reverse_gear = yield self.dec2.rm_dec.reverse_gear
2723 sv_ptype = yield self.dec2.dec.op.SV_Ptype
2724 out_vec = not (yield self.dec2.no_out_vec)
2725 in_vec = not (yield self.dec2.no_in_vec)
2726 log(" svstate.vl", vl)
2727 log(" svstate.mvl", mvl)
2728 log(" rm.subvl", subvl)
2729 log(" svstate.srcstep", srcstep)
2730 log(" svstate.dststep", dststep)
2731 log(" svstate.ssubstep", ssubstep)
2732 log(" svstate.dsubstep", dsubstep)
2733 log(" svstate.pack", pack)
2734 log(" svstate.unpack", unpack)
2735 log(" mode", rm_mode)
2736 log(" reverse", reverse_gear)
2737 log(" out_vec", out_vec)
2738 log(" in_vec", in_vec)
2739 log(" sv_ptype", sv_ptype, sv_ptype == SVPType.P2.value)
2740 # check if this was an sv.bc* and if so did it succeed
2741 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
2742 end_loop = self.namespace['end_loop']
2743 log("branch %s end_loop" % insn_name, end_loop)
2744 if end_loop.value:
2745 self.svp64_reset_loop()
2746 self.update_pc_next()
2747 return False
2748 # check if srcstep needs incrementing by one, stop PC advancing
2749 # but for 2-pred both src/dest have to be checked.
2750 # XXX this might not be true! it may just be LD/ST
2751 if sv_ptype == SVPType.P2.value:
2752 svp64_is_vector = (out_vec or in_vec)
2753 else:
2754 svp64_is_vector = out_vec
2755 # loops end at the first "hit" (source or dest)
2756 yield from self.advance_svstate_steps()
2757 loopend = self.loopend
2758 log("loopend", svp64_is_vector, loopend)
2759 if not svp64_is_vector or loopend:
2760 # reset loop to zero and update NIA
2761 self.svp64_reset_loop()
2762 self.update_nia()
2763
2764 return True
2765
2766 # still looping, advance and update NIA
2767 self.namespace['SVSTATE'] = self.svstate
2768
2769 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2770 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2771 # this way we keep repeating the same instruction (with new steps)
2772 self.pc.NIA.value = self.pc.CIA.value
2773 self.namespace['NIA'] = self.pc.NIA
2774 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
2775 return False # DO NOT allow PC update whilst Sub-PC loop running
2776
2777 def update_pc_next(self):
2778 # UPDATE program counter
2779 self.pc.update(self.namespace, self.is_svp64_mode)
2780 #self.svstate.spr = self.namespace['SVSTATE']
2781 log("end of call", self.namespace['CIA'],
2782 self.namespace['NIA'],
2783 self.namespace['SVSTATE'])
2784
2785 def svp64_reset_loop(self):
2786 self.svstate.srcstep = 0
2787 self.svstate.dststep = 0
2788 self.svstate.ssubstep = 0
2789 self.svstate.dsubstep = 0
2790 self.loopend = False
2791 log(" svstate.srcstep loop end (PC to update)")
2792 self.namespace['SVSTATE'] = self.svstate
2793
2794 def update_nia(self):
2795 self.pc.update_nia(self.is_svp64_mode)
2796 self.namespace['NIA'] = self.pc.NIA
2797
2798
2799 def inject():
2800 """Decorator factory.
2801
2802 this decorator will "inject" variables into the function's namespace,
2803 from the *dictionary* in self.namespace. it therefore becomes possible
2804 to make it look like a whole stack of variables which would otherwise
2805 need "self." inserted in front of them (*and* for those variables to be
2806 added to the instance) "appear" in the function.
2807
2808 "self.namespace['SI']" for example becomes accessible as just "SI" but
2809 *only* inside the function, when decorated.
2810 """
2811 def variable_injector(func):
2812 @wraps(func)
2813 def decorator(*args, **kwargs):
2814 try:
2815 func_globals = func.__globals__ # Python 2.6+
2816 except AttributeError:
2817 func_globals = func.func_globals # Earlier versions.
2818
2819 context = args[0].namespace # variables to be injected
2820 saved_values = func_globals.copy() # Shallow copy of dict.
2821 log("globals before", context.keys())
2822 func_globals.update(context)
2823 result = func(*args, **kwargs)
2824 log("globals after", func_globals['CIA'], func_globals['NIA'])
2825 log("args[0]", args[0].namespace['CIA'],
2826 args[0].namespace['NIA'],
2827 args[0].namespace['SVSTATE'])
2828 if 'end_loop' in func_globals:
2829 log("args[0] end_loop", func_globals['end_loop'])
2830 args[0].namespace = func_globals
2831 #exec (func.__code__, func_globals)
2832
2833 # finally:
2834 # func_globals = saved_values # Undo changes.
2835
2836 return result
2837
2838 return decorator
2839
2840 return variable_injector