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