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