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