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