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