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