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