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