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