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