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