15a4ad9fe3a35580944800d3e699ea465dbeff33
[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 # argh - these are *always* Rc=1 (but not really, they do write to CR0)
1699 if ins_name == 'pcdec': # TODO add stbcx etc. when supported
1700 log ("hack-enable Rc=1 for %s - CR0" % ins_name, cr0)
1701 rc_en = True
1702 # don't do Rc=1 for svstep it is handled explicitly.
1703 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
1704 # to write directly to CR0 instead of in ISACaller. hooyahh.
1705 if rc_en and ins_name not in ['svstep']:
1706 yield from self.do_rc_ov(ins_name, results, overflow, cr0)
1707
1708 # any modified return results?
1709 yield from self.do_outregs_nia(asmop, ins_name, info,
1710 output_names, results,
1711 carry_en, rc_en)
1712
1713 def do_rc_ov(self, ins_name, results, overflow, cr0):
1714 if ins_name.startswith("f"):
1715 rc_reg = "CR1" # not calculated correctly yet (not FP compares)
1716 else:
1717 rc_reg = "CR0"
1718 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, rc_reg)
1719 cmps = results
1720 # hang on... for `setvl` actually you want to test SVSTATE.VL
1721 is_setvl = ins_name == 'setvl'
1722 if is_setvl:
1723 vl = results[0].vl
1724 cmps = (SelectableInt(vl, 64), overflow,)
1725 else:
1726 overflow = None # do not override overflow except in setvl
1727
1728 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
1729 if cr0 is None:
1730 self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
1731 return
1732 # otherwise we just blat CR0 into the required regnum
1733 log("explicit rc0", cr0)
1734 self.crl[regnum].eq(cr0)
1735
1736 def do_outregs_nia(self, asmop, ins_name, info, output_names, results,
1737 carry_en, rc_en):
1738 # write out any regs for this instruction
1739 if info.write_regs:
1740 for name, output in zip(output_names, results):
1741 yield from self.check_write(info, name, output, carry_en)
1742
1743 # check advancement of src/dst/sub-steps and if PC needs updating
1744 nia_update = (yield from self.check_step_increment(results, rc_en,
1745 asmop, ins_name))
1746 if nia_update:
1747 self.update_pc_next()
1748
1749 def check_replace_d(self, info, remap_active):
1750 replace_d = False # update / replace constant in pseudocode
1751 ldstmode = yield self.dec2.rm_dec.ldstmode
1752 vl = self.svstate.vl
1753 subvl = yield self.dec2.rm_dec.rm_in.subvl
1754 srcstep, dststep = self.new_srcstep, self.new_dststep
1755 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1756 if info.form == 'DS':
1757 # DS-Form, multiply by 4 then knock 2 bits off after
1758 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1759 else:
1760 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1761 imm = exts(imm, 16) # sign-extend to integer
1762 # get the right step. LD is from srcstep, ST is dststep
1763 op = yield self.dec2.e.do.insn_type
1764 offsmul = 0
1765 if op == MicrOp.OP_LOAD.value:
1766 if remap_active:
1767 offsmul = yield self.dec2.in1_step
1768 log("D-field REMAP src", imm, offsmul)
1769 else:
1770 offsmul = (srcstep * (subvl+1)) + ssubstep
1771 log("D-field src", imm, offsmul)
1772 elif op == MicrOp.OP_STORE.value:
1773 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1774 offsmul = (dststep * (subvl+1)) + dsubstep
1775 log("D-field dst", imm, offsmul)
1776 # Unit-Strided LD/ST adds offset*width to immediate
1777 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1778 ldst_len = yield self.dec2.e.do.data_len
1779 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1780 replace_d = True
1781 # Element-strided multiplies the immediate by element step
1782 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1783 imm = SelectableInt(imm * offsmul, 32)
1784 replace_d = True
1785 if replace_d:
1786 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1787 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1788 log("LDSTmode", SVP64LDSTmode(ldstmode),
1789 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1790 # new replacement D... errr.. DS
1791 if replace_d:
1792 if info.form == 'DS':
1793 # TODO: assert 2 LSBs are zero?
1794 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1795 imm.value = imm.value >> 2
1796 self.namespace['DS'] = imm
1797 else:
1798 self.namespace['D'] = imm
1799
1800 def get_input(self, name):
1801 # using PowerDecoder2, first, find the decoder index.
1802 # (mapping name RA RB RC RS to in1, in2, in3)
1803 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1804 if regnum is None:
1805 # doing this is not part of svp64, it's because output
1806 # registers, to be modified, need to be in the namespace.
1807 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1808 if regnum is None:
1809 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1810
1811 # in case getting the register number is needed, _RA, _RB
1812 regname = "_" + name
1813 self.namespace[regname] = regnum
1814 if not self.is_svp64_mode or not self.pred_src_zero:
1815 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1816 if name in fregs:
1817 reg_val = SelectableInt(self.fpr(regnum))
1818 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1819 elif name is not None:
1820 reg_val = SelectableInt(self.gpr(regnum))
1821 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1822 else:
1823 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1824 reg_val = 0
1825 return reg_val
1826
1827 def remap_set_steps(self, remaps):
1828 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1829 they work in concert with PowerDecoder2 at the moment,
1830 there is no HDL implementation of REMAP. therefore this
1831 function, because ISACaller still uses PowerDecoder2,
1832 will *explicitly* write the dec2.XX_step values. this has
1833 to get sorted out.
1834 """
1835 # just some convenient debug info
1836 for i in range(4):
1837 sname = 'SVSHAPE%d' % i
1838 shape = self.spr[sname]
1839 log(sname, bin(shape.value))
1840 log(" lims", shape.lims)
1841 log(" mode", shape.mode)
1842 log(" skip", shape.skip)
1843
1844 # set up the list of steps to remap
1845 mi0 = self.svstate.mi0
1846 mi1 = self.svstate.mi1
1847 mi2 = self.svstate.mi2
1848 mo0 = self.svstate.mo0
1849 mo1 = self.svstate.mo1
1850 steps = [(self.dec2.in1_step, mi0), # RA
1851 (self.dec2.in2_step, mi1), # RB
1852 (self.dec2.in3_step, mi2), # RC
1853 (self.dec2.o_step, mo0), # RT
1854 (self.dec2.o2_step, mo1), # EA
1855 ]
1856 remap_idxs = self.remap_idxs
1857 rremaps = []
1858 # now cross-index the required SHAPE for each of 3-in 2-out regs
1859 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1860 for i, (dstep, shape_idx) in enumerate(steps):
1861 (shape, remap) = remaps[shape_idx]
1862 remap_idx = remap_idxs[shape_idx]
1863 # zero is "disabled"
1864 if shape.value == 0x0:
1865 continue
1866 # now set the actual requested step to the current index
1867 yield dstep.eq(remap_idx)
1868
1869 # debug printout info
1870 rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
1871 for x in rremaps:
1872 log("shape remap", x)
1873
1874 def check_write(self, info, name, output, carry_en):
1875 if name == 'overflow': # ignore, done already (above)
1876 return
1877 if name == 'CR0': # ignore, done already (above)
1878 return
1879 if isinstance(output, int):
1880 output = SelectableInt(output, 256)
1881 # write carry flafs
1882 if name in ['CA', 'CA32']:
1883 if carry_en:
1884 log("writing %s to XER" % name, output)
1885 log("write XER %s 0x%x" % (name, output.value))
1886 self.spr['XER'][XER_bits[name]] = output.value
1887 else:
1888 log("NOT writing %s to XER" % name, output)
1889 return
1890 # write special SPRs
1891 if name in info.special_regs:
1892 log('writing special %s' % name, output, special_sprs)
1893 log("write reg %s 0x%x" % (name, output.value))
1894 if name in special_sprs:
1895 self.spr[name] = output
1896 else:
1897 self.namespace[name].eq(output)
1898 if name == 'MSR':
1899 log('msr written', hex(self.msr.value))
1900 return
1901 # find out1/out2 PR/FPR
1902 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1903 if regnum is None:
1904 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1905 if regnum is None:
1906 # temporary hack for not having 2nd output
1907 regnum = yield getattr(self.decoder, name)
1908 is_vec = False
1909 # convenient debug prefix
1910 if name in fregs:
1911 reg_prefix = 'f'
1912 else:
1913 reg_prefix = 'r'
1914 # check zeroing due to predicate bit being zero
1915 if self.is_svp64_mode and self.pred_dst_zero:
1916 log('zeroing reg %d %s' % (regnum, str(output)), is_vec)
1917 output = SelectableInt(0, 256)
1918 log("write reg %s%d 0x%x" % (reg_prefix, regnum, output.value),
1919 kind=LogKind.InstrInOuts)
1920 # zero-extend tov64 bit begore storing (should use EXT oh well)
1921 if output.bits > 64:
1922 output = SelectableInt(output.value, 64)
1923 if name in fregs:
1924 self.fpr[regnum] = output
1925 else:
1926 self.gpr[regnum] = output
1927
1928 def check_step_increment(self, results, rc_en, asmop, ins_name):
1929 # check if it is the SVSTATE.src/dest step that needs incrementing
1930 # this is our Sub-Program-Counter loop from 0 to VL-1
1931 if not self.allow_next_step_inc:
1932 if self.is_svp64_mode:
1933 return (yield from self.svstate_post_inc(ins_name))
1934
1935 # XXX only in non-SVP64 mode!
1936 # record state of whether the current operation was an svshape,
1937 # OR svindex!
1938 # to be able to know if it should apply in the next instruction.
1939 # also (if going to use this instruction) should disable ability
1940 # to interrupt in between. sigh.
1941 self.last_op_svshape = asmop in ['svremap', 'svindex',
1942 'svshape2']
1943 return True
1944
1945 pre = False
1946 post = False
1947 nia_update = True
1948 log("SVSTATE_NEXT: inc requested, mode",
1949 self.svstate_next_mode, self.allow_next_step_inc)
1950 yield from self.svstate_pre_inc()
1951 pre = yield from self.update_new_svstate_steps()
1952 if pre:
1953 # reset at end of loop including exit Vertical Mode
1954 log("SVSTATE_NEXT: end of loop, reset")
1955 self.svp64_reset_loop()
1956 self.svstate.vfirst = 0
1957 self.update_nia()
1958 if not rc_en:
1959 return True
1960 results = [SelectableInt(0, 64)]
1961 self.handle_comparison(results) # CR0
1962 return True
1963 if self.allow_next_step_inc == 2:
1964 log("SVSTATE_NEXT: read")
1965 nia_update = (yield from self.svstate_post_inc(ins_name))
1966 else:
1967 log("SVSTATE_NEXT: post-inc")
1968 # use actual src/dst-step here to check end, do NOT
1969 # use bit-reversed version
1970 srcstep, dststep = self.new_srcstep, self.new_dststep
1971 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1972 remaps = self.get_remap_indices()
1973 remap_idxs = self.remap_idxs
1974 vl = self.svstate.vl
1975 subvl = yield self.dec2.rm_dec.rm_in.subvl
1976 end_src = srcstep == vl-1
1977 end_dst = dststep == vl-1
1978 if self.allow_next_step_inc != 2:
1979 yield from self.advance_svstate_steps(end_src, end_dst)
1980 #self.namespace['SVSTATE'] = self.svstate.spr
1981 # set CR0 (if Rc=1) based on end
1982 if rc_en:
1983 endtest = 1 if (end_src or end_dst) else 0
1984 #results = [SelectableInt(endtest, 64)]
1985 # self.handle_comparison(results) # CR0
1986
1987 # see if svstep was requested, if so, which SVSTATE
1988 endings = 0b111
1989 if self.svstate_next_mode > 0:
1990 shape_idx = self.svstate_next_mode.value-1
1991 endings = self.remap_loopends[shape_idx]
1992 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
1993 log("svstep Rc=1, CR0", cr_field)
1994 self.crl[0].eq(cr_field) # CR0
1995 if end_src or end_dst:
1996 # reset at end of loop including exit Vertical Mode
1997 log("SVSTATE_NEXT: after increments, reset")
1998 self.svp64_reset_loop()
1999 self.svstate.vfirst = 0
2000 return nia_update
2001
2002 def SVSTATE_NEXT(self, mode, submode):
2003 """explicitly moves srcstep/dststep on to next element, for
2004 "Vertical-First" mode. this function is called from
2005 setvl pseudo-code, as a pseudo-op "svstep"
2006
2007 WARNING: this function uses information that was created EARLIER
2008 due to it being in the middle of a yield, but this function is
2009 *NOT* called from yield (it's called from compiled pseudocode).
2010 """
2011 self.allow_next_step_inc = submode.value + 1
2012 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
2013 self.svstate_next_mode = mode
2014 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
2015 shape_idx = self.svstate_next_mode.value-1
2016 return SelectableInt(self.remap_idxs[shape_idx], 7)
2017 if self.svstate_next_mode == 5:
2018 self.svstate_next_mode = 0
2019 return SelectableInt(self.svstate.srcstep, 7)
2020 if self.svstate_next_mode == 6:
2021 self.svstate_next_mode = 0
2022 return SelectableInt(self.svstate.dststep, 7)
2023 return SelectableInt(0, 7)
2024
2025 def get_src_dststeps(self):
2026 """gets srcstep, dststep, and ssubstep, dsubstep
2027 """
2028 return (self.new_srcstep, self.new_dststep,
2029 self.new_ssubstep, self.new_dsubstep)
2030
2031 def update_new_svstate_steps(self):
2032 # note, do not get the bit-reversed srcstep here!
2033 srcstep, dststep = self.new_srcstep, self.new_dststep
2034 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
2035
2036 # update SVSTATE with new srcstep
2037 self.svstate.srcstep = srcstep
2038 self.svstate.dststep = dststep
2039 self.svstate.ssubstep = ssubstep
2040 self.svstate.dsubstep = dsubstep
2041 self.namespace['SVSTATE'] = self.svstate
2042 yield self.dec2.state.svstate.eq(self.svstate.value)
2043 yield Settle() # let decoder update
2044 srcstep = self.svstate.srcstep
2045 dststep = self.svstate.dststep
2046 ssubstep = self.svstate.ssubstep
2047 dsubstep = self.svstate.dsubstep
2048 pack = self.svstate.pack
2049 unpack = self.svstate.unpack
2050 vl = self.svstate.vl
2051 subvl = yield self.dec2.rm_dec.rm_in.subvl
2052 log(" srcstep", srcstep)
2053 log(" dststep", dststep)
2054 log(" pack", pack)
2055 log(" unpack", unpack)
2056 log(" ssubstep", ssubstep)
2057 log(" dsubstep", dsubstep)
2058 log(" vl", vl)
2059 log(" subvl", subvl)
2060
2061 # check if end reached (we let srcstep overrun, above)
2062 # nothing needs doing (TODO zeroing): just do next instruction
2063 return ((ssubstep == subvl and srcstep == vl) or
2064 (dsubstep == subvl and dststep == vl))
2065
2066 def svstate_post_inc(self, insn_name, vf=0):
2067 # check if SV "Vertical First" mode is enabled
2068 vfirst = self.svstate.vfirst
2069 log(" SV Vertical First", vf, vfirst)
2070 if not vf and vfirst == 1:
2071 self.update_nia()
2072 return True
2073
2074 # check if it is the SVSTATE.src/dest step that needs incrementing
2075 # this is our Sub-Program-Counter loop from 0 to VL-1
2076 # XXX twin predication TODO
2077 vl = self.svstate.vl
2078 subvl = yield self.dec2.rm_dec.rm_in.subvl
2079 mvl = self.svstate.maxvl
2080 srcstep = self.svstate.srcstep
2081 dststep = self.svstate.dststep
2082 ssubstep = self.svstate.ssubstep
2083 dsubstep = self.svstate.dsubstep
2084 pack = self.svstate.pack
2085 unpack = self.svstate.unpack
2086 rm_mode = yield self.dec2.rm_dec.mode
2087 reverse_gear = yield self.dec2.rm_dec.reverse_gear
2088 sv_ptype = yield self.dec2.dec.op.SV_Ptype
2089 out_vec = not (yield self.dec2.no_out_vec)
2090 in_vec = not (yield self.dec2.no_in_vec)
2091 log(" svstate.vl", vl)
2092 log(" svstate.mvl", mvl)
2093 log(" rm.subvl", subvl)
2094 log(" svstate.srcstep", srcstep)
2095 log(" svstate.dststep", dststep)
2096 log(" svstate.ssubstep", ssubstep)
2097 log(" svstate.dsubstep", dsubstep)
2098 log(" svstate.pack", pack)
2099 log(" svstate.unpack", unpack)
2100 log(" mode", rm_mode)
2101 log(" reverse", reverse_gear)
2102 log(" out_vec", out_vec)
2103 log(" in_vec", in_vec)
2104 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
2105 # check if this was an sv.bc* and if so did it succeed
2106 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
2107 end_loop = self.namespace['end_loop']
2108 log("branch %s end_loop" % insn_name, end_loop)
2109 if end_loop.value:
2110 self.svp64_reset_loop()
2111 self.update_pc_next()
2112 return False
2113 # check if srcstep needs incrementing by one, stop PC advancing
2114 # but for 2-pred both src/dest have to be checked.
2115 # XXX this might not be true! it may just be LD/ST
2116 if sv_ptype == SVPtype.P2.value:
2117 svp64_is_vector = (out_vec or in_vec)
2118 else:
2119 svp64_is_vector = out_vec
2120 # loops end at the first "hit" (source or dest)
2121 end_src = srcstep == vl-1
2122 end_dst = dststep == vl-1
2123 loopend = ((end_src and ssubstep == subvl) or
2124 (end_dst and dsubstep == subvl))
2125 log("loopend", svp64_is_vector, loopend, end_src, end_dst,
2126 ssubstep == subvl, dsubstep == subvl)
2127 if not svp64_is_vector or loopend:
2128 # reset loop to zero and update NIA
2129 self.svp64_reset_loop()
2130 self.update_nia()
2131
2132 return True
2133
2134 # still looping, advance and update NIA
2135 yield from self.advance_svstate_steps(end_src, end_dst)
2136 self.namespace['SVSTATE'] = self.svstate
2137
2138 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2139 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2140 # this way we keep repeating the same instruction (with new steps)
2141 self.pc.NIA.value = self.pc.CIA.value
2142 self.namespace['NIA'] = self.pc.NIA
2143 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
2144 return False # DO NOT allow PC update whilst Sub-PC loop running
2145
2146 def update_pc_next(self):
2147 # UPDATE program counter
2148 self.pc.update(self.namespace, self.is_svp64_mode)
2149 #self.svstate.spr = self.namespace['SVSTATE']
2150 log("end of call", self.namespace['CIA'],
2151 self.namespace['NIA'],
2152 self.namespace['SVSTATE'])
2153
2154 def svp64_reset_loop(self):
2155 self.svstate.srcstep = 0
2156 self.svstate.dststep = 0
2157 self.svstate.ssubstep = 0
2158 self.svstate.dsubstep = 0
2159 log(" svstate.srcstep loop end (PC to update)")
2160 self.namespace['SVSTATE'] = self.svstate
2161
2162 def update_nia(self):
2163 self.pc.update_nia(self.is_svp64_mode)
2164 self.namespace['NIA'] = self.pc.NIA
2165
2166
2167 def inject():
2168 """Decorator factory.
2169
2170 this decorator will "inject" variables into the function's namespace,
2171 from the *dictionary* in self.namespace. it therefore becomes possible
2172 to make it look like a whole stack of variables which would otherwise
2173 need "self." inserted in front of them (*and* for those variables to be
2174 added to the instance) "appear" in the function.
2175
2176 "self.namespace['SI']" for example becomes accessible as just "SI" but
2177 *only* inside the function, when decorated.
2178 """
2179 def variable_injector(func):
2180 @wraps(func)
2181 def decorator(*args, **kwargs):
2182 try:
2183 func_globals = func.__globals__ # Python 2.6+
2184 except AttributeError:
2185 func_globals = func.func_globals # Earlier versions.
2186
2187 context = args[0].namespace # variables to be injected
2188 saved_values = func_globals.copy() # Shallow copy of dict.
2189 log("globals before", context.keys())
2190 func_globals.update(context)
2191 result = func(*args, **kwargs)
2192 log("globals after", func_globals['CIA'], func_globals['NIA'])
2193 log("args[0]", args[0].namespace['CIA'],
2194 args[0].namespace['NIA'],
2195 args[0].namespace['SVSTATE'])
2196 if 'end_loop' in func_globals:
2197 log("args[0] end_loop", func_globals['end_loop'])
2198 args[0].namespace = func_globals
2199 #exec (func.__code__, func_globals)
2200
2201 # finally:
2202 # func_globals = saved_values # Undo changes.
2203
2204 return result
2205
2206 return decorator
2207
2208 return variable_injector