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