d57a8fc12387dfa63e231ec952ad6a59d169f823
[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 # this is for setvl "Vertical" mode: if set true,
1107 # srcstep/dststep is explicitly advanced
1108 self.allow_next_step_inc = False
1109
1110 # nop has to be supported, we could let the actual op calculate
1111 # but PowerDecoder has a pattern for nop
1112 if name is 'nop':
1113 self.update_pc_next()
1114 return
1115
1116 info = self.instrs[name]
1117 yield from self.prep_namespace(info.form, info.op_fields)
1118
1119 # preserve order of register names
1120 input_names = create_args(list(info.read_regs) +
1121 list(info.uninit_regs))
1122 log(input_names)
1123
1124 # get SVP64 entry for the current instruction
1125 sv_rm = self.svp64rm.instrs.get(name)
1126 if sv_rm is not None:
1127 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1128 else:
1129 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1130 log ("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1131
1132 # see if srcstep/dststep need skipping over masked-out predicate bits
1133 if self.is_svp64_mode:
1134 yield from self.svstate_pre_inc()
1135 pre = yield from self.update_new_svstate_steps()
1136 if pre:
1137 self.svp64_reset_loop()
1138 self.update_nia()
1139 self.update_pc_next()
1140 return
1141 srcstep, dststep = self.new_srcstep, self.new_dststep
1142 pred_dst_zero = self.pred_dst_zero
1143 pred_src_zero = self.pred_src_zero
1144 vl = self.svstate.vl.asint(msb0=True)
1145
1146 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1147 if self.is_svp64_mode and vl == 0:
1148 self.pc.update(self.namespace, self.is_svp64_mode)
1149 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1150 self.namespace['NIA'])
1151 return
1152
1153 # for when SVSHAPE is active, a very bad hack here (to be replaced)
1154 # using pre-arranged schedule. all of this is awful but it is a
1155 # start. next job will be to put the proper activation in place
1156 yield self.dec2.remap_active.eq(1 if self.last_op_svshape else 0)
1157 yield Settle()
1158 if self.is_svp64_mode and self.last_op_svshape:
1159 # get four SVSHAPEs. here we are hard-coding
1160 # SVSHAPE0 to FRT, SVSHAPE1 to FRA, SVSHAPE2 to FRC and
1161 # SVSHAPE3 to FRB, assuming "fmadd FRT, FRA, FRC, FRB."
1162 SVSHAPE0 = self.spr['SVSHAPE0']
1163 SVSHAPE1 = self.spr['SVSHAPE1']
1164 SVSHAPE2 = self.spr['SVSHAPE2']
1165 SVSHAPE3 = self.spr['SVSHAPE3']
1166 for i in range(4):
1167 sname = 'SVSHAPE%d' % i
1168 shape = self.spr[sname]
1169 print (sname, bin(shape.value))
1170 print (" lims", shape.lims)
1171 print (" mode", shape.mode)
1172 print (" skip", shape.skip)
1173
1174 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1175 (SVSHAPE1, SVSHAPE1.get_iterator()),
1176 (SVSHAPE2, SVSHAPE2.get_iterator()),
1177 (SVSHAPE3, SVSHAPE3.get_iterator()),
1178 ]
1179 rremaps = []
1180 for i, (shape, remap) in enumerate(remaps):
1181 # zero is "disabled"
1182 if shape.value == 0x0:
1183 continue
1184 # XXX hardcoded! pick dststep for out (i==0) else srcstep
1185 if shape.mode == 0b00: # multiply mode
1186 step = dststep if (i == 0) else srcstep
1187 if shape.mode == 0b01: # FFT butterfly mode
1188 step = srcstep # XXX HACK - for now only use srcstep
1189 # this is terrible. O(N^2) looking for the match. but hey.
1190 for idx, remap_idx in enumerate(remap):
1191 if idx == step:
1192 break
1193 # multiply mode
1194 if shape.mode == 0b00:
1195 if i == 0:
1196 yield self.dec2.o_step.eq(remap_idx) # RT
1197 yield self.dec2.o2_step.eq(remap_idx) # EA
1198 elif i == 1:
1199 yield self.dec2.in1_step.eq(remap_idx) # RA
1200 elif i == 2:
1201 yield self.dec2.in3_step.eq(remap_idx) # RB
1202 elif i == 3:
1203 yield self.dec2.in2_step.eq(remap_idx) # RC
1204 # FFT butterfly mode
1205 if shape.mode == 0b01:
1206 if i == 0:
1207 yield self.dec2.o_step.eq(remap_idx) # RT
1208 yield self.dec2.in2_step.eq(remap_idx) # RB
1209 elif i == 1:
1210 yield self.dec2.in1_step.eq(remap_idx) # RA
1211 yield self.dec2.o2_step.eq(remap_idx) # EA (FRS)
1212 elif i == 2:
1213 yield self.dec2.in3_step.eq(remap_idx) # RC
1214 elif i == 3:
1215 pass # no SVSHAPE3
1216 rremaps.append((shape.mode, i, idx, remap_idx)) # debug printing
1217 for x in rremaps:
1218 print ("shape remap", x)
1219 # after that, settle down (combinatorial) to let Vector reg numbers
1220 # work themselves out
1221 yield Settle()
1222 remap_active = yield self.dec2.remap_active
1223 print ("remap active", remap_active)
1224
1225 # main input registers (RT, RA ...)
1226 inputs = []
1227 for name in input_names:
1228 # using PowerDecoder2, first, find the decoder index.
1229 # (mapping name RA RB RC RS to in1, in2, in3)
1230 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1231 if regnum is None:
1232 # doing this is not part of svp64, it's because output
1233 # registers, to be modified, need to be in the namespace.
1234 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1235 if regnum is None:
1236 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2,
1237 name)
1238
1239 # in case getting the register number is needed, _RA, _RB
1240 regname = "_" + name
1241 self.namespace[regname] = regnum
1242 if not self.is_svp64_mode or not pred_src_zero:
1243 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1244 if name in fregs:
1245 reg_val = self.fpr(regnum)
1246 elif name is not None:
1247 reg_val = self.gpr(regnum)
1248 else:
1249 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1250 reg_val = 0
1251 inputs.append(reg_val)
1252 # arrrrgh, awful hack, to get _RT into namespace
1253 if asmop == 'setvl':
1254 regname = "_RT"
1255 RT = yield self.dec2.dec.RT
1256 self.namespace[regname] = SelectableInt(RT, 5)
1257
1258 # in SVP64 mode for LD/ST work out immediate
1259 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1260 # use info.form to detect
1261 replace_d = False # update / replace constant in pseudocode
1262 if self.is_svp64_mode:
1263 ldstmode = yield self.dec2.rm_dec.ldstmode
1264 # bitreverse mode reads SVD (or SVDS - TODO)
1265 # *BUT*... because this is "overloading" of LD operations,
1266 # it gets *STORED* into D (or DS, TODO)
1267 if ldstmode == SVP64LDSTmode.BITREVERSE.value:
1268 imm = yield self.dec2.dec.fields.FormSVD.SVD[0:11]
1269 imm = exts(imm, 11) # sign-extend to integer
1270 print ("bitrev SVD", imm)
1271 replace_d = True
1272 else:
1273 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1274 imm = exts(imm, 16) # sign-extend to integer
1275 # get the right step. LD is from srcstep, ST is dststep
1276 op = yield self.dec2.e.do.insn_type
1277 offsmul = 0
1278 if op == MicrOp.OP_LOAD.value:
1279 offsmul = srcstep
1280 log("D-field src", imm, offsmul)
1281 elif op == MicrOp.OP_STORE.value:
1282 offsmul = dststep
1283 log("D-field dst", imm, offsmul)
1284 # bit-reverse mode
1285 if ldstmode == SVP64LDSTmode.BITREVERSE.value:
1286 # manually look up RC, sigh
1287 RC = yield self.dec2.dec.RC[0:5]
1288 RC = self.gpr(RC)
1289 log ("RC", RC.value, "imm", imm, "offs", bin(offsmul),
1290 "rev", bin(bitrev(offsmul, vl)))
1291 imm = SelectableInt((imm * bitrev(offsmul, vl)) << RC.value, 32)
1292 # Unit-Strided LD/ST adds offset*width to immediate
1293 elif ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1294 ldst_len = yield self.dec2.e.do.data_len
1295 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1296 replace_d = True
1297 # Element-strided multiplies the immediate by element step
1298 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1299 imm = SelectableInt(imm * offsmul, 32)
1300 replace_d = True
1301 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1302 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1303 log("LDSTmode", ldstmode, SVP64LDSTmode.BITREVERSE.value,
1304 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1305 # new replacement D
1306 if replace_d:
1307 self.namespace['D'] = imm
1308
1309 # "special" registers
1310 for special in info.special_regs:
1311 if special in special_sprs:
1312 inputs.append(self.spr[special])
1313 else:
1314 inputs.append(self.namespace[special])
1315
1316 # clear trap (trap) NIA
1317 self.trap_nia = None
1318
1319 # execute actual instruction here (finally)
1320 log("inputs", inputs)
1321 results = info.func(self, *inputs)
1322 log("results", results)
1323
1324 # "inject" decorator takes namespace from function locals: we need to
1325 # overwrite NIA being overwritten (sigh)
1326 if self.trap_nia is not None:
1327 self.namespace['NIA'] = self.trap_nia
1328
1329 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1330
1331 # check if op was a LD/ST so that debugging can check the
1332 # address
1333 if int_op in [MicrOp.OP_STORE.value,
1334 ]:
1335 self.last_st_addr = self.mem.last_st_addr
1336 if int_op in [MicrOp.OP_LOAD.value,
1337 ]:
1338 self.last_ld_addr = self.mem.last_ld_addr
1339 log ("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1340 self.last_st_addr, self.last_ld_addr)
1341
1342 # detect if CA/CA32 already in outputs (sra*, basically)
1343 already_done = 0
1344 if info.write_regs:
1345 output_names = create_args(info.write_regs)
1346 for name in output_names:
1347 if name == 'CA':
1348 already_done |= 1
1349 if name == 'CA32':
1350 already_done |= 2
1351
1352 log("carry already done?", bin(already_done))
1353 if hasattr(self.dec2.e.do, "output_carry"):
1354 carry_en = yield self.dec2.e.do.output_carry
1355 else:
1356 carry_en = False
1357 if carry_en:
1358 yield from self.handle_carry_(inputs, results, already_done)
1359
1360 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1361 # detect if overflow was in return result
1362 overflow = None
1363 if info.write_regs:
1364 for name, output in zip(output_names, results):
1365 if name == 'overflow':
1366 overflow = output
1367
1368 if hasattr(self.dec2.e.do, "oe"):
1369 ov_en = yield self.dec2.e.do.oe.oe
1370 ov_ok = yield self.dec2.e.do.oe.ok
1371 else:
1372 ov_en = False
1373 ov_ok = False
1374 log("internal overflow", overflow, ov_en, ov_ok)
1375 if ov_en & ov_ok:
1376 yield from self.handle_overflow(inputs, results, overflow)
1377
1378 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1379 rc_en = False
1380 if not self.is_svp64_mode or not pred_dst_zero:
1381 if hasattr(self.dec2.e.do, "rc"):
1382 rc_en = yield self.dec2.e.do.rc.rc
1383 if rc_en:
1384 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1385 self.handle_comparison(results, regnum)
1386
1387 # any modified return results?
1388 if info.write_regs:
1389 for name, output in zip(output_names, results):
1390 if name == 'overflow': # ignore, done already (above)
1391 continue
1392 if isinstance(output, int):
1393 output = SelectableInt(output, 256)
1394 if name in ['CA', 'CA32']:
1395 if carry_en:
1396 log("writing %s to XER" % name, output)
1397 self.spr['XER'][XER_bits[name]] = output.value
1398 else:
1399 log("NOT writing %s to XER" % name, output)
1400 elif name in info.special_regs:
1401 log('writing special %s' % name, output, special_sprs)
1402 if name in special_sprs:
1403 self.spr[name] = output
1404 else:
1405 self.namespace[name].eq(output)
1406 if name == 'MSR':
1407 log('msr written', hex(self.msr.value))
1408 else:
1409 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2,
1410 name)
1411 if regnum is None:
1412 regnum, is_vec = yield from get_pdecode_idx_out2(
1413 self.dec2, name)
1414 if regnum is None:
1415 # temporary hack for not having 2nd output
1416 regnum = yield getattr(self.decoder, name)
1417 is_vec = False
1418 if self.is_svp64_mode and pred_dst_zero:
1419 log('zeroing reg %d %s' % (regnum, str(output)),
1420 is_vec)
1421 output = SelectableInt(0, 256)
1422 else:
1423 if name in fregs:
1424 ftype = 'fpr'
1425 else:
1426 ftype = 'gpr'
1427 log('writing %s %s %s' % (regnum, ftype, str(output)),
1428 is_vec)
1429 if output.bits > 64:
1430 output = SelectableInt(output.value, 64)
1431 if name in fregs:
1432 self.fpr[regnum] = output
1433 else:
1434 self.gpr[regnum] = output
1435
1436 # check if it is the SVSTATE.src/dest step that needs incrementing
1437 # this is our Sub-Program-Counter loop from 0 to VL-1
1438 pre = False
1439 post = False
1440 if self.allow_next_step_inc:
1441 log("SVSTATE_NEXT: inc requested")
1442 yield from self.svstate_pre_inc()
1443 pre = yield from self.update_new_svstate_steps()
1444 if pre:
1445 log ("SVSTATE_NEXT: end of loop, reset (TODO, update CR0)")
1446 self.svp64_reset_loop()
1447 self.update_nia()
1448 else:
1449 log ("SVSTATE_NEXT: post-inc")
1450 srcstep, dststep = self.new_srcstep, self.new_dststep
1451 vl = self.svstate.vl.asint(msb0=True)
1452 end_src = srcstep == vl-1
1453 end_dst = dststep == vl-1
1454 if not end_src:
1455 self.svstate.srcstep += SelectableInt(1, 7)
1456 if not end_dst:
1457 self.svstate.dststep += SelectableInt(1, 7)
1458 self.namespace['SVSTATE'] = self.svstate.spr
1459 if end_src or end_dst:
1460 self.svp64_reset_loop()
1461 # TODO: set CR0 (if Rc=1) based on end
1462 elif self.is_svp64_mode:
1463 yield from self.svstate_post_inc()
1464 else:
1465 # XXX only in non-SVP64 mode!
1466 # record state of whether the current operation was an svshape,
1467 # to be able to know if it should apply in the next instruction.
1468 # also (if going to use this instruction) should disable ability
1469 # to interrupt in between. sigh.
1470 self.last_op_svshape = asmop == 'svremap'
1471
1472 self.update_pc_next()
1473
1474 def SVSTATE_NEXT(self):
1475 """explicitly moves srcstep/dststep on to next element, for
1476 "Vertical-First" mode. this function is called from
1477 setvl pseudo-code, as a pseudo-op "svstep"
1478 """
1479 log("SVSTATE_NEXT")
1480 self.allow_next_step_inc = True
1481
1482 def svstate_pre_inc(self):
1483 """check if srcstep/dststep need to skip over masked-out predicate bits
1484 """
1485 # get SVSTATE VL (oh and print out some debug stuff)
1486 vl = self.svstate.vl.asint(msb0=True)
1487 srcstep = self.svstate.srcstep.asint(msb0=True)
1488 dststep = self.svstate.dststep.asint(msb0=True)
1489 sv_a_nz = yield self.dec2.sv_a_nz
1490 fft_mode = yield self.dec2.use_svp64_fft
1491 in1 = yield self.dec2.e.read_reg1.data
1492 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft",
1493 vl, srcstep, dststep, sv_a_nz, in1, fft_mode)
1494
1495 # get predicate mask
1496 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1497
1498 pmode = yield self.dec2.rm_dec.predmode
1499 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1500 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1501 srcpred = yield self.dec2.rm_dec.srcpred
1502 dstpred = yield self.dec2.rm_dec.dstpred
1503 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1504 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1505 if pmode == SVP64PredMode.INT.value:
1506 srcmask = dstmask = get_predint(self.gpr, dstpred)
1507 if sv_ptype == SVPtype.P2.value:
1508 srcmask = get_predint(self.gpr, srcpred)
1509 elif pmode == SVP64PredMode.CR.value:
1510 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1511 if sv_ptype == SVPtype.P2.value:
1512 srcmask = get_predcr(self.crl, srcpred, vl)
1513 log (" pmode", pmode)
1514 log (" reverse", reverse_gear)
1515 log (" ptype", sv_ptype)
1516 log (" srcpred", bin(srcpred))
1517 log (" dstpred", bin(dstpred))
1518 log (" srcmask", bin(srcmask))
1519 log (" dstmask", bin(dstmask))
1520 log (" pred_sz", bin(pred_src_zero))
1521 log (" pred_dz", bin(pred_dst_zero))
1522
1523 # okaaay, so here we simply advance srcstep (TODO dststep)
1524 # until the predicate mask has a "1" bit... or we run out of VL
1525 # let srcstep==VL be the indicator to move to next instruction
1526 if not pred_src_zero:
1527 while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
1528 log (" skip", bin(1<<srcstep))
1529 srcstep += 1
1530 # same for dststep
1531 if not pred_dst_zero:
1532 while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
1533 log (" skip", bin(1<<dststep))
1534 dststep += 1
1535
1536 # now work out if the relevant mask bits require zeroing
1537 if pred_dst_zero:
1538 pred_dst_zero = ((1<<dststep) & dstmask) == 0
1539 if pred_src_zero:
1540 pred_src_zero = ((1<<srcstep) & srcmask) == 0
1541
1542 # store new srcstep / dststep
1543 self.new_srcstep, self.new_dststep = srcstep, dststep
1544 self.pred_dst_zero, self.pred_src_zero = pred_dst_zero, pred_src_zero
1545 log (" new srcstep", srcstep)
1546 log (" new dststep", dststep)
1547
1548 def update_new_svstate_steps(self):
1549 srcstep, dststep = self.new_srcstep, self.new_dststep
1550
1551 # update SVSTATE with new srcstep
1552 self.svstate.srcstep[0:7] = srcstep
1553 self.svstate.dststep[0:7] = dststep
1554 self.namespace['SVSTATE'] = self.svstate.spr
1555 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
1556 yield Settle() # let decoder update
1557 srcstep = self.svstate.srcstep.asint(msb0=True)
1558 dststep = self.svstate.dststep.asint(msb0=True)
1559 vl = self.svstate.vl.asint(msb0=True)
1560 log (" srcstep", srcstep)
1561 log (" dststep", dststep)
1562
1563 # check if end reached (we let srcstep overrun, above)
1564 # nothing needs doing (TODO zeroing): just do next instruction
1565 return srcstep == vl or dststep == vl
1566
1567 def svstate_post_inc(self, vf=0):
1568 # check if SV "Vertical First" mode is enabled
1569 log (" SV Vertical First", vf, self.msr[MSRb.SVF].value)
1570 if not vf and self.msr[MSRb.SVF].value == 1:
1571 self.update_nia()
1572 return True
1573
1574 # check if it is the SVSTATE.src/dest step that needs incrementing
1575 # this is our Sub-Program-Counter loop from 0 to VL-1
1576 # XXX twin predication TODO
1577 vl = self.svstate.vl.asint(msb0=True)
1578 mvl = self.svstate.maxvl.asint(msb0=True)
1579 srcstep = self.svstate.srcstep.asint(msb0=True)
1580 dststep = self.svstate.dststep.asint(msb0=True)
1581 rm_mode = yield self.dec2.rm_dec.mode
1582 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1583 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1584 out_vec = not (yield self.dec2.no_out_vec)
1585 in_vec = not (yield self.dec2.no_in_vec)
1586 log (" svstate.vl", vl)
1587 log (" svstate.mvl", mvl)
1588 log (" svstate.srcstep", srcstep)
1589 log (" svstate.dststep", dststep)
1590 log (" mode", rm_mode)
1591 log (" reverse", reverse_gear)
1592 log (" out_vec", out_vec)
1593 log (" in_vec", in_vec)
1594 log (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1595 # check if srcstep needs incrementing by one, stop PC advancing
1596 # svp64 loop can end early if the dest is scalar for single-pred
1597 # but for 2-pred both src/dest have to be checked.
1598 # XXX this might not be true! it may just be LD/ST
1599 if sv_ptype == SVPtype.P2.value:
1600 svp64_is_vector = (out_vec or in_vec)
1601 else:
1602 svp64_is_vector = out_vec
1603 if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
1604 self.svstate.srcstep += SelectableInt(1, 7)
1605 self.svstate.dststep += SelectableInt(1, 7)
1606 self.pc.NIA.value = self.pc.CIA.value
1607 self.namespace['NIA'] = self.pc.NIA
1608 self.namespace['SVSTATE'] = self.svstate.spr
1609 log("end of sub-pc call", self.namespace['CIA'],
1610 self.namespace['NIA'])
1611 return False # DO NOT allow PC update whilst Sub-PC loop running
1612
1613 # reset loop to zero and update NIA
1614 self.svp64_reset_loop()
1615 self.update_nia()
1616
1617 return True
1618
1619 def update_pc_next(self):
1620 # UPDATE program counter
1621 self.pc.update(self.namespace, self.is_svp64_mode)
1622 self.svstate.spr = self.namespace['SVSTATE']
1623 log("end of call", self.namespace['CIA'],
1624 self.namespace['NIA'],
1625 self.namespace['SVSTATE'])
1626
1627 def svp64_reset_loop(self):
1628 self.svstate.srcstep[0:7] = 0
1629 self.svstate.dststep[0:7] = 0
1630 log (" svstate.srcstep loop end (PC to update)")
1631 self.namespace['SVSTATE'] = self.svstate.spr
1632
1633 def update_nia(self):
1634 self.pc.update_nia(self.is_svp64_mode)
1635 self.namespace['NIA'] = self.pc.NIA
1636
1637 def inject():
1638 """Decorator factory.
1639
1640 this decorator will "inject" variables into the function's namespace,
1641 from the *dictionary* in self.namespace. it therefore becomes possible
1642 to make it look like a whole stack of variables which would otherwise
1643 need "self." inserted in front of them (*and* for those variables to be
1644 added to the instance) "appear" in the function.
1645
1646 "self.namespace['SI']" for example becomes accessible as just "SI" but
1647 *only* inside the function, when decorated.
1648 """
1649 def variable_injector(func):
1650 @wraps(func)
1651 def decorator(*args, **kwargs):
1652 try:
1653 func_globals = func.__globals__ # Python 2.6+
1654 except AttributeError:
1655 func_globals = func.func_globals # Earlier versions.
1656
1657 context = args[0].namespace # variables to be injected
1658 saved_values = func_globals.copy() # Shallow copy of dict.
1659 func_globals.update(context)
1660 result = func(*args, **kwargs)
1661 log("globals after", func_globals['CIA'], func_globals['NIA'])
1662 log("args[0]", args[0].namespace['CIA'],
1663 args[0].namespace['NIA'],
1664 args[0].namespace['SVSTATE'])
1665 args[0].namespace = func_globals
1666 #exec (func.__code__, func_globals)
1667
1668 # finally:
1669 # func_globals = saved_values # Undo changes.
1670
1671 return result
1672
1673 return decorator
1674
1675 return variable_injector
1676
1677