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