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
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.
13 * https://bugs.libre-soc.org/show_bug.cgi?id=424
16 from collections
import namedtuple
17 from copy
import deepcopy
18 from functools
import wraps
20 from nmigen
.sim
import Settle
21 from openpower
.consts
import (MSRb
, PIb
, # big-endian (PowerISA versions)
22 SVP64CROffs
, SVP64MODEb
)
23 from openpower
.decoder
.helpers
import (ISACallerHelper
, ISAFPHelpers
, exts
,
25 from openpower
.decoder
.isa
.mem
import Mem
, MemException
26 from openpower
.decoder
.isa
.radixmmu
import RADIX
27 from openpower
.decoder
.isa
.svshape
import SVSHAPE
28 from openpower
.decoder
.isa
.svstate
import SVP64State
29 from openpower
.decoder
.orderedset
import OrderedSet
30 from openpower
.decoder
.power_enums
import (FPTRANS_INSNS
, CRInSel
, CROutSel
,
31 In1Sel
, In2Sel
, In3Sel
, LDSTMode
,
32 MicrOp
, OutSel
, SVMode
,
33 SVP64LDSTmode
, SVP64PredCR
,
34 SVP64PredInt
, SVP64PredMode
,
35 SVP64RMMode
, SVPType
, XER_bits
,
36 insns
, spr_byname
, spr_dict
)
37 from openpower
.decoder
.power_insn
import SVP64Instruction
38 from openpower
.decoder
.power_svp64
import SVP64RM
, decode_extra
39 from openpower
.decoder
.selectable_int
import (FieldSelectableInt
,
40 SelectableInt
, selectconcat
,
41 EFFECTIVELY_UNLIMITED
)
42 from openpower
.fpscr
import FPSCRState
43 from openpower
.util
import LogKind
, log
45 instruction_info
= namedtuple('instruction_info',
46 'func read_regs uninit_regs write_regs ' +
47 'special_regs op_fields form asmregs')
57 # rrright. this is here basically because the compiler pywriter returns
58 # results in a specific priority order. to make sure regs match up they
59 # need partial sorting. sigh.
61 # TODO (lkcl): adjust other registers that should be in a particular order
62 # probably CA, CA32, and CR
89 "overflow": 7, # should definitely be last
93 fregs
= ['FRA', 'FRB', 'FRC', 'FRS', 'FRT']
96 def get_masked_reg(regs
, base
, offs
, ew_bits
):
97 # rrrright. start by breaking down into row/col, based on elwidth
98 gpr_offs
= offs
// (64 // ew_bits
)
99 gpr_col
= offs
% (64 // ew_bits
)
100 # compute the mask based on ew_bits
101 mask
= (1 << ew_bits
) - 1
102 # now select the 64-bit register, but get its value (easier)
103 val
= regs
[base
+ gpr_offs
]
104 # shift down so element we want is at LSB
105 val
>>= gpr_col
* ew_bits
106 # mask so we only return the LSB element
110 def set_masked_reg(regs
, base
, offs
, ew_bits
, value
):
111 # rrrright. start by breaking down into row/col, based on elwidth
112 gpr_offs
= offs
// (64//ew_bits
)
113 gpr_col
= offs
% (64//ew_bits
)
114 # compute the mask based on ew_bits
115 mask
= (1 << ew_bits
)-1
116 # now select the 64-bit register, but get its value (easier)
117 val
= regs
[base
+gpr_offs
]
118 # now mask out the bit we don't want
119 val
= val
& ~
(mask
<< (gpr_col
*ew_bits
))
120 # then wipe the bit we don't want from the value
122 # OR the new value in, shifted up
123 val |
= value
<< (gpr_col
*ew_bits
)
124 regs
[base
+gpr_offs
] = val
127 def create_args(reglist
, extra
=None):
128 retval
= list(OrderedSet(reglist
))
129 retval
.sort(key
=lambda reg
: REG_SORT_ORDER
.get(reg
, 0))
130 if extra
is not None:
131 return [extra
] + retval
136 def __init__(self
, decoder
, isacaller
, svstate
, regfile
):
139 self
.isacaller
= isacaller
140 self
.svstate
= svstate
141 for i
in range(len(regfile
)):
142 self
[i
] = SelectableInt(regfile
[i
], 64)
144 def __call__(self
, ridx
, is_vec
=False, offs
=0, elwidth
=64):
145 if isinstance(ridx
, SelectableInt
):
148 return self
[ridx
+offs
]
149 # rrrright. start by breaking down into row/col, based on elwidth
150 gpr_offs
= offs
// (64//elwidth
)
151 gpr_col
= offs
% (64//elwidth
)
152 # now select the 64-bit register, but get its value (easier)
153 val
= self
[ridx
+gpr_offs
].value
154 # now shift down and mask out
155 val
= val
>> (gpr_col
*elwidth
) & ((1 << elwidth
)-1)
156 # finally, return a SelectableInt at the required elwidth
157 log("GPR call", ridx
, "isvec", is_vec
, "offs", offs
,
158 "elwid", elwidth
, "offs/col", gpr_offs
, gpr_col
, "val", hex(val
))
159 return SelectableInt(val
, elwidth
)
161 def set_form(self
, form
):
164 def write(self
, rnum
, value
, is_vec
=False, elwidth
=64):
166 if isinstance(rnum
, SelectableInt
):
168 if isinstance(value
, SelectableInt
):
171 if isinstance(rnum
, tuple):
172 rnum
, base
, offs
= rnum
175 # rrrright. start by breaking down into row/col, based on elwidth
176 gpr_offs
= offs
// (64//elwidth
)
177 gpr_col
= offs
% (64//elwidth
)
178 # compute the mask based on elwidth
179 mask
= (1 << elwidth
)-1
180 # now select the 64-bit register, but get its value (easier)
181 val
= self
[base
+gpr_offs
].value
182 # now mask out the bit we don't want
183 val
= val
& ~
(mask
<< (gpr_col
*elwidth
))
184 # then wipe the bit we don't want from the value
186 # OR the new value in, shifted up
187 val |
= value
<< (gpr_col
*elwidth
)
188 # finally put the damn value into the regfile
189 log("GPR write", base
, "isvec", is_vec
, "offs", offs
,
190 "elwid", elwidth
, "offs/col", gpr_offs
, gpr_col
, "val", hex(val
),
192 dict.__setitem
__(self
, base
+gpr_offs
, SelectableInt(val
, 64))
194 def __setitem__(self
, rnum
, value
):
195 # rnum = rnum.value # only SelectableInt allowed
196 log("GPR setitem", rnum
, value
)
197 if isinstance(rnum
, SelectableInt
):
199 dict.__setitem
__(self
, rnum
, value
)
201 def getz(self
, rnum
):
202 # rnum = rnum.value # only SelectableInt allowed
203 log("GPR getzero?", rnum
)
205 return SelectableInt(0, 64)
208 def _get_regnum(self
, attr
):
209 getform
= self
.sd
.sigforms
[self
.form
]
210 rnum
= getattr(getform
, attr
)
213 def ___getitem__(self
, attr
):
214 """ XXX currently not used
216 rnum
= self
._get
_regnum
(attr
)
217 log("GPR getitem", attr
, rnum
)
218 return self
.regfile
[rnum
]
220 def dump(self
, printout
=True):
222 for i
in range(len(self
)):
223 res
.append(self
[i
].value
)
225 for i
in range(0, len(res
), 8):
228 s
.append("%08x" % res
[i
+j
])
230 print("reg", "%2d" % i
, s
)
235 def __init__(self
, dec2
, initial_sprs
={}):
238 for key
, v
in initial_sprs
.items():
239 if isinstance(key
, SelectableInt
):
241 key
= special_sprs
.get(key
, key
)
242 if isinstance(key
, int):
245 info
= spr_byname
[key
]
246 if not isinstance(v
, SelectableInt
):
247 v
= SelectableInt(v
, info
.length
)
250 def __getitem__(self
, key
):
252 log("dict", self
.items())
253 # if key in special_sprs get the special spr, otherwise return key
254 if isinstance(key
, SelectableInt
):
256 if isinstance(key
, int):
257 key
= spr_dict
[key
].SPR
258 key
= special_sprs
.get(key
, key
)
259 if key
== 'HSRR0': # HACK!
261 if key
== 'HSRR1': # HACK!
264 res
= dict.__getitem
__(self
, key
)
266 if isinstance(key
, int):
269 info
= spr_byname
[key
]
270 dict.__setitem
__(self
, key
, SelectableInt(0, info
.length
))
271 res
= dict.__getitem
__(self
, key
)
272 log("spr returning", key
, res
)
275 def __setitem__(self
, key
, value
):
276 if isinstance(key
, SelectableInt
):
278 if isinstance(key
, int):
279 key
= spr_dict
[key
].SPR
281 key
= special_sprs
.get(key
, key
)
282 if key
== 'HSRR0': # HACK!
283 self
.__setitem
__('SRR0', value
)
284 if key
== 'HSRR1': # HACK!
285 self
.__setitem
__('SRR1', value
)
286 log("setting spr", key
, value
)
287 dict.__setitem
__(self
, key
, value
)
289 def __call__(self
, ridx
):
292 def dump(self
, printout
=True):
294 keys
= list(self
.keys())
297 sprname
= spr_dict
.get(k
, None)
301 sprname
= sprname
.SPR
302 res
.append((sprname
, self
[k
].value
))
304 for sprname
, value
in res
:
305 print(" ", sprname
, hex(value
))
310 def __init__(self
, pc_init
=0):
311 self
.CIA
= SelectableInt(pc_init
, 64)
312 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
314 def update_nia(self
, is_svp64
):
315 increment
= 8 if is_svp64
else 4
316 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
318 def update(self
, namespace
, is_svp64
):
319 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
321 self
.CIA
= namespace
['NIA'].narrow(64)
322 self
.update_nia(is_svp64
)
323 namespace
['CIA'] = self
.CIA
324 namespace
['NIA'] = self
.NIA
328 # See PowerISA Version 3.0 B Book 1
329 # Section 2.3.1 Condition Register pages 30 - 31
331 LT
= FL
= 0 # negative, less than, floating-point less than
332 GT
= FG
= 1 # positive, greater than, floating-point greater than
333 EQ
= FE
= 2 # equal, floating-point equal
334 SO
= FU
= 3 # summary overflow, floating-point unordered
336 def __init__(self
, init
=0):
337 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
338 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
339 self
.cr
= SelectableInt(init
, 64) # underlying reg
340 # field-selectable versions of Condition Register TODO check bitranges?
343 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
344 _cr
= FieldSelectableInt(self
.cr
, bits
)
348 # decode SVP64 predicate integer to reg number and invert
349 def get_predint(gpr
, mask
):
353 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
354 if mask
== SVP64PredInt
.ALWAYS
.value
:
355 return 0xffff_ffff_ffff_ffff # 64 bits of 1
356 if mask
== SVP64PredInt
.R3_UNARY
.value
:
357 return 1 << (r3
.value
& 0b111111)
358 if mask
== SVP64PredInt
.R3
.value
:
360 if mask
== SVP64PredInt
.R3_N
.value
:
362 if mask
== SVP64PredInt
.R10
.value
:
364 if mask
== SVP64PredInt
.R10_N
.value
:
366 if mask
== SVP64PredInt
.R30
.value
:
368 if mask
== SVP64PredInt
.R30_N
.value
:
372 # decode SVP64 predicate CR to reg number and invert status
373 def _get_predcr(mask
):
374 if mask
== SVP64PredCR
.LT
.value
:
376 if mask
== SVP64PredCR
.GE
.value
:
378 if mask
== SVP64PredCR
.GT
.value
:
380 if mask
== SVP64PredCR
.LE
.value
:
382 if mask
== SVP64PredCR
.EQ
.value
:
384 if mask
== SVP64PredCR
.NE
.value
:
386 if mask
== SVP64PredCR
.SO
.value
:
388 if mask
== SVP64PredCR
.NS
.value
:
392 # read individual CR fields (0..VL-1), extract the required bit
393 # and construct the mask
394 def get_predcr(crl
, mask
, vl
):
395 idx
, noninv
= _get_predcr(mask
)
398 cr
= crl
[i
+SVP64CROffs
.CRPred
]
399 if cr
[idx
].value
== noninv
:
404 # TODO, really should just be using PowerDecoder2
405 def get_idx_map(dec2
, name
):
407 in1_sel
= yield op
.in1_sel
408 in2_sel
= yield op
.in2_sel
409 in3_sel
= yield op
.in3_sel
410 in1
= yield dec2
.e
.read_reg1
.data
411 # identify which regnames map to in1/2/3
412 if name
== 'RA' or name
== 'RA_OR_ZERO':
413 if (in1_sel
== In1Sel
.RA
.value
or
414 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
416 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
419 if in2_sel
== In2Sel
.RB
.value
:
421 if in3_sel
== In3Sel
.RB
.value
:
423 # XXX TODO, RC doesn't exist yet!
425 if in3_sel
== In3Sel
.RC
.value
:
427 elif name
in ['EA', 'RS']:
428 if in1_sel
== In1Sel
.RS
.value
:
430 if in2_sel
== In2Sel
.RS
.value
:
432 if in3_sel
== In3Sel
.RS
.value
:
435 if in1_sel
== In1Sel
.FRA
.value
:
437 if in3_sel
== In3Sel
.FRA
.value
:
440 if in2_sel
== In2Sel
.FRB
.value
:
443 if in3_sel
== In3Sel
.FRC
.value
:
446 if in1_sel
== In1Sel
.FRS
.value
:
448 if in3_sel
== In3Sel
.FRS
.value
:
451 if in1_sel
== In1Sel
.FRT
.value
:
454 if in1_sel
== In1Sel
.RT
.value
:
459 # TODO, really should just be using PowerDecoder2
460 def get_idx_in(dec2
, name
, ewmode
=False):
461 idx
= yield from get_idx_map(dec2
, name
)
465 in1_sel
= yield op
.in1_sel
466 in2_sel
= yield op
.in2_sel
467 in3_sel
= yield op
.in3_sel
468 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
469 in1
= yield dec2
.e
.read_reg1
.data
470 in2
= yield dec2
.e
.read_reg2
.data
471 in3
= yield dec2
.e
.read_reg3
.data
473 in1_base
= yield dec2
.e
.read_reg1
.base
474 in2_base
= yield dec2
.e
.read_reg2
.base
475 in3_base
= yield dec2
.e
.read_reg3
.base
476 in1_offs
= yield dec2
.e
.read_reg1
.offs
477 in2_offs
= yield dec2
.e
.read_reg2
.offs
478 in3_offs
= yield dec2
.e
.read_reg3
.offs
479 in1
= (in1
, in1_base
, in1_offs
)
480 in2
= (in2
, in2_base
, in2_offs
)
481 in3
= (in3
, in3_base
, in3_offs
)
483 in1_isvec
= yield dec2
.in1_isvec
484 in2_isvec
= yield dec2
.in2_isvec
485 in3_isvec
= yield dec2
.in3_isvec
486 log("get_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
488 log("get_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
490 log("get_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
492 log("get_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
494 log("get_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
496 log("get_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
499 return in1
, in1_isvec
501 return in2
, in2_isvec
503 return in3
, in3_isvec
507 # TODO, really should just be using PowerDecoder2
508 def get_cr_in(dec2
, name
):
510 in_sel
= yield op
.cr_in
511 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
512 sv_cr_in
= yield op
.sv_cr_in
513 spec
= yield dec2
.crin_svdec
.spec
514 sv_override
= yield dec2
.dec_cr_in
.sv_override
515 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
516 in1
= yield dec2
.e
.read_cr1
.data
517 cr_isvec
= yield dec2
.cr_in_isvec
518 log("get_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
519 log(" sv_cr_in", sv_cr_in
)
520 log(" cr_bf", in_bitfield
)
522 log(" override", sv_override
)
523 # identify which regnames map to in / o2
525 if in_sel
== CRInSel
.BI
.value
:
527 log("get_cr_in not found", name
)
531 # TODO, really should just be using PowerDecoder2
532 def get_cr_out(dec2
, name
):
534 out_sel
= yield op
.cr_out
535 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
536 sv_cr_out
= yield op
.sv_cr_out
537 spec
= yield dec2
.crout_svdec
.spec
538 sv_override
= yield dec2
.dec_cr_out
.sv_override
539 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
540 out
= yield dec2
.e
.write_cr
.data
541 o_isvec
= yield dec2
.cr_out_isvec
542 log("get_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
543 log(" sv_cr_out", sv_cr_out
)
544 log(" cr_bf", out_bitfield
)
546 log(" override", sv_override
)
547 # identify which regnames map to out / o2
549 if out_sel
== CROutSel
.BF
.value
:
552 if out_sel
== CROutSel
.CR0
.value
:
554 if name
== 'CR1': # these are not actually calculated correctly
555 if out_sel
== CROutSel
.CR1
.value
:
557 # check RC1 set? if so return implicit vector, this is a REAL bad hack
558 RC1
= yield dec2
.rm_dec
.RC1
560 log("get_cr_out RC1 mode")
562 return 0, True # XXX TODO: offset CR0 from SVSTATE SPR
564 return 1, True # XXX TODO: offset CR1 from SVSTATE SPR
566 log("get_cr_out not found", name
)
570 # TODO, really should just be using PowerDecoder2
571 def get_out_map(dec2
, name
):
573 out_sel
= yield op
.out_sel
574 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
575 out
= yield dec2
.e
.write_reg
.data
576 # identify which regnames map to out / o2
578 if out_sel
== OutSel
.RA
.value
:
581 if out_sel
== OutSel
.RT
.value
:
583 if out_sel
== OutSel
.RT_OR_ZERO
.value
and out
!= 0:
585 elif name
== 'RT_OR_ZERO':
586 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
589 if out_sel
== OutSel
.FRA
.value
:
592 if out_sel
== OutSel
.FRS
.value
:
595 if out_sel
== OutSel
.FRT
.value
:
600 # TODO, really should just be using PowerDecoder2
601 def get_idx_out(dec2
, name
, ewmode
=False):
603 out_sel
= yield op
.out_sel
604 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
605 out
= yield dec2
.e
.write_reg
.data
606 o_isvec
= yield dec2
.o_isvec
608 offs
= yield dec2
.e
.write_reg
.offs
609 base
= yield dec2
.e
.write_reg
.base
610 out
= (out
, base
, offs
)
611 # identify which regnames map to out / o2
612 ismap
= yield from get_out_map(dec2
, name
)
614 log("get_idx_out", name
, out_sel
, out
, o_isvec
)
616 log("get_idx_out not found", name
, out_sel
, out
, o_isvec
)
620 # TODO, really should just be using PowerDecoder2
621 def get_out2_map(dec2
, name
):
622 # check first if register is activated for write
624 out_sel
= yield op
.out_sel
625 out
= yield dec2
.e
.write_ea
.data
626 out_ok
= yield dec2
.e
.write_ea
.ok
630 if name
in ['EA', 'RA']:
631 if hasattr(op
, "upd"):
632 # update mode LD/ST uses read-reg A also as an output
634 log("get_idx_out2", upd
, LDSTMode
.update
.value
,
635 out_sel
, OutSel
.RA
.value
,
637 if upd
== LDSTMode
.update
.value
:
640 fft_en
= yield dec2
.implicit_rs
642 log("get_idx_out2", out_sel
, OutSel
.RS
.value
,
646 fft_en
= yield dec2
.implicit_rs
648 log("get_idx_out2", out_sel
, OutSel
.FRS
.value
,
654 # TODO, really should just be using PowerDecoder2
655 def get_idx_out2(dec2
, name
, ewmode
=False):
656 # check first if register is activated for write
658 out_sel
= yield op
.out_sel
659 out
= yield dec2
.e
.write_ea
.data
661 offs
= yield dec2
.e
.write_ea
.offs
662 base
= yield dec2
.e
.write_ea
.base
663 out
= (out
, base
, offs
)
664 o_isvec
= yield dec2
.o2_isvec
665 ismap
= yield from get_out2_map(dec2
, name
)
667 log("get_idx_out2", name
, out_sel
, out
, o_isvec
)
673 """deals with svstate looping.
676 def __init__(self
, svstate
):
677 self
.svstate
= svstate
680 def new_iterators(self
):
681 self
.src_it
= self
.src_iterator()
682 self
.dst_it
= self
.dst_iterator()
686 self
.new_ssubstep
= 0
687 self
.new_dsubstep
= 0
688 self
.pred_dst_zero
= 0
689 self
.pred_src_zero
= 0
691 def src_iterator(self
):
692 """source-stepping iterator
694 pack
= self
.svstate
.pack
698 # pack advances subvl in *outer* loop
699 while True: # outer subvl loop
700 while True: # inner vl loop
703 srcmask
= self
.srcmask
704 srcstep
= self
.svstate
.srcstep
705 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
706 if self
.pred_sz
or pred_src_zero
:
707 self
.pred_src_zero
= not pred_src_zero
708 log(" advance src", srcstep
, vl
,
709 self
.svstate
.ssubstep
, subvl
)
710 # yield actual substep/srcstep
711 yield (self
.svstate
.ssubstep
, srcstep
)
712 # the way yield works these could have been modified.
715 srcstep
= self
.svstate
.srcstep
716 log(" advance src check", srcstep
, vl
,
717 self
.svstate
.ssubstep
, subvl
, srcstep
== vl
-1,
718 self
.svstate
.ssubstep
== subvl
)
719 if srcstep
== vl
-1: # end-point
720 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
721 if self
.svstate
.ssubstep
== subvl
: # end-point
722 log(" advance pack stop")
724 break # exit inner loop
725 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance ss
727 if self
.svstate
.ssubstep
== subvl
: # end-point
728 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
729 log(" advance pack stop")
731 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
734 # these cannot be done as for-loops because SVSTATE may change
735 # (srcstep/substep may be modified, interrupted, subvl/vl change)
736 # but they *can* be done as while-loops as long as every SVSTATE
737 # "thing" is re-read every single time a yield gives indices
738 while True: # outer vl loop
739 while True: # inner subvl loop
742 srcmask
= self
.srcmask
743 srcstep
= self
.svstate
.srcstep
744 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
745 if self
.pred_sz
or pred_src_zero
:
746 self
.pred_src_zero
= not pred_src_zero
747 log(" advance src", srcstep
, vl
,
748 self
.svstate
.ssubstep
, subvl
)
749 # yield actual substep/srcstep
750 yield (self
.svstate
.ssubstep
, srcstep
)
751 if self
.svstate
.ssubstep
== subvl
: # end-point
752 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
753 break # exit inner loop
754 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
756 if srcstep
== vl
-1: # end-point
757 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
760 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
762 def dst_iterator(self
):
763 """dest-stepping iterator
765 unpack
= self
.svstate
.unpack
769 # pack advances subvl in *outer* loop
770 while True: # outer subvl loop
771 while True: # inner vl loop
774 dstmask
= self
.dstmask
775 dststep
= self
.svstate
.dststep
776 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
777 if self
.pred_dz
or pred_dst_zero
:
778 self
.pred_dst_zero
= not pred_dst_zero
779 log(" advance dst", dststep
, vl
,
780 self
.svstate
.dsubstep
, subvl
)
781 # yield actual substep/dststep
782 yield (self
.svstate
.dsubstep
, dststep
)
783 # the way yield works these could have been modified.
785 dststep
= self
.svstate
.dststep
786 log(" advance dst check", dststep
, vl
,
787 self
.svstate
.ssubstep
, subvl
)
788 if dststep
== vl
-1: # end-point
789 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
790 if self
.svstate
.dsubstep
== subvl
: # end-point
791 log(" advance unpack stop")
794 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance ds
796 if self
.svstate
.dsubstep
== subvl
: # end-point
797 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
798 log(" advance unpack stop")
800 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
802 # these cannot be done as for-loops because SVSTATE may change
803 # (dststep/substep may be modified, interrupted, subvl/vl change)
804 # but they *can* be done as while-loops as long as every SVSTATE
805 # "thing" is re-read every single time a yield gives indices
806 while True: # outer vl loop
807 while True: # inner subvl loop
809 dstmask
= self
.dstmask
810 dststep
= self
.svstate
.dststep
811 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
812 if self
.pred_dz
or pred_dst_zero
:
813 self
.pred_dst_zero
= not pred_dst_zero
814 log(" advance dst", dststep
, self
.svstate
.vl
,
815 self
.svstate
.dsubstep
, subvl
)
816 # yield actual substep/dststep
817 yield (self
.svstate
.dsubstep
, dststep
)
818 if self
.svstate
.dsubstep
== subvl
: # end-point
819 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
821 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
824 if dststep
== vl
-1: # end-point
825 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
827 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
829 def src_iterate(self
):
830 """source-stepping iterator
834 pack
= self
.svstate
.pack
835 unpack
= self
.svstate
.unpack
836 ssubstep
= self
.svstate
.ssubstep
837 end_ssub
= ssubstep
== subvl
838 end_src
= self
.svstate
.srcstep
== vl
-1
839 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
843 srcstep
= self
.svstate
.srcstep
844 srcmask
= self
.srcmask
846 # pack advances subvl in *outer* loop
848 assert srcstep
<= vl
-1
849 end_src
= srcstep
== vl
-1
854 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
858 srcstep
+= 1 # advance srcstep
859 if not self
.srcstep_skip
:
861 if ((1 << srcstep
) & srcmask
) != 0:
864 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
866 # advance subvl in *inner* loop
869 assert srcstep
<= vl
-1
870 end_src
= srcstep
== vl
-1
871 if end_src
: # end-point
877 if not self
.srcstep_skip
:
879 if ((1 << srcstep
) & srcmask
) != 0:
882 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
883 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
886 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
888 self
.svstate
.srcstep
= SelectableInt(srcstep
, 7)
889 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
892 def dst_iterate(self
):
893 """dest step iterator
897 pack
= self
.svstate
.pack
898 unpack
= self
.svstate
.unpack
899 dsubstep
= self
.svstate
.dsubstep
900 end_dsub
= dsubstep
== subvl
901 dststep
= self
.svstate
.dststep
902 end_dst
= dststep
== vl
-1
903 dstmask
= self
.dstmask
904 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
909 # unpack advances subvl in *outer* loop
911 assert dststep
<= vl
-1
912 end_dst
= dststep
== vl
-1
917 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
921 dststep
+= 1 # advance dststep
922 if not self
.dststep_skip
:
924 if ((1 << dststep
) & dstmask
) != 0:
927 log(" dskip", bin(dstmask
), bin(1 << dststep
))
929 # advance subvl in *inner* loop
932 assert dststep
<= vl
-1
933 end_dst
= dststep
== vl
-1
934 if end_dst
: # end-point
940 if not self
.dststep_skip
:
942 if ((1 << dststep
) & dstmask
) != 0:
945 log(" dskip", bin(dstmask
), bin(1 << dststep
))
946 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
949 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
951 self
.svstate
.dststep
= SelectableInt(dststep
, 7)
952 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
955 def at_loopend(self
):
956 """tells if this is the last possible element. uses the cached values
957 for src/dst-step and sub-steps
961 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
962 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
963 end_ssub
= ssubstep
== subvl
964 end_dsub
= dsubstep
== subvl
965 if srcstep
== vl
-1 and end_ssub
:
967 if dststep
== vl
-1 and end_dsub
:
971 def advance_svstate_steps(self
):
972 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
973 TODO when Pack/Unpack is set, substep becomes the *outer* loop
975 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
976 if self
.loopend
: # huhn??
981 def read_src_mask(self
):
982 """read/update pred_sz and src mask
984 # get SVSTATE VL (oh and print out some debug stuff)
986 srcstep
= self
.svstate
.srcstep
987 ssubstep
= self
.svstate
.ssubstep
989 # get predicate mask (all 64 bits)
990 srcmask
= 0xffff_ffff_ffff_ffff
992 pmode
= yield self
.dec2
.rm_dec
.predmode
993 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
994 srcpred
= yield self
.dec2
.rm_dec
.srcpred
995 dstpred
= yield self
.dec2
.rm_dec
.dstpred
996 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
997 if pmode
== SVP64PredMode
.INT
.value
:
998 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
999 if sv_ptype
== SVPType
.P2
.value
:
1000 srcmask
= get_predint(self
.gpr
, srcpred
)
1001 elif pmode
== SVP64PredMode
.CR
.value
:
1002 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1003 if sv_ptype
== SVPType
.P2
.value
:
1004 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1005 # work out if the ssubsteps are completed
1006 ssubstart
= ssubstep
== 0
1007 log(" pmode", pmode
)
1008 log(" ptype", sv_ptype
)
1009 log(" srcpred", bin(srcpred
))
1010 log(" srcmask", bin(srcmask
))
1011 log(" pred_sz", bin(pred_sz
))
1012 log(" ssubstart", ssubstart
)
1014 # store all that above
1015 self
.srcstep_skip
= False
1016 self
.srcmask
= srcmask
1017 self
.pred_sz
= pred_sz
1018 self
.new_ssubstep
= ssubstep
1019 log(" new ssubstep", ssubstep
)
1020 # until the predicate mask has a "1" bit... or we run out of VL
1021 # let srcstep==VL be the indicator to move to next instruction
1023 self
.srcstep_skip
= True
1025 def read_dst_mask(self
):
1026 """same as read_src_mask - check and record everything needed
1028 # get SVSTATE VL (oh and print out some debug stuff)
1029 # yield Delay(1e-10) # make changes visible
1030 vl
= self
.svstate
.vl
1031 dststep
= self
.svstate
.dststep
1032 dsubstep
= self
.svstate
.dsubstep
1034 # get predicate mask (all 64 bits)
1035 dstmask
= 0xffff_ffff_ffff_ffff
1037 pmode
= yield self
.dec2
.rm_dec
.predmode
1038 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1039 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1040 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1041 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
1042 if pmode
== SVP64PredMode
.INT
.value
:
1043 dstmask
= get_predint(self
.gpr
, dstpred
)
1044 elif pmode
== SVP64PredMode
.CR
.value
:
1045 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1046 # work out if the ssubsteps are completed
1047 dsubstart
= dsubstep
== 0
1048 log(" pmode", pmode
)
1049 log(" ptype", sv_ptype
)
1050 log(" dstpred", bin(dstpred
))
1051 log(" dstmask", bin(dstmask
))
1052 log(" pred_dz", bin(pred_dz
))
1053 log(" dsubstart", dsubstart
)
1055 self
.dststep_skip
= False
1056 self
.dstmask
= dstmask
1057 self
.pred_dz
= pred_dz
1058 self
.new_dsubstep
= dsubstep
1059 log(" new dsubstep", dsubstep
)
1061 self
.dststep_skip
= True
1063 def svstate_pre_inc(self
):
1064 """check if srcstep/dststep need to skip over masked-out predicate bits
1065 note that this is not supposed to do anything to substep,
1066 it is purely for skipping masked-out bits
1069 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1070 yield from self
.read_src_mask()
1071 yield from self
.read_dst_mask()
1078 srcstep
= self
.svstate
.srcstep
1079 srcmask
= self
.srcmask
1080 pred_src_zero
= self
.pred_sz
1081 vl
= self
.svstate
.vl
1082 # srcstep-skipping opportunity identified
1083 if self
.srcstep_skip
:
1084 # cannot do this with sv.bc - XXX TODO
1087 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1088 log(" sskip", bin(1 << srcstep
))
1091 # now work out if the relevant mask bits require zeroing
1093 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
1095 # store new srcstep / dststep
1096 self
.new_srcstep
= srcstep
1097 self
.pred_src_zero
= pred_src_zero
1098 log(" new srcstep", srcstep
)
1101 # dststep-skipping opportunity identified
1102 dststep
= self
.svstate
.dststep
1103 dstmask
= self
.dstmask
1104 pred_dst_zero
= self
.pred_dz
1105 vl
= self
.svstate
.vl
1106 if self
.dststep_skip
:
1107 # cannot do this with sv.bc - XXX TODO
1110 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1111 log(" dskip", bin(1 << dststep
))
1114 # now work out if the relevant mask bits require zeroing
1116 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
1118 # store new srcstep / dststep
1119 self
.new_dststep
= dststep
1120 self
.pred_dst_zero
= pred_dst_zero
1121 log(" new dststep", dststep
)
1124 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
1125 # decoder2 - an instance of power_decoder2
1126 # regfile - a list of initial values for the registers
1127 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
1128 # respect_pc - tracks the program counter. requires initial_insns
1129 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
1130 initial_mem
=None, initial_msr
=0,
1142 self
.bigendian
= bigendian
1144 self
.is_svp64_mode
= False
1145 self
.respect_pc
= respect_pc
1146 if initial_sprs
is None:
1148 if initial_mem
is None:
1150 if fpregfile
is None:
1151 fpregfile
= [0] * 32
1152 if initial_insns
is None:
1154 assert self
.respect_pc
== False, "instructions required to honor pc"
1156 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
1157 log("ISACaller initial_msr", initial_msr
)
1159 # "fake program counter" mode (for unit testing)
1163 if isinstance(initial_mem
, tuple):
1164 self
.fake_pc
= initial_mem
[0]
1165 disasm_start
= self
.fake_pc
1167 disasm_start
= initial_pc
1169 # disassembly: we need this for now (not given from the decoder)
1170 self
.disassembly
= {}
1172 for i
, code
in enumerate(disassembly
):
1173 self
.disassembly
[i
*4 + disasm_start
] = code
1175 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
1176 self
.svp64rm
= SVP64RM()
1177 if initial_svstate
is None:
1179 if isinstance(initial_svstate
, int):
1180 initial_svstate
= SVP64State(initial_svstate
)
1181 # SVSTATE, MSR and PC
1182 StepLoop
.__init
__(self
, initial_svstate
)
1183 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
1185 # GPR FPR SPR registers
1186 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
1187 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
1188 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
1189 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
1191 # set up 4 dummy SVSHAPEs if they aren't already set up
1193 sname
= 'SVSHAPE%d' % i
1194 val
= self
.spr
.get(sname
, 0)
1195 # make sure it's an SVSHAPE
1196 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
1197 self
.last_op_svshape
= False
1200 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
, misaligned_ok
=True)
1201 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
1202 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
1203 # MMU mode, redirect underlying Mem through RADIX
1205 self
.mem
= RADIX(self
.mem
, self
)
1207 self
.imem
= RADIX(self
.imem
, self
)
1209 # TODO, needed here:
1210 # FPR (same as GPR except for FP nums)
1211 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1212 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1213 self
.fpscr
= FPSCRState(initial_fpscr
)
1215 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1216 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1218 # 2.3.2 LR (actually SPR #8) -- Done
1219 # 2.3.3 CTR (actually SPR #9) -- Done
1220 # 2.3.4 TAR (actually SPR #815)
1221 # 3.2.2 p45 XER (actually SPR #1) -- Done
1222 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1224 # create CR then allow portions of it to be "selectable" (below)
1225 self
.cr_fields
= CRFields(initial_cr
)
1226 self
.cr
= self
.cr_fields
.cr
1227 self
.cr_backup
= 0 # sigh, dreadful hack: for fail-first (VLi)
1229 # "undefined", just set to variable-bit-width int (use exts "max")
1230 # self.undefined = SelectableInt(0, EFFECTIVELY_UNLIMITED)
1233 self
.namespace
.update(self
.spr
)
1234 self
.namespace
.update({'GPR': self
.gpr
,
1238 'memassign': self
.memassign
,
1241 'SVSTATE': self
.svstate
,
1242 'SVSHAPE0': self
.spr
['SVSHAPE0'],
1243 'SVSHAPE1': self
.spr
['SVSHAPE1'],
1244 'SVSHAPE2': self
.spr
['SVSHAPE2'],
1245 'SVSHAPE3': self
.spr
['SVSHAPE3'],
1248 'FPSCR': self
.fpscr
,
1249 'undefined': undefined
,
1250 'mode_is_64bit': True,
1251 'SO': XER_bits
['SO'],
1252 'XLEN': 64 # elwidth overrides
1255 # update pc to requested start point
1256 self
.set_pc(initial_pc
)
1258 # field-selectable versions of Condition Register
1259 self
.crl
= self
.cr_fields
.crl
1261 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
1263 self
.decoder
= decoder2
.dec
1264 self
.dec2
= decoder2
1266 super().__init
__(XLEN
=self
.namespace
["XLEN"])
1270 return self
.namespace
["XLEN"]
1272 def call_trap(self
, trap_addr
, trap_bit
):
1273 """calls TRAP and sets up NIA to the new execution location.
1274 next instruction will begin at trap_addr.
1276 self
.TRAP(trap_addr
, trap_bit
)
1277 self
.namespace
['NIA'] = self
.trap_nia
1278 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1280 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1281 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1283 TRAP function is callable from inside the pseudocode itself,
1284 hence the default arguments. when calling from inside ISACaller
1285 it is best to use call_trap()
1287 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1288 kaivb
= self
.spr
['KAIVB'].value
1289 msr
= self
.namespace
['MSR'].value
1290 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1291 # store CIA(+4?) in SRR0, set NIA to 0x700
1292 # store MSR in SRR1, set MSR to um errr something, have to check spec
1293 # store SVSTATE (if enabled) in SVSRR0
1294 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1295 self
.spr
['SRR1'].value
= msr
1296 if self
.is_svp64_mode
:
1297 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1298 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1299 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1301 # set exception bits. TODO: this should, based on the address
1302 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1303 # bits appropriately. however it turns out that *for now* in all
1304 # cases (all trap_addrs) the exact same thing is needed.
1305 self
.msr
[MSRb
.IR
] = 0
1306 self
.msr
[MSRb
.DR
] = 0
1307 self
.msr
[MSRb
.FE0
] = 0
1308 self
.msr
[MSRb
.FE1
] = 0
1309 self
.msr
[MSRb
.EE
] = 0
1310 self
.msr
[MSRb
.RI
] = 0
1311 self
.msr
[MSRb
.SF
] = 1
1312 self
.msr
[MSRb
.TM
] = 0
1313 self
.msr
[MSRb
.VEC
] = 0
1314 self
.msr
[MSRb
.VSX
] = 0
1315 self
.msr
[MSRb
.PR
] = 0
1316 self
.msr
[MSRb
.FP
] = 0
1317 self
.msr
[MSRb
.PMM
] = 0
1318 self
.msr
[MSRb
.TEs
] = 0
1319 self
.msr
[MSRb
.TEe
] = 0
1320 self
.msr
[MSRb
.UND
] = 0
1321 self
.msr
[MSRb
.LE
] = 1
1323 def memassign(self
, ea
, sz
, val
):
1324 self
.mem
.memassign(ea
, sz
, val
)
1326 def prep_namespace(self
, insn_name
, formname
, op_fields
, xlen
):
1327 # TODO: get field names from form in decoder*1* (not decoder2)
1328 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1330 # then "yield" fields only from op_fields rather than hard-coded
1332 fields
= self
.decoder
.sigforms
[formname
]
1333 log("prep_namespace", formname
, op_fields
, insn_name
)
1334 for name
in op_fields
:
1335 # CR immediates. deal with separately. needs modifying
1337 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1338 # BI is a 5-bit, must reconstruct the value
1339 regnum
, is_vec
= yield from get_cr_in(self
.dec2
, name
)
1340 sig
= getattr(fields
, name
)
1342 # low 2 LSBs (CR field selector) remain same, CR num extended
1343 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1344 val
= (val
& 0b11) |
(regnum
<< 2)
1345 elif self
.is_svp64_mode
and name
in ['BF']: # TODO, more CRs
1346 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, "BF")
1347 log('hack %s' % name
, regnum
, is_vec
)
1350 sig
= getattr(fields
, name
)
1352 # these are all opcode fields involved in index-selection of CR,
1353 # and need to do "standard" arithmetic. CR[BA+32] for example
1354 # would, if using SelectableInt, only be 5-bit.
1355 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1356 self
.namespace
[name
] = val
1358 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1360 self
.namespace
['XER'] = self
.spr
['XER']
1361 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1362 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1363 self
.namespace
['OV'] = self
.spr
['XER'][XER_bits
['OV']].value
1364 self
.namespace
['OV32'] = self
.spr
['XER'][XER_bits
['OV32']].value
1365 self
.namespace
['XLEN'] = xlen
1367 # add some SVSTATE convenience variables
1368 vl
= self
.svstate
.vl
1369 srcstep
= self
.svstate
.srcstep
1370 self
.namespace
['VL'] = vl
1371 self
.namespace
['srcstep'] = srcstep
1373 # take a copy of the CR field value: if non-VLi fail-first fails
1374 # this is because the pseudocode writes *directly* to CR. sigh
1375 self
.cr_backup
= self
.cr
.value
1377 # sv.bc* need some extra fields
1378 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1379 # blegh grab bits manually
1380 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1381 # convert to SelectableInt before test
1382 mode
= SelectableInt(mode
, 5)
1383 bc_vlset
= mode
[SVP64MODEb
.BC_VLSET
] != 0
1384 bc_vli
= mode
[SVP64MODEb
.BC_VLI
] != 0
1385 bc_snz
= mode
[SVP64MODEb
.BC_SNZ
] != 0
1386 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1387 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1388 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1389 sz
= yield self
.dec2
.rm_dec
.pred_sz
1390 self
.namespace
['mode'] = SelectableInt(mode
, 5)
1391 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1392 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1393 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1394 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1395 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1396 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1397 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1399 def get_kludged_op_add_ca_ov(self
, inputs
, inp_ca_ov
):
1400 """ this was not at all necessary to do. this function massively
1401 duplicates - in a laborious and complex fashion - the contents of
1402 the CSV files that were extracted two years ago from microwatt's
1403 source code. A-inversion is the "inv A" column, output inversion
1404 is the "inv out" column, carry-in equal to 0 or 1 or CA is the
1407 all of that information is available in
1408 self.instrs[ins_name].op_fields
1409 where info is usually assigned to self.instrs[ins_name]
1411 https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=openpower/isatables/minor_31.csv;hb=HEAD
1413 the immediate constants are *also* decoded correctly and placed
1414 usually by DecodeIn2Imm into operand2, as part of power_decoder2.py
1416 def ca(a
, b
, ca_in
, width
):
1417 mask
= (1 << width
) - 1
1418 y
= (a
& mask
) + (b
& mask
) + ca_in
1421 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1422 insn
= insns
.get(asmcode
)
1423 SI
= yield self
.dec2
.dec
.SI
1426 inputs
= [i
.value
for i
in inputs
]
1429 if insn
in ("add", "addo", "addc", "addco"):
1433 elif insn
== "addic" or insn
== "addic.":
1437 elif insn
in ("subf", "subfo", "subfc", "subfco"):
1441 elif insn
== "subfic":
1445 elif insn
== "adde" or insn
== "addeo":
1449 elif insn
== "subfe" or insn
== "subfeo":
1453 elif insn
== "addme" or insn
== "addmeo":
1457 elif insn
== "addze" or insn
== "addzeo":
1461 elif insn
== "subfme" or insn
== "subfmeo":
1465 elif insn
== "subfze" or insn
== "subfzeo":
1469 elif insn
== "addex":
1470 # CA[32] aren't actually written, just generate so we have
1471 # something to return
1472 ca64
= ov64
= ca(inputs
[0], inputs
[1], OV
, 64)
1473 ca32
= ov32
= ca(inputs
[0], inputs
[1], OV
, 32)
1474 return ca64
, ca32
, ov64
, ov32
1475 elif insn
== "neg" or insn
== "nego":
1480 raise NotImplementedError(
1481 "op_add kludge unimplemented instruction: ", asmcode
, insn
)
1483 ca64
= ca(a
, b
, ca_in
, 64)
1484 ca32
= ca(a
, b
, ca_in
, 32)
1485 ov64
= ca64
!= ca(a
, b
, ca_in
, 63)
1486 ov32
= ca32
!= ca(a
, b
, ca_in
, 31)
1487 return ca64
, ca32
, ov64
, ov32
1489 def handle_carry_(self
, inputs
, output
, ca
, ca32
, inp_ca_ov
):
1490 op
= yield self
.dec2
.e
.do
.insn_type
1491 if op
== MicrOp
.OP_ADD
.value
and ca
is None and ca32
is None:
1492 retval
= yield from self
.get_kludged_op_add_ca_ov(
1494 ca
, ca32
, ov
, ov32
= retval
1495 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1496 if insns
.get(asmcode
) == 'addex':
1497 # TODO: if 32-bit mode, set ov to ov32
1498 self
.spr
['XER'][XER_bits
['OV']] = ov
1499 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1501 # TODO: if 32-bit mode, set ca to ca32
1502 self
.spr
['XER'][XER_bits
['CA']] = ca
1503 self
.spr
['XER'][XER_bits
['CA32']] = ca32
1505 inv_a
= yield self
.dec2
.e
.do
.invert_in
1507 inputs
[0] = ~inputs
[0]
1509 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1511 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1512 inputs
.append(SelectableInt(imm
, 64))
1515 log("gt input", x
, output
)
1516 gt
= (gtu(x
, output
))
1519 cy
= 1 if any(gts
) else 0
1521 if ca
is None: # already written
1522 self
.spr
['XER'][XER_bits
['CA']] = cy
1525 # ARGH... different for OP_ADD... *sigh*...
1526 op
= yield self
.dec2
.e
.do
.insn_type
1527 if op
== MicrOp
.OP_ADD
.value
:
1528 res32
= (output
.value
& (1 << 32)) != 0
1529 a32
= (inputs
[0].value
& (1 << 32)) != 0
1530 if len(inputs
) >= 2:
1531 b32
= (inputs
[1].value
& (1 << 32)) != 0
1534 cy32
= res32 ^ a32 ^ b32
1535 log("CA32 ADD", cy32
)
1539 log("input", x
, output
)
1540 log(" x[32:64]", x
, x
[32:64])
1541 log(" o[32:64]", output
, output
[32:64])
1542 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1544 cy32
= 1 if any(gts
) else 0
1545 log("CA32", cy32
, gts
)
1546 if ca32
is None: # already written
1547 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1549 def handle_overflow(self
, inputs
, output
, div_overflow
, inp_ca_ov
):
1550 op
= yield self
.dec2
.e
.do
.insn_type
1551 if op
== MicrOp
.OP_ADD
.value
:
1552 retval
= yield from self
.get_kludged_op_add_ca_ov(
1554 ca
, ca32
, ov
, ov32
= retval
1555 # TODO: if 32-bit mode, set ov to ov32
1556 self
.spr
['XER'][XER_bits
['OV']] = ov
1557 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1558 self
.spr
['XER'][XER_bits
['SO']] |
= ov
1560 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1561 inv_a
= yield self
.dec2
.e
.do
.invert_in
1563 inputs
[0] = ~inputs
[0]
1565 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1567 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1568 inputs
.append(SelectableInt(imm
, 64))
1569 log("handle_overflow", inputs
, output
, div_overflow
)
1570 if len(inputs
) < 2 and div_overflow
is None:
1573 # div overflow is different: it's returned by the pseudo-code
1574 # because it's more complex than can be done by analysing the output
1575 if div_overflow
is not None:
1576 ov
, ov32
= div_overflow
, div_overflow
1577 # arithmetic overflow can be done by analysing the input and output
1578 elif len(inputs
) >= 2:
1580 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1581 output_sgn
= exts(output
.value
, output
.bits
) < 0
1582 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1583 output_sgn
!= input_sgn
[0] else 0
1586 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1587 output32_sgn
= exts(output
.value
, 32) < 0
1588 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1589 output32_sgn
!= input32_sgn
[0] else 0
1591 # now update XER OV/OV32/SO
1592 so
= self
.spr
['XER'][XER_bits
['SO']]
1593 new_so
= so | ov
# sticky overflow ORs in old with new
1594 self
.spr
['XER'][XER_bits
['OV']] = ov
1595 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1596 self
.spr
['XER'][XER_bits
['SO']] = new_so
1597 log(" set overflow", ov
, ov32
, so
, new_so
)
1599 def handle_comparison(self
, out
, cr_idx
=0, overflow
=None, no_so
=False):
1600 assert isinstance(out
, SelectableInt
), \
1601 "out zero not a SelectableInt %s" % repr(outputs
)
1602 log("handle_comparison", out
.bits
, hex(out
.value
))
1603 # TODO - XXX *processor* in 32-bit mode
1604 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1606 # o32 = exts(out.value, 32)
1607 # print ("handle_comparison exts 32 bit", hex(o32))
1608 out
= exts(out
.value
, out
.bits
)
1609 log("handle_comparison exts", hex(out
))
1610 # create the three main CR flags, EQ GT LT
1611 zero
= SelectableInt(out
== 0, 1)
1612 positive
= SelectableInt(out
> 0, 1)
1613 negative
= SelectableInt(out
< 0, 1)
1614 # get (or not) XER.SO. for setvl this is important *not* to read SO
1616 SO
= SelectableInt(1, 0)
1618 SO
= self
.spr
['XER'][XER_bits
['SO']]
1619 log("handle_comparison SO", SO
.value
,
1620 "overflow", overflow
,
1622 "+ve", positive
.value
,
1623 "-ve", negative
.value
)
1624 # alternative overflow checking (setvl mainly at the moment)
1625 if overflow
is not None and overflow
== 1:
1626 SO
= SelectableInt(1, 1)
1627 # create the four CR field values and set the required CR field
1628 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1629 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1630 self
.crl
[cr_idx
].eq(cr_field
)
1632 def set_pc(self
, pc_val
):
1633 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1634 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1636 def get_next_insn(self
):
1637 """check instruction
1640 pc
= self
.pc
.CIA
.value
1643 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1645 raise KeyError("no instruction at 0x%x" % pc
)
1648 def setup_one(self
):
1649 """set up one instruction
1651 pc
, insn
= self
.get_next_insn()
1652 yield from self
.setup_next_insn(pc
, insn
)
1654 def setup_next_insn(self
, pc
, ins
):
1655 """set up next instruction
1658 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1659 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1661 yield self
.dec2
.sv_rm
.eq(0)
1662 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1663 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1664 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1665 yield self
.dec2
.state
.pc
.eq(pc
)
1666 if self
.svstate
is not None:
1667 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1669 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1671 opcode
= yield self
.dec2
.dec
.opcode_in
1672 opcode
= SelectableInt(value
=opcode
, bits
=32)
1673 pfx
= SVP64Instruction
.Prefix(opcode
)
1674 log("prefix test: opcode:", pfx
.PO
, bin(pfx
.PO
), pfx
.id)
1675 self
.is_svp64_mode
= bool((pfx
.PO
== 0b000001) and (pfx
.id == 0b11))
1676 self
.pc
.update_nia(self
.is_svp64_mode
)
1678 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1679 self
.namespace
['NIA'] = self
.pc
.NIA
1680 self
.namespace
['SVSTATE'] = self
.svstate
1681 if not self
.is_svp64_mode
:
1684 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1685 log("svp64.rm", bin(pfx
.rm
))
1686 log(" svstate.vl", self
.svstate
.vl
)
1687 log(" svstate.mvl", self
.svstate
.maxvl
)
1688 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1689 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1690 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1691 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1694 def execute_one(self
):
1695 """execute one instruction
1697 # get the disassembly code for this instruction
1698 if not self
.disassembly
:
1699 code
= yield from self
.get_assembly_name()
1702 if self
.is_svp64_mode
:
1703 offs
, dbg
= 4, "svp64 "
1704 code
= self
.disassembly
[self
._pc
+offs
]
1705 log(" %s sim-execute" % dbg
, hex(self
._pc
), code
)
1706 opname
= code
.split(' ')[0]
1708 yield from self
.call(opname
) # execute the instruction
1709 except MemException
as e
: # check for memory errors
1710 if e
.args
[0] == 'unaligned': # alignment error
1711 # run a Trap but set DAR first
1712 print("memory unaligned exception, DAR", e
.dar
, repr(e
))
1713 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1714 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1716 elif e
.args
[0] == 'invalid': # invalid
1717 # run a Trap but set DAR first
1718 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1719 if e
.mode
== 'EXECUTE':
1720 # XXX TODO: must set a few bits in SRR1,
1721 # see microwatt loadstore1.vhdl
1722 # if m_in.segerr = '0' then
1723 # v.srr1(47 - 33) := m_in.invalid;
1724 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1725 # v.srr1(47 - 44) := m_in.badtree;
1726 # v.srr1(47 - 45) := m_in.rc_error;
1727 # v.intr_vec := 16#400#;
1729 # v.intr_vec := 16#480#;
1730 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1732 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1734 # not supported yet:
1735 raise e
# ... re-raise
1737 log("gprs after code", code
)
1740 for i
in range(len(self
.crl
)):
1741 crs
.append(bin(self
.crl
[i
].asint()))
1742 log("crs", " ".join(crs
))
1743 log("vl,maxvl", self
.svstate
.vl
, self
.svstate
.maxvl
)
1745 # don't use this except in special circumstances
1746 if not self
.respect_pc
:
1749 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1750 hex(self
.pc
.NIA
.value
))
1752 def get_assembly_name(self
):
1753 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1754 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1755 dec_insn
= yield self
.dec2
.e
.do
.insn
1756 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1757 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1758 int_op
= yield self
.dec2
.dec
.op
.internal_op
1759 log("get assembly name asmcode", asmcode
, int_op
,
1760 hex(dec_insn
), bin(insn_1_11
))
1761 asmop
= insns
.get(asmcode
, None)
1763 # sigh reconstruct the assembly instruction name
1764 if hasattr(self
.dec2
.e
.do
, "oe"):
1765 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1766 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1770 if hasattr(self
.dec2
.e
.do
, "rc"):
1771 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1772 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1776 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1777 RC1
= yield self
.dec2
.rm_dec
.RC1
1781 # grrrr have to special-case MUL op (see DecodeOE)
1782 log("ov %d en %d rc %d en %d op %d" %
1783 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1784 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1789 if not asmop
.endswith("."): # don't add "." to "andis."
1792 if hasattr(self
.dec2
.e
.do
, "lk"):
1793 lk
= yield self
.dec2
.e
.do
.lk
1796 log("int_op", int_op
)
1797 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1798 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1802 spr_msb
= yield from self
.get_spr_msb()
1803 if int_op
== MicrOp
.OP_MFCR
.value
:
1808 # XXX TODO: for whatever weird reason this doesn't work
1809 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1810 if int_op
== MicrOp
.OP_MTCRF
.value
:
1817 def reset_remaps(self
):
1818 self
.remap_loopends
= [0] * 4
1819 self
.remap_idxs
= [0, 1, 2, 3]
1821 def get_remap_indices(self
):
1822 """WARNING, this function stores remap_idxs and remap_loopends
1823 in the class for later use. this to avoid problems with yield
1825 # go through all iterators in lock-step, advance to next remap_idx
1826 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1827 # get four SVSHAPEs. here we are hard-coding
1829 SVSHAPE0
= self
.spr
['SVSHAPE0']
1830 SVSHAPE1
= self
.spr
['SVSHAPE1']
1831 SVSHAPE2
= self
.spr
['SVSHAPE2']
1832 SVSHAPE3
= self
.spr
['SVSHAPE3']
1833 # set up the iterators
1834 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1835 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1836 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1837 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1841 for i
, (shape
, remap
) in enumerate(remaps
):
1842 # zero is "disabled"
1843 if shape
.value
== 0x0:
1844 self
.remap_idxs
[i
] = 0
1845 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1846 step
= dststep
if (i
in [3, 4]) else srcstep
1847 # this is terrible. O(N^2) looking for the match. but hey.
1848 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1851 self
.remap_idxs
[i
] = remap_idx
1852 self
.remap_loopends
[i
] = loopends
1853 dbg
.append((i
, step
, remap_idx
, loopends
))
1854 for (i
, step
, remap_idx
, loopends
) in dbg
:
1855 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1858 def get_spr_msb(self
):
1859 dec_insn
= yield self
.dec2
.e
.do
.insn
1860 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1862 def call(self
, name
):
1863 """call(opcode) - the primary execution point for instructions
1865 self
.last_st_addr
= None # reset the last known store address
1866 self
.last_ld_addr
= None # etc.
1868 ins_name
= name
.strip() # remove spaces if not already done so
1870 log("halted - not executing", ins_name
)
1873 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1874 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1875 asmop
= yield from self
.get_assembly_name()
1876 log("call", ins_name
, asmop
)
1878 # sv.setvl is *not* a loop-function. sigh
1879 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1882 int_op
= yield self
.dec2
.dec
.op
.internal_op
1883 spr_msb
= yield from self
.get_spr_msb()
1885 instr_is_privileged
= False
1886 if int_op
in [MicrOp
.OP_ATTN
.value
,
1887 MicrOp
.OP_MFMSR
.value
,
1888 MicrOp
.OP_MTMSR
.value
,
1889 MicrOp
.OP_MTMSRD
.value
,
1891 MicrOp
.OP_RFID
.value
]:
1892 instr_is_privileged
= True
1893 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1894 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1895 instr_is_privileged
= True
1897 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1899 # check MSR priv bit and whether op is privileged: if so, throw trap
1900 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1901 self
.call_trap(0x700, PIb
.PRIV
)
1904 # check halted condition
1905 if ins_name
== 'attn':
1909 # check illegal instruction
1911 if ins_name
not in ['mtcrf', 'mtocrf']:
1912 illegal
= ins_name
!= asmop
1914 # list of instructions not being supported by binutils (.long)
1915 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1916 if dotstrp
in [*FPTRANS_INSNS
,
1917 'ffmadds', 'fdmadds', 'ffadds',
1919 'setvl', 'svindex', 'svremap', 'svstep',
1920 'svshape', 'svshape2',
1921 'grev', 'ternlogi', 'bmask', 'cprop',
1922 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1923 'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
1924 "dsld", "dsrd", "maddedus",
1925 "shadd", "shaddw", "shadduw",
1926 "fcvttg", "fcvttgo", "fcvttgs", "fcvttgso",
1928 "fcvtfg", "fcvtfgs",
1930 "maddsubrs", "maddrs"
1935 # branch-conditional redirects to sv.bc
1936 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1937 ins_name
= 'sv.%s' % ins_name
1939 # ld-immediate-with-pi mode redirects to ld-with-postinc
1940 ldst_imm_postinc
= False
1941 if 'u' in ins_name
and self
.is_svp64_mode
:
1942 ldst_pi
= yield self
.dec2
.rm_dec
.ldst_postinc
1944 ins_name
= ins_name
.replace("u", "up")
1945 ldst_imm_postinc
= True
1946 log(" enable ld/st postinc", ins_name
)
1948 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1950 # illegal instructions call TRAP at 0x700
1952 print("illegal", ins_name
, asmop
)
1953 self
.call_trap(0x700, PIb
.ILLEG
)
1954 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1955 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1958 # this is for setvl "Vertical" mode: if set true,
1959 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1960 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1961 self
.allow_next_step_inc
= False
1962 self
.svstate_next_mode
= 0
1964 # nop has to be supported, we could let the actual op calculate
1965 # but PowerDecoder has a pattern for nop
1966 if ins_name
== 'nop':
1967 self
.update_pc_next()
1970 # get elwidths, defaults to 64
1974 if self
.is_svp64_mode
:
1975 ew_src
= yield self
.dec2
.rm_dec
.ew_src
1976 ew_dst
= yield self
.dec2
.rm_dec
.ew_dst
1977 ew_src
= 8 << (3-int(ew_src
)) # convert to bitlength
1978 ew_dst
= 8 << (3-int(ew_dst
)) # convert to bitlength
1979 xlen
= max(ew_src
, ew_dst
)
1980 log("elwdith", ew_src
, ew_dst
)
1981 log("XLEN:", self
.is_svp64_mode
, xlen
)
1983 # look up instruction in ISA.instrs, prepare namespace
1984 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1985 info
= self
.instrs
[ins_name
+"."]
1986 elif asmop
[-1] == '.' and asmop
in self
.instrs
:
1987 info
= self
.instrs
[asmop
]
1989 info
= self
.instrs
[ins_name
]
1990 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
,
1993 # preserve order of register names
1994 input_names
= create_args(list(info
.read_regs
) +
1995 list(info
.uninit_regs
))
1996 log("input names", input_names
)
1998 # get SVP64 entry for the current instruction
1999 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
2000 if sv_rm
is not None:
2001 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
2003 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
2004 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
2006 # see if srcstep/dststep need skipping over masked-out predicate bits
2007 # svstep also needs advancement because it calls SVSTATE_NEXT.
2008 # bit the remaps get computed just after pre_inc moves them on
2009 # with remap_set_steps substituting for PowerDecider2 not doing it,
2010 # and SVSTATE_NEXT not being able to.use yield, the preinc on
2011 # svstep is necessary for now.
2013 if (self
.is_svp64_mode
or ins_name
in ['svstep']):
2014 yield from self
.svstate_pre_inc()
2015 if self
.is_svp64_mode
:
2016 pre
= yield from self
.update_new_svstate_steps()
2018 self
.svp64_reset_loop()
2020 self
.update_pc_next()
2022 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
2023 pred_dst_zero
= self
.pred_dst_zero
2024 pred_src_zero
= self
.pred_src_zero
2025 vl
= self
.svstate
.vl
2026 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2028 # VL=0 in SVP64 mode means "do nothing: skip instruction"
2029 if self
.is_svp64_mode
and vl
== 0:
2030 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2031 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
2032 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
2035 # for when SVREMAP is active, using pre-arranged schedule.
2036 # note: modifying PowerDecoder2 needs to "settle"
2037 remap_en
= self
.svstate
.SVme
2038 persist
= self
.svstate
.RMpst
2039 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
2040 if self
.is_svp64_mode
:
2041 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
2043 if persist
or self
.last_op_svshape
:
2044 remaps
= self
.get_remap_indices()
2045 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
2046 yield from self
.remap_set_steps(remaps
)
2047 # after that, settle down (combinatorial) to let Vector reg numbers
2048 # work themselves out
2050 if self
.is_svp64_mode
:
2051 remap_active
= yield self
.dec2
.remap_active
2053 remap_active
= False
2054 log("remap active", bin(remap_active
))
2056 # main input registers (RT, RA ...)
2058 for name
in input_names
:
2059 regval
= (yield from self
.get_input(name
, ew_src
))
2060 log("regval name", name
, regval
)
2061 inputs
.append(regval
)
2063 # arrrrgh, awful hack, to get _RT into namespace
2064 if ins_name
in ['setvl', 'svstep']:
2066 RT
= yield self
.dec2
.dec
.RT
2067 self
.namespace
[regname
] = SelectableInt(RT
, 5)
2069 self
.namespace
["RT"] = SelectableInt(0, 5)
2070 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, "RT")
2071 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
2073 # in SVP64 mode for LD/ST work out immediate
2074 # XXX TODO: replace_ds for DS-Form rather than D-Form.
2075 # use info.form to detect
2076 if self
.is_svp64_mode
and not ldst_imm_postinc
:
2077 yield from self
.check_replace_d(info
, remap_active
)
2079 # "special" registers
2080 for special
in info
.special_regs
:
2081 if special
in special_sprs
:
2082 inputs
.append(self
.spr
[special
])
2084 inputs
.append(self
.namespace
[special
])
2086 # clear trap (trap) NIA
2087 self
.trap_nia
= None
2089 # check if this was an sv.bc* and create an indicator that
2090 # this is the last check to be made as a loop. combined with
2091 # the ALL/ANY mode we can early-exit
2092 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
2093 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
2094 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
2095 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
2097 inp_ca_ov
= (self
.spr
['XER'][XER_bits
['CA']].value
,
2098 self
.spr
['XER'][XER_bits
['OV']].value
)
2100 # execute actual instruction here (finally)
2101 log("inputs", inputs
)
2102 results
= info
.func(self
, *inputs
)
2103 output_names
= create_args(info
.write_regs
)
2105 for out
, n
in zip(results
or [], output_names
):
2107 log("results", outs
)
2109 # "inject" decorator takes namespace from function locals: we need to
2110 # overwrite NIA being overwritten (sigh)
2111 if self
.trap_nia
is not None:
2112 self
.namespace
['NIA'] = self
.trap_nia
2114 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
2116 # check if op was a LD/ST so that debugging can check the
2118 if int_op
in [MicrOp
.OP_STORE
.value
,
2120 self
.last_st_addr
= self
.mem
.last_st_addr
2121 if int_op
in [MicrOp
.OP_LOAD
.value
,
2123 self
.last_ld_addr
= self
.mem
.last_ld_addr
2124 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
2125 self
.last_st_addr
, self
.last_ld_addr
)
2127 # detect if CA/CA32 already in outputs (sra*, basically)
2129 ca32
= outs
.get("CA32")
2131 log("carry already done?", ca
, ca32
, output_names
)
2132 carry_en
= yield self
.dec2
.e
.do
.output_carry
2134 yield from self
.handle_carry_(
2135 inputs
, results
[0], ca
, ca32
, inp_ca_ov
=inp_ca_ov
)
2137 # get outout named "overflow" and "CR0"
2138 overflow
= outs
.get('overflow')
2139 cr0
= outs
.get('CR0')
2141 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
2142 # detect if overflow was in return result
2143 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
2144 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
2145 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
2147 yield from self
.handle_overflow(
2148 inputs
, results
[0], overflow
, inp_ca_ov
=inp_ca_ov
)
2150 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
2152 if not self
.is_svp64_mode
or not pred_dst_zero
:
2153 if hasattr(self
.dec2
.e
.do
, "rc"):
2154 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
2155 # don't do Rc=1 for svstep it is handled explicitly.
2156 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
2157 # to write directly to CR0 instead of in ISACaller. hooyahh.
2158 if rc_en
and ins_name
not in ['svstep']:
2159 yield from self
.do_rc_ov(ins_name
, results
[0], overflow
, cr0
)
2162 ffirst_hit
= False, False
2163 if self
.is_svp64_mode
:
2164 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
2165 is_cr
= sv_mode
== SVMode
.CROP
.value
2166 chk
= rc_en
or is_cr
2167 ffirst_hit
= (yield from self
.check_ffirst(info
, chk
, srcstep
))
2169 # any modified return results?
2170 yield from self
.do_outregs_nia(asmop
, ins_name
, info
, outs
,
2171 carry_en
, rc_en
, ffirst_hit
, ew_dst
)
2173 def check_ffirst(self
, info
, rc_en
, srcstep
):
2174 """fail-first mode: checks a bit of Rc Vector, truncates VL
2176 rm_mode
= yield self
.dec2
.rm_dec
.mode
2177 ff_inv
= yield self
.dec2
.rm_dec
.inv
2178 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2179 RC1
= yield self
.dec2
.rm_dec
.RC1
2180 vli_
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
2181 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
2185 log(" cr_bit", cr_bit
)
2186 log(" rc_en", rc_en
)
2187 if not rc_en
or rm_mode
!= SVP64RMMode
.FFIRST
.value
:
2189 # get the CR vevtor, do BO-test
2191 log("asmregs", info
.asmregs
[0], info
.write_regs
)
2192 if 'CR' in info
.write_regs
and 'BF' in info
.asmregs
[0]:
2194 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, crf
)
2195 crtest
= self
.crl
[regnum
]
2196 ffirst_hit
= crtest
[cr_bit
] != ff_inv
2197 log("cr test", crf
, regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
2198 log("cr test?", ffirst_hit
)
2201 # Fail-first activated, truncate VL
2202 vli
= SelectableInt(int(vli_
), 7)
2203 self
.svstate
.vl
= srcstep
+ vli
2204 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2205 yield Settle() # let decoder update
2208 def do_rc_ov(self
, ins_name
, result
, overflow
, cr0
):
2209 if ins_name
.startswith("f"):
2210 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
2213 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, rc_reg
)
2214 # hang on... for `setvl` actually you want to test SVSTATE.VL
2215 is_setvl
= ins_name
in ('svstep', 'setvl')
2217 result
= SelectableInt(result
.vl
, 64)
2219 # overflow = None # do not override overflow except in setvl
2221 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
2223 self
.handle_comparison(result
, regnum
, overflow
, no_so
=is_setvl
)
2225 # otherwise we just blat CR0 into the required regnum
2226 log("explicit rc0", cr0
)
2227 self
.crl
[regnum
].eq(cr0
)
2229 def do_outregs_nia(self
, asmop
, ins_name
, info
, outs
,
2230 carry_en
, rc_en
, ffirst_hit
, ew_dst
):
2231 ffirst_hit
, vli
= ffirst_hit
2232 # write out any regs for this instruction
2233 for name
, output
in outs
.items():
2234 yield from self
.check_write(info
, name
, output
, carry_en
, ew_dst
)
2235 # restore the CR value on non-VLI failfirst (from sv.cmp and others
2236 # which write directly to CR in the pseudocode (gah, what a mess)
2237 # if ffirst_hit and not vli:
2238 # self.cr.value = self.cr_backup
2241 self
.svp64_reset_loop()
2244 # check advancement of src/dst/sub-steps and if PC needs updating
2245 nia_update
= (yield from self
.check_step_increment(rc_en
,
2248 self
.update_pc_next()
2250 def check_replace_d(self
, info
, remap_active
):
2251 replace_d
= False # update / replace constant in pseudocode
2252 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
2253 vl
= self
.svstate
.vl
2254 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2255 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2256 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2257 if info
.form
== 'DS':
2258 # DS-Form, multiply by 4 then knock 2 bits off after
2259 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
2261 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
2262 imm
= exts(imm
, 16) # sign-extend to integer
2263 # get the right step. LD is from srcstep, ST is dststep
2264 op
= yield self
.dec2
.e
.do
.insn_type
2266 if op
== MicrOp
.OP_LOAD
.value
:
2268 offsmul
= yield self
.dec2
.in1_step
2269 log("D-field REMAP src", imm
, offsmul
, ldstmode
)
2271 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
2272 log("D-field src", imm
, offsmul
, ldstmode
)
2273 elif op
== MicrOp
.OP_STORE
.value
:
2274 # XXX NOTE! no bit-reversed STORE! this should not ever be used
2275 offsmul
= (dststep
* (subvl
+1)) + dsubstep
2276 log("D-field dst", imm
, offsmul
, ldstmode
)
2277 # Unit-Strided LD/ST adds offset*width to immediate
2278 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
2279 ldst_len
= yield self
.dec2
.e
.do
.data_len
2280 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
2282 # Element-strided multiplies the immediate by element step
2283 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
2284 imm
= SelectableInt(imm
* offsmul
, 32)
2287 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
2288 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
2289 log("LDSTmode", SVP64LDSTmode(ldstmode
),
2290 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
2291 # new replacement D... errr.. DS
2293 if info
.form
== 'DS':
2294 # TODO: assert 2 LSBs are zero?
2295 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
2296 imm
.value
= imm
.value
>> 2
2297 self
.namespace
['DS'] = imm
2299 self
.namespace
['D'] = imm
2301 def get_input(self
, name
, ew_src
):
2302 # using PowerDecoder2, first, find the decoder index.
2303 # (mapping name RA RB RC RS to in1, in2, in3)
2304 regnum
, is_vec
= yield from get_idx_in(self
.dec2
, name
, True)
2306 # doing this is not part of svp64, it's because output
2307 # registers, to be modified, need to be in the namespace.
2308 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2310 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
, True)
2312 if isinstance(regnum
, tuple):
2313 (regnum
, base
, offs
) = regnum
2315 base
, offs
= regnum
, 0 # temporary HACK
2317 # in case getting the register number is needed, _RA, _RB
2318 # (HACK: only in straight non-svp64-mode for now, or elwidth == 64)
2319 regname
= "_" + name
2320 if not self
.is_svp64_mode
or ew_src
== 64:
2321 self
.namespace
[regname
] = regnum
2322 elif regname
in self
.namespace
:
2323 del self
.namespace
[regname
]
2325 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
2326 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
2328 reg_val
= SelectableInt(self
.fpr(base
, is_vec
, offs
, ew_src
))
2329 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2330 elif name
is not None:
2331 reg_val
= SelectableInt(self
.gpr(base
, is_vec
, offs
, ew_src
))
2332 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2334 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
2335 reg_val
= SelectableInt(0, ew_src
)
2338 def remap_set_steps(self
, remaps
):
2339 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
2340 they work in concert with PowerDecoder2 at the moment,
2341 there is no HDL implementation of REMAP. therefore this
2342 function, because ISACaller still uses PowerDecoder2,
2343 will *explicitly* write the dec2.XX_step values. this has
2346 # just some convenient debug info
2348 sname
= 'SVSHAPE%d' % i
2349 shape
= self
.spr
[sname
]
2350 log(sname
, bin(shape
.value
))
2351 log(" lims", shape
.lims
)
2352 log(" mode", shape
.mode
)
2353 log(" skip", shape
.skip
)
2355 # set up the list of steps to remap
2356 mi0
= self
.svstate
.mi0
2357 mi1
= self
.svstate
.mi1
2358 mi2
= self
.svstate
.mi2
2359 mo0
= self
.svstate
.mo0
2360 mo1
= self
.svstate
.mo1
2361 steps
= [[self
.dec2
.in1_step
, mi0
], # RA
2362 [self
.dec2
.in2_step
, mi1
], # RB
2363 [self
.dec2
.in3_step
, mi2
], # RC
2364 [self
.dec2
.o_step
, mo0
], # RT
2365 [self
.dec2
.o2_step
, mo1
], # EA
2368 rnames
= ['RA', 'RB', 'RC', 'RT', 'RS']
2369 for i
, reg
in enumerate(rnames
):
2370 idx
= yield from get_idx_map(self
.dec2
, reg
)
2372 idx
= yield from get_idx_map(self
.dec2
, "F"+reg
)
2374 steps
[i
][0] = self
.dec2
.in1_step
2376 steps
[i
][0] = self
.dec2
.in2_step
2378 steps
[i
][0] = self
.dec2
.in3_step
2379 log("remap step", i
, reg
, idx
, steps
[i
][1])
2380 remap_idxs
= self
.remap_idxs
2382 # now cross-index the required SHAPE for each of 3-in 2-out regs
2383 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
2384 for i
, (dstep
, shape_idx
) in enumerate(steps
):
2385 (shape
, remap
) = remaps
[shape_idx
]
2386 remap_idx
= remap_idxs
[shape_idx
]
2387 # zero is "disabled"
2388 if shape
.value
== 0x0:
2390 # now set the actual requested step to the current index
2391 if dstep
is not None:
2392 yield dstep
.eq(remap_idx
)
2394 # debug printout info
2395 rremaps
.append((shape
.mode
, hex(shape
.value
), dstep
,
2396 i
, rnames
[i
], shape_idx
, remap_idx
))
2398 log("shape remap", x
)
2400 def check_write(self
, info
, name
, output
, carry_en
, ew_dst
):
2401 if name
== 'overflow': # ignore, done already (above)
2403 if name
== 'CR0': # ignore, done already (above)
2405 if isinstance(output
, int):
2406 output
= SelectableInt(output
, EFFECTIVELY_UNLIMITED
)
2408 if name
in ['CA', 'CA32']:
2410 log("writing %s to XER" % name
, output
)
2411 log("write XER %s 0x%x" % (name
, output
.value
))
2412 self
.spr
['XER'][XER_bits
[name
]] = output
.value
2414 log("NOT writing %s to XER" % name
, output
)
2416 # write special SPRs
2417 if name
in info
.special_regs
:
2418 log('writing special %s' % name
, output
, special_sprs
)
2419 log("write reg %s 0x%x" % (name
, output
.value
))
2420 if name
in special_sprs
:
2421 self
.spr
[name
] = output
2423 self
.namespace
[name
].eq(output
)
2425 log('msr written', hex(self
.msr
.value
))
2427 # find out1/out2 PR/FPR
2428 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2430 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
, True)
2432 # temporary hack for not having 2nd output
2433 regnum
= yield getattr(self
.decoder
, name
)
2435 # convenient debug prefix
2440 # check zeroing due to predicate bit being zero
2441 if self
.is_svp64_mode
and self
.pred_dst_zero
:
2442 log('zeroing reg %s %s' % (str(regnum
), str(output
)), is_vec
)
2443 output
= SelectableInt(0, EFFECTIVELY_UNLIMITED
)
2444 log("write reg %s%s 0x%x ew %d" % (reg_prefix
, str(regnum
),
2445 output
.value
, ew_dst
),
2446 kind
=LogKind
.InstrInOuts
)
2447 # zero-extend tov64 bit begore storing (should use EXT oh well)
2448 if output
.bits
> 64:
2449 output
= SelectableInt(output
.value
, 64)
2451 self
.fpr
.write(regnum
, output
, is_vec
, ew_dst
)
2453 self
.gpr
.write(regnum
, output
, is_vec
, ew_dst
)
2455 def check_step_increment(self
, rc_en
, asmop
, ins_name
):
2456 # check if it is the SVSTATE.src/dest step that needs incrementing
2457 # this is our Sub-Program-Counter loop from 0 to VL-1
2458 if not self
.allow_next_step_inc
:
2459 if self
.is_svp64_mode
:
2460 return (yield from self
.svstate_post_inc(ins_name
))
2462 # XXX only in non-SVP64 mode!
2463 # record state of whether the current operation was an svshape,
2465 # to be able to know if it should apply in the next instruction.
2466 # also (if going to use this instruction) should disable ability
2467 # to interrupt in between. sigh.
2468 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2475 log("SVSTATE_NEXT: inc requested, mode",
2476 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2477 yield from self
.svstate_pre_inc()
2478 pre
= yield from self
.update_new_svstate_steps()
2480 # reset at end of loop including exit Vertical Mode
2481 log("SVSTATE_NEXT: end of loop, reset")
2482 self
.svp64_reset_loop()
2483 self
.svstate
.vfirst
= 0
2487 self
.handle_comparison(SelectableInt(0, 64)) # CR0
2489 if self
.allow_next_step_inc
== 2:
2490 log("SVSTATE_NEXT: read")
2491 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2493 log("SVSTATE_NEXT: post-inc")
2494 # use actual (cached) src/dst-step here to check end
2495 remaps
= self
.get_remap_indices()
2496 remap_idxs
= self
.remap_idxs
2497 vl
= self
.svstate
.vl
2498 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2499 if self
.allow_next_step_inc
!= 2:
2500 yield from self
.advance_svstate_steps()
2501 #self.namespace['SVSTATE'] = self.svstate.spr
2502 # set CR0 (if Rc=1) based on end
2503 endtest
= 1 if self
.at_loopend() else 0
2505 #results = [SelectableInt(endtest, 64)]
2506 # self.handle_comparison(results) # CR0
2508 # see if svstep was requested, if so, which SVSTATE
2510 if self
.svstate_next_mode
> 0:
2511 shape_idx
= self
.svstate_next_mode
.value
-1
2512 endings
= self
.remap_loopends
[shape_idx
]
2513 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2514 log("svstep Rc=1, CR0", cr_field
, endtest
)
2515 self
.crl
[0].eq(cr_field
) # CR0
2517 # reset at end of loop including exit Vertical Mode
2518 log("SVSTATE_NEXT: after increments, reset")
2519 self
.svp64_reset_loop()
2520 self
.svstate
.vfirst
= 0
2523 def SVSTATE_NEXT(self
, mode
, submode
):
2524 """explicitly moves srcstep/dststep on to next element, for
2525 "Vertical-First" mode. this function is called from
2526 setvl pseudo-code, as a pseudo-op "svstep"
2528 WARNING: this function uses information that was created EARLIER
2529 due to it being in the middle of a yield, but this function is
2530 *NOT* called from yield (it's called from compiled pseudocode).
2532 self
.allow_next_step_inc
= submode
.value
+ 1
2533 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2534 self
.svstate_next_mode
= mode
2535 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2536 shape_idx
= self
.svstate_next_mode
.value
-1
2537 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2538 if self
.svstate_next_mode
== 5:
2539 self
.svstate_next_mode
= 0
2540 return SelectableInt(self
.svstate
.srcstep
, 7)
2541 if self
.svstate_next_mode
== 6:
2542 self
.svstate_next_mode
= 0
2543 return SelectableInt(self
.svstate
.dststep
, 7)
2544 if self
.svstate_next_mode
== 7:
2545 self
.svstate_next_mode
= 0
2546 return SelectableInt(self
.svstate
.ssubstep
, 7)
2547 if self
.svstate_next_mode
== 8:
2548 self
.svstate_next_mode
= 0
2549 return SelectableInt(self
.svstate
.dsubstep
, 7)
2550 return SelectableInt(0, 7)
2552 def get_src_dststeps(self
):
2553 """gets srcstep, dststep, and ssubstep, dsubstep
2555 return (self
.new_srcstep
, self
.new_dststep
,
2556 self
.new_ssubstep
, self
.new_dsubstep
)
2558 def update_svstate_namespace(self
, overwrite_svstate
=True):
2559 if overwrite_svstate
:
2560 # note, do not get the bit-reversed srcstep here!
2561 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2562 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2564 # update SVSTATE with new srcstep
2565 self
.svstate
.srcstep
= srcstep
2566 self
.svstate
.dststep
= dststep
2567 self
.svstate
.ssubstep
= ssubstep
2568 self
.svstate
.dsubstep
= dsubstep
2569 self
.namespace
['SVSTATE'] = self
.svstate
2570 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2571 yield Settle() # let decoder update
2573 def update_new_svstate_steps(self
, overwrite_svstate
=True):
2574 yield from self
.update_svstate_namespace(overwrite_svstate
)
2575 srcstep
= self
.svstate
.srcstep
2576 dststep
= self
.svstate
.dststep
2577 ssubstep
= self
.svstate
.ssubstep
2578 dsubstep
= self
.svstate
.dsubstep
2579 pack
= self
.svstate
.pack
2580 unpack
= self
.svstate
.unpack
2581 vl
= self
.svstate
.vl
2582 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
2583 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2584 rm_mode
= yield self
.dec2
.rm_dec
.mode
2585 ff_inv
= yield self
.dec2
.rm_dec
.inv
2586 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2587 log(" srcstep", srcstep
)
2588 log(" dststep", dststep
)
2590 log(" unpack", unpack
)
2591 log(" ssubstep", ssubstep
)
2592 log(" dsubstep", dsubstep
)
2594 log(" subvl", subvl
)
2595 log(" rm_mode", rm_mode
)
2596 log(" sv_mode", sv_mode
)
2598 log(" cr_bit", cr_bit
)
2600 # check if end reached (we let srcstep overrun, above)
2601 # nothing needs doing (TODO zeroing): just do next instruction
2604 return ((ssubstep
== subvl
and srcstep
== vl
) or
2605 (dsubstep
== subvl
and dststep
== vl
))
2607 def svstate_post_inc(self
, insn_name
, vf
=0):
2608 # check if SV "Vertical First" mode is enabled
2609 vfirst
= self
.svstate
.vfirst
2610 log(" SV Vertical First", vf
, vfirst
)
2611 if not vf
and vfirst
== 1:
2615 # check if it is the SVSTATE.src/dest step that needs incrementing
2616 # this is our Sub-Program-Counter loop from 0 to VL-1
2617 # XXX twin predication TODO
2618 vl
= self
.svstate
.vl
2619 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2620 mvl
= self
.svstate
.maxvl
2621 srcstep
= self
.svstate
.srcstep
2622 dststep
= self
.svstate
.dststep
2623 ssubstep
= self
.svstate
.ssubstep
2624 dsubstep
= self
.svstate
.dsubstep
2625 pack
= self
.svstate
.pack
2626 unpack
= self
.svstate
.unpack
2627 rm_mode
= yield self
.dec2
.rm_dec
.mode
2628 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2629 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2630 out_vec
= not (yield self
.dec2
.no_out_vec
)
2631 in_vec
= not (yield self
.dec2
.no_in_vec
)
2632 log(" svstate.vl", vl
)
2633 log(" svstate.mvl", mvl
)
2634 log(" rm.subvl", subvl
)
2635 log(" svstate.srcstep", srcstep
)
2636 log(" svstate.dststep", dststep
)
2637 log(" svstate.ssubstep", ssubstep
)
2638 log(" svstate.dsubstep", dsubstep
)
2639 log(" svstate.pack", pack
)
2640 log(" svstate.unpack", unpack
)
2641 log(" mode", rm_mode
)
2642 log(" reverse", reverse_gear
)
2643 log(" out_vec", out_vec
)
2644 log(" in_vec", in_vec
)
2645 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPType
.P2
.value
)
2646 # check if this was an sv.bc* and if so did it succeed
2647 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2648 end_loop
= self
.namespace
['end_loop']
2649 log("branch %s end_loop" % insn_name
, end_loop
)
2651 self
.svp64_reset_loop()
2652 self
.update_pc_next()
2654 # check if srcstep needs incrementing by one, stop PC advancing
2655 # but for 2-pred both src/dest have to be checked.
2656 # XXX this might not be true! it may just be LD/ST
2657 if sv_ptype
== SVPType
.P2
.value
:
2658 svp64_is_vector
= (out_vec
or in_vec
)
2660 svp64_is_vector
= out_vec
2661 # loops end at the first "hit" (source or dest)
2662 yield from self
.advance_svstate_steps()
2663 loopend
= self
.loopend
2664 log("loopend", svp64_is_vector
, loopend
)
2665 if not svp64_is_vector
or loopend
:
2666 # reset loop to zero and update NIA
2667 self
.svp64_reset_loop()
2672 # still looping, advance and update NIA
2673 self
.namespace
['SVSTATE'] = self
.svstate
2675 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2676 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2677 # this way we keep repeating the same instruction (with new steps)
2678 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2679 self
.namespace
['NIA'] = self
.pc
.NIA
2680 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2681 return False # DO NOT allow PC update whilst Sub-PC loop running
2683 def update_pc_next(self
):
2684 # UPDATE program counter
2685 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2686 #self.svstate.spr = self.namespace['SVSTATE']
2687 log("end of call", self
.namespace
['CIA'],
2688 self
.namespace
['NIA'],
2689 self
.namespace
['SVSTATE'])
2691 def svp64_reset_loop(self
):
2692 self
.svstate
.srcstep
= 0
2693 self
.svstate
.dststep
= 0
2694 self
.svstate
.ssubstep
= 0
2695 self
.svstate
.dsubstep
= 0
2696 self
.loopend
= False
2697 log(" svstate.srcstep loop end (PC to update)")
2698 self
.namespace
['SVSTATE'] = self
.svstate
2700 def update_nia(self
):
2701 self
.pc
.update_nia(self
.is_svp64_mode
)
2702 self
.namespace
['NIA'] = self
.pc
.NIA
2706 """Decorator factory.
2708 this decorator will "inject" variables into the function's namespace,
2709 from the *dictionary* in self.namespace. it therefore becomes possible
2710 to make it look like a whole stack of variables which would otherwise
2711 need "self." inserted in front of them (*and* for those variables to be
2712 added to the instance) "appear" in the function.
2714 "self.namespace['SI']" for example becomes accessible as just "SI" but
2715 *only* inside the function, when decorated.
2717 def variable_injector(func
):
2719 def decorator(*args
, **kwargs
):
2721 func_globals
= func
.__globals
__ # Python 2.6+
2722 except AttributeError:
2723 func_globals
= func
.func_globals
# Earlier versions.
2725 context
= args
[0].namespace
# variables to be injected
2726 saved_values
= func_globals
.copy() # Shallow copy of dict.
2727 log("globals before", context
.keys())
2728 func_globals
.update(context
)
2729 result
= func(*args
, **kwargs
)
2730 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2731 log("args[0]", args
[0].namespace
['CIA'],
2732 args
[0].namespace
['NIA'],
2733 args
[0].namespace
['SVSTATE'])
2734 if 'end_loop' in func_globals
:
2735 log("args[0] end_loop", func_globals
['end_loop'])
2736 args
[0].namespace
= func_globals
2737 #exec (func.__code__, func_globals)
2740 # func_globals = saved_values # Undo changes.
2746 return variable_injector