redirect sv.bc to new svbranch 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, 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
774 def handle_carry_(self, inputs, outputs, already_done):
775 inv_a = yield self.dec2.e.do.invert_in
776 if inv_a:
777 inputs[0] = ~inputs[0]
778
779 imm_ok = yield self.dec2.e.do.imm_data.ok
780 if imm_ok:
781 imm = yield self.dec2.e.do.imm_data.data
782 inputs.append(SelectableInt(imm, 64))
783 assert len(outputs) >= 1
784 log("outputs", repr(outputs))
785 if isinstance(outputs, list) or isinstance(outputs, tuple):
786 output = outputs[0]
787 else:
788 output = outputs
789 gts = []
790 for x in inputs:
791 log("gt input", x, output)
792 gt = (gtu(x, output))
793 gts.append(gt)
794 log(gts)
795 cy = 1 if any(gts) else 0
796 log("CA", cy, gts)
797 if not (1 & already_done):
798 self.spr['XER'][XER_bits['CA']] = cy
799
800 log("inputs", already_done, inputs)
801 # 32 bit carry
802 # ARGH... different for OP_ADD... *sigh*...
803 op = yield self.dec2.e.do.insn_type
804 if op == MicrOp.OP_ADD.value:
805 res32 = (output.value & (1 << 32)) != 0
806 a32 = (inputs[0].value & (1 << 32)) != 0
807 if len(inputs) >= 2:
808 b32 = (inputs[1].value & (1 << 32)) != 0
809 else:
810 b32 = False
811 cy32 = res32 ^ a32 ^ b32
812 log("CA32 ADD", cy32)
813 else:
814 gts = []
815 for x in inputs:
816 log("input", x, output)
817 log(" x[32:64]", x, x[32:64])
818 log(" o[32:64]", output, output[32:64])
819 gt = (gtu(x[32:64], output[32:64])) == SelectableInt(1, 1)
820 gts.append(gt)
821 cy32 = 1 if any(gts) else 0
822 log("CA32", cy32, gts)
823 if not (2 & already_done):
824 self.spr['XER'][XER_bits['CA32']] = cy32
825
826 def handle_overflow(self, inputs, outputs, div_overflow):
827 if hasattr(self.dec2.e.do, "invert_in"):
828 inv_a = yield self.dec2.e.do.invert_in
829 if inv_a:
830 inputs[0] = ~inputs[0]
831
832 imm_ok = yield self.dec2.e.do.imm_data.ok
833 if imm_ok:
834 imm = yield self.dec2.e.do.imm_data.data
835 inputs.append(SelectableInt(imm, 64))
836 assert len(outputs) >= 1
837 log("handle_overflow", inputs, outputs, div_overflow)
838 if len(inputs) < 2 and div_overflow is None:
839 return
840
841 # div overflow is different: it's returned by the pseudo-code
842 # because it's more complex than can be done by analysing the output
843 if div_overflow is not None:
844 ov, ov32 = div_overflow, div_overflow
845 # arithmetic overflow can be done by analysing the input and output
846 elif len(inputs) >= 2:
847 output = outputs[0]
848
849 # OV (64-bit)
850 input_sgn = [exts(x.value, x.bits) < 0 for x in inputs]
851 output_sgn = exts(output.value, output.bits) < 0
852 ov = 1 if input_sgn[0] == input_sgn[1] and \
853 output_sgn != input_sgn[0] else 0
854
855 # OV (32-bit)
856 input32_sgn = [exts(x.value, 32) < 0 for x in inputs]
857 output32_sgn = exts(output.value, 32) < 0
858 ov32 = 1 if input32_sgn[0] == input32_sgn[1] and \
859 output32_sgn != input32_sgn[0] else 0
860
861 self.spr['XER'][XER_bits['OV']] = ov
862 self.spr['XER'][XER_bits['OV32']] = ov32
863 so = self.spr['XER'][XER_bits['SO']]
864 so = so | ov
865 self.spr['XER'][XER_bits['SO']] = so
866
867 def handle_comparison(self, outputs, cr_idx=0):
868 out = outputs[0]
869 assert isinstance(out, SelectableInt), \
870 "out zero not a SelectableInt %s" % repr(outputs)
871 log("handle_comparison", out.bits, hex(out.value))
872 # TODO - XXX *processor* in 32-bit mode
873 # https://bugs.libre-soc.org/show_bug.cgi?id=424
874 # if is_32bit:
875 # o32 = exts(out.value, 32)
876 # print ("handle_comparison exts 32 bit", hex(o32))
877 out = exts(out.value, out.bits)
878 log("handle_comparison exts", hex(out))
879 zero = SelectableInt(out == 0, 1)
880 positive = SelectableInt(out > 0, 1)
881 negative = SelectableInt(out < 0, 1)
882 SO = self.spr['XER'][XER_bits['SO']]
883 log("handle_comparison SO", SO)
884 cr_field = selectconcat(negative, positive, zero, SO)
885 log("handle_comparison cr_field", self.cr, cr_idx, cr_field)
886 self.crl[cr_idx].eq(cr_field)
887
888 def set_pc(self, pc_val):
889 self.namespace['NIA'] = SelectableInt(pc_val, 64)
890 self.pc.update(self.namespace, self.is_svp64_mode)
891
892 def get_next_insn(self):
893 """check instruction
894 """
895 if self.respect_pc:
896 pc = self.pc.CIA.value
897 else:
898 pc = self.fake_pc
899 ins = self.imem.ld(pc, 4, False, True, instr_fetch=True)
900 if ins is None:
901 raise KeyError("no instruction at 0x%x" % pc)
902 return pc, ins
903
904 def setup_one(self):
905 """set up one instruction
906 """
907 pc, insn = self.get_next_insn()
908 yield from self.setup_next_insn(pc, insn)
909
910 def setup_next_insn(self, pc, ins):
911 """set up next instruction
912 """
913 self._pc = pc
914 log("setup: 0x%x 0x%x %s" % (pc, ins & 0xffffffff, bin(ins)))
915 log("CIA NIA", self.respect_pc, self.pc.CIA.value, self.pc.NIA.value)
916
917 yield self.dec2.sv_rm.eq(0)
918 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff)
919 yield self.dec2.dec.bigendian.eq(self.bigendian)
920 yield self.dec2.state.msr.eq(self.msr.value)
921 yield self.dec2.state.pc.eq(pc)
922 if self.svstate is not None:
923 yield self.dec2.state.svstate.eq(self.svstate.value)
924
925 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
926 yield Settle()
927 opcode = yield self.dec2.dec.opcode_in
928 pfx = SVP64PrefixFields() # TODO should probably use SVP64PrefixDecoder
929 pfx.insn.value = opcode
930 major = pfx.major.asint(msb0=True) # MSB0 inversion
931 log ("prefix test: opcode:", major, bin(major),
932 pfx.insn[7] == 0b1, pfx.insn[9] == 0b1)
933 self.is_svp64_mode = ((major == 0b000001) and
934 pfx.insn[7].value == 0b1 and
935 pfx.insn[9].value == 0b1)
936 self.pc.update_nia(self.is_svp64_mode)
937 yield self.dec2.is_svp64_mode.eq(self.is_svp64_mode) # set SVP64 decode
938 self.namespace['NIA'] = self.pc.NIA
939 self.namespace['SVSTATE'] = self.svstate
940 if not self.is_svp64_mode:
941 return
942
943 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
944 log ("svp64.rm", bin(pfx.rm.asint(msb0=True)))
945 log (" svstate.vl", self.svstate.vl)
946 log (" svstate.mvl", self.svstate.maxvl)
947 sv_rm = pfx.rm.asint(msb0=True)
948 ins = self.imem.ld(pc+4, 4, False, True, instr_fetch=True)
949 log(" svsetup: 0x%x 0x%x %s" % (pc+4, ins & 0xffffffff, bin(ins)))
950 yield self.dec2.dec.raw_opcode_in.eq(ins & 0xffffffff) # v3.0B suffix
951 yield self.dec2.sv_rm.eq(sv_rm) # svp64 prefix
952 yield Settle()
953
954 def execute_one(self):
955 """execute one instruction
956 """
957 # get the disassembly code for this instruction
958 if self.is_svp64_mode:
959 if not self.disassembly:
960 code = yield from self.get_assembly_name()
961 else:
962 code = self.disassembly[self._pc+4]
963 log(" svp64 sim-execute", hex(self._pc), code)
964 else:
965 if not self.disassembly:
966 code = yield from self.get_assembly_name()
967 else:
968 code = self.disassembly[self._pc]
969 log("sim-execute", hex(self._pc), code)
970 opname = code.split(' ')[0]
971 try:
972 yield from self.call(opname) # execute the instruction
973 except MemException as e: # check for memory errors
974 if e.args[0] != 'unaligned': # only doing aligned at the mo
975 raise e # ... re-raise
976 # run a Trap but set DAR first
977 print ("memory unaligned exception, DAR", e.dar)
978 self.spr['DAR'] = SelectableInt(e.dar, 64)
979 self.call_trap(0x600, PIb.PRIV) # 0x600, privileged
980 return
981
982 # don't use this except in special circumstances
983 if not self.respect_pc:
984 self.fake_pc += 4
985
986 log("execute one, CIA NIA", self.pc.CIA.value, self.pc.NIA.value)
987
988 def get_assembly_name(self):
989 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
990 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
991 dec_insn = yield self.dec2.e.do.insn
992 insn_1_11 = yield self.dec2.e.do.insn[1:11]
993 asmcode = yield self.dec2.dec.op.asmcode
994 int_op = yield self.dec2.dec.op.internal_op
995 log("get assembly name asmcode", asmcode, int_op,
996 hex(dec_insn), bin(insn_1_11))
997 asmop = insns.get(asmcode, None)
998
999 # sigh reconstruct the assembly instruction name
1000 if hasattr(self.dec2.e.do, "oe"):
1001 ov_en = yield self.dec2.e.do.oe.oe
1002 ov_ok = yield self.dec2.e.do.oe.ok
1003 else:
1004 ov_en = False
1005 ov_ok = False
1006 if hasattr(self.dec2.e.do, "rc"):
1007 rc_en = yield self.dec2.e.do.rc.rc
1008 rc_ok = yield self.dec2.e.do.rc.ok
1009 else:
1010 rc_en = False
1011 rc_ok = False
1012 # grrrr have to special-case MUL op (see DecodeOE)
1013 log("ov %d en %d rc %d en %d op %d" %
1014 (ov_ok, ov_en, rc_ok, rc_en, int_op))
1015 if int_op in [MicrOp.OP_MUL_H64.value, MicrOp.OP_MUL_H32.value]:
1016 log("mul op")
1017 if rc_en & rc_ok:
1018 asmop += "."
1019 else:
1020 if not asmop.endswith("."): # don't add "." to "andis."
1021 if rc_en & rc_ok:
1022 asmop += "."
1023 if hasattr(self.dec2.e.do, "lk"):
1024 lk = yield self.dec2.e.do.lk
1025 if lk:
1026 asmop += "l"
1027 log("int_op", int_op)
1028 if int_op in [MicrOp.OP_B.value, MicrOp.OP_BC.value]:
1029 AA = yield self.dec2.dec.fields.FormI.AA[0:-1]
1030 log("AA", AA)
1031 if AA:
1032 asmop += "a"
1033 spr_msb = yield from self.get_spr_msb()
1034 if int_op == MicrOp.OP_MFCR.value:
1035 if spr_msb:
1036 asmop = 'mfocrf'
1037 else:
1038 asmop = 'mfcr'
1039 # XXX TODO: for whatever weird reason this doesn't work
1040 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1041 if int_op == MicrOp.OP_MTCRF.value:
1042 if spr_msb:
1043 asmop = 'mtocrf'
1044 else:
1045 asmop = 'mtcrf'
1046 return asmop
1047
1048 def get_remap_indices(self):
1049 """WARNING, this function stores remap_idxs and remap_loopends
1050 in the class for later use. this to avoid problems with yield
1051 """
1052 # go through all iterators in lock-step, advance to next remap_idx
1053 srcstep, dststep = self.get_src_dststeps()
1054 # get four SVSHAPEs. here we are hard-coding
1055 SVSHAPE0 = self.spr['SVSHAPE0']
1056 SVSHAPE1 = self.spr['SVSHAPE1']
1057 SVSHAPE2 = self.spr['SVSHAPE2']
1058 SVSHAPE3 = self.spr['SVSHAPE3']
1059 # set up the iterators
1060 remaps = [(SVSHAPE0, SVSHAPE0.get_iterator()),
1061 (SVSHAPE1, SVSHAPE1.get_iterator()),
1062 (SVSHAPE2, SVSHAPE2.get_iterator()),
1063 (SVSHAPE3, SVSHAPE3.get_iterator()),
1064 ]
1065
1066 self.remap_loopends = [0] * 4
1067 self.remap_idxs = [0, 1, 2, 3]
1068 dbg = []
1069 for i, (shape, remap) in enumerate(remaps):
1070 # zero is "disabled"
1071 if shape.value == 0x0:
1072 self.remap_idxs[i] = 0
1073 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1074 step = dststep if (i in [3, 4]) else srcstep
1075 # this is terrible. O(N^2) looking for the match. but hey.
1076 for idx, (remap_idx, loopends) in enumerate(remap):
1077 if idx == step:
1078 break
1079 self.remap_idxs[i] = remap_idx
1080 self.remap_loopends[i] = loopends
1081 dbg.append((i, step, remap_idx, loopends))
1082 for (i, step, remap_idx, loopends) in dbg:
1083 log ("SVSHAPE %d idx, end" % i, step, remap_idx, bin(loopends))
1084 return remaps
1085
1086 def get_spr_msb(self):
1087 dec_insn = yield self.dec2.e.do.insn
1088 return dec_insn & (1 << 20) != 0 # sigh - XFF.spr[-1]?
1089
1090 def call(self, name):
1091 """call(opcode) - the primary execution point for instructions
1092 """
1093 self.last_st_addr = None # reset the last known store address
1094 self.last_ld_addr = None # etc.
1095
1096 ins_name = name.strip() # remove spaces if not already done so
1097 if self.halted:
1098 log("halted - not executing", ins_name)
1099 return
1100
1101 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1102 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1103 asmop = yield from self.get_assembly_name()
1104 log("call", ins_name, asmop)
1105
1106 # check privileged
1107 int_op = yield self.dec2.dec.op.internal_op
1108 spr_msb = yield from self.get_spr_msb()
1109
1110 instr_is_privileged = False
1111 if int_op in [MicrOp.OP_ATTN.value,
1112 MicrOp.OP_MFMSR.value,
1113 MicrOp.OP_MTMSR.value,
1114 MicrOp.OP_MTMSRD.value,
1115 # TODO: OP_TLBIE
1116 MicrOp.OP_RFID.value]:
1117 instr_is_privileged = True
1118 if int_op in [MicrOp.OP_MFSPR.value,
1119 MicrOp.OP_MTSPR.value] and spr_msb:
1120 instr_is_privileged = True
1121
1122 log("is priv", instr_is_privileged, hex(self.msr.value),
1123 self.msr[MSRb.PR])
1124 # check MSR priv bit and whether op is privileged: if so, throw trap
1125 if instr_is_privileged and self.msr[MSRb.PR] == 1:
1126 self.call_trap(0x700, PIb.PRIV)
1127 return
1128
1129 # check halted condition
1130 if ins_name == 'attn':
1131 self.halted = True
1132 return
1133
1134 # check illegal instruction
1135 illegal = False
1136 if ins_name not in ['mtcrf', 'mtocrf']:
1137 illegal = ins_name != asmop
1138
1139 # sigh deal with setvl not being supported by binutils (.long)
1140 if asmop.startswith('setvl'):
1141 illegal = False
1142 ins_name = 'setvl'
1143
1144 # and svstep not being supported by binutils (.long)
1145 if asmop.startswith('svstep'):
1146 illegal = False
1147 ins_name = 'svstep'
1148
1149 # and svremap not being supported by binutils (.long)
1150 if asmop.startswith('svremap'):
1151 illegal = False
1152 ins_name = 'svremap'
1153
1154 # and svshape not being supported by binutils (.long)
1155 if asmop.startswith('svshape'):
1156 illegal = False
1157 ins_name = 'svshape'
1158
1159 # and fsin and fcos
1160 if asmop == 'fsins':
1161 illegal = False
1162 ins_name = 'fsins'
1163 if asmop == 'fcoss':
1164 illegal = False
1165 ins_name = 'fcoss'
1166
1167 # sigh also deal with ffmadds not being supported by binutils (.long)
1168 if asmop == 'ffmadds':
1169 illegal = False
1170 ins_name = 'ffmadds'
1171
1172 # and fdmadds not being supported by binutils (.long)
1173 if asmop == 'fdmadds':
1174 illegal = False
1175 ins_name = 'fdmadds'
1176
1177 # and ffadds not being supported by binutils (.long)
1178 if asmop == 'ffadds':
1179 illegal = False
1180 ins_name = 'ffadds'
1181
1182 # branch-conditional redirects to sv.bc
1183 if asmop.startswith('bc') and self.is_svp64_mode:
1184 ins_name = 'sv.%s' % ins_name
1185
1186 log(" post-processed name", ins_name, asmop)
1187
1188 # illegal instructions call TRAP at 0x700
1189 if illegal:
1190 print("illegal", ins_name, asmop)
1191 self.call_trap(0x700, PIb.ILLEG)
1192 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1193 (ins_name, asmop, self.pc.CIA.value))
1194 return
1195
1196 # this is for setvl "Vertical" mode: if set true,
1197 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1198 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1199 self.allow_next_step_inc = False
1200 self.svstate_next_mode = 0
1201
1202 # nop has to be supported, we could let the actual op calculate
1203 # but PowerDecoder has a pattern for nop
1204 if ins_name is 'nop':
1205 self.update_pc_next()
1206 return
1207
1208 # look up instruction in ISA.instrs, prepare namespace
1209 info = self.instrs[ins_name]
1210 yield from self.prep_namespace(ins_name, info.form, info.op_fields)
1211
1212 # preserve order of register names
1213 input_names = create_args(list(info.read_regs) +
1214 list(info.uninit_regs))
1215 log("input names", input_names)
1216
1217 # get SVP64 entry for the current instruction
1218 sv_rm = self.svp64rm.instrs.get(ins_name)
1219 if sv_rm is not None:
1220 dest_cr, src_cr, src_byname, dest_byname = decode_extra(sv_rm)
1221 else:
1222 dest_cr, src_cr, src_byname, dest_byname = False, False, {}, {}
1223 log ("sv rm", sv_rm, dest_cr, src_cr, src_byname, dest_byname)
1224
1225 # see if srcstep/dststep need skipping over masked-out predicate bits
1226 if (self.is_svp64_mode or ins_name == 'setvl' or
1227 ins_name.startswith("sv")):
1228 yield from self.svstate_pre_inc()
1229 if self.is_svp64_mode:
1230 pre = yield from self.update_new_svstate_steps()
1231 if pre:
1232 self.svp64_reset_loop()
1233 self.update_nia()
1234 self.update_pc_next()
1235 return
1236 srcstep, dststep = self.get_src_dststeps()
1237 pred_dst_zero = self.pred_dst_zero
1238 pred_src_zero = self.pred_src_zero
1239 vl = self.svstate.vl
1240
1241 # VL=0 in SVP64 mode means "do nothing: skip instruction"
1242 if self.is_svp64_mode and vl == 0:
1243 self.pc.update(self.namespace, self.is_svp64_mode)
1244 log("SVP64: VL=0, end of call", self.namespace['CIA'],
1245 self.namespace['NIA'])
1246 return
1247
1248 # for when SVREMAP is active, using pre-arranged schedule.
1249 # note: modifying PowerDecoder2 needs to "settle"
1250 remap_en = self.svstate.SVme
1251 persist = self.svstate.RMpst
1252 active = (persist or self.last_op_svshape) and remap_en != 0
1253 yield self.dec2.remap_active.eq(remap_en if active else 0)
1254 yield Settle()
1255 if persist or self.last_op_svshape:
1256 remaps = self.get_remap_indices()
1257 if self.is_svp64_mode and (persist or self.last_op_svshape):
1258 # just some convenient debug info
1259 for i in range(4):
1260 sname = 'SVSHAPE%d' % i
1261 shape = self.spr[sname]
1262 log (sname, bin(shape.value))
1263 log (" lims", shape.lims)
1264 log (" mode", shape.mode)
1265 log (" skip", shape.skip)
1266
1267 # set up the list of steps to remap
1268 mi0 = self.svstate.mi0
1269 mi1 = self.svstate.mi1
1270 mi2 = self.svstate.mi2
1271 mo0 = self.svstate.mo0
1272 mo1 = self.svstate.mo1
1273 steps = [(self.dec2.in1_step, mi0), # RA
1274 (self.dec2.in2_step, mi1), # RB
1275 (self.dec2.in3_step, mi2), # RC
1276 (self.dec2.o_step, mo0), # RT
1277 (self.dec2.o2_step, mo1), # EA
1278 ]
1279 remap_idxs = self.remap_idxs
1280 rremaps = []
1281 # now cross-index the required SHAPE for each of 3-in 2-out regs
1282 rnames = ['RA', 'RB', 'RC', 'RT', 'EA']
1283 for i, (dstep, shape_idx) in enumerate(steps):
1284 (shape, remap) = remaps[shape_idx]
1285 remap_idx = remap_idxs[shape_idx]
1286 # zero is "disabled"
1287 if shape.value == 0x0:
1288 continue
1289 # now set the actual requested step to the current index
1290 yield dstep.eq(remap_idx)
1291
1292 # debug printout info
1293 rremaps.append((shape.mode, i, rnames[i], shape_idx,
1294 remap_idx))
1295 for x in rremaps:
1296 log ("shape remap", x)
1297 # after that, settle down (combinatorial) to let Vector reg numbers
1298 # work themselves out
1299 yield Settle()
1300 remap_active = yield self.dec2.remap_active
1301 log ("remap active", bin(remap_active))
1302
1303 # main input registers (RT, RA ...)
1304 inputs = []
1305 for name in input_names:
1306 # using PowerDecoder2, first, find the decoder index.
1307 # (mapping name RA RB RC RS to in1, in2, in3)
1308 regnum, is_vec = yield from get_pdecode_idx_in(self.dec2, name)
1309 if regnum is None:
1310 # doing this is not part of svp64, it's because output
1311 # registers, to be modified, need to be in the namespace.
1312 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, name)
1313 if regnum is None:
1314 regnum, is_vec = yield from get_pdecode_idx_out2(self.dec2,
1315 name)
1316
1317 # in case getting the register number is needed, _RA, _RB
1318 regname = "_" + name
1319 self.namespace[regname] = regnum
1320 if not self.is_svp64_mode or not pred_src_zero:
1321 log('reading reg %s %s' % (name, str(regnum)), is_vec)
1322 if name in fregs:
1323 reg_val = self.fpr(regnum)
1324 elif name is not None:
1325 reg_val = self.gpr(regnum)
1326 else:
1327 log('zero input reg %s %s' % (name, str(regnum)), is_vec)
1328 reg_val = 0
1329 inputs.append(reg_val)
1330 # arrrrgh, awful hack, to get _RT into namespace
1331 if ins_name in ['setvl', 'svstep']:
1332 regname = "_RT"
1333 RT = yield self.dec2.dec.RT
1334 self.namespace[regname] = SelectableInt(RT, 5)
1335 if RT == 0:
1336 self.namespace["RT"] = SelectableInt(0, 5)
1337 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2, "RT")
1338 log('hack input reg %s %s' % (name, str(regnum)), is_vec)
1339
1340 # in SVP64 mode for LD/ST work out immediate
1341 # XXX TODO: replace_ds for DS-Form rather than D-Form.
1342 # use info.form to detect
1343 replace_d = False # update / replace constant in pseudocode
1344 if self.is_svp64_mode:
1345 ldstmode = yield self.dec2.rm_dec.ldstmode
1346 # shift mode reads SVD (or SVDS - TODO)
1347 # *BUT*... because this is "overloading" of LD operations,
1348 # it gets *STORED* into D (or DS, TODO)
1349 if ldstmode == SVP64LDSTmode.SHIFT.value:
1350 imm = yield self.dec2.dec.fields.FormSVD.SVD[0:11]
1351 imm = exts(imm, 11) # sign-extend to integer
1352 log ("shift SVD", imm)
1353 replace_d = True
1354 else:
1355 if info.form == 'DS':
1356 # DS-Form, multiply by 4 then knock 2 bits off after
1357 imm = yield self.dec2.dec.fields.FormDS.DS[0:14] * 4
1358 else:
1359 imm = yield self.dec2.dec.fields.FormD.D[0:16]
1360 imm = exts(imm, 16) # sign-extend to integer
1361 # get the right step. LD is from srcstep, ST is dststep
1362 op = yield self.dec2.e.do.insn_type
1363 offsmul = 0
1364 if op == MicrOp.OP_LOAD.value:
1365 if remap_active:
1366 offsmul = yield self.dec2.in1_step
1367 log("D-field REMAP src", imm, offsmul)
1368 else:
1369 offsmul = srcstep
1370 log("D-field src", imm, offsmul)
1371 elif op == MicrOp.OP_STORE.value:
1372 # XXX NOTE! no bit-reversed STORE! this should not ever be used
1373 offsmul = dststep
1374 log("D-field dst", imm, offsmul)
1375 # bit-reverse mode, rev already done through get_src_dst_steps()
1376 if ldstmode == SVP64LDSTmode.SHIFT.value:
1377 # manually look up RC, sigh
1378 RC = yield self.dec2.dec.RC[0:5]
1379 RC = self.gpr(RC)
1380 log ("LD-SHIFT:", "VL", vl,
1381 "RC", RC.value, "imm", imm,
1382 "offs", bin(offsmul),
1383 )
1384 imm = SelectableInt((imm * offsmul) << RC.value, 32)
1385 # Unit-Strided LD/ST adds offset*width to immediate
1386 elif ldstmode == SVP64LDSTmode.UNITSTRIDE.value:
1387 ldst_len = yield self.dec2.e.do.data_len
1388 imm = SelectableInt(imm + offsmul * ldst_len, 32)
1389 replace_d = True
1390 # Element-strided multiplies the immediate by element step
1391 elif ldstmode == SVP64LDSTmode.ELSTRIDE.value:
1392 imm = SelectableInt(imm * offsmul, 32)
1393 replace_d = True
1394 if replace_d:
1395 ldst_ra_vec = yield self.dec2.rm_dec.ldst_ra_vec
1396 ldst_imz_in = yield self.dec2.rm_dec.ldst_imz_in
1397 log("LDSTmode", SVP64LDSTmode(ldstmode),
1398 offsmul, imm, ldst_ra_vec, ldst_imz_in)
1399 # new replacement D... errr.. DS
1400 if replace_d:
1401 if info.form == 'DS':
1402 # TODO: assert 2 LSBs are zero?
1403 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm.value))
1404 imm.value = imm.value >> 2
1405 self.namespace['DS'] = imm
1406 else:
1407 self.namespace['D'] = imm
1408
1409 # "special" registers
1410 for special in info.special_regs:
1411 if special in special_sprs:
1412 inputs.append(self.spr[special])
1413 else:
1414 inputs.append(self.namespace[special])
1415
1416 # clear trap (trap) NIA
1417 self.trap_nia = None
1418
1419 # execute actual instruction here (finally)
1420 log("inputs", inputs)
1421 results = info.func(self, *inputs)
1422 log("results", results)
1423
1424 # "inject" decorator takes namespace from function locals: we need to
1425 # overwrite NIA being overwritten (sigh)
1426 if self.trap_nia is not None:
1427 self.namespace['NIA'] = self.trap_nia
1428
1429 log("after func", self.namespace['CIA'], self.namespace['NIA'])
1430
1431 # check if op was a LD/ST so that debugging can check the
1432 # address
1433 if int_op in [MicrOp.OP_STORE.value,
1434 ]:
1435 self.last_st_addr = self.mem.last_st_addr
1436 if int_op in [MicrOp.OP_LOAD.value,
1437 ]:
1438 self.last_ld_addr = self.mem.last_ld_addr
1439 log ("op", int_op, MicrOp.OP_STORE.value, MicrOp.OP_LOAD.value,
1440 self.last_st_addr, self.last_ld_addr)
1441
1442 # detect if CA/CA32 already in outputs (sra*, basically)
1443 already_done = 0
1444 if info.write_regs:
1445 output_names = create_args(info.write_regs)
1446 for name in output_names:
1447 if name == 'CA':
1448 already_done |= 1
1449 if name == 'CA32':
1450 already_done |= 2
1451
1452 log("carry already done?", bin(already_done))
1453 if hasattr(self.dec2.e.do, "output_carry"):
1454 carry_en = yield self.dec2.e.do.output_carry
1455 else:
1456 carry_en = False
1457 if carry_en:
1458 yield from self.handle_carry_(inputs, results, already_done)
1459
1460 if not self.is_svp64_mode: # yeah just no. not in parallel processing
1461 # detect if overflow was in return result
1462 overflow = None
1463 if info.write_regs:
1464 for name, output in zip(output_names, results):
1465 if name == 'overflow':
1466 overflow = output
1467
1468 if hasattr(self.dec2.e.do, "oe"):
1469 ov_en = yield self.dec2.e.do.oe.oe
1470 ov_ok = yield self.dec2.e.do.oe.ok
1471 else:
1472 ov_en = False
1473 ov_ok = False
1474 log("internal overflow", overflow, ov_en, ov_ok)
1475 if ov_en & ov_ok:
1476 yield from self.handle_overflow(inputs, results, overflow)
1477
1478 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
1479 rc_en = False
1480 if not self.is_svp64_mode or not pred_dst_zero:
1481 if hasattr(self.dec2.e.do, "rc"):
1482 rc_en = yield self.dec2.e.do.rc.rc
1483 if rc_en and ins_name not in ['svstep']:
1484 regnum, is_vec = yield from get_pdecode_cr_out(self.dec2, "CR0")
1485 self.handle_comparison(results, regnum)
1486
1487 # any modified return results?
1488 if info.write_regs:
1489 for name, output in zip(output_names, results):
1490 if name == 'overflow': # ignore, done already (above)
1491 continue
1492 if isinstance(output, int):
1493 output = SelectableInt(output, 256)
1494 if name in ['CA', 'CA32']:
1495 if carry_en:
1496 log("writing %s to XER" % name, output)
1497 self.spr['XER'][XER_bits[name]] = output.value
1498 else:
1499 log("NOT writing %s to XER" % name, output)
1500 elif name in info.special_regs:
1501 log('writing special %s' % name, output, special_sprs)
1502 if name in special_sprs:
1503 self.spr[name] = output
1504 else:
1505 self.namespace[name].eq(output)
1506 if name == 'MSR':
1507 log('msr written', hex(self.msr.value))
1508 else:
1509 regnum, is_vec = yield from get_pdecode_idx_out(self.dec2,
1510 name)
1511 if regnum is None:
1512 regnum, is_vec = yield from get_pdecode_idx_out2(
1513 self.dec2, name)
1514 if regnum is None:
1515 # temporary hack for not having 2nd output
1516 regnum = yield getattr(self.decoder, name)
1517 is_vec = False
1518 if self.is_svp64_mode and pred_dst_zero:
1519 log('zeroing reg %d %s' % (regnum, str(output)),
1520 is_vec)
1521 output = SelectableInt(0, 256)
1522 else:
1523 if name in fregs:
1524 ftype = 'fpr'
1525 else:
1526 ftype = 'gpr'
1527 log('writing %s %s %s' % (ftype, regnum, str(output)),
1528 is_vec)
1529 if output.bits > 64:
1530 output = SelectableInt(output.value, 64)
1531 if name in fregs:
1532 self.fpr[regnum] = output
1533 else:
1534 self.gpr[regnum] = output
1535
1536 # check if it is the SVSTATE.src/dest step that needs incrementing
1537 # this is our Sub-Program-Counter loop from 0 to VL-1
1538 pre = False
1539 post = False
1540 if self.allow_next_step_inc:
1541 log("SVSTATE_NEXT: inc requested, mode",
1542 self.svstate_next_mode, self.allow_next_step_inc)
1543 yield from self.svstate_pre_inc()
1544 pre = yield from self.update_new_svstate_steps()
1545 if pre:
1546 # reset at end of loop including exit Vertical Mode
1547 log ("SVSTATE_NEXT: end of loop, reset")
1548 self.svp64_reset_loop()
1549 self.svstate.vfirst = 0
1550 self.update_nia()
1551 if rc_en:
1552 results = [SelectableInt(0, 64)]
1553 self.handle_comparison(results) # CR0
1554 else:
1555 if self.allow_next_step_inc == 2:
1556 log ("SVSTATE_NEXT: read")
1557 yield from self.svstate_post_inc()
1558 else:
1559 log ("SVSTATE_NEXT: post-inc")
1560 # use actual src/dst-step here to check end, do NOT
1561 # use bit-reversed version
1562 srcstep, dststep = self.new_srcstep, self.new_dststep
1563 remaps = self.get_remap_indices()
1564 remap_idxs = self.remap_idxs
1565 vl = self.svstate.vl
1566 end_src = srcstep == vl-1
1567 end_dst = dststep == vl-1
1568 if self.allow_next_step_inc != 2:
1569 if not end_src:
1570 self.svstate.srcstep += SelectableInt(1, 7)
1571 if not end_dst:
1572 self.svstate.dststep += SelectableInt(1, 7)
1573 self.namespace['SVSTATE'] = self.svstate.spr
1574 # set CR0 (if Rc=1) based on end
1575 if rc_en:
1576 srcstep = self.svstate.srcstep
1577 dststep = self.svstate.srcstep
1578 endtest = 1 if (end_src or end_dst) else 0
1579 #results = [SelectableInt(endtest, 64)]
1580 #self.handle_comparison(results) # CR0
1581
1582 # see if svstep was requested, if so, which SVSTATE
1583 endings = 0b111
1584 if self.svstate_next_mode > 0:
1585 shape_idx = self.svstate_next_mode.value-1
1586 endings = self.remap_loopends[shape_idx]
1587 cr_field = SelectableInt((~endings)<<1 | endtest, 4)
1588 print ("svstep Rc=1, CR0", cr_field)
1589 self.crl[0].eq(cr_field) # CR0
1590 if end_src or end_dst:
1591 # reset at end of loop including exit Vertical Mode
1592 log ("SVSTATE_NEXT: after increments, reset")
1593 self.svp64_reset_loop()
1594 self.svstate.vfirst = 0
1595
1596 elif self.is_svp64_mode:
1597 yield from self.svstate_post_inc()
1598 else:
1599 # XXX only in non-SVP64 mode!
1600 # record state of whether the current operation was an svshape,
1601 # to be able to know if it should apply in the next instruction.
1602 # also (if going to use this instruction) should disable ability
1603 # to interrupt in between. sigh.
1604 self.last_op_svshape = asmop == 'svremap'
1605
1606 self.update_pc_next()
1607
1608 def SVSTATE_NEXT(self, mode, submode):
1609 """explicitly moves srcstep/dststep on to next element, for
1610 "Vertical-First" mode. this function is called from
1611 setvl pseudo-code, as a pseudo-op "svstep"
1612
1613 WARNING: this function uses information that was created EARLIER
1614 due to it being in the middle of a yield, but this function is
1615 *NOT* called from yield (it's called from compiled pseudocode).
1616 """
1617 self.allow_next_step_inc = submode.value + 1
1618 log("SVSTATE_NEXT mode", mode, submode, self.allow_next_step_inc)
1619 self.svstate_next_mode = mode
1620 if self.svstate_next_mode > 0:
1621 shape_idx = self.svstate_next_mode.value-1
1622 return SelectableInt(self.remap_idxs[shape_idx], 7)
1623 return SelectableInt(0, 7)
1624
1625 def svstate_pre_inc(self):
1626 """check if srcstep/dststep need to skip over masked-out predicate bits
1627 """
1628 # get SVSTATE VL (oh and print out some debug stuff)
1629 vl = self.svstate.vl
1630 srcstep = self.svstate.srcstep
1631 dststep = self.svstate.dststep
1632 sv_a_nz = yield self.dec2.sv_a_nz
1633 fft_mode = yield self.dec2.use_svp64_fft
1634 in1 = yield self.dec2.e.read_reg1.data
1635 log ("SVP64: VL, srcstep, dststep, sv_a_nz, in1 fft, svp64",
1636 vl, srcstep, dststep, sv_a_nz, in1, fft_mode,
1637 self.is_svp64_mode)
1638
1639 # get predicate mask
1640 srcmask = dstmask = 0xffff_ffff_ffff_ffff
1641
1642 pmode = yield self.dec2.rm_dec.predmode
1643 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1644 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1645 srcpred = yield self.dec2.rm_dec.srcpred
1646 dstpred = yield self.dec2.rm_dec.dstpred
1647 pred_src_zero = yield self.dec2.rm_dec.pred_sz
1648 pred_dst_zero = yield self.dec2.rm_dec.pred_dz
1649 if pmode == SVP64PredMode.INT.value:
1650 srcmask = dstmask = get_predint(self.gpr, dstpred)
1651 if sv_ptype == SVPtype.P2.value:
1652 srcmask = get_predint(self.gpr, srcpred)
1653 elif pmode == SVP64PredMode.CR.value:
1654 srcmask = dstmask = get_predcr(self.crl, dstpred, vl)
1655 if sv_ptype == SVPtype.P2.value:
1656 srcmask = get_predcr(self.crl, srcpred, vl)
1657 log (" pmode", pmode)
1658 log (" reverse", reverse_gear)
1659 log (" ptype", sv_ptype)
1660 log (" srcpred", bin(srcpred))
1661 log (" dstpred", bin(dstpred))
1662 log (" srcmask", bin(srcmask))
1663 log (" dstmask", bin(dstmask))
1664 log (" pred_sz", bin(pred_src_zero))
1665 log (" pred_dz", bin(pred_dst_zero))
1666
1667 # okaaay, so here we simply advance srcstep (TODO dststep)
1668 # until the predicate mask has a "1" bit... or we run out of VL
1669 # let srcstep==VL be the indicator to move to next instruction
1670 if not pred_src_zero:
1671 while (((1<<srcstep) & srcmask) == 0) and (srcstep != vl):
1672 log (" skip", bin(1<<srcstep))
1673 srcstep += 1
1674 # same for dststep
1675 if not pred_dst_zero:
1676 while (((1<<dststep) & dstmask) == 0) and (dststep != vl):
1677 log (" skip", bin(1<<dststep))
1678 dststep += 1
1679
1680 # now work out if the relevant mask bits require zeroing
1681 if pred_dst_zero:
1682 pred_dst_zero = ((1<<dststep) & dstmask) == 0
1683 if pred_src_zero:
1684 pred_src_zero = ((1<<srcstep) & srcmask) == 0
1685
1686 # store new srcstep / dststep
1687 self.new_srcstep, self.new_dststep = srcstep, dststep
1688 self.pred_dst_zero, self.pred_src_zero = pred_dst_zero, pred_src_zero
1689 log (" new srcstep", srcstep)
1690 log (" new dststep", dststep)
1691
1692 def get_src_dststeps(self):
1693 """gets srcstep and dststep
1694 """
1695 return self.new_srcstep, self.new_dststep
1696
1697 def update_new_svstate_steps(self):
1698 # note, do not get the bit-reversed srcstep here!
1699 srcstep, dststep = self.new_srcstep, self.new_dststep
1700
1701 # update SVSTATE with new srcstep
1702 self.svstate.srcstep = srcstep
1703 self.svstate.dststep = dststep
1704 self.namespace['SVSTATE'] = self.svstate
1705 yield self.dec2.state.svstate.eq(self.svstate.value)
1706 yield Settle() # let decoder update
1707 srcstep = self.svstate.srcstep
1708 dststep = self.svstate.dststep
1709 vl = self.svstate.vl
1710 log (" srcstep", srcstep)
1711 log (" dststep", dststep)
1712 log (" vl", vl)
1713
1714 # check if end reached (we let srcstep overrun, above)
1715 # nothing needs doing (TODO zeroing): just do next instruction
1716 return srcstep == vl or dststep == vl
1717
1718 def svstate_post_inc(self, vf=0):
1719 # check if SV "Vertical First" mode is enabled
1720 vfirst = self.svstate.vfirst
1721 log (" SV Vertical First", vf, vfirst)
1722 if not vf and vfirst == 1:
1723 self.update_nia()
1724 return True
1725
1726 # check if it is the SVSTATE.src/dest step that needs incrementing
1727 # this is our Sub-Program-Counter loop from 0 to VL-1
1728 # XXX twin predication TODO
1729 vl = self.svstate.vl
1730 mvl = self.svstate.maxvl
1731 srcstep = self.svstate.srcstep
1732 dststep = self.svstate.dststep
1733 rm_mode = yield self.dec2.rm_dec.mode
1734 reverse_gear = yield self.dec2.rm_dec.reverse_gear
1735 sv_ptype = yield self.dec2.dec.op.SV_Ptype
1736 out_vec = not (yield self.dec2.no_out_vec)
1737 in_vec = not (yield self.dec2.no_in_vec)
1738 log (" svstate.vl", vl)
1739 log (" svstate.mvl", mvl)
1740 log (" svstate.srcstep", srcstep)
1741 log (" svstate.dststep", dststep)
1742 log (" mode", rm_mode)
1743 log (" reverse", reverse_gear)
1744 log (" out_vec", out_vec)
1745 log (" in_vec", in_vec)
1746 log (" sv_ptype", sv_ptype, sv_ptype == SVPtype.P2.value)
1747 # check if srcstep needs incrementing by one, stop PC advancing
1748 # svp64 loop can end early if the dest is scalar for single-pred
1749 # but for 2-pred both src/dest have to be checked.
1750 # XXX this might not be true! it may just be LD/ST
1751 if sv_ptype == SVPtype.P2.value:
1752 svp64_is_vector = (out_vec or in_vec)
1753 else:
1754 svp64_is_vector = out_vec
1755 if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
1756 self.svstate.srcstep += SelectableInt(1, 7)
1757 self.svstate.dststep += SelectableInt(1, 7)
1758 self.pc.NIA.value = self.pc.CIA.value
1759 self.namespace['NIA'] = self.pc.NIA
1760 self.namespace['SVSTATE'] = self.svstate
1761 log("end of sub-pc call", self.namespace['CIA'],
1762 self.namespace['NIA'])
1763 return False # DO NOT allow PC update whilst Sub-PC loop running
1764
1765 # reset loop to zero and update NIA
1766 self.svp64_reset_loop()
1767 self.update_nia()
1768
1769 return True
1770
1771 def update_pc_next(self):
1772 # UPDATE program counter
1773 self.pc.update(self.namespace, self.is_svp64_mode)
1774 self.svstate.spr = self.namespace['SVSTATE']
1775 log("end of call", self.namespace['CIA'],
1776 self.namespace['NIA'],
1777 self.namespace['SVSTATE'])
1778
1779 def svp64_reset_loop(self):
1780 self.svstate.srcstep = 0
1781 self.svstate.dststep = 0
1782 log (" svstate.srcstep loop end (PC to update)")
1783 self.namespace['SVSTATE'] = self.svstate
1784
1785 def update_nia(self):
1786 self.pc.update_nia(self.is_svp64_mode)
1787 self.namespace['NIA'] = self.pc.NIA
1788
1789 def inject():
1790 """Decorator factory.
1791
1792 this decorator will "inject" variables into the function's namespace,
1793 from the *dictionary* in self.namespace. it therefore becomes possible
1794 to make it look like a whole stack of variables which would otherwise
1795 need "self." inserted in front of them (*and* for those variables to be
1796 added to the instance) "appear" in the function.
1797
1798 "self.namespace['SI']" for example becomes accessible as just "SI" but
1799 *only* inside the function, when decorated.
1800 """
1801 def variable_injector(func):
1802 @wraps(func)
1803 def decorator(*args, **kwargs):
1804 try:
1805 func_globals = func.__globals__ # Python 2.6+
1806 except AttributeError:
1807 func_globals = func.func_globals # Earlier versions.
1808
1809 context = args[0].namespace # variables to be injected
1810 saved_values = func_globals.copy() # Shallow copy of dict.
1811 log("globals before", context.keys())
1812 func_globals.update(context)
1813 result = func(*args, **kwargs)
1814 log("globals after", func_globals['CIA'], func_globals['NIA'])
1815 log("args[0]", args[0].namespace['CIA'],
1816 args[0].namespace['NIA'],
1817 args[0].namespace['SVSTATE'])
1818 args[0].namespace = func_globals
1819 #exec (func.__code__, func_globals)
1820
1821 # finally:
1822 # func_globals = saved_values # Undo changes.
1823
1824 return result
1825
1826 return decorator
1827
1828 return variable_injector
1829
1830