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