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