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