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