add fptrans support to isa caller
[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 if name == 'spr':
747 sig = getattr(fields, name.upper())
748 else:
749 sig = getattr(fields, name)
750 val = yield sig
751 # these are all opcode fields involved in index-selection of CR,
752 # and need to do "standard" arithmetic. CR[BA+32] for example
753 # would, if using SelectableInt, only be 5-bit.
754 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
755 self.namespace[name] = val
756 else:
757 self.namespace[name] = SelectableInt(val, sig.width)
758
759 self.namespace['XER'] = self.spr['XER']
760 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
761 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
762
763 # add some SVSTATE convenience variables
764 vl = self.svstate.vl
765 srcstep = self.svstate.srcstep
766 self.namespace['VL'] = vl
767 self.namespace['srcstep'] = srcstep
768
769 # sv.bc* need some extra fields
770 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
771 # blegh grab bits manually
772 mode = yield self.dec2.rm_dec.rm_in.mode
773 bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0
774 bc_vli = (mode & SVP64MODE.BC_VLI) != 0
775 bc_snz = (mode & SVP64MODE.BC_SNZ) != 0
776 bc_vsb = yield self.dec2.rm_dec.bc_vsb
777 bc_lru = yield self.dec2.rm_dec.bc_lru
778 bc_gate = yield self.dec2.rm_dec.bc_gate
779 sz = yield self.dec2.rm_dec.pred_sz
780 self.namespace['ALL'] = SelectableInt(bc_gate, 1)
781 self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
782 self.namespace['LRu'] = SelectableInt(bc_lru, 1)
783 self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
784 self.namespace['VLI'] = SelectableInt(bc_vli, 1)
785 self.namespace['sz'] = SelectableInt(sz, 1)
786 self.namespace['SNZ'] = SelectableInt(bc_snz, 1)
787
788 def handle_carry_(self, inputs, outputs, already_done):
789 inv_a = yield self.dec2.e.do.invert_in
790 if inv_a:
791 inputs[0] = ~inputs[0]
792
793 imm_ok = yield self.dec2.e.do.imm_data.ok
794 if imm_ok:
795 imm = yield self.dec2.e.do.imm_data.data
796 inputs.append(SelectableInt(imm, 64))
797 assert len(outputs) >= 1
798 log("outputs", repr(outputs))
799 if isinstance(outputs, list) or isinstance(outputs, tuple):
800 output = outputs[0]
801 else:
802 output = outputs
803 gts = []
804 for x in inputs:
805 log("gt input", x, output)
806 gt = (gtu(x, output))
807 gts.append(gt)
808 log(gts)
809 cy = 1 if any(gts) else 0
810 log("CA", cy, gts)
811 if not (1 & already_done):
812 self.spr['XER'][XER_bits['CA']] = cy
813
814 log("inputs", already_done, inputs)
815 # 32 bit carry
816 # ARGH... different for OP_ADD... *sigh*...
817 op = yield self.dec2.e.do.insn_type
818 if op == MicrOp.OP_ADD.value:
819 res32 = (output.value & (1 << 32)) != 0
820 a32 = (inputs[0].value & (1 << 32)) != 0
821 if len(inputs) >= 2:
822 b32 = (inputs[1].value & (1 << 32)) != 0
823 else:
824 b32 = False
825 cy32 = res32 ^ a32 ^ b32
826 log("CA32 ADD", cy32)
827 else:
828 gts = []
829 for x in inputs:
830 log("input", x, output)
831 log(" x[32:64]", x, x[32:64])
832 log(" o[32:64]", output, output[32:64])
833 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
834 gts.append(gt)
835 cy32 = 1 if any(gts) else 0
836 log("CA32", cy32, gts)
837 if not (2 & already_done):
838 self.spr['XER'][XER_bits['CA32']] = cy32
839
840 def handle_overflow(self, inputs, outputs, div_overflow):
841 if hasattr(self.dec2.e.do, "invert_in"):
842 inv_a = yield self.dec2.e.do.invert_in
843 if inv_a:
844 inputs[0] = ~inputs[0]
845
846 imm_ok = yield self.dec2.e.do.imm_data.ok
847 if imm_ok:
848 imm = yield self.dec2.e.do.imm_data.data
849 inputs.append(SelectableInt(imm, 64))
850 assert len(outputs) >= 1
851 log("handle_overflow", inputs, outputs, div_overflow)
852 if len(inputs) < 2 and div_overflow is None:
853 return
854
855 # div overflow is different: it's returned by the pseudo-code
856 # because it's more complex than can be done by analysing the output
857 if div_overflow is not None:
858 ov, ov32 = div_overflow, div_overflow
859 # arithmetic overflow can be done by analysing the input and output
860 elif len(inputs) >= 2:
861 output = outputs[0]
862
863 # OV (64-bit)
864 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
865 output_sgn = exts(output.value, output.bits) < 0
866 ov = 1 if input_sgn[0] == input_sgn[1] and \
867 output_sgn != input_sgn[0] else 0
868
869 # OV (32-bit)
870 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
871 output32_sgn = exts(output.value, 32) < 0
872 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
873 output32_sgn != input32_sgn[0] else 0
874
875 # now update XER OV/OV32/SO
876 so = self.spr['XER'][XER_bits['SO']]
877 new_so = so | ov # sticky overflow ORs in old with new
878 self.spr['XER'][XER_bits['OV']] = ov
879 self.spr['XER'][XER_bits['OV32']] = ov32
880 self.spr['XER'][XER_bits['SO']] = new_so
881 log(" set overflow", ov, ov32, so, new_so)
882
883 def handle_comparison(self, outputs, cr_idx=0, overflow=None, no_so=False):
884 out = outputs[0]
885 assert isinstance(out, SelectableInt), \
886 "out zero not a SelectableInt %s" % repr(outputs)
887 log("handle_comparison", out.bits, hex(out.value))
888 # TODO - XXX *processor* in 32-bit mode
889 # https://bugs.libre-soc.org/show_bug.cgi?id=424
890 # if is_32bit:
891 # o32 = exts(out.value, 32)
892 # print ("handle_comparison exts 32 bit", hex(o32))
893 out = exts(out.value, out.bits)
894 log("handle_comparison exts", hex(out))
895 # create the three main CR flags, EQ GT LT
896 zero = SelectableInt(out == 0, 1)
897 positive = SelectableInt(out > 0, 1)
898 negative = SelectableInt(out < 0, 1)
899 # get (or not) XER.SO. for setvl this is important *not* to read SO
900 if no_so:
901 SO = SelectableInt(1, 0)
902 else:
903 SO = self.spr['XER'][XER_bits['SO']]
904 log("handle_comparison SO overflow", SO, overflow)
905 # alternative overflow checking (setvl mainly at the moment)
906 if overflow is not None and overflow == 1:
907 SO = SelectableInt(1, 1)
908 # create the four CR field values and set the required CR field
909 cr_field = selectconcat(negative, positive, zero, SO)
910 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
911 self.crl[cr_idx].eq(cr_field)
912
913 def set_pc(self, pc_val):
914 self.namespace['NIA'] = SelectableInt(pc_val, 64)
915 self.pc.update(self.namespace, self.is_svp64_mode)
916
917 def get_next_insn(self):
918 """check instruction
919 """
920 if self.respect_pc:
921 pc = self.pc.CIA.value
922 else:
923 pc = self.fake_pc
924 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
925 if ins is None:
926 raise KeyError("no instruction at 0x%x" % pc)
927 return pc, ins
928
929 def setup_one(self):
930 """set up one instruction
931 """
932 pc, insn = self.get_next_insn()
933 yield from self.setup_next_insn(pc, insn)
934
935 def setup_next_insn(self, pc, ins):
936 """set up next instruction
937 """
938 self._pc = pc
939 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
940 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
941
942 yield self.dec2.sv_rm.eq(0)
943 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
944 yield self.dec2.dec.bigendian.eq(self.bigendian)
945 yield self.dec2.state.msr.eq(self.msr.value)
946 yield self.dec2.state.pc.eq(pc)
947 if self.svstate is not None:
948 yield self.dec2.state.svstate.eq(self.svstate.value)
949
950 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
951 yield Settle()
952 opcode = yield self.dec2.dec.opcode_in
953 opcode = SelectableInt(value=opcode, bits=32)
954 pfx = SVP64Instruction.Prefix(opcode)
955 log("prefix test: opcode:", pfx.po, bin(pfx.po), pfx.id)
956 self.is_svp64_mode = bool((pfx.po == 0b000001) and (pfx.id == 0b11))
957 self.pc.update_nia(self.is_svp64_mode)
958 # set SVP64 decode
959 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode)
960 self.namespace['NIA'] = self.pc.NIA
961 self.namespace['SVSTATE'] = self.svstate
962 if not self.is_svp64_mode:
963 return
964
965 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
966 log("svp64.rm", bin(pfx.rm))
967 log(" svstate.vl", self.svstate.vl)
968 log(" svstate.mvl", self.svstate.maxvl)
969 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
970 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
971 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
972 yield self.dec2.sv_rm.eq(int(pfx.rm)) # svp64 prefix
973 yield Settle()
974
975 def execute_one(self):
976 """execute one instruction
977 """
978 # get the disassembly code for this instruction
979 if self.is_svp64_mode:
980 if not self.disassembly:
981 code = yield from self.get_assembly_name()
982 else:
983 code = self.disassembly[self._pc+4]
984 log(" svp64 sim-execute", hex(self._pc), code)
985 else:
986 if not self.disassembly:
987 code = yield from self.get_assembly_name()
988 else:
989 code = self.disassembly[self._pc]
990 log("sim-execute", hex(self._pc), code)
991 opname = code.split(' ')[0]
992 try:
993 yield from self.call(opname) # execute the instruction
994 except MemException as e: # check for memory errors
995 if e.args[0] == 'unaligned': # alignment error
996 # run a Trap but set DAR first
997 print("memory unaligned exception, DAR", e.dar)
998 self.spr['DAR'] = SelectableInt(e.dar, 64)
999 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
1000 return
1001 elif e.args[0] == 'invalid': # invalid
1002 # run a Trap but set DAR first
1003 log("RADIX MMU memory invalid error, mode %s" % e.mode)
1004 if e.mode == 'EXECUTE':
1005 # XXX TODO: must set a few bits in SRR1,
1006 # see microwatt loadstore1.vhdl
1007 # if m_in.segerr = '0' then
1008 # v.srr1(47 - 33) := m_in.invalid;
1009 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1010 # v.srr1(47 - 44) := m_in.badtree;
1011 # v.srr1(47 - 45) := m_in.rc_error;
1012 # v.intr_vec := 16#400#;
1013 # else
1014 # v.intr_vec := 16#480#;
1015 self.call_trap(0x400, PIb.PRIV) # 0x400, privileged
1016 else:
1017 self.call_trap(0x300, PIb.PRIV) # 0x300, privileged
1018 return
1019 # not supported yet:
1020 raise e # ... re-raise
1021
1022 # don't use this except in special circumstances
1023 if not self.respect_pc:
1024 self.fake_pc += 4
1025
1026 log("execute one, CIA NIA", hex(self.pc.CIA.value),
1027 hex(self.pc.NIA.value))
1028
1029 def get_assembly_name(self):
1030 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1031 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1032 dec_insn = yield self.dec2.e.do.insn
1033 insn_1_11 = yield self.dec2.e.do.insn[1:11]
1034 asmcode = yield self.dec2.dec.op.asmcode
1035 int_op = yield self.dec2.dec.op.internal_op
1036 log("get assembly name asmcode", asmcode, int_op,
1037 hex(dec_insn), bin(insn_1_11))
1038 asmop = insns.get(asmcode, None)
1039
1040 # sigh reconstruct the assembly instruction name
1041 if hasattr(self.dec2.e.do, "oe"):
1042 ov_en = yield self.dec2.e.do.oe.oe
1043 ov_ok = yield self.dec2.e.do.oe.ok
1044 else:
1045 ov_en = False
1046 ov_ok = False
1047 if hasattr(self.dec2.e.do, "rc"):
1048 rc_en = yield self.dec2.e.do.rc.rc
1049 rc_ok = yield self.dec2.e.do.rc.ok
1050 else:
1051 rc_en = False
1052 rc_ok = False
1053 # grrrr have to special-case MUL op (see DecodeOE)
1054 log("ov %d en %d rc %d en %d op %d" %
1055 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1056 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1057 log("mul op")
1058 if rc_en & rc_ok:
1059 asmop += "."
1060 else:
1061 if not asmop.endswith("."): # don't add "." to "andis."
1062 if rc_en & rc_ok:
1063 asmop += "."
1064 if hasattr(self.dec2.e.do, "lk"):
1065 lk = yield self.dec2.e.do.lk
1066 if lk:
1067 asmop += "l"
1068 log("int_op", int_op)
1069 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1070 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1071 log("AA", AA)
1072 if AA:
1073 asmop += "a"
1074 spr_msb = yield from self.get_spr_msb()
1075 if int_op == MicrOp.OP_MFCR.value:
1076 if spr_msb:
1077 asmop = 'mfocrf'
1078 else:
1079 asmop = 'mfcr'
1080 # XXX TODO: for whatever weird reason this doesn't work
1081 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1082 if int_op == MicrOp.OP_MTCRF.value:
1083 if spr_msb:
1084 asmop = 'mtocrf'
1085 else:
1086 asmop = 'mtcrf'
1087 return asmop
1088
1089 def get_remap_indices(self):
1090 """WARNING, this function stores remap_idxs and remap_loopends
1091 in the class for later use. this to avoid problems with yield
1092 """
1093 # go through all iterators in lock-step, advance to next remap_idx
1094 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1095 # get four SVSHAPEs. here we are hard-coding
1096 SVSHAPE0 = self.spr['SVSHAPE0']
1097 SVSHAPE1 = self.spr['SVSHAPE1']
1098 SVSHAPE2 = self.spr['SVSHAPE2']
1099 SVSHAPE3 = self.spr['SVSHAPE3']
1100 # set up the iterators
1101 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1102 (SVSHAPE1, SVSHAPE1.get_iterator()),
1103 (SVSHAPE2, SVSHAPE2.get_iterator()),
1104 (SVSHAPE3, SVSHAPE3.get_iterator()),
1105 ]
1106
1107 self.remap_loopends = [0] * 4
1108 self.remap_idxs = [0, 1, 2, 3]
1109 dbg = []
1110 for i, (shape, remap) in enumerate(remaps):
1111 # zero is "disabled"
1112 if shape.value == 0x0:
1113 self.remap_idxs[i] = 0
1114 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1115 step = dststep if (i in [3, 4]) else srcstep
1116 # this is terrible. O(N^2) looking for the match. but hey.
1117 for idx, (remap_idx, loopends) in enumerate(remap):
1118 if idx == step:
1119 break
1120 self.remap_idxs[i] = remap_idx
1121 self.remap_loopends[i] = loopends
1122 dbg.append((i, step, remap_idx, loopends))
1123 for (i, step, remap_idx, loopends) in dbg:
1124 log("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1125 return remaps
1126
1127 def get_spr_msb(self):
1128 dec_insn = yield self.dec2.e.do.insn
1129 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1130
1131 def call(self, name):
1132 """call(opcode) - the primary execution point for instructions
1133 """
1134 self.last_st_addr = None # reset the last known store address
1135 self.last_ld_addr = None # etc.
1136
1137 ins_name = name.strip() # remove spaces if not already done so
1138 if self.halted:
1139 log("halted - not executing", ins_name)
1140 return
1141
1142 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1143 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1144 asmop = yield from self.get_assembly_name()
1145 log("call", ins_name, asmop)
1146
1147 # check privileged
1148 int_op = yield self.dec2.dec.op.internal_op
1149 spr_msb = yield from self.get_spr_msb()
1150
1151 instr_is_privileged = False
1152 if int_op in [MicrOp.OP_ATTN.value,
1153 MicrOp.OP_MFMSR.value,
1154 MicrOp.OP_MTMSR.value,
1155 MicrOp.OP_MTMSRD.value,
1156 # TODO: OP_TLBIE
1157 MicrOp.OP_RFID.value]:
1158 instr_is_privileged = True
1159 if int_op in [MicrOp.OP_MFSPR.value,
1160 MicrOp.OP_MTSPR.value] and spr_msb:
1161 instr_is_privileged = True
1162
1163 log("is priv", instr_is_privileged, hex(self.msr.value),
1164 self.msr[MSRb.PR])
1165 # check MSR priv bit and whether op is privileged: if so, throw trap
1166 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1167 self.call_trap(0x700, PIb.PRIV)
1168 return
1169
1170 # check halted condition
1171 if ins_name == 'attn':
1172 self.halted = True
1173 return
1174
1175 # check illegal instruction
1176 illegal = False
1177 if ins_name not in ['mtcrf', 'mtocrf']:
1178 illegal = ins_name != asmop
1179
1180 # list of instructions not being supported by binutils (.long)
1181 dotstrp = asmop[:-1] if asmop[-1] == '.' else asmop
1182 if dotstrp in [*FPTRANS_INSNS,
1183 'ffmadds', 'fdmadds', 'ffadds',
1184 'mins', 'maxs', 'minu', 'maxu',
1185 'setvl', 'svindex', 'svremap', 'svstep',
1186 'svshape', 'svshape2',
1187 'grev', 'ternlogi', 'bmask', 'cprop',
1188 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1189 'fmvis', 'fishmv',
1190 ]:
1191 illegal = False
1192 ins_name = dotstrp
1193
1194 # branch-conditional redirects to sv.bc
1195 if asmop.startswith('bc') and self.is_svp64_mode:
1196 ins_name = 'sv.%s' % ins_name
1197
1198 log(" post-processed name", dotstrp, ins_name, asmop)
1199
1200 # illegal instructions call TRAP at 0x700
1201 if illegal:
1202 print("illegal", ins_name, asmop)
1203 self.call_trap(0x700, PIb.ILLEG)
1204 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1205 (ins_name, asmop, self.pc.CIA.value))
1206 return
1207
1208 # this is for setvl "Vertical" mode: if set true,
1209 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1210 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1211 self.allow_next_step_inc = False
1212 self.svstate_next_mode = 0
1213
1214 # nop has to be supported, we could let the actual op calculate
1215 # but PowerDecoder has a pattern for nop
1216 if ins_name == 'nop':
1217 self.update_pc_next()
1218 return
1219
1220 # look up instruction in ISA.instrs, prepare namespace
1221 info = self.instrs[ins_name]
1222 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1223
1224 # preserve order of register names
1225 input_names = create_args(list(info.read_regs) +
1226 list(info.uninit_regs))
1227 log("input names", input_names)
1228
1229 # get SVP64 entry for the current instruction
1230 sv_rm = self.svp64rm.instrs.get(ins_name)
1231 if sv_rm is not None:
1232 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1233 else:
1234 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1235 log("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1236
1237 # see if srcstep/dststep need skipping over masked-out predicate bits
1238 if (self.is_svp64_mode or ins_name == 'setvl' or
1239 ins_name in ['svremap', 'svstate']):
1240 yield from self.svstate_pre_inc()
1241 if self.is_svp64_mode:
1242 pre = yield from self.update_new_svstate_steps()
1243 if pre:
1244 self.svp64_reset_loop()
1245 self.update_nia()
1246 self.update_pc_next()
1247 return
1248 srcstep, dststep, ssubstep, dsubstep = self.get_src_dststeps()
1249 pred_dst_zero = self.pred_dst_zero
1250 pred_src_zero = self.pred_src_zero
1251 vl = self.svstate.vl
1252 subvl = yield self.dec2.rm_dec.rm_in.subvl
1253
1254 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1255 if self.is_svp64_mode and vl == 0:
1256 self.pc.update(self.namespace, self.is_svp64_mode)
1257 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1258 self.namespace['NIA'], kind=LogKind.InstrInOuts)
1259 return
1260
1261 # for when SVREMAP is active, using pre-arranged schedule.
1262 # note: modifying PowerDecoder2 needs to "settle"
1263 remap_en = self.svstate.SVme
1264 persist = self.svstate.RMpst
1265 active = (persist or self.last_op_svshape) and remap_en != 0
1266 if self.is_svp64_mode:
1267 yield self.dec2.remap_active.eq(remap_en if active else 0)
1268 yield Settle()
1269 if persist or self.last_op_svshape:
1270 remaps = self.get_remap_indices()
1271 if self.is_svp64_mode and (persist or self.last_op_svshape):
1272 yield from self.remap_set_steps(remaps)
1273 # after that, settle down (combinatorial) to let Vector reg numbers
1274 # work themselves out
1275 yield Settle()
1276 if self.is_svp64_mode:
1277 remap_active = yield self.dec2.remap_active
1278 else:
1279 remap_active = False
1280 log("remap active", bin(remap_active))
1281
1282 # main input registers (RT, RA ...)
1283 inputs = []
1284 for name in input_names:
1285 log("name", name)
1286 regval = (yield from self.get_input(name))
1287 log("regval", regval)
1288 inputs.append(regval)
1289
1290 # arrrrgh, awful hack, to get _RT into namespace
1291 if ins_name in ['setvl', 'svstep']:
1292 regname = "_RT"
1293 RT = yield self.dec2.dec.RT
1294 self.namespace[regname] = SelectableInt(RT, 5)
1295 if RT == 0:
1296 self.namespace["RT"] = SelectableInt(0, 5)
1297 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1298 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1299
1300 # in SVP64 mode for LD/ST work out immediate
1301 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1302 # use info.form to detect
1303 if self.is_svp64_mode:
1304 yield from self.check_replace_d(info, remap_active)
1305
1306 # "special" registers
1307 for special in info.special_regs:
1308 if special in special_sprs:
1309 inputs.append(self.spr[special])
1310 else:
1311 inputs.append(self.namespace[special])
1312
1313 # clear trap (trap) NIA
1314 self.trap_nia = None
1315
1316 # check if this was an sv.bc* and create an indicator that
1317 # this is the last check to be made as a loop. combined with
1318 # the ALL/ANY mode we can early-exit
1319 if self.is_svp64_mode and ins_name.startswith("sv.bc"):
1320 no_in_vec = yield self.dec2.no_in_vec # BI is scalar
1321 # XXX TODO - pack/unpack here
1322 end_loop = no_in_vec or srcstep == vl-1 or dststep == vl-1
1323 self.namespace['end_loop'] = SelectableInt(end_loop, 1)
1324
1325 # execute actual instruction here (finally)
1326 log("inputs", inputs)
1327 results = info.func(self, *inputs)
1328 log("results", results)
1329
1330 # "inject" decorator takes namespace from function locals: we need to
1331 # overwrite NIA being overwritten (sigh)
1332 if self.trap_nia is not None:
1333 self.namespace['NIA'] = self.trap_nia
1334
1335 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1336
1337 # check if op was a LD/ST so that debugging can check the
1338 # address
1339 if int_op in [MicrOp.OP_STORE.value,
1340 ]:
1341 self.last_st_addr = self.mem.last_st_addr
1342 if int_op in [MicrOp.OP_LOAD.value,
1343 ]:
1344 self.last_ld_addr = self.mem.last_ld_addr
1345 log("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1346 self.last_st_addr, self.last_ld_addr)
1347
1348 # detect if CA/CA32 already in outputs (sra*, basically)
1349 already_done = 0
1350 if info.write_regs:
1351 output_names = create_args(info.write_regs)
1352 for name in output_names:
1353 if name == 'CA':
1354 already_done |= 1
1355 if name == 'CA32':
1356 already_done |= 2
1357
1358 log("carry already done?", bin(already_done))
1359 if hasattr(self.dec2.e.do, "output_carry"):
1360 carry_en = yield self.dec2.e.do.output_carry
1361 else:
1362 carry_en = False
1363 if carry_en:
1364 yield from self.handle_carry_(inputs, results, already_done)
1365
1366 # check if one of the regs was named "overflow"
1367 overflow = None
1368 if info.write_regs:
1369 for name, output in zip(output_names, results):
1370 if name == 'overflow':
1371 overflow = output
1372
1373 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1374 # detect if overflow was in return result
1375 if hasattr(self.dec2.e.do, "oe"):
1376 ov_en = yield self.dec2.e.do.oe.oe
1377 ov_ok = yield self.dec2.e.do.oe.ok
1378 else:
1379 ov_en = False
1380 ov_ok = False
1381 log("internal overflow", ins_name, overflow, "en?", ov_en, ov_ok)
1382 if ov_en & ov_ok:
1383 yield from self.handle_overflow(inputs, results, overflow)
1384
1385 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1386 rc_en = False
1387 if not self.is_svp64_mode or not pred_dst_zero:
1388 if hasattr(self.dec2.e.do, "rc"):
1389 rc_en = yield self.dec2.e.do.rc.rc
1390 if rc_en and ins_name not in ['svstep']:
1391 if ins_name.startswith("f"):
1392 rc_reg = "CR1" # not calculated correctly yet (not FP compares)
1393 else:
1394 rc_reg = "CR0"
1395 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, rc_reg)
1396 cmps = results
1397 # hang on... for `setvl` actually you want to test SVSTATE.VL
1398 is_setvl = ins_name == 'setvl'
1399 if is_setvl:
1400 vl = results[0].vl
1401 cmps = (SelectableInt(vl, 64), overflow,)
1402 else:
1403 overflow = None # do not override overflow except in setvl
1404 self.handle_comparison(cmps, regnum, overflow, no_so=is_setvl)
1405
1406 # any modified return results?
1407 if info.write_regs:
1408 for name, output in zip(output_names, results):
1409 yield from self.check_write(info, name, output, carry_en)
1410
1411 nia_update = (yield from self.check_step_increment(results, rc_en,
1412 asmop, ins_name))
1413 if nia_update:
1414 self.update_pc_next()
1415
1416 def check_replace_d(self, info, remap_active):
1417 replace_d = False # update / replace constant in pseudocode
1418 ldstmode = yield self.dec2.rm_dec.ldstmode
1419 vl = self.svstate.vl
1420 subvl = yield self.dec2.rm_dec.rm_in.subvl
1421 srcstep, dststep = self.new_srcstep, self.new_dststep
1422 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1423 if info.form == 'DS':
1424 # DS-Form, multiply by 4 then knock 2 bits off after
1425 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1426 else:
1427 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1428 imm = exts(imm, 16) # sign-extend to integer
1429 # get the right step. LD is from srcstep, ST is dststep
1430 op = yield self.dec2.e.do.insn_type
1431 offsmul = 0
1432 if op == MicrOp.OP_LOAD.value:
1433 if remap_active:
1434 offsmul = yield self.dec2.in1_step
1435 log("D-field REMAP src", imm, offsmul)
1436 else:
1437 offsmul = (srcstep * (subvl+1)) + ssubstep
1438 log("D-field src", imm, offsmul)
1439 elif op == MicrOp.OP_STORE.value:
1440 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1441 offsmul = (dststep * (subvl+1)) + dsubstep
1442 log("D-field dst", imm, offsmul)
1443 # Unit-Strided LD/ST adds offset*width to immediate
1444 if ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1445 ldst_len = yield self.dec2.e.do.data_len
1446 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1447 replace_d = True
1448 # Element-strided multiplies the immediate by element step
1449 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1450 imm = SelectableInt(imm * offsmul, 32)
1451 replace_d = True
1452 if replace_d:
1453 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1454 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1455 log("LDSTmode", SVP64LDSTmode(ldstmode),
1456 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1457 # new replacement D... errr.. DS
1458 if replace_d:
1459 if info.form == 'DS':
1460 # TODO: assert 2 LSBs are zero?
1461 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1462 imm.value = imm.value >> 2
1463 self.namespace['DS'] = imm
1464 else:
1465 self.namespace['D'] = imm
1466
1467 def get_input(self, name):
1468 # using PowerDecoder2, first, find the decoder index.
1469 # (mapping name RA RB RC RS to in1, in2, in3)
1470 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1471 if regnum is None:
1472 # doing this is not part of svp64, it's because output
1473 # registers, to be modified, need to be in the namespace.
1474 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1475 if regnum is None:
1476 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2, name)
1477
1478 # in case getting the register number is needed, _RA, _RB
1479 regname = "_" + name
1480 self.namespace[regname] = regnum
1481 if not self.is_svp64_mode or not self.pred_src_zero:
1482 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1483 if name in fregs:
1484 reg_val = SelectableInt(self.fpr(regnum))
1485 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1486 elif name is not None:
1487 reg_val = SelectableInt(self.gpr(regnum))
1488 log("read reg %d: 0x%x" % (regnum, reg_val.value))
1489 else:
1490 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1491 reg_val = 0
1492 return reg_val
1493
1494 def remap_set_steps(self, remaps):
1495 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
1496 they work in concert with PowerDecoder2 at the moment,
1497 there is no HDL implementation of REMAP. therefore this
1498 function, because ISACaller still uses PowerDecoder2,
1499 will *explicitly* write the dec2.XX_step values. this has
1500 to get sorted out.
1501 """
1502 # just some convenient debug info
1503 for i in range(4):
1504 sname = 'SVSHAPE%d' % i
1505 shape = self.spr[sname]
1506 log(sname, bin(shape.value))
1507 log(" lims", shape.lims)
1508 log(" mode", shape.mode)
1509 log(" skip", shape.skip)
1510
1511 # set up the list of steps to remap
1512 mi0 = self.svstate.mi0
1513 mi1 = self.svstate.mi1
1514 mi2 = self.svstate.mi2
1515 mo0 = self.svstate.mo0
1516 mo1 = self.svstate.mo1
1517 steps = [(self.dec2.in1_step, mi0), # RA
1518 (self.dec2.in2_step, mi1), # RB
1519 (self.dec2.in3_step, mi2), # RC
1520 (self.dec2.o_step, mo0), # RT
1521 (self.dec2.o2_step, mo1), # EA
1522 ]
1523 remap_idxs = self.remap_idxs
1524 rremaps = []
1525 # now cross-index the required SHAPE for each of 3-in 2-out regs
1526 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1527 for i, (dstep, shape_idx) in enumerate(steps):
1528 (shape, remap) = remaps[shape_idx]
1529 remap_idx = remap_idxs[shape_idx]
1530 # zero is "disabled"
1531 if shape.value == 0x0:
1532 continue
1533 # now set the actual requested step to the current index
1534 yield dstep.eq(remap_idx)
1535
1536 # debug printout info
1537 rremaps.append((shape.mode, i, rnames[i], shape_idx, remap_idx))
1538 for x in rremaps:
1539 log("shape remap", x)
1540
1541 def check_write(self, info, name, output, carry_en):
1542 if name == 'overflow': # ignore, done already (above)
1543 return
1544 if isinstance(output, int):
1545 output = SelectableInt(output, 256)
1546 if name in ['CA', 'CA32']:
1547 if carry_en:
1548 log("writing %s to XER" % name, output)
1549 log("write XER %s 0x%x" % (name, output.value))
1550 self.spr['XER'][XER_bits[name]] = output.value
1551 else:
1552 log("NOT writing %s to XER" % name, output)
1553 elif name in info.special_regs:
1554 log('writing special %s' % name, output, special_sprs)
1555 log("write reg %s 0x%x" % (name, output.value))
1556 if name in special_sprs:
1557 self.spr[name] = output
1558 else:
1559 self.namespace[name].eq(output)
1560 if name == 'MSR':
1561 log('msr written', hex(self.msr.value))
1562 else:
1563 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1564 if regnum is None:
1565 regnum, is_vec = yield from get_pdecode_idx_out2(
1566 self.dec2, name)
1567 if regnum is None:
1568 # temporary hack for not having 2nd output
1569 regnum = yield getattr(self.decoder, name)
1570 is_vec = False
1571 if self.is_svp64_mode and self.pred_dst_zero:
1572 log('zeroing reg %d %s' % (regnum, str(output)),
1573 is_vec)
1574 output = SelectableInt(0, 256)
1575 else:
1576 if name in fregs:
1577 reg_prefix = 'f'
1578 else:
1579 reg_prefix = 'r'
1580 log("write reg %s%d %0xx" % (reg_prefix, regnum, output.value))
1581 if output.bits > 64:
1582 output = SelectableInt(output.value, 64)
1583 if name in fregs:
1584 self.fpr[regnum] = output
1585 else:
1586 self.gpr[regnum] = output
1587
1588 def check_step_increment(self, results, rc_en, asmop, ins_name):
1589 # check if it is the SVSTATE.src/dest step that needs incrementing
1590 # this is our Sub-Program-Counter loop from 0 to VL-1
1591 pre = False
1592 post = False
1593 nia_update = True
1594 if self.allow_next_step_inc:
1595 log("SVSTATE_NEXT: inc requested, mode",
1596 self.svstate_next_mode, self.allow_next_step_inc)
1597 yield from self.svstate_pre_inc()
1598 pre = yield from self.update_new_svstate_steps()
1599 if pre:
1600 # reset at end of loop including exit Vertical Mode
1601 log("SVSTATE_NEXT: end of loop, reset")
1602 self.svp64_reset_loop()
1603 self.svstate.vfirst = 0
1604 self.update_nia()
1605 if not rc_en:
1606 return True
1607 results = [SelectableInt(0, 64)]
1608 self.handle_comparison(results) # CR0
1609 return True
1610 if self.allow_next_step_inc == 2:
1611 log("SVSTATE_NEXT: read")
1612 nia_update = (yield from self.svstate_post_inc(ins_name))
1613 else:
1614 log("SVSTATE_NEXT: post-inc")
1615 # use actual src/dst-step here to check end, do NOT
1616 # use bit-reversed version
1617 srcstep, dststep = self.new_srcstep, self.new_dststep
1618 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1619 remaps = self.get_remap_indices()
1620 remap_idxs = self.remap_idxs
1621 vl = self.svstate.vl
1622 subvl = yield self.dec2.rm_dec.rm_in.subvl
1623 end_src = srcstep == vl-1
1624 end_dst = dststep == vl-1
1625 if self.allow_next_step_inc != 2:
1626 yield from self.advance_svstate_steps(end_src, end_dst)
1627 self.namespace['SVSTATE'] = self.svstate.spr
1628 # set CR0 (if Rc=1) based on end
1629 if rc_en:
1630 endtest = 1 if (end_src or end_dst) else 0
1631 #results = [SelectableInt(endtest, 64)]
1632 # self.handle_comparison(results) # CR0
1633
1634 # see if svstep was requested, if so, which SVSTATE
1635 endings = 0b111
1636 if self.svstate_next_mode > 0:
1637 shape_idx = self.svstate_next_mode.value-1
1638 endings = self.remap_loopends[shape_idx]
1639 cr_field = SelectableInt((~endings) << 1 | endtest, 4)
1640 log("svstep Rc=1, CR0", cr_field)
1641 self.crl[0].eq(cr_field) # CR0
1642 if end_src or end_dst:
1643 # reset at end of loop including exit Vertical Mode
1644 log("SVSTATE_NEXT: after increments, reset")
1645 self.svp64_reset_loop()
1646 self.svstate.vfirst = 0
1647 return nia_update
1648
1649 if self.is_svp64_mode:
1650 return (yield from self.svstate_post_inc(ins_name))
1651
1652 # XXX only in non-SVP64 mode!
1653 # record state of whether the current operation was an svshape,
1654 # OR svindex!
1655 # to be able to know if it should apply in the next instruction.
1656 # also (if going to use this instruction) should disable ability
1657 # to interrupt in between. sigh.
1658 self.last_op_svshape = asmop in ['svremap', 'svindex', 'svshape2']
1659
1660 return True
1661
1662 def SVSTATE_NEXT(self, mode, submode):
1663 """explicitly moves srcstep/dststep on to next element, for
1664 "Vertical-First" mode. this function is called from
1665 setvl pseudo-code, as a pseudo-op "svstep"
1666
1667 WARNING: this function uses information that was created EARLIER
1668 due to it being in the middle of a yield, but this function is
1669 *NOT* called from yield (it's called from compiled pseudocode).
1670 """
1671 self.allow_next_step_inc = submode.value + 1
1672 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
1673 self.svstate_next_mode = mode
1674 if self.svstate_next_mode > 0 and self.svstate_next_mode < 5:
1675 shape_idx = self.svstate_next_mode.value-1
1676 return SelectableInt(self.remap_idxs[shape_idx], 7)
1677 if self.svstate_next_mode == 5:
1678 self.svstate_next_mode = 0
1679 return SelectableInt(self.svstate.srcstep, 7)
1680 if self.svstate_next_mode == 6:
1681 self.svstate_next_mode = 0
1682 return SelectableInt(self.svstate.dststep, 7)
1683 return SelectableInt(0, 7)
1684
1685 def svstate_pre_inc(self):
1686 """check if srcstep/dststep need to skip over masked-out predicate bits
1687 note that this is not supposed to do anything to substep,
1688 it is purely for skipping masked-out bits
1689 """
1690 # get SVSTATE VL (oh and print out some debug stuff)
1691 # yield Delay(1e-10) # make changes visible
1692 vl = self.svstate.vl
1693 subvl = yield self.dec2.rm_dec.rm_in.subvl
1694 srcstep = self.svstate.srcstep
1695 dststep = self.svstate.dststep
1696 ssubstep = self.svstate.ssubstep
1697 dsubstep = self.svstate.dsubstep
1698 pack = self.svstate.pack
1699 unpack = self.svstate.unpack
1700 sv_a_nz = yield self.dec2.sv_a_nz
1701 fft_mode = yield self.dec2.use_svp64_fft
1702 in1 = yield self.dec2.e.read_reg1.data
1703 log("SVP64: VL, subvl, srcstep, dststep, ssubstep, dsybstep, sv_a_nz, "
1704 "in1 fft, svp64",
1705 vl, subvl, srcstep, dststep, ssubstep, dsubstep,
1706 sv_a_nz, in1, fft_mode,
1707 self.is_svp64_mode)
1708
1709 # get predicate mask (all 64 bits)
1710 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1711
1712 pmode = yield self.dec2.rm_dec.predmode
1713 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1714 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1715 srcpred = yield self.dec2.rm_dec.srcpred
1716 dstpred = yield self.dec2.rm_dec.dstpred
1717 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1718 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1719 if pmode == SVP64PredMode.INT.value:
1720 srcmask = dstmask = get_predint(self.gpr, dstpred)
1721 if sv_ptype == SVPtype.P2.value:
1722 srcmask = get_predint(self.gpr, srcpred)
1723 elif pmode == SVP64PredMode.CR.value:
1724 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1725 if sv_ptype == SVPtype.P2.value:
1726 srcmask = get_predcr(self.crl, srcpred, vl)
1727 # work out if the ssubsteps are completed
1728 ssubstart = ssubstep == 0
1729 dsubstart = dsubstep == 0
1730 log(" pmode", pmode)
1731 log(" pack/unpack", pack, unpack)
1732 log(" reverse", reverse_gear)
1733 log(" ptype", sv_ptype)
1734 log(" srcpred", bin(srcpred))
1735 log(" dstpred", bin(dstpred))
1736 log(" srcmask", bin(srcmask))
1737 log(" dstmask", bin(dstmask))
1738 log(" pred_sz", bin(pred_src_zero))
1739 log(" pred_dz", bin(pred_dst_zero))
1740 log(" ssubstart", ssubstart)
1741 log(" dsubstart", dsubstart)
1742
1743 # okaaay, so here we simply advance srcstep (TODO dststep)
1744 # this can ONLY be done at the beginning of the "for" loop
1745 # (this is all actually a FSM so it's hell to keep track sigh)
1746 srcstep_skip = False
1747 if ssubstart:
1748 # until the predicate mask has a "1" bit... or we run out of VL
1749 # let srcstep==VL be the indicator to move to next instruction
1750 if not pred_src_zero:
1751 srcstep_skip = True
1752
1753 # srcstep-skipping opportunity identified
1754 if srcstep_skip:
1755 while (((1 << srcstep) & srcmask) == 0) and (srcstep != vl):
1756 log(" sskip", bin(1 << srcstep))
1757 srcstep += 1
1758
1759 dststep_skip = False
1760 if dsubstart:
1761 # same for dststep
1762 if not pred_dst_zero:
1763 dststep_skip = True
1764
1765 # dststep-skipping opportunity identified
1766 if dststep_skip:
1767 while (((1 << dststep) & dstmask) == 0) and (dststep != vl):
1768 log(" dskip", bin(1 << dststep))
1769 dststep += 1
1770
1771 # now work out if the relevant mask bits require zeroing
1772 if pred_dst_zero:
1773 pred_dst_zero = ((1 << dststep) & dstmask) == 0
1774 if pred_src_zero:
1775 pred_src_zero = ((1 << srcstep) & srcmask) == 0
1776
1777 # store new srcstep / dststep
1778 self.new_srcstep, self.new_dststep = (srcstep, dststep)
1779 self.new_ssubstep, self.new_dsubstep = (ssubstep, dsubstep)
1780 self.pred_dst_zero, self.pred_src_zero = (pred_dst_zero, pred_src_zero)
1781 log(" new srcstep", srcstep)
1782 log(" new dststep", dststep)
1783 log(" new ssubstep", ssubstep)
1784 log(" new dsubstep", dsubstep)
1785
1786 def get_src_dststeps(self):
1787 """gets srcstep, dststep, and ssubstep, dsubstep
1788 """
1789 return (self.new_srcstep, self.new_dststep,
1790 self.new_ssubstep, self.new_dsubstep)
1791
1792 def update_new_svstate_steps(self):
1793 # note, do not get the bit-reversed srcstep here!
1794 srcstep, dststep = self.new_srcstep, self.new_dststep
1795 ssubstep, dsubstep = self.new_ssubstep, self.new_dsubstep
1796
1797 # update SVSTATE with new srcstep
1798 self.svstate.srcstep = srcstep
1799 self.svstate.dststep = dststep
1800 self.svstate.ssubstep = ssubstep
1801 self.svstate.dsubstep = dsubstep
1802 self.namespace['SVSTATE'] = self.svstate
1803 yield self.dec2.state.svstate.eq(self.svstate.value)
1804 yield Settle() # let decoder update
1805 srcstep = self.svstate.srcstep
1806 dststep = self.svstate.dststep
1807 ssubstep = self.svstate.ssubstep
1808 dsubstep = self.svstate.dsubstep
1809 pack = self.svstate.pack
1810 unpack = self.svstate.unpack
1811 vl = self.svstate.vl
1812 subvl = yield self.dec2.rm_dec.rm_in.subvl
1813 log(" srcstep", srcstep)
1814 log(" dststep", dststep)
1815 log(" pack", pack)
1816 log(" unpack", unpack)
1817 log(" ssubstep", ssubstep)
1818 log(" dsubstep", dsubstep)
1819 log(" vl", vl)
1820 log(" subvl", subvl)
1821
1822 # check if end reached (we let srcstep overrun, above)
1823 # nothing needs doing (TODO zeroing): just do next instruction
1824 return srcstep == vl or dststep == vl
1825
1826 def svstate_post_inc(self, insn_name, vf=0):
1827 # check if SV "Vertical First" mode is enabled
1828 vfirst = self.svstate.vfirst
1829 log(" SV Vertical First", vf, vfirst)
1830 if not vf and vfirst == 1:
1831 self.update_nia()
1832 return True
1833
1834 # check if it is the SVSTATE.src/dest step that needs incrementing
1835 # this is our Sub-Program-Counter loop from 0 to VL-1
1836 # XXX twin predication TODO
1837 vl = self.svstate.vl
1838 subvl = yield self.dec2.rm_dec.rm_in.subvl
1839 mvl = self.svstate.maxvl
1840 srcstep = self.svstate.srcstep
1841 dststep = self.svstate.dststep
1842 ssubstep = self.svstate.ssubstep
1843 dsubstep = self.svstate.dsubstep
1844 pack = self.svstate.pack
1845 unpack = self.svstate.unpack
1846 rm_mode = yield self.dec2.rm_dec.mode
1847 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1848 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1849 out_vec = not (yield self.dec2.no_out_vec)
1850 in_vec = not (yield self.dec2.no_in_vec)
1851 log(" svstate.vl", vl)
1852 log(" svstate.mvl", mvl)
1853 log(" rm.subvl", subvl)
1854 log(" svstate.srcstep", srcstep)
1855 log(" svstate.dststep", dststep)
1856 log(" svstate.ssubstep", ssubstep)
1857 log(" svstate.dsubstep", dsubstep)
1858 log(" svstate.pack", pack)
1859 log(" svstate.unpack", unpack)
1860 log(" mode", rm_mode)
1861 log(" reverse", reverse_gear)
1862 log(" out_vec", out_vec)
1863 log(" in_vec", in_vec)
1864 log(" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1865 # check if this was an sv.bc* and if so did it succeed
1866 if self.is_svp64_mode and insn_name.startswith("sv.bc"):
1867 end_loop = self.namespace['end_loop']
1868 log("branch %s end_loop" % insn_name, end_loop)
1869 if end_loop.value:
1870 self.svp64_reset_loop()
1871 self.update_pc_next()
1872 return False
1873 # check if srcstep needs incrementing by one, stop PC advancing
1874 # but for 2-pred both src/dest have to be checked.
1875 # XXX this might not be true! it may just be LD/ST
1876 if sv_ptype == SVPtype.P2.value:
1877 svp64_is_vector = (out_vec or in_vec)
1878 else:
1879 svp64_is_vector = out_vec
1880 # loops end at the first "hit" (source or dest)
1881 end_src = srcstep == vl-1
1882 end_dst = dststep == vl-1
1883 loopend = ((end_src and ssubstep == subvl) or
1884 (end_dst and dsubstep == subvl))
1885 if not svp64_is_vector or loopend:
1886 # reset loop to zero and update NIA
1887 self.svp64_reset_loop()
1888 self.update_nia()
1889
1890 return True
1891
1892 # still looping, advance and update NIA
1893 yield from self.advance_svstate_steps(end_src, end_dst)
1894 self.namespace['SVSTATE'] = self.svstate
1895
1896 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
1897 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
1898 # this way we keep repeating the same instruction (with new steps)
1899 self.pc.NIA.value = self.pc.CIA.value
1900 self.namespace['NIA'] = self.pc.NIA
1901 log("end of sub-pc call", self.namespace['CIA'], self.namespace['NIA'])
1902 return False # DO NOT allow PC update whilst Sub-PC loop running
1903
1904 def advance_svstate_steps(self, end_src=False, end_dst=False):
1905 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
1906 TODO when Pack/Unpack is set, substep becomes the *outer* loop
1907 """
1908 subvl = yield self.dec2.rm_dec.rm_in.subvl
1909 # first source step
1910 pack = self.svstate.pack
1911 ssubstep = self.svstate.ssubstep
1912 srcstep = self.svstate.srcstep
1913 end_sub = ssubstep == subvl
1914 if pack:
1915 # pack advances subvl in *outer* loop
1916 if end_src:
1917 if not end_sub:
1918 self.svstate.ssubstep += SelectableInt(1, 7)
1919 self.svstate.srcstep = SelectableInt(0, 2) # reset
1920 else:
1921 self.svstate.srcstep += SelectableInt(1, 2) # advance srcstep
1922 else:
1923 # advance subvl in *inner* loop
1924 if end_sub:
1925 if not end_src:
1926 self.svstate.srcstep += SelectableInt(1, 7)
1927 self.svstate.ssubstep = SelectableInt(0, 2) # reset
1928 else:
1929 self.svstate.ssubstep += SelectableInt(1, 2) # advance ssubstep
1930
1931 # now dest step
1932 dsubstep = self.svstate.dsubstep
1933 unpack = self.svstate.unpack
1934 end_sub = dsubstep == subvl
1935 if unpack:
1936 # unpack advances subvl in *outer* loop
1937 if end_dst:
1938 if not end_sub:
1939 self.svstate.dsubstep += SelectableInt(1, 7)
1940 self.svstate.dststep = SelectableInt(0, 2) # reset
1941 else:
1942 self.svstate.dststep += SelectableInt(1, 2) # advance dststep
1943 else:
1944 # advance subvl in *inner* loop
1945 if end_sub:
1946 if not end_dst:
1947 self.svstate.dststep += SelectableInt(1, 7)
1948 self.svstate.dsubstep = SelectableInt(0, 2) # reset
1949 else:
1950 self.svstate.dsubstep += SelectableInt(1, 2) # advance ssubstep
1951
1952 def update_pc_next(self):
1953 # UPDATE program counter
1954 self.pc.update(self.namespace, self.is_svp64_mode)
1955 self.svstate.spr = self.namespace['SVSTATE']
1956 log("end of call", self.namespace['CIA'],
1957 self.namespace['NIA'],
1958 self.namespace['SVSTATE'])
1959
1960 def svp64_reset_loop(self):
1961 self.svstate.srcstep = 0
1962 self.svstate.dststep = 0
1963 self.svstate.ssubstep = 0
1964 self.svstate.dsubstep = 0
1965 log(" svstate.srcstep loop end (PC to update)")
1966 self.namespace['SVSTATE'] = self.svstate
1967
1968 def update_nia(self):
1969 self.pc.update_nia(self.is_svp64_mode)
1970 self.namespace['NIA'] = self.pc.NIA
1971
1972
1973 def inject():
1974 """Decorator factory.
1975
1976 this decorator will "inject" variables into the function's namespace,
1977 from the *dictionary* in self.namespace. it therefore becomes possible
1978 to make it look like a whole stack of variables which would otherwise
1979 need "self." inserted in front of them (*and* for those variables to be
1980 added to the instance) "appear" in the function.
1981
1982 "self.namespace['SI']" for example becomes accessible as just "SI" but
1983 *only* inside the function, when decorated.
1984 """
1985 def variable_injector(func):
1986 @wraps(func)
1987 def decorator(*args, **kwargs):
1988 try:
1989 func_globals = func.__globals__ # Python 2.6+
1990 except AttributeError:
1991 func_globals = func.func_globals # Earlier versions.
1992
1993 context = args[0].namespace # variables to be injected
1994 saved_values = func_globals.copy() # Shallow copy of dict.
1995 log("globals before", context.keys())
1996 func_globals.update(context)
1997 result = func(*args, **kwargs)
1998 log("globals after", func_globals['CIA'], func_globals['NIA'])
1999 log("args[0]", args[0].namespace['CIA'],
2000 args[0].namespace['NIA'],
2001 args[0].namespace['SVSTATE'])
2002 if 'end_loop' in func_globals:
2003 log("args[0] end_loop", func_globals['end_loop'])
2004 args[0].namespace = func_globals
2005 #exec (func.__code__, func_globals)
2006
2007 # finally:
2008 # func_globals = saved_values # Undo changes.
2009
2010 return result
2011
2012 return decorator
2013
2014 return variable_injector