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