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