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