275be81fb1c86afc3612bb12662f3777a91f72f2
[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 self.spr[sname] = SVSHAPE(0)
655 else:
656 # make sure it's an SVSHAPE
657 val = self.spr[sname].value
658 self.spr[sname] = SVSHAPE(val)
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 log("TRAP:", hex(trap_addr), hex(self.namespace['MSR'].value))
745 # store CIA(+4?) in SRR0, set NIA to 0x700
746 # store MSR in SRR1, set MSR to um errr something, have to check spec
747 # store SVSTATE (if enabled) in SVSRR0
748 self.spr['SRR0'].value = self.pc.CIA.value
749 self.spr['SRR1'].value = self.namespace['MSR'].value
750 if self.is_svp64_mode:
751 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
752 self.trap_nia = SelectableInt(trap_addr, 64)
753 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
754
755 # set exception bits. TODO: this should, based on the address
756 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
757 # bits appropriately. however it turns out that *for now* in all
758 # cases (all trap_addrs) the exact same thing is needed.
759 self.msr[MSRb.IR] = 0
760 self.msr[MSRb.DR] = 0
761 self.msr[MSRb.FE0] = 0
762 self.msr[MSRb.FE1] = 0
763 self.msr[MSRb.EE] = 0
764 self.msr[MSRb.RI] = 0
765 self.msr[MSRb.SF] = 1
766 self.msr[MSRb.TM] = 0
767 self.msr[MSRb.VEC] = 0
768 self.msr[MSRb.VSX] = 0
769 self.msr[MSRb.PR] = 0
770 self.msr[MSRb.FP] = 0
771 self.msr[MSRb.PMM] = 0
772 self.msr[MSRb.TEs] = 0
773 self.msr[MSRb.TEe] = 0
774 self.msr[MSRb.UND] = 0
775 self.msr[MSRb.LE] = 1
776
777 def memassign(self, ea, sz, val):
778 self.mem.memassign(ea, sz, val)
779
780 def prep_namespace(self, insn_name, formname, op_fields):
781 # TODO: get field names from form in decoder*1* (not decoder2)
782 # decoder2 is hand-created, and decoder1.sigform is auto-generated
783 # from spec
784 # then "yield" fields only from op_fields rather than hard-coded
785 # list, here.
786 fields = self.decoder.sigforms[formname]
787 log("prep_namespace", formname, op_fields)
788 for name in op_fields:
789 # CR immediates. deal with separately. needs modifying
790 # pseudocode
791 if self.is_svp64_mode and name in ['BI']: # TODO, more CRs
792 # BI is a 5-bit, must reconstruct the value
793 regnum, is_vec = yield from get_pdecode_cr_in(self.dec2, name)
794 sig = getattr(fields, name)
795 val = yield sig
796 # low 2 LSBs (CR field selector) remain same, CR num extended
797 assert regnum <= 7, "sigh, TODO, 128 CR fields"
798 val = (val & 0b11) | (regnum << 2)
799 else:
800 if name == 'spr':
801 sig = getattr(fields, name.upper())
802 else:
803 sig = getattr(fields, name)
804 val = yield sig
805 # these are all opcode fields involved in index-selection of CR,
806 # and need to do "standard" arithmetic. CR[BA+32] for example
807 # would, if using SelectableInt, only be 5-bit.
808 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
809 self.namespace[name] = val
810 else:
811 self.namespace[name] = SelectableInt(val, sig.width)
812
813 self.namespace['XER'] = self.spr['XER']
814 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
815 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
816
817 # add some SVSTATE convenience variables
818 vl = self.svstate.vl
819 srcstep = self.svstate.srcstep
820 self.namespace['VL'] = vl
821 self.namespace['srcstep'] = srcstep
822
823 # sv.bc* need some extra fields
824 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
825 # blegh grab bits manually
826 mode = yield self.dec2.rm_dec.rm_in.mode
827 bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0
828 bc_vli = (mode & SVP64MODE.BC_VLI) != 0
829 bc_snz = (mode & SVP64MODE.BC_SNZ) != 0
830 bc_vsb = yield self.dec2.rm_dec.bc_vsb
831 bc_lru = yield self.dec2.rm_dec.bc_lru
832 bc_gate = yield self.dec2.rm_dec.bc_gate
833 sz = yield self.dec2.rm_dec.pred_sz
834 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
835 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
836 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
837 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
838 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
839 self.namespace['sz'] = SelectableInt(sz, 1)
840 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
841
842 def handle_carry_(self, inputs, outputs, already_done):
843 inv_a = yield self.dec2.e.do.invert_in
844 if inv_a:
845 inputs[0] = ~inputs[0]
846
847 imm_ok = yield self.dec2.e.do.imm_data.ok
848 if imm_ok:
849 imm = yield self.dec2.e.do.imm_data.data
850 inputs.append(SelectableInt(imm, 64))
851 assert len(outputs) >= 1
852 log("outputs", repr(outputs))
853 if isinstance(outputs, list) or isinstance(outputs, tuple):
854 output = outputs[0]
855 else:
856 output = outputs
857 gts = []
858 for x in inputs:
859 log("gt input", x, output)
860 gt = (gtu(x, output))
861 gts.append(gt)
862 log(gts)
863 cy = 1 if any(gts) else 0
864 log("CA", cy, gts)
865 if not (1 & already_done):
866 self.spr['XER'][XER_bits['CA']] = cy
867
868 log("inputs", already_done, inputs)
869 # 32 bit carry
870 # ARGH... different for OP_ADD... *sigh*...
871 op = yield self.dec2.e.do.insn_type
872 if op == MicrOp.OP_ADD.value:
873 res32 = (output.value & (1 << 32)) != 0
874 a32 = (inputs[0].value & (1 << 32)) != 0
875 if len(inputs) >= 2:
876 b32 = (inputs[1].value & (1 << 32)) != 0
877 else:
878 b32 = False
879 cy32 = res32 ^ a32 ^ b32
880 log("CA32 ADD", cy32)
881 else:
882 gts = []
883 for x in inputs:
884 log("input", x, output)
885 log(" x[32:64]", x, x[32:64])
886 log(" o[32:64]", output, output[32:64])
887 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
888 gts.append(gt)
889 cy32 = 1 if any(gts) else 0
890 log("CA32", cy32, gts)
891 if not (2 & already_done):
892 self.spr['XER'][XER_bits['CA32']] = cy32
893
894 def handle_overflow(self, inputs, outputs, div_overflow):
895 if hasattr(self.dec2.e.do, "invert_in"):
896 inv_a = yield self.dec2.e.do.invert_in
897 if inv_a:
898 inputs[0] = ~inputs[0]
899
900 imm_ok = yield self.dec2.e.do.imm_data.ok
901 if imm_ok:
902 imm = yield self.dec2.e.do.imm_data.data
903 inputs.append(SelectableInt(imm, 64))
904 assert len(outputs) >= 1
905 log("handle_overflow", inputs, outputs, div_overflow)
906 if len(inputs) < 2 and div_overflow is None:
907 return
908
909 # div overflow is different: it's returned by the pseudo-code
910 # because it's more complex than can be done by analysing the output
911 if div_overflow is not None:
912 ov, ov32 = div_overflow, div_overflow
913 # arithmetic overflow can be done by analysing the input and output
914 elif len(inputs) >= 2:
915 output = outputs[0]
916
917 # OV (64-bit)
918 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
919 output_sgn = exts(output.value, output.bits) < 0
920 ov = 1 if input_sgn[0] == input_sgn[1] and \
921 output_sgn != input_sgn[0] else 0
922
923 # OV (32-bit)
924 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
925 output32_sgn = exts(output.value, 32) < 0
926 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
927 output32_sgn != input32_sgn[0] else 0
928
929 self.spr['XER'][XER_bits['OV']] = ov
930 self.spr['XER'][XER_bits['OV32']] = ov32
931 so = self.spr['XER'][XER_bits['SO']]
932 so = so | ov
933 self.spr['XER'][XER_bits['SO']] = so
934
935 def handle_comparison(self, outputs, cr_idx=0):
936 out = outputs[0]
937 assert isinstance(out, SelectableInt), \
938 "out zero not a SelectableInt %s" % repr(outputs)
939 log("handle_comparison", out.bits, hex(out.value))
940 # TODO - XXX *processor* in 32-bit mode
941 # https://bugs.libre-soc.org/show_bug.cgi?id=424
942 # if is_32bit:
943 # o32 = exts(out.value, 32)
944 # print ("handle_comparison exts 32 bit", hex(o32))
945 out = exts(out.value, out.bits)
946 log("handle_comparison exts", hex(out))
947 zero = SelectableInt(out == 0, 1)
948 positive = SelectableInt(out > 0, 1)
949 negative = SelectableInt(out < 0, 1)
950 SO = self.spr['XER'][XER_bits['SO']]
951 log("handle_comparison SO", SO)
952 cr_field = selectconcat(negative, positive, zero, SO)
953 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
954 self.crl[cr_idx].eq(cr_field)
955
956 def set_pc(self, pc_val):
957 self.namespace['NIA'] = SelectableInt(pc_val, 64)
958 self.pc.update(self.namespace, self.is_svp64_mode)
959
960 def get_next_insn(self):
961 """check instruction
962 """
963 if self.respect_pc:
964 pc = self.pc.CIA.value
965 else:
966 pc = self.fake_pc
967 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
968 if ins is None:
969 raise KeyError("no instruction at 0x%x" % pc)
970 return pc, ins
971
972 def setup_one(self):
973 """set up one instruction
974 """
975 pc, insn = self.get_next_insn()
976 yield from self.setup_next_insn(pc, insn)
977
978 def setup_next_insn(self, pc, ins):
979 """set up next instruction
980 """
981 self._pc = pc
982 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
983 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
984
985 yield self.dec2.sv_rm.eq(0)
986 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
987 yield self.dec2.dec.bigendian.eq(self.bigendian)
988 yield self.dec2.state.msr.eq(self.msr.value)
989 yield self.dec2.state.pc.eq(pc)
990 if self.svstate is not None:
991 yield self.dec2.state.svstate.eq(self.svstate.value)
992
993 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
994 yield Settle()
995 opcode = yield self.dec2.dec.opcode_in
996 pfx = SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
997 pfx.insn.value = opcode
998 major = pfx.major.asint(msb0=True) # MSB0 inversion
999 log("prefix test: opcode:", major, bin(major),
1000 pfx.insn[7] == 0b1, pfx.insn[9] == 0b1)
1001 self.is_svp64_mode = ((major == 0b000001) and
1002 pfx.insn[7].value == 0b1 and
1003 pfx.insn[9].value == 0b1)
1004 self.pc.update_nia(self.is_svp64_mode)
1005 # set SVP64 decode
1006 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
1007 self.namespace['NIA'] = self.pc.NIA
1008 self.namespace['SVSTATE'] = self.svstate
1009 if not self.is_svp64_mode:
1010 return
1011
1012 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1013 log("svp64.rm", bin(pfx.rm.asint(msb0=True)))
1014 log(" svstate.vl", self.svstate.vl)
1015 log(" svstate.mvl", self.svstate.maxvl)
1016 sv_rm = pfx.rm.asint(msb0=True)
1017 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
1018 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
1019 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
1020 yield self.dec2.sv_rm.eq(sv_rm) # svp64 prefix
1021 yield Settle()
1022
1023 def execute_one(self):
1024 """execute one instruction
1025 """
1026 # get the disassembly code for this instruction
1027 if self.is_svp64_mode:
1028 if not self.disassembly:
1029 code = yield from self.get_assembly_name()
1030 else:
1031 code = self.disassembly[self._pc+4]
1032 log(" svp64 sim-execute", hex(self._pc), code)
1033 else:
1034 if not self.disassembly:
1035 code = yield from self.get_assembly_name()
1036 else:
1037 code = self.disassembly[self._pc]
1038 log("sim-execute", hex(self._pc), code)
1039 opname = code.split(' ')[0]
1040 try:
1041 yield from self.call(opname) # execute the instruction
1042 except MemException as e: # check for memory errors
1043 if e.args[0] == 'unaligned': # alignment error
1044 # run a Trap but set DAR first
1045 print("memory unaligned exception, DAR", e.dar)
1046 self.spr['DAR'] = SelectableInt(e.dar, 64)
1047 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1048 return
1049 elif e.args[0] == 'invalid': # invalid
1050 # run a Trap but set DAR first
1051 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1052 if e.mode == 'EXECUTE':
1053 # XXX TODO: must set a few bits in SRR1,
1054 # see microwatt loadstore1.vhdl
1055 # if m_in.segerr = '0' then
1056 # v.srr1(47 - 33) := m_in.invalid;
1057 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1058 # v.srr1(47 - 44) := m_in.badtree;
1059 # v.srr1(47 - 45) := m_in.rc_error;
1060 # v.intr_vec := 16#400#;
1061 # else
1062 # v.intr_vec := 16#480#;
1063 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1064 else:
1065 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1066 return
1067 # not supported yet:
1068 raise e # ... re-raise
1069
1070 # don't use this except in special circumstances
1071 if not self.respect_pc:
1072 self.fake_pc += 4
1073
1074 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1075 hex(self.pc.NIA.value))
1076
1077 def get_assembly_name(self):
1078 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1079 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1080 dec_insn = yield self.dec2.e.do.insn
1081 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1082 asmcode = yield self.dec2.dec.op.asmcode
1083 int_op = yield self.dec2.dec.op.internal_op
1084 log("get assembly name asmcode", asmcode, int_op,
1085 hex(dec_insn), bin(insn_1_11))
1086 asmop = insns.get(asmcode, None)
1087
1088 # sigh reconstruct the assembly instruction name
1089 if hasattr(self.dec2.e.do, "oe"):
1090 ov_en = yield self.dec2.e.do.oe.oe
1091 ov_ok = yield self.dec2.e.do.oe.ok
1092 else:
1093 ov_en = False
1094 ov_ok = False
1095 if hasattr(self.dec2.e.do, "rc"):
1096 rc_en = yield self.dec2.e.do.rc.rc
1097 rc_ok = yield self.dec2.e.do.rc.ok
1098 else:
1099 rc_en = False
1100 rc_ok = False
1101 # grrrr have to special-case MUL op (see DecodeOE)
1102 log("ov %d en %d rc %d en %d op %d" %
1103 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1104 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1105 log("mul op")
1106 if rc_en & rc_ok:
1107 asmop += "."
1108 else:
1109 if not asmop.endswith("."): # don't add "." to "andis."
1110 if rc_en & rc_ok:
1111 asmop += "."
1112 if hasattr(self.dec2.e.do, "lk"):
1113 lk = yield self.dec2.e.do.lk
1114 if lk:
1115 asmop += "l"
1116 log("int_op", int_op)
1117 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1118 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1119 log("AA", AA)
1120 if AA:
1121 asmop += "a"
1122 spr_msb = yield from self.get_spr_msb()
1123 if int_op == MicrOp.OP_MFCR.value:
1124 if spr_msb:
1125 asmop = 'mfocrf'
1126 else:
1127 asmop = 'mfcr'
1128 # XXX TODO: for whatever weird reason this doesn't work
1129 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1130 if int_op == MicrOp.OP_MTCRF.value:
1131 if spr_msb:
1132 asmop = 'mtocrf'
1133 else:
1134 asmop = 'mtcrf'
1135 return asmop
1136
1137 def get_remap_indices(self):
1138 """WARNING, this function stores remap_idxs and remap_loopends
1139 in the class for later use. this to avoid problems with yield
1140 """
1141 # go through all iterators in lock-step, advance to next remap_idx
1142 srcstep, dststep = self.get_src_dststeps()
1143 # get four SVSHAPEs. here we are hard-coding
1144 SVSHAPE0 = self.spr['SVSHAPE0']
1145 SVSHAPE1 = self.spr['SVSHAPE1']
1146 SVSHAPE2 = self.spr['SVSHAPE2']
1147 SVSHAPE3 = self.spr['SVSHAPE3']
1148 # set up the iterators
1149 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1150 (SVSHAPE1, SVSHAPE1.get_iterator()),
1151 (SVSHAPE2, SVSHAPE2.get_iterator()),
1152 (SVSHAPE3, SVSHAPE3.get_iterator()),
1153 ]
1154
1155 self.remap_loopends = [0] * 4
1156 self.remap_idxs = [0, 1, 2, 3]
1157 dbg = []
1158 for i, (shape, remap) in enumerate(remaps):
1159 # zero is "disabled"
1160 if shape.value == 0x0:
1161 self.remap_idxs[i] = 0
1162 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1163 step = dststep if (i in [3, 4]) else srcstep
1164 # this is terrible. O(N^2) looking for the match. but hey.
1165 for idx, (remap_idx, loopends) in enumerate(remap):
1166 if idx == step:
1167 break
1168 self.remap_idxs[i] = remap_idx
1169 self.remap_loopends[i] = loopends
1170 dbg.append((i, step, remap_idx, loopends))
1171 for (i, step, remap_idx, loopends) in dbg:
1172 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1173 return remaps
1174
1175 def get_spr_msb(self):
1176 dec_insn = yield self.dec2.e.do.insn
1177 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1178
1179 def call(self, name):
1180 """call(opcode) - the primary execution point for instructions
1181 """
1182 self.last_st_addr = None # reset the last known store address
1183 self.last_ld_addr = None # etc.
1184
1185 ins_name = name.strip() # remove spaces if not already done so
1186 if self.halted:
1187 log("halted - not executing", ins_name)
1188 return
1189
1190 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1191 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1192 asmop = yield from self.get_assembly_name()
1193 log("call", ins_name, asmop)
1194
1195 # check privileged
1196 int_op = yield self.dec2.dec.op.internal_op
1197 spr_msb = yield from self.get_spr_msb()
1198
1199 instr_is_privileged = False
1200 if int_op in [MicrOp.OP_ATTN.value,
1201 MicrOp.OP_MFMSR.value,
1202 MicrOp.OP_MTMSR.value,
1203 MicrOp.OP_MTMSRD.value,
1204 # TODO: OP_TLBIE
1205 MicrOp.OP_RFID.value]:
1206 instr_is_privileged = True
1207 if int_op in [MicrOp.OP_MFSPR.value,
1208 MicrOp.OP_MTSPR.value] and spr_msb:
1209 instr_is_privileged = True
1210
1211 log("is priv", instr_is_privileged, hex(self.msr.value),
1212 self.msr[MSRb.PR])
1213 # check MSR priv bit and whether op is privileged: if so, throw trap
1214 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1215 self.call_trap(0x700, PIb.PRIV)
1216 return
1217
1218 # check halted condition
1219 if ins_name == 'attn':
1220 self.halted = True
1221 return
1222
1223 # check illegal instruction
1224 illegal = False
1225 if ins_name not in ['mtcrf', 'mtocrf']:
1226 illegal = ins_name != asmop
1227
1228 # sigh deal with setvl not being supported by binutils (.long)
1229 if asmop.startswith('setvl'):
1230 illegal = False
1231 ins_name = 'setvl'
1232
1233 # and svstep not being supported by binutils (.long)
1234 if asmop.startswith('svstep'):
1235 illegal = False
1236 ins_name = 'svstep'
1237
1238 # and svremap not being supported by binutils (.long)
1239 if asmop.startswith('svremap'):
1240 illegal = False
1241 ins_name = 'svremap'
1242
1243 # and svshape not being supported by binutils (.long)
1244 if asmop.startswith('svshape'):
1245 illegal = False
1246 ins_name = 'svshape'
1247
1248 # and fsin and fcos
1249 if asmop == 'fsins':
1250 illegal = False
1251 ins_name = 'fsins'
1252 if asmop == 'fcoss':
1253 illegal = False
1254 ins_name = 'fcoss'
1255
1256 # sigh also deal with ffmadds not being supported by binutils (.long)
1257 if asmop == 'ffmadds':
1258 illegal = False
1259 ins_name = 'ffmadds'
1260
1261 # and fdmadds not being supported by binutils (.long)
1262 if asmop == 'fdmadds':
1263 illegal = False
1264 ins_name = 'fdmadds'
1265
1266 # and ffadds not being supported by binutils (.long)
1267 if asmop == 'ffadds':
1268 illegal = False
1269 ins_name = 'ffadds'
1270
1271 # and min/max/su
1272 if asmop in ['mins', 'maxs', 'minu', 'maxu',
1273 'mins.', 'maxs.', 'minu.', 'maxu.']:
1274 illegal = False
1275 ins_name = asmop
1276
1277 # and anything avgadd
1278 if asmop.startswith('avgadd'):
1279 illegal = False
1280 ins_name = asmop
1281
1282 # and anything absdu
1283 if asmop.startswith('absdu'):
1284 illegal = False
1285 ins_name = asmop
1286
1287 # and anything absds
1288 if asmop.startswith('absds'):
1289 illegal = False
1290 ins_name = asmop
1291
1292 # and anything absadd
1293 if asmop.startswith('absdac'):
1294 illegal = False
1295 ins_name = asmop
1296
1297 # and anything cprop
1298 if asmop.startswith('cprop'):
1299 illegal = False
1300 ins_name = asmop
1301
1302 # and anything ternlog
1303 if asmop.startswith('ternlog'):
1304 illegal = False
1305 ins_name = asmop
1306
1307 # and anything grev
1308 if asmop.startswith('grev'):
1309 illegal = False
1310 ins_name = asmop
1311
1312 # branch-conditional redirects to sv.bc
1313 if asmop.startswith('bc') and self.is_svp64_mode:
1314 ins_name = 'sv.%s' % ins_name
1315
1316 log(" post-processed name", ins_name, asmop)
1317
1318 # illegal instructions call TRAP at 0x700
1319 if illegal:
1320 print("illegal", ins_name, asmop)
1321 self.call_trap(0x700, PIb.ILLEG)
1322 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1323 (ins_name, asmop, self.pc.CIA.value))
1324 return
1325
1326 # this is for setvl "Vertical" mode: if set true,
1327 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1328 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1329 self.allow_next_step_inc = False
1330 self.svstate_next_mode = 0
1331
1332 # nop has to be supported, we could let the actual op calculate
1333 # but PowerDecoder has a pattern for nop
1334 if ins_name is 'nop':
1335 self.update_pc_next()
1336 return
1337
1338 # look up instruction in ISA.instrs, prepare namespace
1339 info = self.instrs[ins_name]
1340 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1341
1342 # preserve order of register names
1343 input_names = create_args(list(info.read_regs) +
1344 list(info.uninit_regs))
1345 log("input names", input_names)
1346
1347 # get SVP64 entry for the current instruction
1348 sv_rm = self.svp64rm.instrs.get(ins_name)
1349 if sv_rm is not None:
1350 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1351 else:
1352 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1353 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1354
1355 # see if srcstep/dststep need skipping over masked-out predicate bits
1356 if (self.is_svp64_mode or ins_name == 'setvl' or
1357 ins_name in ['svremap', 'svstate']):
1358 yield from self.svstate_pre_inc()
1359 if self.is_svp64_mode:
1360 pre = yield from self.update_new_svstate_steps()
1361 if pre:
1362 self.svp64_reset_loop()
1363 self.update_nia()
1364 self.update_pc_next()
1365 return
1366 srcstep, dststep = self.get_src_dststeps()
1367 pred_dst_zero = self.pred_dst_zero
1368 pred_src_zero = self.pred_src_zero
1369 vl = self.svstate.vl
1370
1371 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1372 if self.is_svp64_mode and vl == 0:
1373 self.pc.update(self.namespace, self.is_svp64_mode)
1374 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1375 self.namespace['NIA'])
1376 return
1377
1378 # for when SVREMAP is active, using pre-arranged schedule.
1379 # note: modifying PowerDecoder2 needs to "settle"
1380 remap_en = self.svstate.SVme
1381 persist = self.svstate.RMpst
1382 active = (persist or self.last_op_svshape) and remap_en != 0
1383 if self.is_svp64_mode:
1384 yield self.dec2.remap_active.eq(remap_en if active else 0)
1385 yield Settle()
1386 if persist or self.last_op_svshape:
1387 remaps = self.get_remap_indices()
1388 if self.is_svp64_mode and (persist or self.last_op_svshape):
1389 # just some convenient debug info
1390 for i in range(4):
1391 sname = 'SVSHAPE%d' % i
1392 shape = self.spr[sname]
1393 log(sname, bin(shape.value))
1394 log(" lims", shape.lims)
1395 log(" mode", shape.mode)
1396 log(" skip", shape.skip)
1397
1398 # set up the list of steps to remap
1399 mi0 = self.svstate.mi0
1400 mi1 = self.svstate.mi1
1401 mi2 = self.svstate.mi2
1402 mo0 = self.svstate.mo0
1403 mo1 = self.svstate.mo1
1404 steps = [(self.dec2.in1_step, mi0), # RA
1405 (self.dec2.in2_step, mi1), # RB
1406 (self.dec2.in3_step, mi2), # RC
1407 (self.dec2.o_step, mo0), # RT
1408 (self.dec2.o2_step, mo1), # EA
1409 ]
1410 remap_idxs = self.remap_idxs
1411 rremaps = []
1412 # now cross-index the required SHAPE for each of 3-in 2-out regs
1413 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1414 for i, (dstep, shape_idx) in enumerate(steps):
1415 (shape, remap) = remaps[shape_idx]
1416 remap_idx = remap_idxs[shape_idx]
1417 # zero is "disabled"
1418 if shape.value == 0x0:
1419 continue
1420 # now set the actual requested step to the current index
1421 yield dstep.eq(remap_idx)
1422
1423 # debug printout info
1424 rremaps.append((shape.mode, i, rnames[i], shape_idx,
1425 remap_idx))
1426 for x in rremaps:
1427 log("shape remap", x)
1428 # after that, settle down (combinatorial) to let Vector reg numbers
1429 # work themselves out
1430 yield Settle()
1431 if self.is_svp64_mode:
1432 remap_active = yield self.dec2.remap_active
1433 else:
1434 remap_active = False
1435 log("remap active", bin(remap_active))
1436
1437 # main input registers (RT, RA ...)
1438 inputs = []
1439 for name in input_names:
1440 # using PowerDecoder2, first, find the decoder index.
1441 # (mapping name RA RB RC RS to in1, in2, in3)
1442 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1443 if regnum is None:
1444 # doing this is not part of svp64, it's because output
1445 # registers, to be modified, need to be in the namespace.
1446 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1447 if regnum is None:
1448 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2,
1449 name)
1450
1451 # in case getting the register number is needed, _RA, _RB
1452 regname = "_" + name
1453 self.namespace[regname] = regnum
1454 if not self.is_svp64_mode or not pred_src_zero:
1455 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1456 if name in fregs:
1457 reg_val = SelectableInt(self.fpr(regnum))
1458 elif name is not None:
1459 reg_val = SelectableInt(self.gpr(regnum))
1460 else:
1461 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1462 reg_val = 0
1463 inputs.append(reg_val)
1464 # arrrrgh, awful hack, to get _RT into namespace
1465 if ins_name in ['setvl', 'svstep']:
1466 regname = "_RT"
1467 RT = yield self.dec2.dec.RT
1468 self.namespace[regname] = SelectableInt(RT, 5)
1469 if RT == 0:
1470 self.namespace["RT"] = SelectableInt(0, 5)
1471 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1472 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1473
1474 # in SVP64 mode for LD/ST work out immediate
1475 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1476 # use info.form to detect
1477 replace_d = False # update / replace constant in pseudocode
1478 if self.is_svp64_mode:
1479 ldstmode = yield self.dec2.rm_dec.ldstmode
1480 # shift mode reads SVD (or SVDS - TODO)
1481 # *BUT*... because this is "overloading" of LD operations,
1482 # it gets *STORED* into D (or DS, TODO)
1483 if ldstmode == SVP64LDSTmode.SHIFT.value:
1484 imm = yield self.dec2.dec.fields.FormSVD.SVD[0:11]
1485 imm = exts(imm, 11) # sign-extend to integer
1486 log("shift SVD", imm)
1487 replace_d = True
1488 else:
1489 if info.form == 'DS':
1490 # DS-Form, multiply by 4 then knock 2 bits off after
1491 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1492 else:
1493 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1494 imm = exts(imm, 16) # sign-extend to integer
1495 # get the right step. LD is from srcstep, ST is dststep
1496 op = yield self.dec2.e.do.insn_type
1497 offsmul = 0
1498 if op == MicrOp.OP_LOAD.value:
1499 if remap_active:
1500 offsmul = yield self.dec2.in1_step
1501 log("D-field REMAP src", imm, offsmul)
1502 else:
1503 offsmul = srcstep
1504 log("D-field src", imm, offsmul)
1505 elif op == MicrOp.OP_STORE.value:
1506 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1507 offsmul = dststep
1508 log("D-field dst", imm, offsmul)
1509 # bit-reverse mode, rev already done through get_src_dst_steps()
1510 if ldstmode == SVP64LDSTmode.SHIFT.value:
1511 # manually look up RC, sigh
1512 RC = yield self.dec2.dec.RC[0:5]
1513 RC = self.gpr(RC)
1514 log("LD-SHIFT:", "VL", vl,
1515 "RC", RC.value, "imm", imm,
1516 "offs", bin(offsmul),
1517 )
1518 imm = SelectableInt((imm * offsmul) << RC.value, 32)
1519 # Unit-Strided LD/ST adds offset*width to immediate
1520 elif ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1521 ldst_len = yield self.dec2.e.do.data_len
1522 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1523 replace_d = True
1524 # Element-strided multiplies the immediate by element step
1525 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1526 imm = SelectableInt(imm * offsmul, 32)
1527 replace_d = True
1528 if replace_d:
1529 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1530 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1531 log("LDSTmode", SVP64LDSTmode(ldstmode),
1532 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1533 # new replacement D... errr.. DS
1534 if replace_d:
1535 if info.form == 'DS':
1536 # TODO: assert 2 LSBs are zero?
1537 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1538 imm.value = imm.value >> 2
1539 self.namespace['DS'] = imm
1540 else:
1541 self.namespace['D'] = imm
1542
1543 # "special" registers
1544 for special in info.special_regs:
1545 if special in special_sprs:
1546 inputs.append(self.spr[special])
1547 else:
1548 inputs.append(self.namespace[special])
1549
1550 # clear trap (trap) NIA
1551 self.trap_nia = None
1552
1553 # check if this was an sv.bc* and create an indicator that
1554 # this is the last check to be made as a loop. combined with
1555 # the ALL/ANY mode we can early-exit
1556 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
1557 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
1558 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
1559 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
1560
1561 # execute actual instruction here (finally)
1562 log("inputs", inputs)
1563 results = info.func(self, *inputs)
1564 log("results", results)
1565
1566 # "inject" decorator takes namespace from function locals: we need to
1567 # overwrite NIA being overwritten (sigh)
1568 if self.trap_nia is not None:
1569 self.namespace['NIA'] = self.trap_nia
1570
1571 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1572
1573 # check if op was a LD/ST so that debugging can check the
1574 # address
1575 if int_op in [MicrOp.OP_STORE.value,
1576 ]:
1577 self.last_st_addr = self.mem.last_st_addr
1578 if int_op in [MicrOp.OP_LOAD.value,
1579 ]:
1580 self.last_ld_addr = self.mem.last_ld_addr
1581 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1582 self.last_st_addr, self.last_ld_addr)
1583
1584 # detect if CA/CA32 already in outputs (sra*, basically)
1585 already_done = 0
1586 if info.write_regs:
1587 output_names = create_args(info.write_regs)
1588 for name in output_names:
1589 if name == 'CA':
1590 already_done |= 1
1591 if name == 'CA32':
1592 already_done |= 2
1593
1594 log("carry already done?", bin(already_done))
1595 if hasattr(self.dec2.e.do, "output_carry"):
1596 carry_en = yield self.dec2.e.do.output_carry
1597 else:
1598 carry_en = False
1599 if carry_en:
1600 yield from self.handle_carry_(inputs, results, already_done)
1601
1602 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1603 # detect if overflow was in return result
1604 overflow = None
1605 if info.write_regs:
1606 for name, output in zip(output_names, results):
1607 if name == 'overflow':
1608 overflow = output
1609
1610 if hasattr(self.dec2.e.do, "oe"):
1611 ov_en = yield self.dec2.e.do.oe.oe
1612 ov_ok = yield self.dec2.e.do.oe.ok
1613 else:
1614 ov_en = False
1615 ov_ok = False
1616 log("internal overflow", overflow, ov_en, ov_ok)
1617 if ov_en & ov_ok:
1618 yield from self.handle_overflow(inputs, results, overflow)
1619
1620 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1621 rc_en = False
1622 if not self.is_svp64_mode or not pred_dst_zero:
1623 if hasattr(self.dec2.e.do, "rc"):
1624 rc_en = yield self.dec2.e.do.rc.rc
1625 if rc_en and ins_name not in ['svstep']:
1626 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1627 self.handle_comparison(results, regnum)
1628
1629 # any modified return results?
1630 if info.write_regs:
1631 for name, output in zip(output_names, results):
1632 if name == 'overflow': # ignore, done already (above)
1633 continue
1634 if isinstance(output, int):
1635 output = SelectableInt(output, 256)
1636 if name in ['CA', 'CA32']:
1637 if carry_en:
1638 log("writing %s to XER" % name, output)
1639 self.spr['XER'][XER_bits[name]] = output.value
1640 else:
1641 log("NOT writing %s to XER" % name, output)
1642 elif name in info.special_regs:
1643 log('writing special %s' % name, output, special_sprs)
1644 if name in special_sprs:
1645 self.spr[name] = output
1646 else:
1647 self.namespace[name].eq(output)
1648 if name == 'MSR':
1649 log('msr written', hex(self.msr.value))
1650 else:
1651 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2,
1652 name)
1653 if regnum is None:
1654 regnum, is_vec = yield from get_pdecode_idx_out2(
1655 self.dec2, name)
1656 if regnum is None:
1657 # temporary hack for not having 2nd output
1658 regnum = yield getattr(self.decoder, name)
1659 is_vec = False
1660 if self.is_svp64_mode and pred_dst_zero:
1661 log('zeroing reg %d %s' % (regnum, str(output)),
1662 is_vec)
1663 output = SelectableInt(0, 256)
1664 else:
1665 if name in fregs:
1666 ftype = 'fpr'
1667 else:
1668 ftype = 'gpr'
1669 log('writing %s %s %s' % (ftype, regnum, str(output)),
1670 is_vec)
1671 if output.bits > 64:
1672 output = SelectableInt(output.value, 64)
1673 if name in fregs:
1674 self.fpr[regnum] = output
1675 else:
1676 self.gpr[regnum] = output
1677
1678 # check if it is the SVSTATE.src/dest step that needs incrementing
1679 # this is our Sub-Program-Counter loop from 0 to VL-1
1680 pre = False
1681 post = False
1682 nia_update = True
1683 if self.allow_next_step_inc:
1684 log("SVSTATE_NEXT: inc requested, mode",
1685 self.svstate_next_mode, self.allow_next_step_inc)
1686 yield from self.svstate_pre_inc()
1687 pre = yield from self.update_new_svstate_steps()
1688 if pre:
1689 # reset at end of loop including exit Vertical Mode
1690 log("SVSTATE_NEXT: end of loop, reset")
1691 self.svp64_reset_loop()
1692 self.svstate.vfirst = 0
1693 self.update_nia()
1694 if rc_en:
1695 results = [SelectableInt(0, 64)]
1696 self.handle_comparison(results) # CR0
1697 else:
1698 if self.allow_next_step_inc == 2:
1699 log("SVSTATE_NEXT: read")
1700 nia_update = (yield from self.svstate_post_inc(ins_name))
1701 else:
1702 log("SVSTATE_NEXT: post-inc")
1703 # use actual src/dst-step here to check end, do NOT
1704 # use bit-reversed version
1705 srcstep, dststep = self.new_srcstep, self.new_dststep
1706 remaps = self.get_remap_indices()
1707 remap_idxs = self.remap_idxs
1708 vl = self.svstate.vl
1709 end_src = srcstep == vl-1
1710 end_dst = dststep == vl-1
1711 if self.allow_next_step_inc != 2:
1712 if not end_src:
1713 self.svstate.srcstep += SelectableInt(1, 7)
1714 if not end_dst:
1715 self.svstate.dststep += SelectableInt(1, 7)
1716 self.namespace['SVSTATE'] = self.svstate.spr
1717 # set CR0 (if Rc=1) based on end
1718 if rc_en:
1719 srcstep = self.svstate.srcstep
1720 dststep = self.svstate.srcstep
1721 endtest = 1 if (end_src or end_dst) else 0
1722 #results = [SelectableInt(endtest, 64)]
1723 # self.handle_comparison(results) # CR0
1724
1725 # see if svstep was requested, if so, which SVSTATE
1726 endings = 0b111
1727 if self.svstate_next_mode > 0:
1728 shape_idx = self.svstate_next_mode.value-1
1729 endings = self.remap_loopends[shape_idx]
1730 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
1731 print("svstep Rc=1, CR0", cr_field)
1732 self.crl[0].eq(cr_field) # CR0
1733 if end_src or end_dst:
1734 # reset at end of loop including exit Vertical Mode
1735 log("SVSTATE_NEXT: after increments, reset")
1736 self.svp64_reset_loop()
1737 self.svstate.vfirst = 0
1738
1739 elif self.is_svp64_mode:
1740 nia_update = (yield from self.svstate_post_inc(ins_name))
1741 else:
1742 # XXX only in non-SVP64 mode!
1743 # record state of whether the current operation was an svshape,
1744 # to be able to know if it should apply in the next instruction.
1745 # also (if going to use this instruction) should disable ability
1746 # to interrupt in between. sigh.
1747 self.last_op_svshape = asmop == 'svremap'
1748
1749 if nia_update:
1750 self.update_pc_next()
1751
1752 def SVSTATE_NEXT(self, mode, submode):
1753 """explicitly moves srcstep/dststep on to next element, for
1754 "Vertical-First" mode. this function is called from
1755 setvl pseudo-code, as a pseudo-op "svstep"
1756
1757 WARNING: this function uses information that was created EARLIER
1758 due to it being in the middle of a yield, but this function is
1759 *NOT* called from yield (it's called from compiled pseudocode).
1760 """
1761 self.allow_next_step_inc = submode.value + 1
1762 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
1763 self.svstate_next_mode = mode
1764 if self.svstate_next_mode > 0:
1765 shape_idx = self.svstate_next_mode.value-1
1766 return SelectableInt(self.remap_idxs[shape_idx], 7)
1767 return SelectableInt(0, 7)
1768
1769 def svstate_pre_inc(self):
1770 """check if srcstep/dststep need to skip over masked-out predicate bits
1771 """
1772 # get SVSTATE VL (oh and print out some debug stuff)
1773 vl = self.svstate.vl
1774 srcstep = self.svstate.srcstep
1775 dststep = self.svstate.dststep
1776 sv_a_nz = yield self.dec2.sv_a_nz
1777 fft_mode = yield self.dec2.use_svp64_fft
1778 in1 = yield self.dec2.e.read_reg1.data
1779 log("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft, svp64",
1780 vl, srcstep, dststep, sv_a_nz, in1, fft_mode,
1781 self.is_svp64_mode)
1782
1783 # get predicate mask (all 64 bits)
1784 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1785
1786 pmode = yield self.dec2.rm_dec.predmode
1787 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1788 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1789 srcpred = yield self.dec2.rm_dec.srcpred
1790 dstpred = yield self.dec2.rm_dec.dstpred
1791 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1792 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1793 if pmode == SVP64PredMode.INT.value:
1794 srcmask = dstmask = get_predint(self.gpr, dstpred)
1795 if sv_ptype == SVPtype.P2.value:
1796 srcmask = get_predint(self.gpr, srcpred)
1797 elif pmode == SVP64PredMode.CR.value:
1798 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1799 if sv_ptype == SVPtype.P2.value:
1800 srcmask = get_predcr(self.crl, srcpred, vl)
1801 log(" pmode", pmode)
1802 log(" reverse", reverse_gear)
1803 log(" ptype", sv_ptype)
1804 log(" srcpred", bin(srcpred))
1805 log(" dstpred", bin(dstpred))
1806 log(" srcmask", bin(srcmask))
1807 log(" dstmask", bin(dstmask))
1808 log(" pred_sz", bin(pred_src_zero))
1809 log(" pred_dz", bin(pred_dst_zero))
1810
1811 # okaaay, so here we simply advance srcstep (TODO dststep)
1812 # until the predicate mask has a "1" bit... or we run out of VL
1813 # let srcstep==VL be the indicator to move to next instruction
1814 if not pred_src_zero:
1815 while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl):
1816 log(" skip", bin(1 << srcstep))
1817 srcstep += 1
1818 # same for dststep
1819 if not pred_dst_zero:
1820 while (((1 << dststep) & dstmask) == 0) and (dststep != vl):
1821 log(" skip", bin(1 << dststep))
1822 dststep += 1
1823
1824 # now work out if the relevant mask bits require zeroing
1825 if pred_dst_zero:
1826 pred_dst_zero = ((1 << dststep) & dstmask) == 0
1827 if pred_src_zero:
1828 pred_src_zero = ((1 << srcstep) & srcmask) == 0
1829
1830 # store new srcstep / dststep
1831 self.new_srcstep, self.new_dststep = srcstep, dststep
1832 self.pred_dst_zero, self.pred_src_zero = pred_dst_zero, pred_src_zero
1833 log(" new srcstep", srcstep)
1834 log(" new dststep", dststep)
1835
1836 def get_src_dststeps(self):
1837 """gets srcstep and dststep
1838 """
1839 return self.new_srcstep, self.new_dststep
1840
1841 def update_new_svstate_steps(self):
1842 # note, do not get the bit-reversed srcstep here!
1843 srcstep, dststep = self.new_srcstep, self.new_dststep
1844
1845 # update SVSTATE with new srcstep
1846 self.svstate.srcstep = srcstep
1847 self.svstate.dststep = dststep
1848 self.namespace['SVSTATE'] = self.svstate
1849 yield self.dec2.state.svstate.eq(self.svstate.value)
1850 yield Settle() # let decoder update
1851 srcstep = self.svstate.srcstep
1852 dststep = self.svstate.dststep
1853 vl = self.svstate.vl
1854 log(" srcstep", srcstep)
1855 log(" dststep", dststep)
1856 log(" vl", vl)
1857
1858 # check if end reached (we let srcstep overrun, above)
1859 # nothing needs doing (TODO zeroing): just do next instruction
1860 return srcstep == vl or dststep == vl
1861
1862 def svstate_post_inc(self, insn_name, vf=0):
1863 # check if SV "Vertical First" mode is enabled
1864 vfirst = self.svstate.vfirst
1865 log(" SV Vertical First", vf, vfirst)
1866 if not vf and vfirst == 1:
1867 self.update_nia()
1868 return True
1869
1870 # check if it is the SVSTATE.src/dest step that needs incrementing
1871 # this is our Sub-Program-Counter loop from 0 to VL-1
1872 # XXX twin predication TODO
1873 vl = self.svstate.vl
1874 mvl = self.svstate.maxvl
1875 srcstep = self.svstate.srcstep
1876 dststep = self.svstate.dststep
1877 rm_mode = yield self.dec2.rm_dec.mode
1878 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1879 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1880 out_vec = not (yield self.dec2.no_out_vec)
1881 in_vec = not (yield self.dec2.no_in_vec)
1882 log(" svstate.vl", vl)
1883 log(" svstate.mvl", mvl)
1884 log(" svstate.srcstep", srcstep)
1885 log(" svstate.dststep", dststep)
1886 log(" mode", rm_mode)
1887 log(" reverse", reverse_gear)
1888 log(" out_vec", out_vec)
1889 log(" in_vec", in_vec)
1890 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1891 # check if srcstep needs incrementing by one, stop PC advancing
1892 # svp64 loop can end early if the dest is scalar for single-pred
1893 # but for 2-pred both src/dest have to be checked.
1894 # XXX this might not be true! it may just be LD/ST
1895 if sv_ptype == SVPtype.P2.value:
1896 svp64_is_vector = (out_vec or in_vec)
1897 else:
1898 svp64_is_vector = out_vec
1899 # check if this was an sv.bc* and if so did it succeed
1900 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1901 end_loop = self.namespace['end_loop']
1902 log("branch %s end_loop" % insn_name, end_loop)
1903 if end_loop.value:
1904 self.svp64_reset_loop()
1905 self.update_pc_next()
1906 return False
1907 if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
1908 self.svstate.srcstep += SelectableInt(1, 7)
1909 self.svstate.dststep += SelectableInt(1, 7)
1910 self.namespace['SVSTATE'] = self.svstate
1911 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1912 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1913 # this way we keep repeating the same instruction (with new steps)
1914 self.pc.NIA.value = self.pc.CIA.value
1915 self.namespace['NIA'] = self.pc.NIA
1916 log("end of sub-pc call", self.namespace['CIA'],
1917 self.namespace['NIA'])
1918 return False # DO NOT allow PC update whilst Sub-PC loop running
1919
1920 # reset loop to zero and update NIA
1921 self.svp64_reset_loop()
1922 self.update_nia()
1923
1924 return True
1925
1926 def update_pc_next(self):
1927 # UPDATE program counter
1928 self.pc.update(self.namespace, self.is_svp64_mode)
1929 self.svstate.spr = self.namespace['SVSTATE']
1930 log("end of call", self.namespace['CIA'],
1931 self.namespace['NIA'],
1932 self.namespace['SVSTATE'])
1933
1934 def svp64_reset_loop(self):
1935 self.svstate.srcstep = 0
1936 self.svstate.dststep = 0
1937 log(" svstate.srcstep loop end (PC to update)")
1938 self.namespace['SVSTATE'] = self.svstate
1939
1940 def update_nia(self):
1941 self.pc.update_nia(self.is_svp64_mode)
1942 self.namespace['NIA'] = self.pc.NIA
1943
1944
1945 def inject():
1946 """Decorator factory.
1947
1948 this decorator will "inject" variables into the function's namespace,
1949 from the *dictionary* in self.namespace. it therefore becomes possible
1950 to make it look like a whole stack of variables which would otherwise
1951 need "self." inserted in front of them (*and* for those variables to be
1952 added to the instance) "appear" in the function.
1953
1954 "self.namespace['SI']" for example becomes accessible as just "SI" but
1955 *only* inside the function, when decorated.
1956 """
1957 def variable_injector(func):
1958 @wraps(func)
1959 def decorator(*args, **kwargs):
1960 try:
1961 func_globals = func.__globals__ # Python 2.6+
1962 except AttributeError:
1963 func_globals = func.func_globals # Earlier versions.
1964
1965 context = args[0].namespace # variables to be injected
1966 saved_values = func_globals.copy() # Shallow copy of dict.
1967 log("globals before", context.keys())
1968 func_globals.update(context)
1969 result = func(*args, **kwargs)
1970 log("globals after", func_globals['CIA'], func_globals['NIA'])
1971 log("args[0]", args[0].namespace['CIA'],
1972 args[0].namespace['NIA'],
1973 args[0].namespace['SVSTATE'])
1974 if 'end_loop' in func_globals:
1975 log("args[0] end_loop", func_globals['end_loop'])
1976 args[0].namespace = func_globals
1977 #exec (func.__code__, func_globals)
1978
1979 # finally:
1980 # func_globals = saved_values # Undo changes.
1981
1982 return result
1983
1984 return decorator
1985
1986 return variable_injector