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