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