revert register reordering in 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,
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)
462 return None, False
463
464
465 # XXX TODO
466 def get_pdecode_idx_out2(dec2, name):
467 op = dec2.dec.op
468 print ("TODO: get_pdecode_idx_out2", name)
469 return None, False
470
471
472 class ISACaller:
473 # decoder2 - an instance of power_decoder2
474 # regfile - a list of initial values for the registers
475 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
476 # respect_pc - tracks the program counter. requires initial_insns
477 def __init__(self, decoder2, regfile, initial_sprs=None, initial_cr=0,
478 initial_mem=None, initial_msr=0,
479 initial_svstate=0,
480 initial_insns=None,
481 fpregfile=None,
482 respect_pc=False,
483 disassembly=None,
484 initial_pc=0,
485 bigendian=False,
486 mmu=False,
487 icachemmu=False):
488
489 self.bigendian = bigendian
490 self.halted = False
491 self.is_svp64_mode = False
492 self.respect_pc = respect_pc
493 if initial_sprs is None:
494 initial_sprs = {}
495 if initial_mem is None:
496 initial_mem = {}
497 if fpregfile is None:
498 fpregfile = [0] * 32
499 if initial_insns is None:
500 initial_insns = {}
501 assert self.respect_pc == False, "instructions required to honor pc"
502
503 print("ISACaller insns", respect_pc, initial_insns, disassembly)
504 print("ISACaller initial_msr", initial_msr)
505
506 # "fake program counter" mode (for unit testing)
507 self.fake_pc = 0
508 disasm_start = 0
509 if not respect_pc:
510 if isinstance(initial_mem, tuple):
511 self.fake_pc = initial_mem[0]
512 disasm_start = self.fake_pc
513 else:
514 disasm_start = initial_pc
515
516 # disassembly: we need this for now (not given from the decoder)
517 self.disassembly = {}
518 if disassembly:
519 for i, code in enumerate(disassembly):
520 self.disassembly[i*4 + disasm_start] = code
521
522 # set up registers, instruction memory, data memory, PC, SPRs, MSR
523 self.svp64rm = SVP64RM()
524 if initial_svstate is None:
525 initial_svstate = 0
526 if isinstance(initial_svstate, int):
527 initial_svstate = SVP64State(initial_svstate)
528 self.svstate = initial_svstate
529 self.gpr = GPR(decoder2, self, self.svstate, regfile)
530 self.fpr = GPR(decoder2, self, self.svstate, fpregfile)
531 self.spr = SPR(decoder2, initial_sprs) # initialise SPRs before MMU
532 self.mem = Mem(row_bytes=8, initial_mem=initial_mem)
533 self.imem = Mem(row_bytes=4, initial_mem=initial_insns)
534 # MMU mode, redirect underlying Mem through RADIX
535 self.msr = SelectableInt(initial_msr, 64) # underlying reg
536 if mmu:
537 self.mem = RADIX(self.mem, self)
538 if icachemmu:
539 self.imem = RADIX(self.imem, self)
540 self.pc = PC()
541
542 # TODO, needed here:
543 # FPR (same as GPR except for FP nums)
544 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
545 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
546 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
547 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
548 # -- Done
549 # 2.3.2 LR (actually SPR #8) -- Done
550 # 2.3.3 CTR (actually SPR #9) -- Done
551 # 2.3.4 TAR (actually SPR #815)
552 # 3.2.2 p45 XER (actually SPR #1) -- Done
553 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
554
555 # create CR then allow portions of it to be "selectable" (below)
556 self.cr_fields = CRFields(initial_cr)
557 self.cr = self.cr_fields.cr
558
559 # "undefined", just set to variable-bit-width int (use exts "max")
560 #self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
561
562 self.namespace = {}
563 self.namespace.update(self.spr)
564 self.namespace.update({'GPR': self.gpr,
565 'FPR': self.fpr,
566 'MEM': self.mem,
567 'SPR': self.spr,
568 'memassign': self.memassign,
569 'NIA': self.pc.NIA,
570 'CIA': self.pc.CIA,
571 'SVSTATE': self.svstate.spr,
572 'CR': self.cr,
573 'MSR': self.msr,
574 'undefined': undefined,
575 'mode_is_64bit': True,
576 'SO': XER_bits['SO']
577 })
578
579 # update pc to requested start point
580 self.set_pc(initial_pc)
581
582 # field-selectable versions of Condition Register
583 self.crl = self.cr_fields.crl
584 for i in range(8):
585 self.namespace["CR%d" % i] = self.crl[i]
586
587 self.decoder = decoder2.dec
588 self.dec2 = decoder2
589
590 def call_trap(self, trap_addr, trap_bit):
591 """calls TRAP and sets up NIA to the new execution location.
592 next instruction will begin at trap_addr.
593 """
594 self.TRAP(trap_addr, trap_bit)
595 self.namespace['NIA'] = self.trap_nia
596 self.pc.update(self.namespace, self.is_svp64_mode)
597
598 def TRAP(self, trap_addr=0x700, trap_bit=PIb.TRAP):
599 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
600
601 TRAP function is callable from inside the pseudocode itself,
602 hence the default arguments. when calling from inside ISACaller
603 it is best to use call_trap()
604 """
605 print("TRAP:", hex(trap_addr), hex(self.namespace['MSR'].value))
606 # store CIA(+4?) in SRR0, set NIA to 0x700
607 # store MSR in SRR1, set MSR to um errr something, have to check spec
608 # store SVSTATE (if enabled) in SVSRR0
609 self.spr['SRR0'].value = self.pc.CIA.value
610 self.spr['SRR1'].value = self.namespace['MSR'].value
611 if self.is_svp64_mode:
612 self.spr['SVSRR0'] = self.namespace['SVSTATE'].value
613 self.trap_nia = SelectableInt(trap_addr, 64)
614 self.spr['SRR1'][trap_bit] = 1 # change *copy* of MSR in SRR1
615
616 # set exception bits. TODO: this should, based on the address
617 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
618 # bits appropriately. however it turns out that *for now* in all
619 # cases (all trap_addrs) the exact same thing is needed.
620 self.msr[MSRb.IR] = 0
621 self.msr[MSRb.DR] = 0
622 self.msr[MSRb.FE0] = 0
623 self.msr[MSRb.FE1] = 0
624 self.msr[MSRb.EE] = 0
625 self.msr[MSRb.RI] = 0
626 self.msr[MSRb.SF] = 1
627 self.msr[MSRb.TM] = 0
628 self.msr[MSRb.VEC] = 0
629 self.msr[MSRb.VSX] = 0
630 self.msr[MSRb.PR] = 0
631 self.msr[MSRb.FP] = 0
632 self.msr[MSRb.PMM] = 0
633 self.msr[MSRb.TEs] = 0
634 self.msr[MSRb.TEe] = 0
635 self.msr[MSRb.UND] = 0
636 self.msr[MSRb.LE] = 1
637
638 def memassign(self, ea, sz, val):
639 self.mem.memassign(ea, sz, val)
640
641 def prep_namespace(self, formname, op_fields):
642 # TODO: get field names from form in decoder*1* (not decoder2)
643 # decoder2 is hand-created, and decoder1.sigform is auto-generated
644 # from spec
645 # then "yield" fields only from op_fields rather than hard-coded
646 # list, here.
647 fields = self.decoder.sigforms[formname]
648 for name in op_fields:
649 if name == 'spr':
650 sig = getattr(fields, name.upper())
651 else:
652 sig = getattr(fields, name)
653 val = yield sig
654 # these are all opcode fields involved in index-selection of CR,
655 # and need to do "standard" arithmetic. CR[BA+32] for example
656 # would, if using SelectableInt, only be 5-bit.
657 if name in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
658 self.namespace[name] = val
659 else:
660 self.namespace[name] = SelectableInt(val, sig.width)
661
662 self.namespace['XER'] = self.spr['XER']
663 self.namespace['CA'] = self.spr['XER'][XER_bits['CA']].value
664 self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
665
666 def handle_carry_(self, inputs, outputs, already_done):
667 inv_a = yield self.dec2.e.do.invert_in
668 if inv_a:
669 inputs[0] = ~inputs[0]
670
671 imm_ok = yield self.dec2.e.do.imm_data.ok
672 if imm_ok:
673 imm = yield self.dec2.e.do.imm_data.data
674 inputs.append(SelectableInt(imm, 64))
675 assert len(outputs) >= 1
676 print("outputs", repr(outputs))
677 if isinstance(outputs, list) or isinstance(outputs, tuple):
678 output = outputs[0]
679 else:
680 output = outputs
681 gts = []
682 for x in inputs:
683 print("gt input", x, output)
684 gt = (gtu(x, output))
685 gts.append(gt)
686 print(gts)
687 cy = 1 if any(gts) else 0
688 print("CA", cy, gts)
689 if not (1 & already_done):
690 self.spr['XER'][XER_bits['CA']] = cy
691
692 print("inputs", already_done, inputs)
693 # 32 bit carry
694 # ARGH... different for OP_ADD... *sigh*...
695 op = yield self.dec2.e.do.insn_type
696 if op == MicrOp.OP_ADD.value:
697 res32 = (output.value & (1 << 32)) != 0
698 a32 = (inputs[0].value & (1 << 32)) != 0
699 if len(inputs) >= 2:
700 b32 = (inputs[1].value & (1 << 32)) != 0
701 else:
702 b32 = False
703 cy32 = res32 ^ a32 ^ b32
704 print("CA32 ADD", cy32)
705 else:
706 gts = []
707 for x in inputs:
708 print("input", x, output)
709 print(" x[32:64]", x, x[32:64])
710 print(" o[32:64]", output, output[32:64])
711 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
712 gts.append(gt)
713 cy32 = 1 if any(gts) else 0
714 print("CA32", cy32, gts)
715 if not (2 & already_done):
716 self.spr['XER'][XER_bits['CA32']] = cy32
717
718 def handle_overflow(self, inputs, outputs, div_overflow):
719 if hasattr(self.dec2.e.do, "invert_in"):
720 inv_a = yield self.dec2.e.do.invert_in
721 if inv_a:
722 inputs[0] = ~inputs[0]
723
724 imm_ok = yield self.dec2.e.do.imm_data.ok
725 if imm_ok:
726 imm = yield self.dec2.e.do.imm_data.data
727 inputs.append(SelectableInt(imm, 64))
728 assert len(outputs) >= 1
729 print("handle_overflow", inputs, outputs, div_overflow)
730 if len(inputs) < 2 and div_overflow is None:
731 return
732
733 # div overflow is different: it's returned by the pseudo-code
734 # because it's more complex than can be done by analysing the output
735 if div_overflow is not None:
736 ov, ov32 = div_overflow, div_overflow
737 # arithmetic overflow can be done by analysing the input and output
738 elif len(inputs) >= 2:
739 output = outputs[0]
740
741 # OV (64-bit)
742 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
743 output_sgn = exts(output.value, output.bits) < 0
744 ov = 1 if input_sgn[0] == input_sgn[1] and \
745 output_sgn != input_sgn[0] else 0
746
747 # OV (32-bit)
748 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
749 output32_sgn = exts(output.value, 32) < 0
750 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
751 output32_sgn != input32_sgn[0] else 0
752
753 self.spr['XER'][XER_bits['OV']] = ov
754 self.spr['XER'][XER_bits['OV32']] = ov32
755 so = self.spr['XER'][XER_bits['SO']]
756 so = so | ov
757 self.spr['XER'][XER_bits['SO']] = so
758
759 def handle_comparison(self, outputs, cr_idx=0):
760 out = outputs[0]
761 assert isinstance(out, SelectableInt), \
762 "out zero not a SelectableInt %s" % repr(outputs)
763 print("handle_comparison", out.bits, hex(out.value))
764 # TODO - XXX *processor* in 32-bit mode
765 # https://bugs.libre-soc.org/show_bug.cgi?id=424
766 # if is_32bit:
767 # o32 = exts(out.value, 32)
768 # print ("handle_comparison exts 32 bit", hex(o32))
769 out = exts(out.value, out.bits)
770 print("handle_comparison exts", hex(out))
771 zero = SelectableInt(out == 0, 1)
772 positive = SelectableInt(out > 0, 1)
773 negative = SelectableInt(out < 0, 1)
774 SO = self.spr['XER'][XER_bits['SO']]
775 print("handle_comparison SO", SO)
776 cr_field = selectconcat(negative, positive, zero, SO)
777 self.crl[cr_idx].eq(cr_field)
778
779 def set_pc(self, pc_val):
780 self.namespace['NIA'] = SelectableInt(pc_val, 64)
781 self.pc.update(self.namespace, self.is_svp64_mode)
782
783 def setup_one(self):
784 """set up one instruction
785 """
786 if self.respect_pc:
787 pc = self.pc.CIA.value
788 else:
789 pc = self.fake_pc
790 self._pc = pc
791 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
792 if ins is None:
793 raise KeyError("no instruction at 0x%x" % pc)
794 print("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
795 print("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
796
797 yield self.dec2.sv_rm.eq(0)
798 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
799 yield self.dec2.dec.bigendian.eq(self.bigendian)
800 yield self.dec2.state.msr.eq(self.msr.value)
801 yield self.dec2.state.pc.eq(pc)
802 if self.svstate is not None:
803 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
804
805 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
806 yield Settle()
807 opcode = yield self.dec2.dec.opcode_in
808 pfx = SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
809 pfx.insn.value = opcode
810 major = pfx.major.asint(msb0=True) # MSB0 inversion
811 print ("prefix test: opcode:", major, bin(major),
812 pfx.insn[7] == 0b1, pfx.insn[9] == 0b1)
813 self.is_svp64_mode = ((major == 0b000001) and
814 pfx.insn[7].value == 0b1 and
815 pfx.insn[9].value == 0b1)
816 self.pc.update_nia(self.is_svp64_mode)
817 self.namespace['NIA'] = self.pc.NIA
818 self.namespace['SVSTATE'] = self.svstate.spr
819 if not self.is_svp64_mode:
820 return
821
822 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
823 print ("svp64.rm", bin(pfx.rm.asint(msb0=True)))
824 print (" svstate.vl", self.svstate.vl.asint(msb0=True))
825 print (" svstate.mvl", self.svstate.maxvl.asint(msb0=True))
826 sv_rm = pfx.rm.asint(msb0=True)
827 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
828 print(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
829 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
830 yield self.dec2.sv_rm.eq(sv_rm) # svp64 prefix
831 yield Settle()
832
833 def execute_one(self):
834 """execute one instruction
835 """
836 # get the disassembly code for this instruction
837 if self.is_svp64_mode:
838 code = self.disassembly[self._pc+4]
839 print(" svp64 sim-execute", hex(self._pc), code)
840 else:
841 code = self.disassembly[self._pc]
842 print("sim-execute", hex(self._pc), code)
843 opname = code.split(' ')[0]
844 try:
845 yield from self.call(opname) # execute the instruction
846 except MemException as e: # check for memory errors
847 if e.args[0] != 'unaligned': # only doing aligned at the mo
848 raise e # ... re-raise
849 # run a Trap but set DAR first
850 print ("memory unaligned exception, DAR", e.dar)
851 self.spr['DAR'] = SelectableInt(e.dar, 64)
852 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
853 return
854
855 # don't use this except in special circumstances
856 if not self.respect_pc:
857 self.fake_pc += 4
858
859 print("execute one, CIA NIA", self.pc.CIA.value, self.pc.NIA.value)
860
861 def get_assembly_name(self):
862 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
863 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
864 dec_insn = yield self.dec2.e.do.insn
865 insn_1_11 = yield self.dec2.e.do.insn[1:11]
866 asmcode = yield self.dec2.dec.op.asmcode
867 int_op = yield self.dec2.dec.op.internal_op
868 print("get assembly name asmcode", asmcode, int_op,
869 hex(dec_insn), bin(insn_1_11))
870 asmop = insns.get(asmcode, None)
871
872 # sigh reconstruct the assembly instruction name
873 if hasattr(self.dec2.e.do, "oe"):
874 ov_en = yield self.dec2.e.do.oe.oe
875 ov_ok = yield self.dec2.e.do.oe.ok
876 else:
877 ov_en = False
878 ov_ok = False
879 if hasattr(self.dec2.e.do, "rc"):
880 rc_en = yield self.dec2.e.do.rc.rc
881 rc_ok = yield self.dec2.e.do.rc.ok
882 else:
883 rc_en = False
884 rc_ok = False
885 # grrrr have to special-case MUL op (see DecodeOE)
886 print("ov %d en %d rc %d en %d op %d" %
887 (ov_ok, ov_en, rc_ok, rc_en, int_op))
888 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
889 print("mul op")
890 if rc_en & rc_ok:
891 asmop += "."
892 else:
893 if not asmop.endswith("."): # don't add "." to "andis."
894 if rc_en & rc_ok:
895 asmop += "."
896 if hasattr(self.dec2.e.do, "lk"):
897 lk = yield self.dec2.e.do.lk
898 if lk:
899 asmop += "l"
900 print("int_op", int_op)
901 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
902 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
903 print("AA", AA)
904 if AA:
905 asmop += "a"
906 spr_msb = yield from self.get_spr_msb()
907 if int_op == MicrOp.OP_MFCR.value:
908 if spr_msb:
909 asmop = 'mfocrf'
910 else:
911 asmop = 'mfcr'
912 # XXX TODO: for whatever weird reason this doesn't work
913 # https://bugs.libre-soc.org/show_bug.cgi?id=390
914 if int_op == MicrOp.OP_MTCRF.value:
915 if spr_msb:
916 asmop = 'mtocrf'
917 else:
918 asmop = 'mtcrf'
919 return asmop
920
921 def get_spr_msb(self):
922 dec_insn = yield self.dec2.e.do.insn
923 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
924
925 def call(self, name):
926 """call(opcode) - the primary execution point for instructions
927 """
928 name = name.strip() # remove spaces if not already done so
929 if self.halted:
930 print("halted - not executing", name)
931 return
932
933 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
934 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
935 asmop = yield from self.get_assembly_name()
936 print("call", name, asmop)
937
938 # check privileged
939 int_op = yield self.dec2.dec.op.internal_op
940 spr_msb = yield from self.get_spr_msb()
941
942 instr_is_privileged = False
943 if int_op in [MicrOp.OP_ATTN.value,
944 MicrOp.OP_MFMSR.value,
945 MicrOp.OP_MTMSR.value,
946 MicrOp.OP_MTMSRD.value,
947 # TODO: OP_TLBIE
948 MicrOp.OP_RFID.value]:
949 instr_is_privileged = True
950 if int_op in [MicrOp.OP_MFSPR.value,
951 MicrOp.OP_MTSPR.value] and spr_msb:
952 instr_is_privileged = True
953
954 print("is priv", instr_is_privileged, hex(self.msr.value),
955 self.msr[MSRb.PR])
956 # check MSR priv bit and whether op is privileged: if so, throw trap
957 if instr_is_privileged and self.msr[MSRb.PR] == 1:
958 self.call_trap(0x700, PIb.PRIV)
959 return
960
961 # check halted condition
962 if name == 'attn':
963 self.halted = True
964 return
965
966 # check illegal instruction
967 illegal = False
968 if name not in ['mtcrf', 'mtocrf']:
969 illegal = name != asmop
970
971 # sigh deal with setvl not being supported by binutils (.long)
972 if asmop.startswith('setvl'):
973 illegal = False
974 name = 'setvl'
975
976 if illegal:
977 print("illegal", name, asmop)
978 self.call_trap(0x700, PIb.ILLEG)
979 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
980 (name, asmop, self.pc.CIA.value))
981 return
982
983 info = self.instrs[name]
984 yield from self.prep_namespace(info.form, info.op_fields)
985
986 # preserve order of register names
987 input_names = create_args(list(info.read_regs) +
988 list(info.uninit_regs))
989 print(input_names)
990
991 # get SVP64 entry for the current instruction
992 sv_rm = self.svp64rm.instrs.get(name)
993 if sv_rm is not None:
994 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
995 else:
996 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
997 print ("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
998
999 # get SVSTATE VL (oh and print out some debug stuff)
1000 if self.is_svp64_mode:
1001 vl = self.svstate.vl.asint(msb0=True)
1002 srcstep = self.svstate.srcstep.asint(msb0=True)
1003 dststep = self.svstate.dststep.asint(msb0=True)
1004 sv_a_nz = yield self.dec2.sv_a_nz
1005 in1 = yield self.dec2.e.read_reg1.data
1006 print ("SVP64: VL, srcstep, dststep, sv_a_nz, in1",
1007 vl, srcstep, dststep, sv_a_nz, in1)
1008
1009 # get predicate mask
1010 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1011 if self.is_svp64_mode:
1012 pmode = yield self.dec2.rm_dec.predmode
1013 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1014 srcpred = yield self.dec2.rm_dec.srcpred
1015 dstpred = yield self.dec2.rm_dec.dstpred
1016 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1017 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1018 if pmode == SVP64PredMode.INT.value:
1019 srcmask = dstmask = get_predint(self.gpr, dstpred)
1020 if sv_ptype == SVPtype.P2.value:
1021 srcmask = get_predint(self.gpr, srcpred)
1022 elif pmode == SVP64PredMode.CR.value:
1023 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1024 if sv_ptype == SVPtype.P2.value:
1025 srcmask = get_predcr(self.crl, srcpred, vl)
1026 print (" pmode", pmode)
1027 print (" ptype", sv_ptype)
1028 print (" srcpred", bin(srcpred))
1029 print (" dstpred", bin(dstpred))
1030 print (" srcmask", bin(srcmask))
1031 print (" dstmask", bin(dstmask))
1032 print (" pred_sz", bin(pred_src_zero))
1033 print (" pred_dz", bin(pred_dst_zero))
1034
1035 # okaaay, so here we simply advance srcstep (TODO dststep)
1036 # until the predicate mask has a "1" bit... or we run out of VL
1037 # let srcstep==VL be the indicator to move to next instruction
1038 if not pred_src_zero:
1039 while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
1040 print (" skip", bin(1<<srcstep))
1041 srcstep += 1
1042 # same for dststep
1043 if not pred_dst_zero:
1044 while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
1045 print (" skip", bin(1<<dststep))
1046 dststep += 1
1047
1048 # now work out if the relevant mask bits require zeroing
1049 if pred_dst_zero:
1050 pred_dst_zero = ((1<<dststep) & dstmask) == 0
1051 if pred_src_zero:
1052 pred_src_zero = ((1<<srcstep) & srcmask) == 0
1053
1054 # update SVSTATE with new srcstep
1055 self.svstate.srcstep[0:7] = srcstep
1056 self.svstate.dststep[0:7] = dststep
1057 self.namespace['SVSTATE'] = self.svstate.spr
1058 yield self.dec2.state.svstate.eq(self.svstate.spr.value)
1059 yield Settle() # let decoder update
1060 srcstep = self.svstate.srcstep.asint(msb0=True)
1061 dststep = self.svstate.dststep.asint(msb0=True)
1062 print (" srcstep", srcstep)
1063 print (" dststep", dststep)
1064
1065 # check if end reached (we let srcstep overrun, above)
1066 # nothing needs doing (TODO zeroing): just do next instruction
1067 if srcstep == vl or dststep == vl:
1068 self.svp64_reset_loop()
1069 self.update_pc_next()
1070 return
1071
1072 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1073 if self.is_svp64_mode and vl == 0:
1074 self.pc.update(self.namespace, self.is_svp64_mode)
1075 print("SVP64: VL=0, end of call", self.namespace['CIA'],
1076 self.namespace['NIA'])
1077 return
1078
1079 # main input registers (RT, RA ...)
1080 inputs = []
1081 for name in input_names:
1082 # using PowerDecoder2, first, find the decoder index.
1083 # (mapping name RA RB RC RS to in1, in2, in3)
1084 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1085 if regnum is None:
1086 # doing this is not part of svp64, it's because output
1087 # registers, to be modified, need to be in the namespace.
1088 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1089
1090 # in case getting the register number is needed, _RA, _RB
1091 regname = "_" + name
1092 self.namespace[regname] = regnum
1093 if not self.is_svp64_mode or not pred_src_zero:
1094 print('reading reg %s %s' % (name, str(regnum)), is_vec)
1095 if name in fregs:
1096 reg_val = self.fpr(regnum)
1097 else:
1098 reg_val = self.gpr(regnum)
1099 else:
1100 print('zero input reg %s %s' % (name, str(regnum)), is_vec)
1101 reg_val = 0
1102 inputs.append(reg_val)
1103
1104 # "special" registers
1105 for special in info.special_regs:
1106 if special in special_sprs:
1107 inputs.append(self.spr[special])
1108 else:
1109 inputs.append(self.namespace[special])
1110
1111 # clear trap (trap) NIA
1112 self.trap_nia = None
1113
1114 # execute actual instruction here
1115 print("inputs", inputs)
1116 results = info.func(self, *inputs)
1117 print("results", results)
1118
1119 # "inject" decorator takes namespace from function locals: we need to
1120 # overwrite NIA being overwritten (sigh)
1121 if self.trap_nia is not None:
1122 self.namespace['NIA'] = self.trap_nia
1123
1124 print("after func", self.namespace['CIA'], self.namespace['NIA'])
1125
1126 # detect if CA/CA32 already in outputs (sra*, basically)
1127 already_done = 0
1128 if info.write_regs:
1129 output_names = create_args(info.write_regs)
1130 for name in output_names:
1131 if name == 'CA':
1132 already_done |= 1
1133 if name == 'CA32':
1134 already_done |= 2
1135
1136 print("carry already done?", bin(already_done))
1137 if hasattr(self.dec2.e.do, "output_carry"):
1138 carry_en = yield self.dec2.e.do.output_carry
1139 else:
1140 carry_en = False
1141 if carry_en:
1142 yield from self.handle_carry_(inputs, results, already_done)
1143
1144 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1145 # detect if overflow was in return result
1146 overflow = None
1147 if info.write_regs:
1148 for name, output in zip(output_names, results):
1149 if name == 'overflow':
1150 overflow = output
1151
1152 if hasattr(self.dec2.e.do, "oe"):
1153 ov_en = yield self.dec2.e.do.oe.oe
1154 ov_ok = yield self.dec2.e.do.oe.ok
1155 else:
1156 ov_en = False
1157 ov_ok = False
1158 print("internal overflow", overflow, ov_en, ov_ok)
1159 if ov_en & ov_ok:
1160 yield from self.handle_overflow(inputs, results, overflow)
1161
1162 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1163 rc_en = False
1164 if not self.is_svp64_mode or not pred_dst_zero:
1165 if hasattr(self.dec2.e.do, "rc"):
1166 rc_en = yield self.dec2.e.do.rc.rc
1167 if rc_en:
1168 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1169 self.handle_comparison(results, regnum)
1170
1171 # any modified return results?
1172 if info.write_regs:
1173 for name, output in zip(output_names, results):
1174 if name == 'overflow': # ignore, done already (above)
1175 continue
1176 if isinstance(output, int):
1177 output = SelectableInt(output, 256)
1178 if name in ['CA', 'CA32']:
1179 if carry_en:
1180 print("writing %s to XER" % name, output)
1181 self.spr['XER'][XER_bits[name]] = output.value
1182 else:
1183 print("NOT writing %s to XER" % name, output)
1184 elif name in info.special_regs:
1185 print('writing special %s' % name, output, special_sprs)
1186 if name in special_sprs:
1187 self.spr[name] = output
1188 else:
1189 self.namespace[name].eq(output)
1190 if name == 'MSR':
1191 print('msr written', hex(self.msr.value))
1192 else:
1193 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2,
1194 name)
1195 if regnum is None:
1196 # temporary hack for not having 2nd output
1197 regnum = yield getattr(self.decoder, name)
1198 is_vec = False
1199 if self.is_svp64_mode and pred_dst_zero:
1200 print('zeroing reg %d %s' % (regnum, str(output)),
1201 is_vec)
1202 output = SelectableInt(0, 256)
1203 else:
1204 if name in fregs:
1205 ftype = 'fpr'
1206 else:
1207 ftype = 'gpr'
1208 print('writing %s %s %s' % (regnum, ftype, str(output)),
1209 is_vec)
1210 if output.bits > 64:
1211 output = SelectableInt(output.value, 64)
1212 if name in fregs:
1213 self.fpr[regnum] = output
1214 else:
1215 self.gpr[regnum] = output
1216
1217 # check if it is the SVSTATE.src/dest step that needs incrementing
1218 # this is our Sub-Program-Counter loop from 0 to VL-1
1219 if self.is_svp64_mode:
1220 # XXX twin predication TODO
1221 vl = self.svstate.vl.asint(msb0=True)
1222 mvl = self.svstate.maxvl.asint(msb0=True)
1223 srcstep = self.svstate.srcstep.asint(msb0=True)
1224 dststep = self.svstate.dststep.asint(msb0=True)
1225 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1226 no_out_vec = not (yield self.dec2.no_out_vec)
1227 no_in_vec = not (yield self.dec2.no_in_vec)
1228 print (" svstate.vl", vl)
1229 print (" svstate.mvl", mvl)
1230 print (" svstate.srcstep", srcstep)
1231 print (" svstate.dststep", dststep)
1232 print (" no_out_vec", no_out_vec)
1233 print (" no_in_vec", no_in_vec)
1234 print (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1235 # check if srcstep needs incrementing by one, stop PC advancing
1236 # svp64 loop can end early if the dest is scalar for single-pred
1237 # but for 2-pred both src/dest have to be checked.
1238 # XXX this might not be true! it may just be LD/ST
1239 if sv_ptype == SVPtype.P2.value:
1240 svp64_is_vector = (no_out_vec or no_in_vec)
1241 else:
1242 svp64_is_vector = no_out_vec
1243 if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
1244 self.svstate.srcstep += SelectableInt(1, 7)
1245 self.svstate.dststep += SelectableInt(1, 7)
1246 self.pc.NIA.value = self.pc.CIA.value
1247 self.namespace['NIA'] = self.pc.NIA
1248 self.namespace['SVSTATE'] = self.svstate.spr
1249 print("end of sub-pc call", self.namespace['CIA'],
1250 self.namespace['NIA'])
1251 return # DO NOT allow PC to update whilst Sub-PC loop running
1252 # reset loop to zero
1253 self.svp64_reset_loop()
1254
1255 self.update_pc_next()
1256
1257 def update_pc_next(self):
1258 # UPDATE program counter
1259 self.pc.update(self.namespace, self.is_svp64_mode)
1260 self.svstate.spr = self.namespace['SVSTATE']
1261 print("end of call", self.namespace['CIA'],
1262 self.namespace['NIA'],
1263 self.namespace['SVSTATE'])
1264
1265 def svp64_reset_loop(self):
1266 self.svstate.srcstep[0:7] = 0
1267 self.svstate.dststep[0:7] = 0
1268 print (" svstate.srcstep loop end (PC to update)")
1269 self.pc.update_nia(self.is_svp64_mode)
1270 self.namespace['NIA'] = self.pc.NIA
1271 self.namespace['SVSTATE'] = self.svstate.spr
1272
1273 def inject():
1274 """Decorator factory.
1275
1276 this decorator will "inject" variables into the function's namespace,
1277 from the *dictionary* in self.namespace. it therefore becomes possible
1278 to make it look like a whole stack of variables which would otherwise
1279 need "self." inserted in front of them (*and* for those variables to be
1280 added to the instance) "appear" in the function.
1281
1282 "self.namespace['SI']" for example becomes accessible as just "SI" but
1283 *only* inside the function, when decorated.
1284 """
1285 def variable_injector(func):
1286 @wraps(func)
1287 def decorator(*args, **kwargs):
1288 try:
1289 func_globals = func.__globals__ # Python 2.6+
1290 except AttributeError:
1291 func_globals = func.func_globals # Earlier versions.
1292
1293 context = args[0].namespace # variables to be injected
1294 saved_values = func_globals.copy() # Shallow copy of dict.
1295 func_globals.update(context)
1296 result = func(*args, **kwargs)
1297 print("globals after", func_globals['CIA'], func_globals['NIA'])
1298 print("args[0]", args[0].namespace['CIA'],
1299 args[0].namespace['NIA'],
1300 args[0].namespace['SVSTATE'])
1301 args[0].namespace = func_globals
1302 #exec (func.__code__, func_globals)
1303
1304 # finally:
1305 # func_globals = saved_values # Undo changes.
1306
1307 return result
1308
1309 return decorator
1310
1311 return variable_injector
1312
1313