more generic allow fft mode 2nd output detection. REALLY need a CSV Out2 column
[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 if fft_en:
534 log ("get_pdecode_idx_out2", out_sel, OutSel.FRS.value,
535 out, o_isvec)
536 return out, o_isvec
537 return None, False
538
539
540 class ISACaller:
541 # decoder2 - an instance of power_decoder2
542 # regfile - a list of initial values for the registers
543 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
544 # respect_pc - tracks the program counter. requires initial_insns
545 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
546 initial_mem=None, initial_msr=0,
547 initial_svstate=0,
548 initial_insns=None,
549 fpregfile=None,
550 respect_pc=False,
551 disassembly=None,
552 initial_pc=0,
553 bigendian=False,
554 mmu=False,
555 icachemmu=False):
556
557 self.bigendian = bigendian
558 self.halted = False
559 self.is_svp64_mode = False
560 self.respect_pc = respect_pc
561 if initial_sprs is None:
562 initial_sprs = {}
563 if initial_mem is None:
564 initial_mem = {}
565 if fpregfile is None:
566 fpregfile = [0] * 32
567 if initial_insns is None:
568 initial_insns = {}
569 assert self.respect_pc == False, "instructions required to honor pc"
570
571 log("ISACaller insns", respect_pc, initial_insns, disassembly)
572 log("ISACaller initial_msr", initial_msr)
573
574 # "fake program counter" mode (for unit testing)
575 self.fake_pc = 0
576 disasm_start = 0
577 if not respect_pc:
578 if isinstance(initial_mem, tuple):
579 self.fake_pc = initial_mem[0]
580 disasm_start = self.fake_pc
581 else:
582 disasm_start = initial_pc
583
584 # disassembly: we need this for now (not given from the decoder)
585 self.disassembly = {}
586 if disassembly:
587 for i, code in enumerate(disassembly):
588 self.disassembly[i*4 + disasm_start] = code
589
590 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
591 self.svp64rm = SVP64RM()
592 if initial_svstate is None:
593 initial_svstate = 0
594 if isinstance(initial_svstate, int):
595 initial_svstate = SVP64State(initial_svstate)
596 # SVSTATE, MSR and PC
597 self.svstate = initial_svstate
598 self.msr = SelectableInt(initial_msr, 64) # underlying reg
599 self.pc = PC()
600 # GPR FPR SPR registers
601 self.gpr = GPR(decoder2, self, self.svstate, regfile)
602 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
603 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
604
605 # set up 4 dummy SVSHAPEs if they aren't already set up
606 for i in range(4):
607 sname = 'SVSHAPE%d' % i
608 if sname not in self.spr:
609 self.spr[sname] = SVSHAPE(0)
610 else:
611 # make sure it's an SVSHAPE
612 val = self.spr[sname].value
613 self.spr[sname] = SVSHAPE(val)
614 self.last_op_svshape = False
615
616 # "raw" memory
617 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
618 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
619 # MMU mode, redirect underlying Mem through RADIX
620 if mmu:
621 self.mem = RADIX(self.mem, self)
622 if icachemmu:
623 self.imem = RADIX(self.imem, self)
624
625 # TODO, needed here:
626 # FPR (same as GPR except for FP nums)
627 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
628 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
629 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
630 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
631 # -- Done
632 # 2.3.2 LR (actually SPR #8) -- Done
633 # 2.3.3 CTR (actually SPR #9) -- Done
634 # 2.3.4 TAR (actually SPR #815)
635 # 3.2.2 p45 XER (actually SPR #1) -- Done
636 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
637
638 # create CR then allow portions of it to be "selectable" (below)
639 self.cr_fields = CRFields(initial_cr)
640 self.cr = self.cr_fields.cr
641
642 # "undefined", just set to variable-bit-width int (use exts "max")
643 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
644
645 self.namespace = {}
646 self.namespace.update(self.spr)
647 self.namespace.update({'GPR': self.gpr,
648 'FPR': self.fpr,
649 'MEM': self.mem,
650 'SPR': self.spr,
651 'memassign': self.memassign,
652 'NIA': self.pc.NIA,
653 'CIA': self.pc.CIA,
654 'SVSTATE': self.svstate.spr,
655 'SVSHAPE0': self.spr['SVSHAPE0'],
656 'SVSHAPE1': self.spr['SVSHAPE1'],
657 'SVSHAPE2': self.spr['SVSHAPE2'],
658 'SVSHAPE3': self.spr['SVSHAPE3'],
659 'CR': self.cr,
660 'MSR': self.msr,
661 'undefined': undefined,
662 'mode_is_64bit': True,
663 'SO': XER_bits['SO']
664 })
665
666 # update pc to requested start point
667 self.set_pc(initial_pc)
668
669 # field-selectable versions of Condition Register
670 self.crl = self.cr_fields.crl
671 for i in range(8):
672 self.namespace["CR%d" % i] = self.crl[i]
673
674 self.decoder = decoder2.dec
675 self.dec2 = decoder2
676
677 def call_trap(self, trap_addr, trap_bit):
678 """calls TRAP and sets up NIA to the new execution location.
679 next instruction will begin at trap_addr.
680 """
681 self.TRAP(trap_addr, trap_bit)
682 self.namespace['NIA'] = self.trap_nia
683 self.pc.update(self.namespace, self.is_svp64_mode)
684
685 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
686 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
687
688 TRAP function is callable from inside the pseudocode itself,
689 hence the default arguments. when calling from inside ISACaller
690 it is best to use call_trap()
691 """
692 log("TRAP:", hex(trap_addr), hex(self.namespace['MSR'].value))
693 # store CIA(+4?) in SRR0, set NIA to 0x700
694 # store MSR in SRR1, set MSR to um errr something, have to check spec
695 # store SVSTATE (if enabled) in SVSRR0
696 self.spr['SRR0'].value = self.pc.CIA.value
697 self.spr['SRR1'].value = self.namespace['MSR'].value
698 if self.is_svp64_mode:
699 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
700 self.trap_nia = SelectableInt(trap_addr, 64)
701 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
702
703 # set exception bits. TODO: this should, based on the address
704 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
705 # bits appropriately. however it turns out that *for now* in all
706 # cases (all trap_addrs) the exact same thing is needed.
707 self.msr[MSRb.IR] = 0
708 self.msr[MSRb.DR] = 0
709 self.msr[MSRb.FE0] = 0
710 self.msr[MSRb.FE1] = 0
711 self.msr[MSRb.EE] = 0
712 self.msr[MSRb.RI] = 0
713 self.msr[MSRb.SF] = 1
714 self.msr[MSRb.TM] = 0
715 self.msr[MSRb.VEC] = 0
716 self.msr[MSRb.VSX] = 0
717 self.msr[MSRb.PR] = 0
718 self.msr[MSRb.FP] = 0
719 self.msr[MSRb.PMM] = 0
720 self.msr[MSRb.TEs] = 0
721 self.msr[MSRb.TEe] = 0
722 self.msr[MSRb.UND] = 0
723 self.msr[MSRb.LE] = 1
724
725 def memassign(self, ea, sz, val):
726 self.mem.memassign(ea, sz, val)
727
728 def prep_namespace(self, formname, op_fields):
729 # TODO: get field names from form in decoder*1* (not decoder2)
730 # decoder2 is hand-created, and decoder1.sigform is auto-generated
731 # from spec
732 # then "yield" fields only from op_fields rather than hard-coded
733 # list, here.
734 fields = self.decoder.sigforms[formname]
735 for name in op_fields:
736 if name == 'spr':
737 sig = getattr(fields, name.upper())
738 else:
739 sig = getattr(fields, name)
740 val = yield sig
741 # these are all opcode fields involved in index-selection of CR,
742 # and need to do "standard" arithmetic. CR[BA+32] for example
743 # would, if using SelectableInt, only be 5-bit.
744 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
745 self.namespace[name] = val
746 else:
747 self.namespace[name] = SelectableInt(val, sig.width)
748
749 self.namespace['XER'] = self.spr['XER']
750 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
751 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
752
753 # add some SVSTATE convenience variables
754 vl = self.svstate.vl.asint(msb0=True)
755 srcstep = self.svstate.srcstep.asint(msb0=True)
756 self.namespace['VL'] = vl
757 self.namespace['srcstep'] = srcstep
758
759 def handle_carry_(self, inputs, outputs, already_done):
760 inv_a = yield self.dec2.e.do.invert_in
761 if inv_a:
762 inputs[0] = ~inputs[0]
763
764 imm_ok = yield self.dec2.e.do.imm_data.ok
765 if imm_ok:
766 imm = yield self.dec2.e.do.imm_data.data
767 inputs.append(SelectableInt(imm, 64))
768 assert len(outputs) >= 1
769 log("outputs", repr(outputs))
770 if isinstance(outputs, list) or isinstance(outputs, tuple):
771 output = outputs[0]
772 else:
773 output = outputs
774 gts = []
775 for x in inputs:
776 log("gt input", x, output)
777 gt = (gtu(x, output))
778 gts.append(gt)
779 log(gts)
780 cy = 1 if any(gts) else 0
781 log("CA", cy, gts)
782 if not (1 & already_done):
783 self.spr['XER'][XER_bits['CA']] = cy
784
785 log("inputs", already_done, inputs)
786 # 32 bit carry
787 # ARGH... different for OP_ADD... *sigh*...
788 op = yield self.dec2.e.do.insn_type
789 if op == MicrOp.OP_ADD.value:
790 res32 = (output.value & (1 << 32)) != 0
791 a32 = (inputs[0].value & (1 << 32)) != 0
792 if len(inputs) >= 2:
793 b32 = (inputs[1].value & (1 << 32)) != 0
794 else:
795 b32 = False
796 cy32 = res32 ^ a32 ^ b32
797 log("CA32 ADD", cy32)
798 else:
799 gts = []
800 for x in inputs:
801 log("input", x, output)
802 log(" x[32:64]", x, x[32:64])
803 log(" o[32:64]", output, output[32:64])
804 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
805 gts.append(gt)
806 cy32 = 1 if any(gts) else 0
807 log("CA32", cy32, gts)
808 if not (2 & already_done):
809 self.spr['XER'][XER_bits['CA32']] = cy32
810
811 def handle_overflow(self, inputs, outputs, div_overflow):
812 if hasattr(self.dec2.e.do, "invert_in"):
813 inv_a = yield self.dec2.e.do.invert_in
814 if inv_a:
815 inputs[0] = ~inputs[0]
816
817 imm_ok = yield self.dec2.e.do.imm_data.ok
818 if imm_ok:
819 imm = yield self.dec2.e.do.imm_data.data
820 inputs.append(SelectableInt(imm, 64))
821 assert len(outputs) >= 1
822 log("handle_overflow", inputs, outputs, div_overflow)
823 if len(inputs) < 2 and div_overflow is None:
824 return
825
826 # div overflow is different: it's returned by the pseudo-code
827 # because it's more complex than can be done by analysing the output
828 if div_overflow is not None:
829 ov, ov32 = div_overflow, div_overflow
830 # arithmetic overflow can be done by analysing the input and output
831 elif len(inputs) >= 2:
832 output = outputs[0]
833
834 # OV (64-bit)
835 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
836 output_sgn = exts(output.value, output.bits) < 0
837 ov = 1 if input_sgn[0] == input_sgn[1] and \
838 output_sgn != input_sgn[0] else 0
839
840 # OV (32-bit)
841 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
842 output32_sgn = exts(output.value, 32) < 0
843 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
844 output32_sgn != input32_sgn[0] else 0
845
846 self.spr['XER'][XER_bits['OV']] = ov
847 self.spr['XER'][XER_bits['OV32']] = ov32
848 so = self.spr['XER'][XER_bits['SO']]
849 so = so | ov
850 self.spr['XER'][XER_bits['SO']] = so
851
852 def handle_comparison(self, outputs, cr_idx=0):
853 out = outputs[0]
854 assert isinstance(out, SelectableInt), \
855 "out zero not a SelectableInt %s" % repr(outputs)
856 log("handle_comparison", out.bits, hex(out.value))
857 # TODO - XXX *processor* in 32-bit mode
858 # https://bugs.libre-soc.org/show_bug.cgi?id=424
859 # if is_32bit:
860 # o32 = exts(out.value, 32)
861 # print ("handle_comparison exts 32 bit", hex(o32))
862 out = exts(out.value, out.bits)
863 log("handle_comparison exts", hex(out))
864 zero = SelectableInt(out == 0, 1)
865 positive = SelectableInt(out > 0, 1)
866 negative = SelectableInt(out < 0, 1)
867 SO = self.spr['XER'][XER_bits['SO']]
868 log("handle_comparison SO", SO)
869 cr_field = selectconcat(negative, positive, zero, SO)
870 self.crl[cr_idx].eq(cr_field)
871
872 def set_pc(self, pc_val):
873 self.namespace['NIA'] = SelectableInt(pc_val, 64)
874 self.pc.update(self.namespace, self.is_svp64_mode)
875
876 def get_next_insn(self):
877 """check instruction
878 """
879 if self.respect_pc:
880 pc = self.pc.CIA.value
881 else:
882 pc = self.fake_pc
883 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
884 if ins is None:
885 raise KeyError("no instruction at 0x%x" % pc)
886 return pc, ins
887
888 def setup_one(self):
889 """set up one instruction
890 """
891 pc, insn = self.get_next_insn()
892 yield from self.setup_next_insn(pc, insn)
893
894 def setup_next_insn(self, pc, ins):
895 """set up next instruction
896 """
897 self._pc = pc
898 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
899 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
900
901 yield self.dec2.sv_rm.eq(0)
902 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
903 yield self.dec2.dec.bigendian.eq(self.bigendian)
904 yield self.dec2.state.msr.eq(self.msr.value)
905 yield self.dec2.state.pc.eq(pc)
906 if self.svstate is not None:
907 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
908
909 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
910 yield Settle()
911 opcode = yield self.dec2.dec.opcode_in
912 pfx = SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
913 pfx.insn.value = opcode
914 major = pfx.major.asint(msb0=True) # MSB0 inversion
915 log ("prefix test: opcode:", major, bin(major),
916 pfx.insn[7] == 0b1, pfx.insn[9] == 0b1)
917 self.is_svp64_mode = ((major == 0b000001) and
918 pfx.insn[7].value == 0b1 and
919 pfx.insn[9].value == 0b1)
920 self.pc.update_nia(self.is_svp64_mode)
921 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode) # set SVP64 decode
922 self.namespace['NIA'] = self.pc.NIA
923 self.namespace['SVSTATE'] = self.svstate.spr
924 if not self.is_svp64_mode:
925 return
926
927 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
928 log ("svp64.rm", bin(pfx.rm.asint(msb0=True)))
929 log (" svstate.vl", self.svstate.vl.asint(msb0=True))
930 log (" svstate.mvl", self.svstate.maxvl.asint(msb0=True))
931 sv_rm = pfx.rm.asint(msb0=True)
932 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
933 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
934 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
935 yield self.dec2.sv_rm.eq(sv_rm) # svp64 prefix
936 yield Settle()
937
938 def execute_one(self):
939 """execute one instruction
940 """
941 # get the disassembly code for this instruction
942 if self.is_svp64_mode:
943 if not self.disassembly:
944 code = yield from self.get_assembly_name()
945 else:
946 code = self.disassembly[self._pc+4]
947 log(" svp64 sim-execute", hex(self._pc), code)
948 else:
949 if not self.disassembly:
950 code = yield from self.get_assembly_name()
951 else:
952 code = self.disassembly[self._pc]
953 log("sim-execute", hex(self._pc), code)
954 opname = code.split(' ')[0]
955 try:
956 yield from self.call(opname) # execute the instruction
957 except MemException as e: # check for memory errors
958 if e.args[0] != 'unaligned': # only doing aligned at the mo
959 raise e # ... re-raise
960 # run a Trap but set DAR first
961 print ("memory unaligned exception, DAR", e.dar)
962 self.spr['DAR'] = SelectableInt(e.dar, 64)
963 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
964 return
965
966 # don't use this except in special circumstances
967 if not self.respect_pc:
968 self.fake_pc += 4
969
970 log("execute one, CIA NIA", self.pc.CIA.value, self.pc.NIA.value)
971
972 def get_assembly_name(self):
973 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
974 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
975 dec_insn = yield self.dec2.e.do.insn
976 insn_1_11 = yield self.dec2.e.do.insn[1:11]
977 asmcode = yield self.dec2.dec.op.asmcode
978 int_op = yield self.dec2.dec.op.internal_op
979 log("get assembly name asmcode", asmcode, int_op,
980 hex(dec_insn), bin(insn_1_11))
981 asmop = insns.get(asmcode, None)
982
983 # sigh reconstruct the assembly instruction name
984 if hasattr(self.dec2.e.do, "oe"):
985 ov_en = yield self.dec2.e.do.oe.oe
986 ov_ok = yield self.dec2.e.do.oe.ok
987 else:
988 ov_en = False
989 ov_ok = False
990 if hasattr(self.dec2.e.do, "rc"):
991 rc_en = yield self.dec2.e.do.rc.rc
992 rc_ok = yield self.dec2.e.do.rc.ok
993 else:
994 rc_en = False
995 rc_ok = False
996 # grrrr have to special-case MUL op (see DecodeOE)
997 log("ov %d en %d rc %d en %d op %d" %
998 (ov_ok, ov_en, rc_ok, rc_en, int_op))
999 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1000 log("mul op")
1001 if rc_en & rc_ok:
1002 asmop += "."
1003 else:
1004 if not asmop.endswith("."): # don't add "." to "andis."
1005 if rc_en & rc_ok:
1006 asmop += "."
1007 if hasattr(self.dec2.e.do, "lk"):
1008 lk = yield self.dec2.e.do.lk
1009 if lk:
1010 asmop += "l"
1011 log("int_op", int_op)
1012 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1013 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1014 log("AA", AA)
1015 if AA:
1016 asmop += "a"
1017 spr_msb = yield from self.get_spr_msb()
1018 if int_op == MicrOp.OP_MFCR.value:
1019 if spr_msb:
1020 asmop = 'mfocrf'
1021 else:
1022 asmop = 'mfcr'
1023 # XXX TODO: for whatever weird reason this doesn't work
1024 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1025 if int_op == MicrOp.OP_MTCRF.value:
1026 if spr_msb:
1027 asmop = 'mtocrf'
1028 else:
1029 asmop = 'mtcrf'
1030 return asmop
1031
1032 def get_spr_msb(self):
1033 dec_insn = yield self.dec2.e.do.insn
1034 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1035
1036 def call(self, name):
1037 """call(opcode) - the primary execution point for instructions
1038 """
1039 self.last_st_addr = None # reset the last known store address
1040 self.last_ld_addr = None # etc.
1041
1042 name = name.strip() # remove spaces if not already done so
1043 if self.halted:
1044 log("halted - not executing", name)
1045 return
1046
1047 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1048 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1049 asmop = yield from self.get_assembly_name()
1050 log("call", name, asmop)
1051
1052 # check privileged
1053 int_op = yield self.dec2.dec.op.internal_op
1054 spr_msb = yield from self.get_spr_msb()
1055
1056 instr_is_privileged = False
1057 if int_op in [MicrOp.OP_ATTN.value,
1058 MicrOp.OP_MFMSR.value,
1059 MicrOp.OP_MTMSR.value,
1060 MicrOp.OP_MTMSRD.value,
1061 # TODO: OP_TLBIE
1062 MicrOp.OP_RFID.value]:
1063 instr_is_privileged = True
1064 if int_op in [MicrOp.OP_MFSPR.value,
1065 MicrOp.OP_MTSPR.value] and spr_msb:
1066 instr_is_privileged = True
1067
1068 log("is priv", instr_is_privileged, hex(self.msr.value),
1069 self.msr[MSRb.PR])
1070 # check MSR priv bit and whether op is privileged: if so, throw trap
1071 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1072 self.call_trap(0x700, PIb.PRIV)
1073 return
1074
1075 # check halted condition
1076 if name == 'attn':
1077 self.halted = True
1078 return
1079
1080 # check illegal instruction
1081 illegal = False
1082 if name not in ['mtcrf', 'mtocrf']:
1083 illegal = name != asmop
1084
1085 # sigh deal with setvl not being supported by binutils (.long)
1086 if asmop.startswith('setvl'):
1087 illegal = False
1088 name = 'setvl'
1089
1090 # and svremap not being supported by binutils (.long)
1091 if asmop.startswith('svremap'):
1092 illegal = False
1093 name = 'svremap'
1094
1095 # sigh also deal with ffmadds not being supported by binutils (.long)
1096 if asmop == 'ffmadds':
1097 illegal = False
1098 name = 'ffmadds'
1099
1100 # and ffadds not being supported by binutils (.long)
1101 if asmop == 'ffadds':
1102 illegal = False
1103 name = 'ffadds'
1104
1105 if illegal:
1106 print("illegal", name, asmop)
1107 self.call_trap(0x700, PIb.ILLEG)
1108 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1109 (name, asmop, self.pc.CIA.value))
1110 return
1111
1112 # this is for setvl "Vertical" mode: if set true,
1113 # srcstep/dststep is explicitly advanced
1114 self.allow_next_step_inc = False
1115
1116 # nop has to be supported, we could let the actual op calculate
1117 # but PowerDecoder has a pattern for nop
1118 if name is 'nop':
1119 self.update_pc_next()
1120 return
1121
1122 info = self.instrs[name]
1123 yield from self.prep_namespace(info.form, info.op_fields)
1124
1125 # preserve order of register names
1126 input_names = create_args(list(info.read_regs) +
1127 list(info.uninit_regs))
1128 log(input_names)
1129
1130 # get SVP64 entry for the current instruction
1131 sv_rm = self.svp64rm.instrs.get(name)
1132 if sv_rm is not None:
1133 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1134 else:
1135 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1136 log ("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1137
1138 # see if srcstep/dststep need skipping over masked-out predicate bits
1139 if self.is_svp64_mode:
1140 yield from self.svstate_pre_inc()
1141 pre = yield from self.update_new_svstate_steps()
1142 if pre:
1143 self.svp64_reset_loop()
1144 self.update_nia()
1145 self.update_pc_next()
1146 return
1147 srcstep, dststep = self.new_srcstep, self.new_dststep
1148 pred_dst_zero = self.pred_dst_zero
1149 pred_src_zero = self.pred_src_zero
1150 vl = self.svstate.vl.asint(msb0=True)
1151
1152 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1153 if self.is_svp64_mode and vl == 0:
1154 self.pc.update(self.namespace, self.is_svp64_mode)
1155 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1156 self.namespace['NIA'])
1157 return
1158
1159 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1160 # using pre-arranged schedule. all of this is awful but it is a
1161 # start. next job will be to put the proper activation in place
1162 yield self.dec2.remap_active.eq(1 if self.last_op_svshape else 0)
1163 yield Settle()
1164 if self.is_svp64_mode and self.last_op_svshape:
1165 # get four SVSHAPEs. here we are hard-coding
1166 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1167 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1168 SVSHAPE0 = self.spr['SVSHAPE0']
1169 SVSHAPE1 = self.spr['SVSHAPE1']
1170 SVSHAPE2 = self.spr['SVSHAPE2']
1171 SVSHAPE3 = self.spr['SVSHAPE3']
1172 for i in range(4):
1173 sname = 'SVSHAPE%d' % i
1174 shape = self.spr[sname]
1175 print (sname, bin(shape.value))
1176 print (" lims", shape.lims)
1177 print (" mode", shape.mode)
1178 print (" skip", shape.skip)
1179
1180 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1181 (SVSHAPE1, SVSHAPE1.get_iterator()),
1182 (SVSHAPE2, SVSHAPE2.get_iterator()),
1183 (SVSHAPE3, SVSHAPE3.get_iterator()),
1184 ]
1185 rremaps = []
1186 for i, (shape, remap) in enumerate(remaps):
1187 # zero is "disabled"
1188 if shape.value == 0x0:
1189 continue
1190 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1191 if shape.mode == 0b00: # multiply mode
1192 step = dststep if (i == 0) else srcstep
1193 if shape.mode == 0b01: # FFT butterfly mode
1194 step = srcstep # XXX HACK - for now only use srcstep
1195 # this is terrible. O(N^2) looking for the match. but hey.
1196 for idx, remap_idx in enumerate(remap):
1197 if idx == step:
1198 break
1199 # multiply mode
1200 if shape.mode == 0b00:
1201 if i == 0:
1202 yield self.dec2.o_step.eq(remap_idx) # RT
1203 yield self.dec2.o2_step.eq(remap_idx) # EA
1204 elif i == 1:
1205 yield self.dec2.in1_step.eq(remap_idx) # RA
1206 elif i == 2:
1207 yield self.dec2.in3_step.eq(remap_idx) # RB
1208 elif i == 3:
1209 yield self.dec2.in2_step.eq(remap_idx) # RC
1210 # FFT butterfly mode
1211 if shape.mode == 0b01:
1212 if i == 0:
1213 yield self.dec2.o_step.eq(remap_idx) # RT
1214 yield self.dec2.in2_step.eq(remap_idx) # RB
1215 elif i == 1:
1216 yield self.dec2.in1_step.eq(remap_idx) # RA
1217 yield self.dec2.o2_step.eq(remap_idx) # EA (FRS)
1218 elif i == 2:
1219 yield self.dec2.in3_step.eq(remap_idx) # RC
1220 elif i == 3:
1221 pass # no SVSHAPE3
1222 rremaps.append((shape.mode, i, idx, remap_idx)) # debug printing
1223 for x in rremaps:
1224 print ("shape remap", x)
1225 # after that, settle down (combinatorial) to let Vector reg numbers
1226 # work themselves out
1227 yield Settle()
1228 remap_active = yield self.dec2.remap_active
1229 print ("remap active", remap_active)
1230
1231 # main input registers (RT, RA ...)
1232 inputs = []
1233 for name in input_names:
1234 # using PowerDecoder2, first, find the decoder index.
1235 # (mapping name RA RB RC RS to in1, in2, in3)
1236 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1237 if regnum is None:
1238 # doing this is not part of svp64, it's because output
1239 # registers, to be modified, need to be in the namespace.
1240 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1241 if regnum is None:
1242 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2,
1243 name)
1244
1245 # in case getting the register number is needed, _RA, _RB
1246 regname = "_" + name
1247 self.namespace[regname] = regnum
1248 if not self.is_svp64_mode or not pred_src_zero:
1249 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1250 if name in fregs:
1251 reg_val = self.fpr(regnum)
1252 elif name is not None:
1253 reg_val = self.gpr(regnum)
1254 else:
1255 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1256 reg_val = 0
1257 inputs.append(reg_val)
1258 # arrrrgh, awful hack, to get _RT into namespace
1259 if asmop == 'setvl':
1260 regname = "_RT"
1261 RT = yield self.dec2.dec.RT
1262 self.namespace[regname] = SelectableInt(RT, 5)
1263
1264 # in SVP64 mode for LD/ST work out immediate
1265 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1266 # use info.form to detect
1267 replace_d = False # update / replace constant in pseudocode
1268 if self.is_svp64_mode:
1269 ldstmode = yield self.dec2.rm_dec.ldstmode
1270 # bitreverse mode reads SVD (or SVDS - TODO)
1271 # *BUT*... because this is "overloading" of LD operations,
1272 # it gets *STORED* into D (or DS, TODO)
1273 if ldstmode == SVP64LDSTmode.BITREVERSE.value:
1274 imm = yield self.dec2.dec.fields.FormSVD.SVD[0:11]
1275 imm = exts(imm, 11) # sign-extend to integer
1276 print ("bitrev SVD", imm)
1277 replace_d = True
1278 else:
1279 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1280 imm = exts(imm, 16) # sign-extend to integer
1281 # get the right step. LD is from srcstep, ST is dststep
1282 op = yield self.dec2.e.do.insn_type
1283 offsmul = 0
1284 if op == MicrOp.OP_LOAD.value:
1285 offsmul = srcstep
1286 log("D-field src", imm, offsmul)
1287 elif op == MicrOp.OP_STORE.value:
1288 offsmul = dststep
1289 log("D-field dst", imm, offsmul)
1290 # bit-reverse mode
1291 if ldstmode == SVP64LDSTmode.BITREVERSE.value:
1292 # manually look up RC, sigh
1293 RC = yield self.dec2.dec.RC[0:5]
1294 RC = self.gpr(RC)
1295 log ("RC", RC.value, "imm", imm, "offs", bin(offsmul),
1296 "rev", bin(bitrev(offsmul, vl)))
1297 imm = SelectableInt((imm * bitrev(offsmul, vl)) << RC.value, 32)
1298 # Unit-Strided LD/ST adds offset*width to immediate
1299 elif ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1300 ldst_len = yield self.dec2.e.do.data_len
1301 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1302 replace_d = True
1303 # Element-strided multiplies the immediate by element step
1304 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1305 imm = SelectableInt(imm * offsmul, 32)
1306 replace_d = True
1307 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1308 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1309 log("LDSTmode", ldstmode, SVP64LDSTmode.BITREVERSE.value,
1310 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1311 # new replacement D
1312 if replace_d:
1313 self.namespace['D'] = imm
1314
1315 # "special" registers
1316 for special in info.special_regs:
1317 if special in special_sprs:
1318 inputs.append(self.spr[special])
1319 else:
1320 inputs.append(self.namespace[special])
1321
1322 # clear trap (trap) NIA
1323 self.trap_nia = None
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 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1367 # detect if overflow was in return result
1368 overflow = None
1369 if info.write_regs:
1370 for name, output in zip(output_names, results):
1371 if name == 'overflow':
1372 overflow = output
1373
1374 if hasattr(self.dec2.e.do, "oe"):
1375 ov_en = yield self.dec2.e.do.oe.oe
1376 ov_ok = yield self.dec2.e.do.oe.ok
1377 else:
1378 ov_en = False
1379 ov_ok = False
1380 log("internal overflow", overflow, ov_en, ov_ok)
1381 if ov_en & ov_ok:
1382 yield from self.handle_overflow(inputs, results, overflow)
1383
1384 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1385 rc_en = False
1386 if not self.is_svp64_mode or not pred_dst_zero:
1387 if hasattr(self.dec2.e.do, "rc"):
1388 rc_en = yield self.dec2.e.do.rc.rc
1389 if rc_en:
1390 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1391 self.handle_comparison(results, regnum)
1392
1393 # any modified return results?
1394 if info.write_regs:
1395 for name, output in zip(output_names, results):
1396 if name == 'overflow': # ignore, done already (above)
1397 continue
1398 if isinstance(output, int):
1399 output = SelectableInt(output, 256)
1400 if name in ['CA', 'CA32']:
1401 if carry_en:
1402 log("writing %s to XER" % name, output)
1403 self.spr['XER'][XER_bits[name]] = output.value
1404 else:
1405 log("NOT writing %s to XER" % name, output)
1406 elif name in info.special_regs:
1407 log('writing special %s' % name, output, special_sprs)
1408 if name in special_sprs:
1409 self.spr[name] = output
1410 else:
1411 self.namespace[name].eq(output)
1412 if name == 'MSR':
1413 log('msr written', hex(self.msr.value))
1414 else:
1415 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2,
1416 name)
1417 if regnum is None:
1418 regnum, is_vec = yield from get_pdecode_idx_out2(
1419 self.dec2, name)
1420 if regnum is None:
1421 # temporary hack for not having 2nd output
1422 regnum = yield getattr(self.decoder, name)
1423 is_vec = False
1424 if self.is_svp64_mode and pred_dst_zero:
1425 log('zeroing reg %d %s' % (regnum, str(output)),
1426 is_vec)
1427 output = SelectableInt(0, 256)
1428 else:
1429 if name in fregs:
1430 ftype = 'fpr'
1431 else:
1432 ftype = 'gpr'
1433 log('writing %s %s %s' % (regnum, ftype, str(output)),
1434 is_vec)
1435 if output.bits > 64:
1436 output = SelectableInt(output.value, 64)
1437 if name in fregs:
1438 self.fpr[regnum] = output
1439 else:
1440 self.gpr[regnum] = output
1441
1442 # check if it is the SVSTATE.src/dest step that needs incrementing
1443 # this is our Sub-Program-Counter loop from 0 to VL-1
1444 pre = False
1445 post = False
1446 if self.allow_next_step_inc:
1447 log("SVSTATE_NEXT: inc requested")
1448 yield from self.svstate_pre_inc()
1449 pre = yield from self.update_new_svstate_steps()
1450 if pre:
1451 # reset at end of loop including exit Vertical Mode
1452 log ("SVSTATE_NEXT: end of loop, reset")
1453 self.svp64_reset_loop()
1454 self.msr[MSRb.SVF] = 0
1455 self.update_nia()
1456 if rc_en:
1457 results = [SelectableInt(0, 64)]
1458 self.handle_comparison(results) # CR0
1459 else:
1460 log ("SVSTATE_NEXT: post-inc")
1461 srcstep, dststep = self.new_srcstep, self.new_dststep
1462 vl = self.svstate.vl.asint(msb0=True)
1463 end_src = srcstep == vl-1
1464 end_dst = dststep == vl-1
1465 if not end_src:
1466 self.svstate.srcstep += SelectableInt(1, 7)
1467 if not end_dst:
1468 self.svstate.dststep += SelectableInt(1, 7)
1469 self.namespace['SVSTATE'] = self.svstate.spr
1470 # set CR0 (if Rc=1) based on end
1471 if rc_en:
1472 srcstep = self.svstate.srcstep.asint(msb0=True)
1473 dststep = self.svstate.srcstep.asint(msb0=True)
1474 endtest = 0 if (end_src or end_dst) else 1
1475 results = [SelectableInt(endtest, 64)]
1476 self.handle_comparison(results) # CR0
1477 if end_src or end_dst:
1478 # reset at end of loop including exit Vertical Mode
1479 log ("SVSTATE_NEXT: after increments, reset")
1480 self.svp64_reset_loop()
1481 self.msr[MSRb.SVF] = 0
1482
1483 elif self.is_svp64_mode:
1484 yield from self.svstate_post_inc()
1485 else:
1486 # XXX only in non-SVP64 mode!
1487 # record state of whether the current operation was an svshape,
1488 # to be able to know if it should apply in the next instruction.
1489 # also (if going to use this instruction) should disable ability
1490 # to interrupt in between. sigh.
1491 self.last_op_svshape = asmop == 'svremap'
1492
1493 self.update_pc_next()
1494
1495 def SVSTATE_NEXT(self):
1496 """explicitly moves srcstep/dststep on to next element, for
1497 "Vertical-First" mode. this function is called from
1498 setvl pseudo-code, as a pseudo-op "svstep"
1499 """
1500 log("SVSTATE_NEXT")
1501 self.allow_next_step_inc = True
1502
1503 def svstate_pre_inc(self):
1504 """check if srcstep/dststep need to skip over masked-out predicate bits
1505 """
1506 # get SVSTATE VL (oh and print out some debug stuff)
1507 vl = self.svstate.vl.asint(msb0=True)
1508 srcstep = self.svstate.srcstep.asint(msb0=True)
1509 dststep = self.svstate.dststep.asint(msb0=True)
1510 sv_a_nz = yield self.dec2.sv_a_nz
1511 fft_mode = yield self.dec2.use_svp64_fft
1512 in1 = yield self.dec2.e.read_reg1.data
1513 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1514 vl, srcstep, dststep, sv_a_nz, in1, fft_mode)
1515
1516 # get predicate mask
1517 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1518
1519 pmode = yield self.dec2.rm_dec.predmode
1520 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1521 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1522 srcpred = yield self.dec2.rm_dec.srcpred
1523 dstpred = yield self.dec2.rm_dec.dstpred
1524 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1525 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1526 if pmode == SVP64PredMode.INT.value:
1527 srcmask = dstmask = get_predint(self.gpr, dstpred)
1528 if sv_ptype == SVPtype.P2.value:
1529 srcmask = get_predint(self.gpr, srcpred)
1530 elif pmode == SVP64PredMode.CR.value:
1531 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1532 if sv_ptype == SVPtype.P2.value:
1533 srcmask = get_predcr(self.crl, srcpred, vl)
1534 log (" pmode", pmode)
1535 log (" reverse", reverse_gear)
1536 log (" ptype", sv_ptype)
1537 log (" srcpred", bin(srcpred))
1538 log (" dstpred", bin(dstpred))
1539 log (" srcmask", bin(srcmask))
1540 log (" dstmask", bin(dstmask))
1541 log (" pred_sz", bin(pred_src_zero))
1542 log (" pred_dz", bin(pred_dst_zero))
1543
1544 # okaaay, so here we simply advance srcstep (TODO dststep)
1545 # until the predicate mask has a "1" bit... or we run out of VL
1546 # let srcstep==VL be the indicator to move to next instruction
1547 if not pred_src_zero:
1548 while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
1549 log (" skip", bin(1<<srcstep))
1550 srcstep += 1
1551 # same for dststep
1552 if not pred_dst_zero:
1553 while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
1554 log (" skip", bin(1<<dststep))
1555 dststep += 1
1556
1557 # now work out if the relevant mask bits require zeroing
1558 if pred_dst_zero:
1559 pred_dst_zero = ((1<<dststep) & dstmask) == 0
1560 if pred_src_zero:
1561 pred_src_zero = ((1<<srcstep) & srcmask) == 0
1562
1563 # store new srcstep / dststep
1564 self.new_srcstep, self.new_dststep = srcstep, dststep
1565 self.pred_dst_zero, self.pred_src_zero = pred_dst_zero, pred_src_zero
1566 log (" new srcstep", srcstep)
1567 log (" new dststep", dststep)
1568
1569 def update_new_svstate_steps(self):
1570 srcstep, dststep = self.new_srcstep, self.new_dststep
1571
1572 # update SVSTATE with new srcstep
1573 self.svstate.srcstep[0:7] = srcstep
1574 self.svstate.dststep[0:7] = dststep
1575 self.namespace['SVSTATE'] = self.svstate.spr
1576 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
1577 yield Settle() # let decoder update
1578 srcstep = self.svstate.srcstep.asint(msb0=True)
1579 dststep = self.svstate.dststep.asint(msb0=True)
1580 vl = self.svstate.vl.asint(msb0=True)
1581 log (" srcstep", srcstep)
1582 log (" dststep", dststep)
1583
1584 # check if end reached (we let srcstep overrun, above)
1585 # nothing needs doing (TODO zeroing): just do next instruction
1586 return srcstep == vl or dststep == vl
1587
1588 def svstate_post_inc(self, vf=0):
1589 # check if SV "Vertical First" mode is enabled
1590 log (" SV Vertical First", vf, self.msr[MSRb.SVF].value)
1591 if not vf and self.msr[MSRb.SVF].value == 1:
1592 self.update_nia()
1593 return True
1594
1595 # check if it is the SVSTATE.src/dest step that needs incrementing
1596 # this is our Sub-Program-Counter loop from 0 to VL-1
1597 # XXX twin predication TODO
1598 vl = self.svstate.vl.asint(msb0=True)
1599 mvl = self.svstate.maxvl.asint(msb0=True)
1600 srcstep = self.svstate.srcstep.asint(msb0=True)
1601 dststep = self.svstate.dststep.asint(msb0=True)
1602 rm_mode = yield self.dec2.rm_dec.mode
1603 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1604 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1605 out_vec = not (yield self.dec2.no_out_vec)
1606 in_vec = not (yield self.dec2.no_in_vec)
1607 log (" svstate.vl", vl)
1608 log (" svstate.mvl", mvl)
1609 log (" svstate.srcstep", srcstep)
1610 log (" svstate.dststep", dststep)
1611 log (" mode", rm_mode)
1612 log (" reverse", reverse_gear)
1613 log (" out_vec", out_vec)
1614 log (" in_vec", in_vec)
1615 log (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1616 # check if srcstep needs incrementing by one, stop PC advancing
1617 # svp64 loop can end early if the dest is scalar for single-pred
1618 # but for 2-pred both src/dest have to be checked.
1619 # XXX this might not be true! it may just be LD/ST
1620 if sv_ptype == SVPtype.P2.value:
1621 svp64_is_vector = (out_vec or in_vec)
1622 else:
1623 svp64_is_vector = out_vec
1624 if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
1625 self.svstate.srcstep += SelectableInt(1, 7)
1626 self.svstate.dststep += SelectableInt(1, 7)
1627 self.pc.NIA.value = self.pc.CIA.value
1628 self.namespace['NIA'] = self.pc.NIA
1629 self.namespace['SVSTATE'] = self.svstate.spr
1630 log("end of sub-pc call", self.namespace['CIA'],
1631 self.namespace['NIA'])
1632 return False # DO NOT allow PC update whilst Sub-PC loop running
1633
1634 # reset loop to zero and update NIA
1635 self.svp64_reset_loop()
1636 self.update_nia()
1637
1638 return True
1639
1640 def update_pc_next(self):
1641 # UPDATE program counter
1642 self.pc.update(self.namespace, self.is_svp64_mode)
1643 self.svstate.spr = self.namespace['SVSTATE']
1644 log("end of call", self.namespace['CIA'],
1645 self.namespace['NIA'],
1646 self.namespace['SVSTATE'])
1647
1648 def svp64_reset_loop(self):
1649 self.svstate.srcstep[0:7] = 0
1650 self.svstate.dststep[0:7] = 0
1651 log (" svstate.srcstep loop end (PC to update)")
1652 self.namespace['SVSTATE'] = self.svstate.spr
1653
1654 def update_nia(self):
1655 self.pc.update_nia(self.is_svp64_mode)
1656 self.namespace['NIA'] = self.pc.NIA
1657
1658 def inject():
1659 """Decorator factory.
1660
1661 this decorator will "inject" variables into the function's namespace,
1662 from the *dictionary* in self.namespace. it therefore becomes possible
1663 to make it look like a whole stack of variables which would otherwise
1664 need "self." inserted in front of them (*and* for those variables to be
1665 added to the instance) "appear" in the function.
1666
1667 "self.namespace['SI']" for example becomes accessible as just "SI" but
1668 *only* inside the function, when decorated.
1669 """
1670 def variable_injector(func):
1671 @wraps(func)
1672 def decorator(*args, **kwargs):
1673 try:
1674 func_globals = func.__globals__ # Python 2.6+
1675 except AttributeError:
1676 func_globals = func.func_globals # Earlier versions.
1677
1678 context = args[0].namespace # variables to be injected
1679 saved_values = func_globals.copy() # Shallow copy of dict.
1680 func_globals.update(context)
1681 result = func(*args, **kwargs)
1682 log("globals after", func_globals['CIA'], func_globals['NIA'])
1683 log("args[0]", args[0].namespace['CIA'],
1684 args[0].namespace['NIA'],
1685 args[0].namespace['SVSTATE'])
1686 args[0].namespace = func_globals
1687 #exec (func.__code__, func_globals)
1688
1689 # finally:
1690 # func_globals = saved_values # Undo changes.
1691
1692 return result
1693
1694 return decorator
1695
1696 return variable_injector
1697
1698