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