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