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