add data-dependent fail-first mode, Rc=1 variant not RC1 yet
[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
540 def get_iterators(self):
541 self.src_it = self.src_iterator()
542 self.dst_it = self.dst_iterator()
543
544 def src_iterator(self):
545 """source-stepping iterator
546 """
547 pack = self.svstate.pack
548
549 # source step
550 if pack:
551 # pack advances subvl in *outer* loop
552 if end_src:
553 if not end_ssub:
554 self.svstate.ssubstep += SelectableInt(1, 2)
555 self.svstate.srcstep = SelectableInt(0, 7) # reset
556 else:
557 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
558 else:
559 # these cannot be done as for-loops because SVSTATE may change
560 # (srcstep/substep may be modified, interrupted, subvl/vl change)
561 # but they *can* be done as while-loops as long as every SVSTATE
562 # "thing" is re-read every single time a yield gives indices
563 while True: # outer vl loop
564 while True: # inner subvl loop
565 subvl = self.subvl
566 srcmask = self.srcmask
567 srcstep = self.svstate.srcstep
568 if self.pred_sz or ((1 << srcstep) & srcmask) != 0:
569 log(" advance src", srcstep, self.svstate.vl,
570 self.svstate.ssubstep, subvl)
571 # yield actual substep/srcstep
572 yield (self.svstate.ssubstep, srcstep)
573 if self.svstate.ssubstep == subvl: # end-point
574 self.svstate.ssubstep = SelectableInt(0, 2) # reset
575 break
576 self.svstate.ssubstep += SelectableInt(1, 2)
577 vl = self.svstate.vl
578 if srcstep == vl-1: # end-point
579 self.svstate.srcstep = SelectableInt(0, 7) # reset
580 break # trigger StopIteration
581 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
582
583 def dst_iterator(self):
584 """dest-stepping iterator
585 """
586 unpack = self.svstate.unpack
587
588 # dest step
589 if unpack:
590 # pack advances subvl in *outer* loop
591 pass # TODO
592 else:
593 # these cannot be done as for-loops because SVSTATE may change
594 # (dststep/substep may be modified, interrupted, subvl/vl change)
595 # but they *can* be done as while-loops as long as every SVSTATE
596 # "thing" is re-read every single time a yield gives indices
597 while True: # outer vl loop
598 while True: # inner subvl loop
599 subvl = self.subvl
600 dstmask = self.dstmask
601 dststep = self.svstate.dststep
602 if self.pred_dz or ((1 << dststep) & dstmask) != 0:
603 log(" advance dst", dststep, self.svstate.vl,
604 self.svstate.dsubstep, subvl)
605 # yield actual substep/dststep
606 yield (self.svstate.dsubstep, dststep)
607 if self.svstate.dsubstep == subvl: # end-point
608 self.svstate.dsubstep = SelectableInt(0, 2) # reset
609 break
610 self.svstate.dsubstep += SelectableInt(1, 2)
611 vl = self.svstate.vl
612 if dststep == vl-1: # end-point
613 self.svstate.dststep = SelectableInt(0, 7) # reset
614 break # trigger StopIteration
615 self.svstate.dststep += SelectableInt(1, 7) # advance dststep
616
617 def src_iterate(self):
618 """source-stepping iterator
619 """
620 end_src = self.end_src
621 subvl = self.subvl
622 pack = self.svstate.pack
623 unpack = self.svstate.unpack
624 ssubstep = self.svstate.ssubstep
625 end_ssub = ssubstep == subvl
626 log(" pack/unpack/subvl", pack, unpack, subvl,
627 "end", end_src,
628 "sub", end_ssub)
629 # first source step
630 srcstep = self.svstate.srcstep
631 if pack:
632 # pack advances subvl in *outer* loop
633 if end_src:
634 if not end_ssub:
635 self.svstate.ssubstep += SelectableInt(1, 2)
636 self.svstate.srcstep = SelectableInt(0, 7) # reset
637 else:
638 self.svstate.srcstep += SelectableInt(1, 7) # advance srcstep
639 else:
640 # advance subvl in *inner* loop
641 if end_ssub:
642 if not end_src:
643 self.svstate.srcstep += SelectableInt(1, 7)
644 self.svstate.ssubstep = SelectableInt(0, 2) # reset
645 else:
646 # advance ssubstep
647 self.svstate.ssubstep += SelectableInt(1, 2)
648
649 log(" advance src", self.svstate.srcstep, self.svstate.ssubstep)
650
651 def dst_iterate(self):
652 """dest step iterator
653 """
654 end_dst = self.end_dst
655 subvl = self.subvl
656 pack = self.svstate.pack
657 unpack = self.svstate.unpack
658 dsubstep = self.svstate.dsubstep
659 end_dsub = dsubstep == subvl
660 log(" pack/unpack/subvl", pack, unpack, subvl,
661 "end", end_dst,
662 "sub", end_dsub)
663 # now dest step
664 if unpack:
665 # unpack advances subvl in *outer* loop
666 if end_dst:
667 if not end_dsub:
668 self.svstate.dsubstep += SelectableInt(1, 2)
669 self.svstate.dststep = SelectableInt(0, 7) # reset
670 else:
671 self.svstate.dststep += SelectableInt(1, 7) # advance dststep
672 else:
673 # advance subvl in *inner* loop
674 if end_dsub:
675 if not end_dst:
676 self.svstate.dststep += SelectableInt(1, 7)
677 self.svstate.dsubstep = SelectableInt(0, 2) # reset
678 else:
679 # advance ssubstep
680 self.svstate.dsubstep += SelectableInt(1, 2)
681 log(" advance dst", self.svstate.dststep, self.svstate.dsubstep)
682
683 def advance_svstate_steps(self, end_src=False, end_dst=False):
684 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
685 TODO when Pack/Unpack is set, substep becomes the *outer* loop
686 """
687 self.subvl = yield self.dec2.rm_dec.rm_in.subvl
688 self.end_src = end_src
689 self.end_dst = end_dst
690 self.src_iterate()
691 self.dst_iterate()
692
693 def read_src_mask(self):
694 """read/update pred_sz and src mask
695 """
696 # get SVSTATE VL (oh and print out some debug stuff)
697 vl = self.svstate.vl
698 srcstep = self.svstate.srcstep
699 ssubstep = self.svstate.ssubstep
700
701 # get predicate mask (all 64 bits)
702 srcmask = 0xffff_ffff_ffff_ffff
703
704 pmode = yield self.dec2.rm_dec.predmode
705 sv_ptype = yield self.dec2.dec.op.SV_Ptype
706 srcpred = yield self.dec2.rm_dec.srcpred
707 dstpred = yield self.dec2.rm_dec.dstpred
708 pred_sz = yield self.dec2.rm_dec.pred_sz
709 if pmode == SVP64PredMode.INT.value:
710 srcmask = dstmask = get_predint(self.gpr, dstpred)
711 if sv_ptype == SVPtype.P2.value:
712 srcmask = get_predint(self.gpr, srcpred)
713 elif pmode == SVP64PredMode.CR.value:
714 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
715 if sv_ptype == SVPtype.P2.value:
716 srcmask = get_predcr(self.crl, srcpred, vl)
717 # work out if the ssubsteps are completed
718 ssubstart = ssubstep == 0
719 log(" pmode", pmode)
720 log(" ptype", sv_ptype)
721 log(" srcpred", bin(srcpred))
722 log(" srcmask", bin(srcmask))
723 log(" pred_sz", bin(pred_sz))
724 log(" ssubstart", ssubstart)
725
726 # store all that above
727 self.srcstep_skip = False
728 self.srcmask = srcmask
729 self.pred_sz = pred_sz
730 self.new_ssubstep = ssubstep
731 log(" new ssubstep", ssubstep)
732 if ssubstart:
733 # until the predicate mask has a "1" bit... or we run out of VL
734 # let srcstep==VL be the indicator to move to next instruction
735 if not pred_sz:
736 self.srcstep_skip = True
737
738 def read_dst_mask(self):
739 """same as read_src_mask - check and record everything needed
740 """
741 # get SVSTATE VL (oh and print out some debug stuff)
742 # yield Delay(1e-10) # make changes visible
743 vl = self.svstate.vl
744 dststep = self.svstate.dststep
745 dsubstep = self.svstate.dsubstep
746
747 # get predicate mask (all 64 bits)
748 dstmask = 0xffff_ffff_ffff_ffff
749
750 pmode = yield self.dec2.rm_dec.predmode
751 reverse_gear = yield self.dec2.rm_dec.reverse_gear
752 sv_ptype = yield self.dec2.dec.op.SV_Ptype
753 dstpred = yield self.dec2.rm_dec.dstpred
754 pred_dz = yield self.dec2.rm_dec.pred_dz
755 if pmode == SVP64PredMode.INT.value:
756 dstmask = get_predint(self.gpr, dstpred)
757 elif pmode == SVP64PredMode.CR.value:
758 dstmask = get_predcr(self.crl, dstpred, vl)
759 # work out if the ssubsteps are completed
760 dsubstart = dsubstep == 0
761 log(" pmode", pmode)
762 log(" ptype", sv_ptype)
763 log(" dstpred", bin(dstpred))
764 log(" dstmask", bin(dstmask))
765 log(" pred_dz", bin(pred_dz))
766 log(" dsubstart", dsubstart)
767
768 self.dststep_skip = False
769 self.dstmask = dstmask
770 self.pred_dz = pred_dz
771 self.new_dsubstep = dsubstep
772 log(" new dsubstep", dsubstep)
773 if dsubstart:
774 if not pred_dz:
775 self.dststep_skip = True
776
777 def svstate_pre_inc(self):
778 """check if srcstep/dststep need to skip over masked-out predicate bits
779 note that this is not supposed to do anything to substep,
780 it is purely for skipping masked-out bits
781 """
782
783 yield from self.read_src_mask()
784 yield from self.read_dst_mask()
785
786 self.skip_src()
787 self.skip_dst()
788
789 def skip_src(self):
790
791 srcstep = self.svstate.srcstep
792 srcmask = self.srcmask
793 pred_src_zero = self.pred_sz
794 vl = self.svstate.vl
795 # srcstep-skipping opportunity identified
796 if self.srcstep_skip:
797 while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl):
798 log(" sskip", bin(1 << srcstep))
799 srcstep += 1
800
801 # now work out if the relevant mask bits require zeroing
802 if pred_src_zero:
803 pred_src_zero = ((1 << srcstep) & srcmask) == 0
804
805 # store new srcstep / dststep
806 self.new_srcstep = srcstep
807 self.pred_src_zero = pred_src_zero
808 log(" new srcstep", srcstep)
809
810 def skip_dst(self):
811 # dststep-skipping opportunity identified
812 dststep = self.svstate.dststep
813 dstmask = self.dstmask
814 pred_dst_zero = self.pred_dz
815 vl = self.svstate.vl
816 if self.dststep_skip:
817 while (((1 << dststep) & dstmask) == 0) and (dststep != vl):
818 log(" dskip", bin(1 << dststep))
819 dststep += 1
820
821 # now work out if the relevant mask bits require zeroing
822 if pred_dst_zero:
823 pred_dst_zero = ((1 << dststep) & dstmask) == 0
824
825 # store new srcstep / dststep
826 self.new_dststep = dststep
827 self.pred_dst_zero = pred_dst_zero
828 log(" new dststep", dststep)
829
830
831 class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
832 # decoder2 - an instance of power_decoder2
833 # regfile - a list of initial values for the registers
834 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
835 # respect_pc - tracks the program counter. requires initial_insns
836 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
837 initial_mem=None, initial_msr=0,
838 initial_svstate=0,
839 initial_insns=None,
840 fpregfile=None,
841 respect_pc=False,
842 disassembly=None,
843 initial_pc=0,
844 bigendian=False,
845 mmu=False,
846 icachemmu=False):
847
848 self.bigendian = bigendian
849 self.halted = False
850 self.is_svp64_mode = False
851 self.respect_pc = respect_pc
852 if initial_sprs is None:
853 initial_sprs = {}
854 if initial_mem is None:
855 initial_mem = {}
856 if fpregfile is None:
857 fpregfile = [0] * 32
858 if initial_insns is None:
859 initial_insns = {}
860 assert self.respect_pc == False, "instructions required to honor pc"
861
862 log("ISACaller insns", respect_pc, initial_insns, disassembly)
863 log("ISACaller initial_msr", initial_msr)
864
865 # "fake program counter" mode (for unit testing)
866 self.fake_pc = 0
867 disasm_start = 0
868 if not respect_pc:
869 if isinstance(initial_mem, tuple):
870 self.fake_pc = initial_mem[0]
871 disasm_start = self.fake_pc
872 else:
873 disasm_start = initial_pc
874
875 # disassembly: we need this for now (not given from the decoder)
876 self.disassembly = {}
877 if disassembly:
878 for i, code in enumerate(disassembly):
879 self.disassembly[i*4 + disasm_start] = code
880
881 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
882 self.svp64rm = SVP64RM()
883 if initial_svstate is None:
884 initial_svstate = 0
885 if isinstance(initial_svstate, int):
886 initial_svstate = SVP64State(initial_svstate)
887 # SVSTATE, MSR and PC
888 StepLoop.__init__(self, initial_svstate)
889 self.msr = SelectableInt(initial_msr, 64) # underlying reg
890 self.pc = PC()
891 # GPR FPR SPR registers
892 initial_sprs = deepcopy(initial_sprs) # so as not to get modified
893 self.gpr = GPR(decoder2, self, self.svstate, regfile)
894 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
895 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
896
897 # set up 4 dummy SVSHAPEs if they aren't already set up
898 for i in range(4):
899 sname = 'SVSHAPE%d' % i
900 if sname not in self.spr:
901 val = 0
902 else:
903 val = self.spr[sname].value
904 # make sure it's an SVSHAPE
905 self.spr[sname] = SVSHAPE(val, self.gpr)
906 self.last_op_svshape = False
907
908 # "raw" memory
909 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
910 self.mem.log_fancy(kind=LogKind.InstrInOuts)
911 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
912 # MMU mode, redirect underlying Mem through RADIX
913 if mmu:
914 self.mem = RADIX(self.mem, self)
915 if icachemmu:
916 self.imem = RADIX(self.imem, self)
917
918 # TODO, needed here:
919 # FPR (same as GPR except for FP nums)
920 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
921 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
922 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
923 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
924 # -- Done
925 # 2.3.2 LR (actually SPR #8) -- Done
926 # 2.3.3 CTR (actually SPR #9) -- Done
927 # 2.3.4 TAR (actually SPR #815)
928 # 3.2.2 p45 XER (actually SPR #1) -- Done
929 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
930
931 # create CR then allow portions of it to be "selectable" (below)
932 self.cr_fields = CRFields(initial_cr)
933 self.cr = self.cr_fields.cr
934
935 # "undefined", just set to variable-bit-width int (use exts "max")
936 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
937
938 self.namespace = {}
939 self.namespace.update(self.spr)
940 self.namespace.update({'GPR': self.gpr,
941 'FPR': self.fpr,
942 'MEM': self.mem,
943 'SPR': self.spr,
944 'memassign': self.memassign,
945 'NIA': self.pc.NIA,
946 'CIA': self.pc.CIA,
947 'SVSTATE': self.svstate,
948 'SVSHAPE0': self.spr['SVSHAPE0'],
949 'SVSHAPE1': self.spr['SVSHAPE1'],
950 'SVSHAPE2': self.spr['SVSHAPE2'],
951 'SVSHAPE3': self.spr['SVSHAPE3'],
952 'CR': self.cr,
953 'MSR': self.msr,
954 'undefined': undefined,
955 'mode_is_64bit': True,
956 'SO': XER_bits['SO'],
957 'XLEN': 64 # elwidth overrides, later
958 })
959
960 # update pc to requested start point
961 self.set_pc(initial_pc)
962
963 # field-selectable versions of Condition Register
964 self.crl = self.cr_fields.crl
965 for i in range(8):
966 self.namespace["CR%d" % i] = self.crl[i]
967
968 self.decoder = decoder2.dec
969 self.dec2 = decoder2
970
971 super().__init__(XLEN=self.namespace["XLEN"])
972
973 @property
974 def XLEN(self):
975 return self.namespace["XLEN"]
976
977 def call_trap(self, trap_addr, trap_bit):
978 """calls TRAP and sets up NIA to the new execution location.
979 next instruction will begin at trap_addr.
980 """
981 self.TRAP(trap_addr, trap_bit)
982 self.namespace['NIA'] = self.trap_nia
983 self.pc.update(self.namespace, self.is_svp64_mode)
984
985 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
986 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
987
988 TRAP function is callable from inside the pseudocode itself,
989 hence the default arguments. when calling from inside ISACaller
990 it is best to use call_trap()
991 """
992 # https://bugs.libre-soc.org/show_bug.cgi?id=859
993 kaivb = self.spr['KAIVB'].value
994 msr = self.namespace['MSR'].value
995 log("TRAP:", hex(trap_addr), hex(msr), "kaivb", hex(kaivb))
996 # store CIA(+4?) in SRR0, set NIA to 0x700
997 # store MSR in SRR1, set MSR to um errr something, have to check spec
998 # store SVSTATE (if enabled) in SVSRR0
999 self.spr['SRR0'].value = self.pc.CIA.value
1000 self.spr['SRR1'].value = msr
1001 if self.is_svp64_mode:
1002 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
1003 self.trap_nia = SelectableInt(trap_addr | (kaivb & ~0x1fff), 64)
1004 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
1005
1006 # set exception bits. TODO: this should, based on the address
1007 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1008 # bits appropriately. however it turns out that *for now* in all
1009 # cases (all trap_addrs) the exact same thing is needed.
1010 self.msr[MSRb.IR] = 0
1011 self.msr[MSRb.DR] = 0
1012 self.msr[MSRb.FE0] = 0
1013 self.msr[MSRb.FE1] = 0
1014 self.msr[MSRb.EE] = 0
1015 self.msr[MSRb.RI] = 0
1016 self.msr[MSRb.SF] = 1
1017 self.msr[MSRb.TM] = 0
1018 self.msr[MSRb.VEC] = 0
1019 self.msr[MSRb.VSX] = 0
1020 self.msr[MSRb.PR] = 0
1021 self.msr[MSRb.FP] = 0
1022 self.msr[MSRb.PMM] = 0
1023 self.msr[MSRb.TEs] = 0
1024 self.msr[MSRb.TEe] = 0
1025 self.msr[MSRb.UND] = 0
1026 self.msr[MSRb.LE] = 1
1027
1028 def memassign(self, ea, sz, val):
1029 self.mem.memassign(ea, sz, val)
1030
1031 def prep_namespace(self, insn_name, formname, op_fields):
1032 # TODO: get field names from form in decoder*1* (not decoder2)
1033 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1034 # from spec
1035 # then "yield" fields only from op_fields rather than hard-coded
1036 # list, here.
1037 fields = self.decoder.sigforms[formname]
1038 log("prep_namespace", formname, op_fields, insn_name)
1039 for name in op_fields:
1040 # CR immediates. deal with separately. needs modifying
1041 # pseudocode
1042 if self.is_svp64_mode and name in ['BI']: # TODO, more CRs
1043 # BI is a 5-bit, must reconstruct the value
1044 regnum, is_vec = yield from get_pdecode_cr_in(self.dec2, name)
1045 sig = getattr(fields, name)
1046 val = yield sig
1047 # low 2 LSBs (CR field selector) remain same, CR num extended
1048 assert regnum <= 7, "sigh, TODO, 128 CR fields"
1049 val = (val & 0b11) | (regnum << 2)
1050 else:
1051 sig = getattr(fields, name)
1052 val = yield sig
1053 # these are all opcode fields involved in index-selection of CR,
1054 # and need to do "standard" arithmetic. CR[BA+32] for example
1055 # would, if using SelectableInt, only be 5-bit.
1056 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1057 self.namespace[name] = val
1058 else:
1059 self.namespace[name] = SelectableInt(val, sig.width)
1060
1061 self.namespace['XER'] = self.spr['XER']
1062 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
1063 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
1064
1065 # add some SVSTATE convenience variables
1066 vl = self.svstate.vl
1067 srcstep = self.svstate.srcstep
1068 self.namespace['VL'] = vl
1069 self.namespace['srcstep'] = srcstep
1070
1071 # sv.bc* need some extra fields
1072 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1073 # blegh grab bits manually
1074 mode = yield self.dec2.rm_dec.rm_in.mode
1075 bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0
1076 bc_vli = (mode & SVP64MODE.BC_VLI) != 0
1077 bc_snz = (mode & SVP64MODE.BC_SNZ) != 0
1078 bc_vsb = yield self.dec2.rm_dec.bc_vsb
1079 bc_lru = yield self.dec2.rm_dec.bc_lru
1080 bc_gate = yield self.dec2.rm_dec.bc_gate
1081 sz = yield self.dec2.rm_dec.pred_sz
1082 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
1083 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
1084 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
1085 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
1086 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
1087 self.namespace['sz'] = SelectableInt(sz, 1)
1088 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
1089
1090 def handle_carry_(self, inputs, outputs, already_done):
1091 inv_a = yield self.dec2.e.do.invert_in
1092 if inv_a:
1093 inputs[0] = ~inputs[0]
1094
1095 imm_ok = yield self.dec2.e.do.imm_data.ok
1096 if imm_ok:
1097 imm = yield self.dec2.e.do.imm_data.data
1098 inputs.append(SelectableInt(imm, 64))
1099 assert len(outputs) >= 1
1100 log("outputs", repr(outputs))
1101 if isinstance(outputs, list) or isinstance(outputs, tuple):
1102 output = outputs[0]
1103 else:
1104 output = outputs
1105 gts = []
1106 for x in inputs:
1107 log("gt input", x, output)
1108 gt = (gtu(x, output))
1109 gts.append(gt)
1110 log(gts)
1111 cy = 1 if any(gts) else 0
1112 log("CA", cy, gts)
1113 if not (1 & already_done):
1114 self.spr['XER'][XER_bits['CA']] = cy
1115
1116 log("inputs", already_done, inputs)
1117 # 32 bit carry
1118 # ARGH... different for OP_ADD... *sigh*...
1119 op = yield self.dec2.e.do.insn_type
1120 if op == MicrOp.OP_ADD.value:
1121 res32 = (output.value & (1 << 32)) != 0
1122 a32 = (inputs[0].value & (1 << 32)) != 0
1123 if len(inputs) >= 2:
1124 b32 = (inputs[1].value & (1 << 32)) != 0
1125 else:
1126 b32 = False
1127 cy32 = res32 ^ a32 ^ b32
1128 log("CA32 ADD", cy32)
1129 else:
1130 gts = []
1131 for x in inputs:
1132 log("input", x, output)
1133 log(" x[32:64]", x, x[32:64])
1134 log(" o[32:64]", output, output[32:64])
1135 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
1136 gts.append(gt)
1137 cy32 = 1 if any(gts) else 0
1138 log("CA32", cy32, gts)
1139 if not (2 & already_done):
1140 self.spr['XER'][XER_bits['CA32']] = cy32
1141
1142 def handle_overflow(self, inputs, outputs, div_overflow):
1143 if hasattr(self.dec2.e.do, "invert_in"):
1144 inv_a = yield self.dec2.e.do.invert_in
1145 if inv_a:
1146 inputs[0] = ~inputs[0]
1147
1148 imm_ok = yield self.dec2.e.do.imm_data.ok
1149 if imm_ok:
1150 imm = yield self.dec2.e.do.imm_data.data
1151 inputs.append(SelectableInt(imm, 64))
1152 assert len(outputs) >= 1
1153 log("handle_overflow", inputs, outputs, div_overflow)
1154 if len(inputs) < 2 and div_overflow is None:
1155 return
1156
1157 # div overflow is different: it's returned by the pseudo-code
1158 # because it's more complex than can be done by analysing the output
1159 if div_overflow is not None:
1160 ov, ov32 = div_overflow, div_overflow
1161 # arithmetic overflow can be done by analysing the input and output
1162 elif len(inputs) >= 2:
1163 output = outputs[0]
1164
1165 # OV (64-bit)
1166 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
1167 output_sgn = exts(output.value, output.bits) < 0
1168 ov = 1 if input_sgn[0] == input_sgn[1] and \
1169 output_sgn != input_sgn[0] else 0
1170
1171 # OV (32-bit)
1172 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
1173 output32_sgn = exts(output.value, 32) < 0
1174 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
1175 output32_sgn != input32_sgn[0] else 0
1176
1177 # now update XER OV/OV32/SO
1178 so = self.spr['XER'][XER_bits['SO']]
1179 new_so = so | ov # sticky overflow ORs in old with new
1180 self.spr['XER'][XER_bits['OV']] = ov
1181 self.spr['XER'][XER_bits['OV32']] = ov32
1182 self.spr['XER'][XER_bits['SO']] = new_so
1183 log(" set overflow", ov, ov32, so, new_so)
1184
1185 def handle_comparison(self, outputs, cr_idx=0, overflow=None, no_so=False):
1186 out = outputs[0]
1187 assert isinstance(out, SelectableInt), \
1188 "out zero not a SelectableInt %s" % repr(outputs)
1189 log("handle_comparison", out.bits, hex(out.value))
1190 # TODO - XXX *processor* in 32-bit mode
1191 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1192 # if is_32bit:
1193 # o32 = exts(out.value, 32)
1194 # print ("handle_comparison exts 32 bit", hex(o32))
1195 out = exts(out.value, out.bits)
1196 log("handle_comparison exts", hex(out))
1197 # create the three main CR flags, EQ GT LT
1198 zero = SelectableInt(out == 0, 1)
1199 positive = SelectableInt(out > 0, 1)
1200 negative = SelectableInt(out < 0, 1)
1201 # get (or not) XER.SO. for setvl this is important *not* to read SO
1202 if no_so:
1203 SO = SelectableInt(1, 0)
1204 else:
1205 SO = self.spr['XER'][XER_bits['SO']]
1206 log("handle_comparison SO overflow", SO, overflow)
1207 # alternative overflow checking (setvl mainly at the moment)
1208 if overflow is not None and overflow == 1:
1209 SO = SelectableInt(1, 1)
1210 # create the four CR field values and set the required CR field
1211 cr_field = selectconcat(negative, positive, zero, SO)
1212 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
1213 self.crl[cr_idx].eq(cr_field)
1214
1215 def set_pc(self, pc_val):
1216 self.namespace['NIA'] = SelectableInt(pc_val, 64)
1217 self.pc.update(self.namespace, self.is_svp64_mode)
1218
1219 def get_next_insn(self):
1220 """check instruction
1221 """
1222 if self.respect_pc:
1223 pc = self.pc.CIA.value
1224 else:
1225 pc = self.fake_pc
1226 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
1227 if ins is None:
1228 raise KeyError("no instruction at 0x%x" % pc)
1229 return pc, ins
1230
1231 def setup_one(self):
1232 """set up one instruction
1233 """
1234 pc, insn = self.get_next_insn()
1235 yield from self.setup_next_insn(pc, insn)
1236
1237 def setup_next_insn(self, pc, ins):
1238 """set up next instruction
1239 """
1240 self._pc = pc
1241 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
1242 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
1243
1244 yield self.dec2.sv_rm.eq(0)
1245 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
1246 yield self.dec2.dec.bigendian.eq(self.bigendian)
1247 yield self.dec2.state.msr.eq(self.msr.value)
1248 yield self.dec2.state.pc.eq(pc)
1249 if self.svstate is not None:
1250 yield self.dec2.state.svstate.eq(self.svstate.value)
1251
1252 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1253 yield Settle()
1254 opcode = yield self.dec2.dec.opcode_in
1255 opcode = SelectableInt(value=opcode, bits=32)
1256 pfx = SVP64Instruction.Prefix(opcode)
1257 log("prefix test: opcode:", pfx.po, bin(pfx.po), pfx.id)
1258 self.is_svp64_mode = bool((pfx.po == 0b000001) and (pfx.id == 0b11))
1259 self.pc.update_nia(self.is_svp64_mode)
1260 # set SVP64 decode
1261 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
1262 self.namespace['NIA'] = self.pc.NIA
1263 self.namespace['SVSTATE'] = self.svstate
1264 if not self.is_svp64_mode:
1265 return
1266
1267 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1268 log("svp64.rm", bin(pfx.rm))
1269 log(" svstate.vl", self.svstate.vl)
1270 log(" svstate.mvl", self.svstate.maxvl)
1271 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
1272 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
1273 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
1274 yield self.dec2.sv_rm.eq(int(pfx.rm)) # svp64 prefix
1275 yield Settle()
1276
1277 def execute_one(self):
1278 """execute one instruction
1279 """
1280 # get the disassembly code for this instruction
1281 if self.is_svp64_mode:
1282 if not self.disassembly:
1283 code = yield from self.get_assembly_name()
1284 else:
1285 code = self.disassembly[self._pc+4]
1286 log(" svp64 sim-execute", hex(self._pc), code)
1287 else:
1288 if not self.disassembly:
1289 code = yield from self.get_assembly_name()
1290 else:
1291 code = self.disassembly[self._pc]
1292 log("sim-execute", hex(self._pc), code)
1293 opname = code.split(' ')[0]
1294 try:
1295 yield from self.call(opname) # execute the instruction
1296 except MemException as e: # check for memory errors
1297 if e.args[0] == 'unaligned': # alignment error
1298 # run a Trap but set DAR first
1299 print("memory unaligned exception, DAR", e.dar)
1300 self.spr['DAR'] = SelectableInt(e.dar, 64)
1301 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1302 return
1303 elif e.args[0] == 'invalid': # invalid
1304 # run a Trap but set DAR first
1305 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1306 if e.mode == 'EXECUTE':
1307 # XXX TODO: must set a few bits in SRR1,
1308 # see microwatt loadstore1.vhdl
1309 # if m_in.segerr = '0' then
1310 # v.srr1(47 - 33) := m_in.invalid;
1311 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1312 # v.srr1(47 - 44) := m_in.badtree;
1313 # v.srr1(47 - 45) := m_in.rc_error;
1314 # v.intr_vec := 16#400#;
1315 # else
1316 # v.intr_vec := 16#480#;
1317 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1318 else:
1319 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1320 return
1321 # not supported yet:
1322 raise e # ... re-raise
1323
1324 # don't use this except in special circumstances
1325 if not self.respect_pc:
1326 self.fake_pc += 4
1327
1328 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1329 hex(self.pc.NIA.value))
1330
1331 def get_assembly_name(self):
1332 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1333 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1334 dec_insn = yield self.dec2.e.do.insn
1335 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1336 asmcode = yield self.dec2.dec.op.asmcode
1337 int_op = yield self.dec2.dec.op.internal_op
1338 log("get assembly name asmcode", asmcode, int_op,
1339 hex(dec_insn), bin(insn_1_11))
1340 asmop = insns.get(asmcode, None)
1341
1342 # sigh reconstruct the assembly instruction name
1343 if hasattr(self.dec2.e.do, "oe"):
1344 ov_en = yield self.dec2.e.do.oe.oe
1345 ov_ok = yield self.dec2.e.do.oe.ok
1346 else:
1347 ov_en = False
1348 ov_ok = False
1349 if hasattr(self.dec2.e.do, "rc"):
1350 rc_en = yield self.dec2.e.do.rc.rc
1351 rc_ok = yield self.dec2.e.do.rc.ok
1352 else:
1353 rc_en = False
1354 rc_ok = False
1355 # grrrr have to special-case MUL op (see DecodeOE)
1356 log("ov %d en %d rc %d en %d op %d" %
1357 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1358 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1359 log("mul op")
1360 if rc_en & rc_ok:
1361 asmop += "."
1362 else:
1363 if not asmop.endswith("."): # don't add "." to "andis."
1364 if rc_en & rc_ok:
1365 asmop += "."
1366 if hasattr(self.dec2.e.do, "lk"):
1367 lk = yield self.dec2.e.do.lk
1368 if lk:
1369 asmop += "l"
1370 log("int_op", int_op)
1371 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1372 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1373 log("AA", AA)
1374 if AA:
1375 asmop += "a"
1376 spr_msb = yield from self.get_spr_msb()
1377 if int_op == MicrOp.OP_MFCR.value:
1378 if spr_msb:
1379 asmop = 'mfocrf'
1380 else:
1381 asmop = 'mfcr'
1382 # XXX TODO: for whatever weird reason this doesn't work
1383 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1384 if int_op == MicrOp.OP_MTCRF.value:
1385 if spr_msb:
1386 asmop = 'mtocrf'
1387 else:
1388 asmop = 'mtcrf'
1389 return asmop
1390
1391 def get_remap_indices(self):
1392 """WARNING, this function stores remap_idxs and remap_loopends
1393 in the class for later use. this to avoid problems with yield
1394 """
1395 # go through all iterators in lock-step, advance to next remap_idx
1396 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1397 # get four SVSHAPEs. here we are hard-coding
1398 SVSHAPE0 = self.spr['SVSHAPE0']
1399 SVSHAPE1 = self.spr['SVSHAPE1']
1400 SVSHAPE2 = self.spr['SVSHAPE2']
1401 SVSHAPE3 = self.spr['SVSHAPE3']
1402 # set up the iterators
1403 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1404 (SVSHAPE1, SVSHAPE1.get_iterator()),
1405 (SVSHAPE2, SVSHAPE2.get_iterator()),
1406 (SVSHAPE3, SVSHAPE3.get_iterator()),
1407 ]
1408
1409 self.remap_loopends = [0] * 4
1410 self.remap_idxs = [0, 1, 2, 3]
1411 dbg = []
1412 for i, (shape, remap) in enumerate(remaps):
1413 # zero is "disabled"
1414 if shape.value == 0x0:
1415 self.remap_idxs[i] = 0
1416 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1417 step = dststep if (i in [3, 4]) else srcstep
1418 # this is terrible. O(N^2) looking for the match. but hey.
1419 for idx, (remap_idx, loopends) in enumerate(remap):
1420 if idx == step:
1421 break
1422 self.remap_idxs[i] = remap_idx
1423 self.remap_loopends[i] = loopends
1424 dbg.append((i, step, remap_idx, loopends))
1425 for (i, step, remap_idx, loopends) in dbg:
1426 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1427 return remaps
1428
1429 def get_spr_msb(self):
1430 dec_insn = yield self.dec2.e.do.insn
1431 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1432
1433 def call(self, name):
1434 """call(opcode) - the primary execution point for instructions
1435 """
1436 self.last_st_addr = None # reset the last known store address
1437 self.last_ld_addr = None # etc.
1438
1439 ins_name = name.strip() # remove spaces if not already done so
1440 if self.halted:
1441 log("halted - not executing", ins_name)
1442 return
1443
1444 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1445 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1446 asmop = yield from self.get_assembly_name()
1447 log("call", ins_name, asmop)
1448
1449 # sv.setvl is *not* a loop-function. sigh
1450 log("is_svp64_mode", self.is_svp64_mode, asmop)
1451
1452 # check privileged
1453 int_op = yield self.dec2.dec.op.internal_op
1454 spr_msb = yield from self.get_spr_msb()
1455
1456 instr_is_privileged = False
1457 if int_op in [MicrOp.OP_ATTN.value,
1458 MicrOp.OP_MFMSR.value,
1459 MicrOp.OP_MTMSR.value,
1460 MicrOp.OP_MTMSRD.value,
1461 # TODO: OP_TLBIE
1462 MicrOp.OP_RFID.value]:
1463 instr_is_privileged = True
1464 if int_op in [MicrOp.OP_MFSPR.value,
1465 MicrOp.OP_MTSPR.value] and spr_msb:
1466 instr_is_privileged = True
1467
1468 log("is priv", instr_is_privileged, hex(self.msr.value),
1469 self.msr[MSRb.PR])
1470 # check MSR priv bit and whether op is privileged: if so, throw trap
1471 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1472 self.call_trap(0x700, PIb.PRIV)
1473 return
1474
1475 # check halted condition
1476 if ins_name == 'attn':
1477 self.halted = True
1478 return
1479
1480 # check illegal instruction
1481 illegal = False
1482 if ins_name not in ['mtcrf', 'mtocrf']:
1483 illegal = ins_name != asmop
1484
1485 # list of instructions not being supported by binutils (.long)
1486 dotstrp = asmop[:-1] if asmop[-1] == '.' else asmop
1487 if dotstrp in [*FPTRANS_INSNS,
1488 'ffmadds', 'fdmadds', 'ffadds',
1489 'mins', 'maxs', 'minu', 'maxu',
1490 'setvl', 'svindex', 'svremap', 'svstep',
1491 'svshape', 'svshape2',
1492 'grev', 'ternlogi', 'bmask', 'cprop',
1493 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1494 'fmvis', 'fishmv', 'pcdec'
1495 ]:
1496 illegal = False
1497 ins_name = dotstrp
1498
1499 # branch-conditional redirects to sv.bc
1500 if asmop.startswith('bc') and self.is_svp64_mode:
1501 ins_name = 'sv.%s' % ins_name
1502
1503 log(" post-processed name", dotstrp, ins_name, asmop)
1504
1505 # illegal instructions call TRAP at 0x700
1506 if illegal:
1507 print("illegal", ins_name, asmop)
1508 self.call_trap(0x700, PIb.ILLEG)
1509 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1510 (ins_name, asmop, self.pc.CIA.value))
1511 return
1512
1513 # this is for setvl "Vertical" mode: if set true,
1514 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1515 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1516 self.allow_next_step_inc = False
1517 self.svstate_next_mode = 0
1518
1519 # nop has to be supported, we could let the actual op calculate
1520 # but PowerDecoder has a pattern for nop
1521 if ins_name == 'nop':
1522 self.update_pc_next()
1523 return
1524
1525 # look up instruction in ISA.instrs, prepare namespace
1526 if ins_name == 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1527 info = self.instrs[ins_name+"."]
1528 else:
1529 info = self.instrs[ins_name]
1530 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1531
1532 # preserve order of register names
1533 input_names = create_args(list(info.read_regs) +
1534 list(info.uninit_regs))
1535 log("input names", input_names)
1536
1537 # get SVP64 entry for the current instruction
1538 sv_rm = self.svp64rm.instrs.get(ins_name)
1539 if sv_rm is not None:
1540 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1541 else:
1542 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1543 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1544
1545 # see if srcstep/dststep need skipping over masked-out predicate bits
1546 if (self.is_svp64_mode or ins_name in ['setvl', 'svremap', 'svstate']):
1547 yield from self.svstate_pre_inc()
1548 if self.is_svp64_mode:
1549 pre = yield from self.update_new_svstate_steps()
1550 if pre:
1551 self.svp64_reset_loop()
1552 self.update_nia()
1553 self.update_pc_next()
1554 return
1555 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1556 pred_dst_zero = self.pred_dst_zero
1557 pred_src_zero = self.pred_src_zero
1558 vl = self.svstate.vl
1559 subvl = yield self.dec2.rm_dec.rm_in.subvl
1560
1561 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1562 if self.is_svp64_mode and vl == 0:
1563 self.pc.update(self.namespace, self.is_svp64_mode)
1564 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1565 self.namespace['NIA'], kind=LogKind.InstrInOuts)
1566 return
1567
1568 # for when SVREMAP is active, using pre-arranged schedule.
1569 # note: modifying PowerDecoder2 needs to "settle"
1570 remap_en = self.svstate.SVme
1571 persist = self.svstate.RMpst
1572 active = (persist or self.last_op_svshape) and remap_en != 0
1573 if self.is_svp64_mode:
1574 yield self.dec2.remap_active.eq(remap_en if active else 0)
1575 yield Settle()
1576 if persist or self.last_op_svshape:
1577 remaps = self.get_remap_indices()
1578 if self.is_svp64_mode and (persist or self.last_op_svshape):
1579 yield from self.remap_set_steps(remaps)
1580 # after that, settle down (combinatorial) to let Vector reg numbers
1581 # work themselves out
1582 yield Settle()
1583 if self.is_svp64_mode:
1584 remap_active = yield self.dec2.remap_active
1585 else:
1586 remap_active = False
1587 log("remap active", bin(remap_active))
1588
1589 # main input registers (RT, RA ...)
1590 inputs = []
1591 for name in input_names:
1592 log("name", name)
1593 regval = (yield from self.get_input(name))
1594 log("regval", regval)
1595 inputs.append(regval)
1596
1597 # arrrrgh, awful hack, to get _RT into namespace
1598 if ins_name in ['setvl', 'svstep']:
1599 regname = "_RT"
1600 RT = yield self.dec2.dec.RT
1601 self.namespace[regname] = SelectableInt(RT, 5)
1602 if RT == 0:
1603 self.namespace["RT"] = SelectableInt(0, 5)
1604 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1605 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1606
1607 # in SVP64 mode for LD/ST work out immediate
1608 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1609 # use info.form to detect
1610 if self.is_svp64_mode:
1611 yield from self.check_replace_d(info, remap_active)
1612
1613 # "special" registers
1614 for special in info.special_regs:
1615 if special in special_sprs:
1616 inputs.append(self.spr[special])
1617 else:
1618 inputs.append(self.namespace[special])
1619
1620 # clear trap (trap) NIA
1621 self.trap_nia = None
1622
1623 # check if this was an sv.bc* and create an indicator that
1624 # this is the last check to be made as a loop. combined with
1625 # the ALL/ANY mode we can early-exit
1626 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
1627 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
1628 # XXX TODO - pack/unpack here
1629 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
1630 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
1631
1632 # execute actual instruction here (finally)
1633 log("inputs", inputs)
1634 results = info.func(self, *inputs)
1635 log("results", results)
1636
1637 # "inject" decorator takes namespace from function locals: we need to
1638 # overwrite NIA being overwritten (sigh)
1639 if self.trap_nia is not None:
1640 self.namespace['NIA'] = self.trap_nia
1641
1642 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1643
1644 # check if op was a LD/ST so that debugging can check the
1645 # address
1646 if int_op in [MicrOp.OP_STORE.value,
1647 ]:
1648 self.last_st_addr = self.mem.last_st_addr
1649 if int_op in [MicrOp.OP_LOAD.value,
1650 ]:
1651 self.last_ld_addr = self.mem.last_ld_addr
1652 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1653 self.last_st_addr, self.last_ld_addr)
1654
1655 # detect if CA/CA32 already in outputs (sra*, basically)
1656 already_done = 0
1657 output_names = []
1658 if info.write_regs:
1659 output_names = create_args(info.write_regs)
1660 for name in output_names:
1661 if name == 'CA':
1662 already_done |= 1
1663 if name == 'CA32':
1664 already_done |= 2
1665
1666 log("carry already done?", bin(already_done), output_names)
1667 carry_en = yield self.dec2.e.do.output_carry
1668 if carry_en:
1669 yield from self.handle_carry_(inputs, results, already_done)
1670
1671 # check if one of the regs was named "overflow"
1672 overflow = None
1673 if info.write_regs:
1674 for name, output in zip(output_names, results):
1675 if name == 'overflow':
1676 overflow = output
1677
1678 # and one called CR0
1679 cr0 = None
1680 if info.write_regs:
1681 for name, output in zip(output_names, results):
1682 if name == 'CR0':
1683 cr0 = output
1684
1685 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1686 # detect if overflow was in return result
1687 ov_en = yield self.dec2.e.do.oe.oe
1688 ov_ok = yield self.dec2.e.do.oe.ok
1689 log("internal overflow", ins_name, overflow, "en?", ov_en, ov_ok)
1690 if ov_en & ov_ok:
1691 yield from self.handle_overflow(inputs, results, overflow)
1692
1693 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1694 rc_en = False
1695 if not self.is_svp64_mode or not pred_dst_zero:
1696 if hasattr(self.dec2.e.do, "rc"):
1697 rc_en = yield self.dec2.e.do.rc.rc
1698 # don't do Rc=1 for svstep it is handled explicitly.
1699 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1700 # to write directly to CR0 instead of in ISACaller. hooyahh.
1701 if rc_en and ins_name not in ['svstep']:
1702 yield from self.do_rc_ov(ins_name, results, overflow, cr0)
1703
1704 # check failfirst
1705 rm_mode = yield self.dec2.rm_dec.mode
1706 ff_inv = yield self.dec2.rm_dec.inv
1707 cr_bit = yield self.dec2.rm_dec.cr_sel
1708 log(" ff rm_mode", rc_en, rm_mode, SVP64RMMode.FFIRST.value)
1709 log(" inv", ff_inv)
1710 log(" cr_bit", cr_bit)
1711 ffirst_hit = False
1712 if rc_en and rm_mode == SVP64RMMode.FFIRST.value:
1713 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1714 crtest = self.crl[regnum]
1715 ffirst_hit = crtest[cr_bit] != ff_inv
1716 log("cr test", regnum, int(crtest), crtest, cr_bit, ff_inv)
1717 log("cr test?", ffirst_hit)
1718 if ffirst_hit:
1719 self.svstate.vl = srcstep
1720 yield self.dec2.state.svstate.eq(self.svstate.value)
1721 yield Settle() # let decoder update
1722
1723 # any modified return results?
1724 yield from self.do_outregs_nia(asmop, ins_name, info,
1725 output_names, results,
1726 carry_en, rc_en, ffirst_hit)
1727
1728 def do_rc_ov(self, ins_name, results, overflow, cr0):
1729 if ins_name.startswith("f"):
1730 rc_reg = "CR1" # not calculated correctly yet (not FP compares)
1731 else:
1732 rc_reg = "CR0"
1733 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, rc_reg)
1734 cmps = results
1735 # hang on... for `setvl` actually you want to test SVSTATE.VL
1736 is_setvl = ins_name == 'setvl'
1737 if is_setvl:
1738 vl = results[0].vl
1739 cmps = (SelectableInt(vl, 64), overflow,)
1740 else:
1741 overflow = None # do not override overflow except in setvl
1742
1743 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
1744 if cr0 is None:
1745 self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
1746 else:
1747 # otherwise we just blat CR0 into the required regnum
1748 log("explicit rc0", cr0)
1749 self.crl[regnum].eq(cr0)
1750
1751 def do_outregs_nia(self, asmop, ins_name, info, output_names, results,
1752 carry_en, rc_en, ffirst_hit):
1753 # write out any regs for this instruction
1754 if info.write_regs:
1755 for name, output in zip(output_names, results):
1756 yield from self.check_write(info, name, output, carry_en)
1757
1758 if ffirst_hit:
1759 self.svp64_reset_loop()
1760 nia_update = True
1761 else:
1762 # check advancement of src/dst/sub-steps and if PC needs updating
1763 nia_update = (yield from self.check_step_increment(results, rc_en,
1764 asmop, ins_name))
1765 if nia_update:
1766 self.update_pc_next()
1767
1768 def check_replace_d(self, info, remap_active):
1769 replace_d = False # update / replace constant in pseudocode
1770 ldstmode = yield self.dec2.rm_dec.ldstmode
1771 vl = self.svstate.vl
1772 subvl = yield self.dec2.rm_dec.rm_in.subvl
1773 srcstep, dststep = self.new_srcstep, self.new_dststep
1774 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1775 if info.form == 'DS':
1776 # DS-Form, multiply by 4 then knock 2 bits off after
1777 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1778 else:
1779 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1780 imm = exts(imm, 16) # sign-extend to integer
1781 # get the right step. LD is from srcstep, ST is dststep
1782 op = yield self.dec2.e.do.insn_type
1783 offsmul = 0
1784 if op == MicrOp.OP_LOAD.value:
1785 if remap_active:
1786 offsmul = yield self.dec2.in1_step
1787 log("D-field REMAP src", imm, offsmul)
1788 else:
1789 offsmul = (srcstep * (subvl+1)) + ssubstep
1790 log("D-field src", imm, offsmul)
1791 elif op == MicrOp.OP_STORE.value:
1792 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1793 offsmul = (dststep * (subvl+1)) + dsubstep
1794 log("D-field dst", imm, offsmul)
1795 # Unit-Strided LD/ST adds offset*width to immediate
1796 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1797 ldst_len = yield self.dec2.e.do.data_len
1798 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1799 replace_d = True
1800 # Element-strided multiplies the immediate by element step
1801 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1802 imm = SelectableInt(imm * offsmul, 32)
1803 replace_d = True
1804 if replace_d:
1805 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1806 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1807 log("LDSTmode", SVP64LDSTmode(ldstmode),
1808 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1809 # new replacement D... errr.. DS
1810 if replace_d:
1811 if info.form == 'DS':
1812 # TODO: assert 2 LSBs are zero?
1813 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1814 imm.value = imm.value >> 2
1815 self.namespace['DS'] = imm
1816 else:
1817 self.namespace['D'] = imm
1818
1819 def get_input(self, name):
1820 # using PowerDecoder2, first, find the decoder index.
1821 # (mapping name RA RB RC RS to in1, in2, in3)
1822 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1823 if regnum is None:
1824 # doing this is not part of svp64, it's because output
1825 # registers, to be modified, need to be in the namespace.
1826 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1827 if regnum is None:
1828 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1829
1830 # in case getting the register number is needed, _RA, _RB
1831 regname = "_" + name
1832 self.namespace[regname] = regnum
1833 if not self.is_svp64_mode or not self.pred_src_zero:
1834 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1835 if name in fregs:
1836 reg_val = SelectableInt(self.fpr(regnum))
1837 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1838 elif name is not None:
1839 reg_val = SelectableInt(self.gpr(regnum))
1840 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1841 else:
1842 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1843 reg_val = 0
1844 return reg_val
1845
1846 def remap_set_steps(self, remaps):
1847 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1848 they work in concert with PowerDecoder2 at the moment,
1849 there is no HDL implementation of REMAP. therefore this
1850 function, because ISACaller still uses PowerDecoder2,
1851 will *explicitly* write the dec2.XX_step values. this has
1852 to get sorted out.
1853 """
1854 # just some convenient debug info
1855 for i in range(4):
1856 sname = 'SVSHAPE%d' % i
1857 shape = self.spr[sname]
1858 log(sname, bin(shape.value))
1859 log(" lims", shape.lims)
1860 log(" mode", shape.mode)
1861 log(" skip", shape.skip)
1862
1863 # set up the list of steps to remap
1864 mi0 = self.svstate.mi0
1865 mi1 = self.svstate.mi1
1866 mi2 = self.svstate.mi2
1867 mo0 = self.svstate.mo0
1868 mo1 = self.svstate.mo1
1869 steps = [(self.dec2.in1_step, mi0), # RA
1870 (self.dec2.in2_step, mi1), # RB
1871 (self.dec2.in3_step, mi2), # RC
1872 (self.dec2.o_step, mo0), # RT
1873 (self.dec2.o2_step, mo1), # EA
1874 ]
1875 remap_idxs = self.remap_idxs
1876 rremaps = []
1877 # now cross-index the required SHAPE for each of 3-in 2-out regs
1878 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1879 for i, (dstep, shape_idx) in enumerate(steps):
1880 (shape, remap) = remaps[shape_idx]
1881 remap_idx = remap_idxs[shape_idx]
1882 # zero is "disabled"
1883 if shape.value == 0x0:
1884 continue
1885 # now set the actual requested step to the current index
1886 yield dstep.eq(remap_idx)
1887
1888 # debug printout info
1889 rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
1890 for x in rremaps:
1891 log("shape remap", x)
1892
1893 def check_write(self, info, name, output, carry_en):
1894 if name == 'overflow': # ignore, done already (above)
1895 return
1896 if name == 'CR0': # ignore, done already (above)
1897 return
1898 if isinstance(output, int):
1899 output = SelectableInt(output, 256)
1900 # write carry flafs
1901 if name in ['CA', 'CA32']:
1902 if carry_en:
1903 log("writing %s to XER" % name, output)
1904 log("write XER %s 0x%x" % (name, output.value))
1905 self.spr['XER'][XER_bits[name]] = output.value
1906 else:
1907 log("NOT writing %s to XER" % name, output)
1908 return
1909 # write special SPRs
1910 if name in info.special_regs:
1911 log('writing special %s' % name, output, special_sprs)
1912 log("write reg %s 0x%x" % (name, output.value))
1913 if name in special_sprs:
1914 self.spr[name] = output
1915 else:
1916 self.namespace[name].eq(output)
1917 if name == 'MSR':
1918 log('msr written', hex(self.msr.value))
1919 return
1920 # find out1/out2 PR/FPR
1921 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1922 if regnum is None:
1923 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1924 if regnum is None:
1925 # temporary hack for not having 2nd output
1926 regnum = yield getattr(self.decoder, name)
1927 is_vec = False
1928 # convenient debug prefix
1929 if name in fregs:
1930 reg_prefix = 'f'
1931 else:
1932 reg_prefix = 'r'
1933 # check zeroing due to predicate bit being zero
1934 if self.is_svp64_mode and self.pred_dst_zero:
1935 log('zeroing reg %d %s' % (regnum, str(output)), is_vec)
1936 output = SelectableInt(0, 256)
1937 log("write reg %s%d 0x%x" % (reg_prefix, regnum, output.value),
1938 kind=LogKind.InstrInOuts)
1939 # zero-extend tov64 bit begore storing (should use EXT oh well)
1940 if output.bits > 64:
1941 output = SelectableInt(output.value, 64)
1942 if name in fregs:
1943 self.fpr[regnum] = output
1944 else:
1945 self.gpr[regnum] = output
1946
1947 def check_step_increment(self, results, rc_en, asmop, ins_name):
1948 # check if it is the SVSTATE.src/dest step that needs incrementing
1949 # this is our Sub-Program-Counter loop from 0 to VL-1
1950 if not self.allow_next_step_inc:
1951 if self.is_svp64_mode:
1952 return (yield from self.svstate_post_inc(ins_name))
1953
1954 # XXX only in non-SVP64 mode!
1955 # record state of whether the current operation was an svshape,
1956 # OR svindex!
1957 # to be able to know if it should apply in the next instruction.
1958 # also (if going to use this instruction) should disable ability
1959 # to interrupt in between. sigh.
1960 self.last_op_svshape = asmop in ['svremap', 'svindex',
1961 'svshape2']
1962 return True
1963
1964 pre = False
1965 post = False
1966 nia_update = True
1967 log("SVSTATE_NEXT: inc requested, mode",
1968 self.svstate_next_mode, self.allow_next_step_inc)
1969 yield from self.svstate_pre_inc()
1970 pre = yield from self.update_new_svstate_steps()
1971 if pre:
1972 # reset at end of loop including exit Vertical Mode
1973 log("SVSTATE_NEXT: end of loop, reset")
1974 self.svp64_reset_loop()
1975 self.svstate.vfirst = 0
1976 self.update_nia()
1977 if not rc_en:
1978 return True
1979 results = [SelectableInt(0, 64)]
1980 self.handle_comparison(results) # CR0
1981 return True
1982 if self.allow_next_step_inc == 2:
1983 log("SVSTATE_NEXT: read")
1984 nia_update = (yield from self.svstate_post_inc(ins_name))
1985 else:
1986 log("SVSTATE_NEXT: post-inc")
1987 # use actual src/dst-step here to check end, do NOT
1988 # use bit-reversed version
1989 srcstep, dststep = self.new_srcstep, self.new_dststep
1990 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1991 remaps = self.get_remap_indices()
1992 remap_idxs = self.remap_idxs
1993 vl = self.svstate.vl
1994 subvl = yield self.dec2.rm_dec.rm_in.subvl
1995 end_src = srcstep == vl-1
1996 end_dst = dststep == vl-1
1997 if self.allow_next_step_inc != 2:
1998 yield from self.advance_svstate_steps(end_src, end_dst)
1999 #self.namespace['SVSTATE'] = self.svstate.spr
2000 # set CR0 (if Rc=1) based on end
2001 if rc_en:
2002 endtest = 1 if (end_src or end_dst) else 0
2003 #results = [SelectableInt(endtest, 64)]
2004 # self.handle_comparison(results) # CR0
2005
2006 # see if svstep was requested, if so, which SVSTATE
2007 endings = 0b111
2008 if self.svstate_next_mode > 0:
2009 shape_idx = self.svstate_next_mode.value-1
2010 endings = self.remap_loopends[shape_idx]
2011 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
2012 log("svstep Rc=1, CR0", cr_field)
2013 self.crl[0].eq(cr_field) # CR0
2014 if end_src or end_dst:
2015 # reset at end of loop including exit Vertical Mode
2016 log("SVSTATE_NEXT: after increments, reset")
2017 self.svp64_reset_loop()
2018 self.svstate.vfirst = 0
2019 return nia_update
2020
2021 def SVSTATE_NEXT(self, mode, submode):
2022 """explicitly moves srcstep/dststep on to next element, for
2023 "Vertical-First" mode. this function is called from
2024 setvl pseudo-code, as a pseudo-op "svstep"
2025
2026 WARNING: this function uses information that was created EARLIER
2027 due to it being in the middle of a yield, but this function is
2028 *NOT* called from yield (it's called from compiled pseudocode).
2029 """
2030 self.allow_next_step_inc = submode.value + 1
2031 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
2032 self.svstate_next_mode = mode
2033 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
2034 shape_idx = self.svstate_next_mode.value-1
2035 return SelectableInt(self.remap_idxs[shape_idx], 7)
2036 if self.svstate_next_mode == 5:
2037 self.svstate_next_mode = 0
2038 return SelectableInt(self.svstate.srcstep, 7)
2039 if self.svstate_next_mode == 6:
2040 self.svstate_next_mode = 0
2041 return SelectableInt(self.svstate.dststep, 7)
2042 return SelectableInt(0, 7)
2043
2044 def get_src_dststeps(self):
2045 """gets srcstep, dststep, and ssubstep, dsubstep
2046 """
2047 return (self.new_srcstep, self.new_dststep,
2048 self.new_ssubstep, self.new_dsubstep)
2049
2050 def update_new_svstate_steps(self):
2051 # note, do not get the bit-reversed srcstep here!
2052 srcstep, dststep = self.new_srcstep, self.new_dststep
2053 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
2054
2055 # update SVSTATE with new srcstep
2056 self.svstate.srcstep = srcstep
2057 self.svstate.dststep = dststep
2058 self.svstate.ssubstep = ssubstep
2059 self.svstate.dsubstep = dsubstep
2060 self.namespace['SVSTATE'] = self.svstate
2061 yield self.dec2.state.svstate.eq(self.svstate.value)
2062 yield Settle() # let decoder update
2063 srcstep = self.svstate.srcstep
2064 dststep = self.svstate.dststep
2065 ssubstep = self.svstate.ssubstep
2066 dsubstep = self.svstate.dsubstep
2067 pack = self.svstate.pack
2068 unpack = self.svstate.unpack
2069 vl = self.svstate.vl
2070 subvl = yield self.dec2.rm_dec.rm_in.subvl
2071 rm_mode = yield self.dec2.rm_dec.mode
2072 ff_inv = yield self.dec2.rm_dec.inv
2073 cr_bit = yield self.dec2.rm_dec.cr_sel
2074 log(" srcstep", srcstep)
2075 log(" dststep", dststep)
2076 log(" pack", pack)
2077 log(" unpack", unpack)
2078 log(" ssubstep", ssubstep)
2079 log(" dsubstep", dsubstep)
2080 log(" vl", vl)
2081 log(" subvl", subvl)
2082 log(" rm_mode", rm_mode)
2083 log(" inv", ff_inv)
2084 log(" cr_bit", cr_bit)
2085
2086 # check if end reached (we let srcstep overrun, above)
2087 # nothing needs doing (TODO zeroing): just do next instruction
2088 return ((ssubstep == subvl and srcstep == vl) or
2089 (dsubstep == subvl and dststep == vl))
2090
2091 def svstate_post_inc(self, insn_name, vf=0):
2092 # check if SV "Vertical First" mode is enabled
2093 vfirst = self.svstate.vfirst
2094 log(" SV Vertical First", vf, vfirst)
2095 if not vf and vfirst == 1:
2096 self.update_nia()
2097 return True
2098
2099 # check if it is the SVSTATE.src/dest step that needs incrementing
2100 # this is our Sub-Program-Counter loop from 0 to VL-1
2101 # XXX twin predication TODO
2102 vl = self.svstate.vl
2103 subvl = yield self.dec2.rm_dec.rm_in.subvl
2104 mvl = self.svstate.maxvl
2105 srcstep = self.svstate.srcstep
2106 dststep = self.svstate.dststep
2107 ssubstep = self.svstate.ssubstep
2108 dsubstep = self.svstate.dsubstep
2109 pack = self.svstate.pack
2110 unpack = self.svstate.unpack
2111 rm_mode = yield self.dec2.rm_dec.mode
2112 reverse_gear = yield self.dec2.rm_dec.reverse_gear
2113 sv_ptype = yield self.dec2.dec.op.SV_Ptype
2114 out_vec = not (yield self.dec2.no_out_vec)
2115 in_vec = not (yield self.dec2.no_in_vec)
2116 log(" svstate.vl", vl)
2117 log(" svstate.mvl", mvl)
2118 log(" rm.subvl", subvl)
2119 log(" svstate.srcstep", srcstep)
2120 log(" svstate.dststep", dststep)
2121 log(" svstate.ssubstep", ssubstep)
2122 log(" svstate.dsubstep", dsubstep)
2123 log(" svstate.pack", pack)
2124 log(" svstate.unpack", unpack)
2125 log(" mode", rm_mode)
2126 log(" reverse", reverse_gear)
2127 log(" out_vec", out_vec)
2128 log(" in_vec", in_vec)
2129 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
2130 # check if this was an sv.bc* and if so did it succeed
2131 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
2132 end_loop = self.namespace['end_loop']
2133 log("branch %s end_loop" % insn_name, end_loop)
2134 if end_loop.value:
2135 self.svp64_reset_loop()
2136 self.update_pc_next()
2137 return False
2138 # check if srcstep needs incrementing by one, stop PC advancing
2139 # but for 2-pred both src/dest have to be checked.
2140 # XXX this might not be true! it may just be LD/ST
2141 if sv_ptype == SVPtype.P2.value:
2142 svp64_is_vector = (out_vec or in_vec)
2143 else:
2144 svp64_is_vector = out_vec
2145 # loops end at the first "hit" (source or dest)
2146 end_src = srcstep == vl-1
2147 end_dst = dststep == vl-1
2148 loopend = ((end_src and ssubstep == subvl) or
2149 (end_dst and dsubstep == subvl))
2150 log("loopend", svp64_is_vector, loopend, end_src, end_dst,
2151 ssubstep == subvl, dsubstep == subvl)
2152 if not svp64_is_vector or loopend:
2153 # reset loop to zero and update NIA
2154 self.svp64_reset_loop()
2155 self.update_nia()
2156
2157 return True
2158
2159 # still looping, advance and update NIA
2160 yield from self.advance_svstate_steps(end_src, end_dst)
2161 self.namespace['SVSTATE'] = self.svstate
2162
2163 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2164 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2165 # this way we keep repeating the same instruction (with new steps)
2166 self.pc.NIA.value = self.pc.CIA.value
2167 self.namespace['NIA'] = self.pc.NIA
2168 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
2169 return False # DO NOT allow PC update whilst Sub-PC loop running
2170
2171 def update_pc_next(self):
2172 # UPDATE program counter
2173 self.pc.update(self.namespace, self.is_svp64_mode)
2174 #self.svstate.spr = self.namespace['SVSTATE']
2175 log("end of call", self.namespace['CIA'],
2176 self.namespace['NIA'],
2177 self.namespace['SVSTATE'])
2178
2179 def svp64_reset_loop(self):
2180 self.svstate.srcstep = 0
2181 self.svstate.dststep = 0
2182 self.svstate.ssubstep = 0
2183 self.svstate.dsubstep = 0
2184 log(" svstate.srcstep loop end (PC to update)")
2185 self.namespace['SVSTATE'] = self.svstate
2186
2187 def update_nia(self):
2188 self.pc.update_nia(self.is_svp64_mode)
2189 self.namespace['NIA'] = self.pc.NIA
2190
2191
2192 def inject():
2193 """Decorator factory.
2194
2195 this decorator will "inject" variables into the function's namespace,
2196 from the *dictionary* in self.namespace. it therefore becomes possible
2197 to make it look like a whole stack of variables which would otherwise
2198 need "self." inserted in front of them (*and* for those variables to be
2199 added to the instance) "appear" in the function.
2200
2201 "self.namespace['SI']" for example becomes accessible as just "SI" but
2202 *only* inside the function, when decorated.
2203 """
2204 def variable_injector(func):
2205 @wraps(func)
2206 def decorator(*args, **kwargs):
2207 try:
2208 func_globals = func.__globals__ # Python 2.6+
2209 except AttributeError:
2210 func_globals = func.func_globals # Earlier versions.
2211
2212 context = args[0].namespace # variables to be injected
2213 saved_values = func_globals.copy() # Shallow copy of dict.
2214 log("globals before", context.keys())
2215 func_globals.update(context)
2216 result = func(*args, **kwargs)
2217 log("globals after", func_globals['CIA'], func_globals['NIA'])
2218 log("args[0]", args[0].namespace['CIA'],
2219 args[0].namespace['NIA'],
2220 args[0].namespace['SVSTATE'])
2221 if 'end_loop' in func_globals:
2222 log("args[0] end_loop", func_globals['end_loop'])
2223 args[0].namespace = func_globals
2224 #exec (func.__code__, func_globals)
2225
2226 # finally:
2227 # func_globals = saved_values # Undo changes.
2228
2229 return result
2230
2231 return decorator
2232
2233 return variable_injector