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