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