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