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