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