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