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