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