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