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