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