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 from openpower
.fpscr
import FPSCRState
42 from openpower
.xer
import XERState
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 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
)
287 value
= XERState(value
)
288 log("setting spr", key
, value
)
289 dict.__setitem
__(self
, key
, value
)
291 def __call__(self
, ridx
):
294 def dump(self
, printout
=True):
296 keys
= list(self
.keys())
299 sprname
= spr_dict
.get(k
, None)
303 sprname
= sprname
.SPR
304 res
.append((sprname
, self
[k
].value
))
306 for sprname
, value
in res
:
307 print(" ", sprname
, hex(value
))
312 def __init__(self
, pc_init
=0):
313 self
.CIA
= SelectableInt(pc_init
, 64)
314 self
.NIA
= self
.CIA
+ SelectableInt(4, 64) # only true for v3.0B!
316 def update_nia(self
, is_svp64
):
317 increment
= 8 if is_svp64
else 4
318 self
.NIA
= self
.CIA
+ SelectableInt(increment
, 64)
320 def update(self
, namespace
, is_svp64
):
321 """updates the program counter (PC) by 4 if v3.0B mode or 8 if SVP64
323 self
.CIA
= namespace
['NIA'].narrow(64)
324 self
.update_nia(is_svp64
)
325 namespace
['CIA'] = self
.CIA
326 namespace
['NIA'] = self
.NIA
330 # See PowerISA Version 3.0 B Book 1
331 # Section 2.3.1 Condition Register pages 30 - 31
333 LT
= FL
= 0 # negative, less than, floating-point less than
334 GT
= FG
= 1 # positive, greater than, floating-point greater than
335 EQ
= FE
= 2 # equal, floating-point equal
336 SO
= FU
= 3 # summary overflow, floating-point unordered
338 def __init__(self
, init
=0):
339 # rev_cr = int('{:016b}'.format(initial_cr)[::-1], 2)
340 # self.cr = FieldSelectableInt(self._cr, list(range(32, 64)))
341 self
.cr
= SelectableInt(init
, 64) # underlying reg
342 # field-selectable versions of Condition Register TODO check bitranges?
345 bits
= tuple(range(i
*4+32, (i
+1)*4+32))
346 _cr
= FieldSelectableInt(self
.cr
, bits
)
350 # decode SVP64 predicate integer to reg number and invert
351 def get_predint(gpr
, mask
):
355 log("get_predint", mask
, SVP64PredInt
.ALWAYS
.value
)
356 if mask
== SVP64PredInt
.ALWAYS
.value
:
357 return 0xffff_ffff_ffff_ffff # 64 bits of 1
358 if mask
== SVP64PredInt
.R3_UNARY
.value
:
359 return 1 << (r3
.value
& 0b111111)
360 if mask
== SVP64PredInt
.R3
.value
:
362 if mask
== SVP64PredInt
.R3_N
.value
:
364 if mask
== SVP64PredInt
.R10
.value
:
366 if mask
== SVP64PredInt
.R10_N
.value
:
368 if mask
== SVP64PredInt
.R30
.value
:
370 if mask
== SVP64PredInt
.R30_N
.value
:
374 # decode SVP64 predicate CR to reg number and invert status
375 def _get_predcr(mask
):
376 if mask
== SVP64PredCR
.LT
.value
:
378 if mask
== SVP64PredCR
.GE
.value
:
380 if mask
== SVP64PredCR
.GT
.value
:
382 if mask
== SVP64PredCR
.LE
.value
:
384 if mask
== SVP64PredCR
.EQ
.value
:
386 if mask
== SVP64PredCR
.NE
.value
:
388 if mask
== SVP64PredCR
.SO
.value
:
390 if mask
== SVP64PredCR
.NS
.value
:
394 # read individual CR fields (0..VL-1), extract the required bit
395 # and construct the mask
396 def get_predcr(crl
, mask
, vl
):
397 idx
, noninv
= _get_predcr(mask
)
400 cr
= crl
[i
+SVP64CROffs
.CRPred
]
401 if cr
[idx
].value
== noninv
:
406 # TODO, really should just be using PowerDecoder2
407 def get_idx_map(dec2
, name
):
409 in1_sel
= yield op
.in1_sel
410 in2_sel
= yield op
.in2_sel
411 in3_sel
= yield op
.in3_sel
412 in1
= yield dec2
.e
.read_reg1
.data
413 # identify which regnames map to in1/2/3
414 if name
== 'RA' or name
== 'RA_OR_ZERO':
415 if (in1_sel
== In1Sel
.RA
.value
or
416 (in1_sel
== In1Sel
.RA_OR_ZERO
.value
and in1
!= 0)):
418 if in1_sel
== In1Sel
.RA_OR_ZERO
.value
:
421 if in2_sel
== In2Sel
.RB
.value
:
423 if in3_sel
== In3Sel
.RB
.value
:
425 # XXX TODO, RC doesn't exist yet!
427 if in3_sel
== In3Sel
.RC
.value
:
429 elif name
in ['EA', 'RS']:
430 if in1_sel
== In1Sel
.RS
.value
:
432 if in2_sel
== In2Sel
.RS
.value
:
434 if in3_sel
== In3Sel
.RS
.value
:
437 if in1_sel
== In1Sel
.FRA
.value
:
439 if in3_sel
== In3Sel
.FRA
.value
:
442 if in2_sel
== In2Sel
.FRB
.value
:
445 if in3_sel
== In3Sel
.FRC
.value
:
448 if in1_sel
== In1Sel
.FRS
.value
:
450 if in3_sel
== In3Sel
.FRS
.value
:
453 if in1_sel
== In1Sel
.FRT
.value
:
456 if in1_sel
== In1Sel
.RT
.value
:
461 # TODO, really should just be using PowerDecoder2
462 def get_idx_in(dec2
, name
, ewmode
=False):
463 idx
= yield from get_idx_map(dec2
, name
)
467 in1_sel
= yield op
.in1_sel
468 in2_sel
= yield op
.in2_sel
469 in3_sel
= yield op
.in3_sel
470 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
471 in1
= yield dec2
.e
.read_reg1
.data
472 in2
= yield dec2
.e
.read_reg2
.data
473 in3
= yield dec2
.e
.read_reg3
.data
475 in1_base
= yield dec2
.e
.read_reg1
.base
476 in2_base
= yield dec2
.e
.read_reg2
.base
477 in3_base
= yield dec2
.e
.read_reg3
.base
478 in1_offs
= yield dec2
.e
.read_reg1
.offs
479 in2_offs
= yield dec2
.e
.read_reg2
.offs
480 in3_offs
= yield dec2
.e
.read_reg3
.offs
481 in1
= (in1
, in1_base
, in1_offs
)
482 in2
= (in2
, in2_base
, in2_offs
)
483 in3
= (in3
, in3_base
, in3_offs
)
485 in1_isvec
= yield dec2
.in1_isvec
486 in2_isvec
= yield dec2
.in2_isvec
487 in3_isvec
= yield dec2
.in3_isvec
488 log("get_idx_in in1", name
, in1_sel
, In1Sel
.RA
.value
,
490 log("get_idx_in in2", name
, in2_sel
, In2Sel
.RB
.value
,
492 log("get_idx_in in3", name
, in3_sel
, In3Sel
.RS
.value
,
494 log("get_idx_in FRS in3", name
, in3_sel
, In3Sel
.FRS
.value
,
496 log("get_idx_in FRB in2", name
, in2_sel
, In2Sel
.FRB
.value
,
498 log("get_idx_in FRC in3", name
, in3_sel
, In3Sel
.FRC
.value
,
501 return in1
, in1_isvec
503 return in2
, in2_isvec
505 return in3
, in3_isvec
509 # TODO, really should just be using PowerDecoder2
510 def get_cr_in(dec2
, name
):
512 in_sel
= yield op
.cr_in
513 in_bitfield
= yield dec2
.dec_cr_in
.cr_bitfield
.data
514 sv_cr_in
= yield op
.sv_cr_in
515 spec
= yield dec2
.crin_svdec
.spec
516 sv_override
= yield dec2
.dec_cr_in
.sv_override
517 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
518 in1
= yield dec2
.e
.read_cr1
.data
519 cr_isvec
= yield dec2
.cr_in_isvec
520 log("get_cr_in", in_sel
, CROutSel
.CR0
.value
, in1
, cr_isvec
)
521 log(" sv_cr_in", sv_cr_in
)
522 log(" cr_bf", in_bitfield
)
524 log(" override", sv_override
)
525 # identify which regnames map to in / o2
527 if in_sel
== CRInSel
.BI
.value
:
529 log("get_cr_in not found", name
)
533 # TODO, really should just be using PowerDecoder2
534 def get_cr_out(dec2
, name
):
536 out_sel
= yield op
.cr_out
537 out_bitfield
= yield dec2
.dec_cr_out
.cr_bitfield
.data
538 sv_cr_out
= yield op
.sv_cr_out
539 spec
= yield dec2
.crout_svdec
.spec
540 sv_override
= yield dec2
.dec_cr_out
.sv_override
541 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
542 out
= yield dec2
.e
.write_cr
.data
543 o_isvec
= yield dec2
.cr_out_isvec
544 log("get_cr_out", out_sel
, CROutSel
.CR0
.value
, out
, o_isvec
)
545 log(" sv_cr_out", sv_cr_out
)
546 log(" cr_bf", out_bitfield
)
548 log(" override", sv_override
)
549 # identify which regnames map to out / o2
551 if out_sel
== CROutSel
.BF
.value
:
554 if out_sel
== CROutSel
.CR0
.value
:
556 if name
== 'CR1': # these are not actually calculated correctly
557 if out_sel
== CROutSel
.CR1
.value
:
559 # check RC1 set? if so return implicit vector, this is a REAL bad hack
560 RC1
= yield dec2
.rm_dec
.RC1
562 log("get_cr_out RC1 mode")
564 return 0, True # XXX TODO: offset CR0 from SVSTATE SPR
566 return 1, True # XXX TODO: offset CR1 from SVSTATE SPR
568 log("get_cr_out not found", name
)
572 # TODO, really should just be using PowerDecoder2
573 def get_out_map(dec2
, name
):
575 out_sel
= yield op
.out_sel
576 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
577 out
= yield dec2
.e
.write_reg
.data
578 # identify which regnames map to out / o2
580 if out_sel
== OutSel
.RA
.value
:
583 if out_sel
== OutSel
.RT
.value
:
585 if out_sel
== OutSel
.RT_OR_ZERO
.value
and out
!= 0:
587 elif name
== 'RT_OR_ZERO':
588 if out_sel
== OutSel
.RT_OR_ZERO
.value
:
591 if out_sel
== OutSel
.FRA
.value
:
594 if out_sel
== OutSel
.FRS
.value
:
597 if out_sel
== OutSel
.FRT
.value
:
602 # TODO, really should just be using PowerDecoder2
603 def get_idx_out(dec2
, name
, ewmode
=False):
605 out_sel
= yield op
.out_sel
606 # get the IN1/2/3 from the decoder (includes SVP64 remap and isvec)
607 out
= yield dec2
.e
.write_reg
.data
608 o_isvec
= yield dec2
.o_isvec
610 offs
= yield dec2
.e
.write_reg
.offs
611 base
= yield dec2
.e
.write_reg
.base
612 out
= (out
, base
, offs
)
613 # identify which regnames map to out / o2
614 ismap
= yield from get_out_map(dec2
, name
)
616 log("get_idx_out", name
, out_sel
, out
, o_isvec
)
618 log("get_idx_out not found", name
, out_sel
, out
, o_isvec
)
622 # TODO, really should just be using PowerDecoder2
623 def get_out2_map(dec2
, name
):
624 # check first if register is activated for write
626 out_sel
= yield op
.out_sel
627 out
= yield dec2
.e
.write_ea
.data
628 out_ok
= yield dec2
.e
.write_ea
.ok
632 if name
in ['EA', 'RA']:
633 if hasattr(op
, "upd"):
634 # update mode LD/ST uses read-reg A also as an output
636 log("get_idx_out2", upd
, LDSTMode
.update
.value
,
637 out_sel
, OutSel
.RA
.value
,
639 if upd
== LDSTMode
.update
.value
:
642 fft_en
= yield dec2
.implicit_rs
644 log("get_idx_out2", out_sel
, OutSel
.RS
.value
,
648 fft_en
= yield dec2
.implicit_rs
650 log("get_idx_out2", out_sel
, OutSel
.FRS
.value
,
656 # TODO, really should just be using PowerDecoder2
657 def get_idx_out2(dec2
, name
, ewmode
=False):
658 # check first if register is activated for write
660 out_sel
= yield op
.out_sel
661 out
= yield dec2
.e
.write_ea
.data
663 offs
= yield dec2
.e
.write_ea
.offs
664 base
= yield dec2
.e
.write_ea
.base
665 out
= (out
, base
, offs
)
666 o_isvec
= yield dec2
.o2_isvec
667 ismap
= yield from get_out2_map(dec2
, name
)
669 log("get_idx_out2", name
, out_sel
, out
, o_isvec
)
675 """deals with svstate looping.
678 def __init__(self
, svstate
):
679 self
.svstate
= svstate
682 def new_iterators(self
):
683 self
.src_it
= self
.src_iterator()
684 self
.dst_it
= self
.dst_iterator()
688 self
.new_ssubstep
= 0
689 self
.new_dsubstep
= 0
690 self
.pred_dst_zero
= 0
691 self
.pred_src_zero
= 0
693 def src_iterator(self
):
694 """source-stepping iterator
696 pack
= self
.svstate
.pack
700 # pack advances subvl in *outer* loop
701 while True: # outer subvl loop
702 while True: # inner vl loop
705 srcmask
= self
.srcmask
706 srcstep
= self
.svstate
.srcstep
707 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
708 if self
.pred_sz
or pred_src_zero
:
709 self
.pred_src_zero
= not pred_src_zero
710 log(" advance src", srcstep
, vl
,
711 self
.svstate
.ssubstep
, subvl
)
712 # yield actual substep/srcstep
713 yield (self
.svstate
.ssubstep
, srcstep
)
714 # the way yield works these could have been modified.
717 srcstep
= self
.svstate
.srcstep
718 log(" advance src check", srcstep
, vl
,
719 self
.svstate
.ssubstep
, subvl
, srcstep
== vl
-1,
720 self
.svstate
.ssubstep
== subvl
)
721 if srcstep
== vl
-1: # end-point
722 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
723 if self
.svstate
.ssubstep
== subvl
: # end-point
724 log(" advance pack stop")
726 break # exit inner loop
727 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance ss
729 if self
.svstate
.ssubstep
== subvl
: # end-point
730 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
731 log(" advance pack stop")
733 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
736 # these cannot be done as for-loops because SVSTATE may change
737 # (srcstep/substep may be modified, interrupted, subvl/vl change)
738 # but they *can* be done as while-loops as long as every SVSTATE
739 # "thing" is re-read every single time a yield gives indices
740 while True: # outer vl loop
741 while True: # inner subvl loop
744 srcmask
= self
.srcmask
745 srcstep
= self
.svstate
.srcstep
746 pred_src_zero
= ((1 << srcstep
) & srcmask
) != 0
747 if self
.pred_sz
or pred_src_zero
:
748 self
.pred_src_zero
= not pred_src_zero
749 log(" advance src", srcstep
, vl
,
750 self
.svstate
.ssubstep
, subvl
)
751 # yield actual substep/srcstep
752 yield (self
.svstate
.ssubstep
, srcstep
)
753 if self
.svstate
.ssubstep
== subvl
: # end-point
754 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
755 break # exit inner loop
756 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
758 if srcstep
== vl
-1: # end-point
759 self
.svstate
.srcstep
= SelectableInt(0, 7) # reset
762 self
.svstate
.srcstep
+= SelectableInt(1, 7) # advance srcstep
764 def dst_iterator(self
):
765 """dest-stepping iterator
767 unpack
= self
.svstate
.unpack
771 # pack advances subvl in *outer* loop
772 while True: # outer subvl loop
773 while True: # inner vl loop
776 dstmask
= self
.dstmask
777 dststep
= self
.svstate
.dststep
778 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
779 if self
.pred_dz
or pred_dst_zero
:
780 self
.pred_dst_zero
= not pred_dst_zero
781 log(" advance dst", dststep
, vl
,
782 self
.svstate
.dsubstep
, subvl
)
783 # yield actual substep/dststep
784 yield (self
.svstate
.dsubstep
, dststep
)
785 # the way yield works these could have been modified.
787 dststep
= self
.svstate
.dststep
788 log(" advance dst check", dststep
, vl
,
789 self
.svstate
.ssubstep
, subvl
)
790 if dststep
== vl
-1: # end-point
791 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
792 if self
.svstate
.dsubstep
== subvl
: # end-point
793 log(" advance unpack stop")
796 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance ds
798 if self
.svstate
.dsubstep
== subvl
: # end-point
799 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
800 log(" advance unpack stop")
802 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
804 # these cannot be done as for-loops because SVSTATE may change
805 # (dststep/substep may be modified, interrupted, subvl/vl change)
806 # but they *can* be done as while-loops as long as every SVSTATE
807 # "thing" is re-read every single time a yield gives indices
808 while True: # outer vl loop
809 while True: # inner subvl loop
811 dstmask
= self
.dstmask
812 dststep
= self
.svstate
.dststep
813 pred_dst_zero
= ((1 << dststep
) & dstmask
) != 0
814 if self
.pred_dz
or pred_dst_zero
:
815 self
.pred_dst_zero
= not pred_dst_zero
816 log(" advance dst", dststep
, self
.svstate
.vl
,
817 self
.svstate
.dsubstep
, subvl
)
818 # yield actual substep/dststep
819 yield (self
.svstate
.dsubstep
, dststep
)
820 if self
.svstate
.dsubstep
== subvl
: # end-point
821 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
823 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
826 if dststep
== vl
-1: # end-point
827 self
.svstate
.dststep
= SelectableInt(0, 7) # reset
829 self
.svstate
.dststep
+= SelectableInt(1, 7) # advance dststep
831 def src_iterate(self
):
832 """source-stepping iterator
836 pack
= self
.svstate
.pack
837 unpack
= self
.svstate
.unpack
838 ssubstep
= self
.svstate
.ssubstep
839 end_ssub
= ssubstep
== subvl
840 end_src
= self
.svstate
.srcstep
== vl
-1
841 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
845 srcstep
= self
.svstate
.srcstep
846 srcmask
= self
.srcmask
848 # pack advances subvl in *outer* loop
850 assert srcstep
<= vl
-1
851 end_src
= srcstep
== vl
-1
856 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
860 srcstep
+= 1 # advance srcstep
861 if not self
.srcstep_skip
:
863 if ((1 << srcstep
) & srcmask
) != 0:
866 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
868 # advance subvl in *inner* loop
871 assert srcstep
<= vl
-1
872 end_src
= srcstep
== vl
-1
873 if end_src
: # end-point
879 if not self
.srcstep_skip
:
881 if ((1 << srcstep
) & srcmask
) != 0:
884 log(" sskip", bin(srcmask
), bin(1 << srcstep
))
885 self
.svstate
.ssubstep
= SelectableInt(0, 2) # reset
888 self
.svstate
.ssubstep
+= SelectableInt(1, 2)
890 self
.svstate
.srcstep
= SelectableInt(srcstep
, 7)
891 log(" advance src", self
.svstate
.srcstep
, self
.svstate
.ssubstep
,
894 def dst_iterate(self
):
895 """dest step iterator
899 pack
= self
.svstate
.pack
900 unpack
= self
.svstate
.unpack
901 dsubstep
= self
.svstate
.dsubstep
902 end_dsub
= dsubstep
== subvl
903 dststep
= self
.svstate
.dststep
904 end_dst
= dststep
== vl
-1
905 dstmask
= self
.dstmask
906 log(" pack/unpack/subvl", pack
, unpack
, subvl
,
911 # unpack advances subvl in *outer* loop
913 assert dststep
<= vl
-1
914 end_dst
= dststep
== vl
-1
919 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
923 dststep
+= 1 # advance dststep
924 if not self
.dststep_skip
:
926 if ((1 << dststep
) & dstmask
) != 0:
929 log(" dskip", bin(dstmask
), bin(1 << dststep
))
931 # advance subvl in *inner* loop
934 assert dststep
<= vl
-1
935 end_dst
= dststep
== vl
-1
936 if end_dst
: # end-point
942 if not self
.dststep_skip
:
944 if ((1 << dststep
) & dstmask
) != 0:
947 log(" dskip", bin(dstmask
), bin(1 << dststep
))
948 self
.svstate
.dsubstep
= SelectableInt(0, 2) # reset
951 self
.svstate
.dsubstep
+= SelectableInt(1, 2)
953 self
.svstate
.dststep
= SelectableInt(dststep
, 7)
954 log(" advance dst", self
.svstate
.dststep
, self
.svstate
.dsubstep
,
957 def at_loopend(self
):
958 """tells if this is the last possible element. uses the cached values
959 for src/dst-step and sub-steps
963 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
964 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
965 end_ssub
= ssubstep
== subvl
966 end_dsub
= dsubstep
== subvl
967 if srcstep
== vl
-1 and end_ssub
:
969 if dststep
== vl
-1 and end_dsub
:
973 def advance_svstate_steps(self
):
974 """ advance sub/steps. note that Pack/Unpack *INVERTS* the order.
975 TODO when Pack/Unpack is set, substep becomes the *outer* loop
977 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
978 if self
.loopend
: # huhn??
983 def read_src_mask(self
):
984 """read/update pred_sz and src mask
986 # get SVSTATE VL (oh and print out some debug stuff)
988 srcstep
= self
.svstate
.srcstep
989 ssubstep
= self
.svstate
.ssubstep
991 # get predicate mask (all 64 bits)
992 srcmask
= 0xffff_ffff_ffff_ffff
994 pmode
= yield self
.dec2
.rm_dec
.predmode
995 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
996 srcpred
= yield self
.dec2
.rm_dec
.srcpred
997 dstpred
= yield self
.dec2
.rm_dec
.dstpred
998 pred_sz
= yield self
.dec2
.rm_dec
.pred_sz
999 if pmode
== SVP64PredMode
.INT
.value
:
1000 srcmask
= dstmask
= get_predint(self
.gpr
, dstpred
)
1001 if sv_ptype
== SVPType
.P2
.value
:
1002 srcmask
= get_predint(self
.gpr
, srcpred
)
1003 elif pmode
== SVP64PredMode
.CR
.value
:
1004 srcmask
= dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1005 if sv_ptype
== SVPType
.P2
.value
:
1006 srcmask
= get_predcr(self
.crl
, srcpred
, vl
)
1007 # work out if the ssubsteps are completed
1008 ssubstart
= ssubstep
== 0
1009 log(" pmode", pmode
)
1010 log(" ptype", sv_ptype
)
1011 log(" srcpred", bin(srcpred
))
1012 log(" srcmask", bin(srcmask
))
1013 log(" pred_sz", bin(pred_sz
))
1014 log(" ssubstart", ssubstart
)
1016 # store all that above
1017 self
.srcstep_skip
= False
1018 self
.srcmask
= srcmask
1019 self
.pred_sz
= pred_sz
1020 self
.new_ssubstep
= ssubstep
1021 log(" new ssubstep", ssubstep
)
1022 # until the predicate mask has a "1" bit... or we run out of VL
1023 # let srcstep==VL be the indicator to move to next instruction
1025 self
.srcstep_skip
= True
1027 def read_dst_mask(self
):
1028 """same as read_src_mask - check and record everything needed
1030 # get SVSTATE VL (oh and print out some debug stuff)
1031 # yield Delay(1e-10) # make changes visible
1032 vl
= self
.svstate
.vl
1033 dststep
= self
.svstate
.dststep
1034 dsubstep
= self
.svstate
.dsubstep
1036 # get predicate mask (all 64 bits)
1037 dstmask
= 0xffff_ffff_ffff_ffff
1039 pmode
= yield self
.dec2
.rm_dec
.predmode
1040 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
1041 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
1042 dstpred
= yield self
.dec2
.rm_dec
.dstpred
1043 pred_dz
= yield self
.dec2
.rm_dec
.pred_dz
1044 if pmode
== SVP64PredMode
.INT
.value
:
1045 dstmask
= get_predint(self
.gpr
, dstpred
)
1046 elif pmode
== SVP64PredMode
.CR
.value
:
1047 dstmask
= get_predcr(self
.crl
, dstpred
, vl
)
1048 # work out if the ssubsteps are completed
1049 dsubstart
= dsubstep
== 0
1050 log(" pmode", pmode
)
1051 log(" ptype", sv_ptype
)
1052 log(" dstpred", bin(dstpred
))
1053 log(" dstmask", bin(dstmask
))
1054 log(" pred_dz", bin(pred_dz
))
1055 log(" dsubstart", dsubstart
)
1057 self
.dststep_skip
= False
1058 self
.dstmask
= dstmask
1059 self
.pred_dz
= pred_dz
1060 self
.new_dsubstep
= dsubstep
1061 log(" new dsubstep", dsubstep
)
1063 self
.dststep_skip
= True
1065 def svstate_pre_inc(self
):
1066 """check if srcstep/dststep need to skip over masked-out predicate bits
1067 note that this is not supposed to do anything to substep,
1068 it is purely for skipping masked-out bits
1071 self
.subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
1072 yield from self
.read_src_mask()
1073 yield from self
.read_dst_mask()
1080 srcstep
= self
.svstate
.srcstep
1081 srcmask
= self
.srcmask
1082 pred_src_zero
= self
.pred_sz
1083 vl
= self
.svstate
.vl
1084 # srcstep-skipping opportunity identified
1085 if self
.srcstep_skip
:
1086 # cannot do this with sv.bc - XXX TODO
1089 while (((1 << srcstep
) & srcmask
) == 0) and (srcstep
!= vl
):
1090 log(" sskip", bin(1 << srcstep
))
1093 # now work out if the relevant mask bits require zeroing
1095 pred_src_zero
= ((1 << srcstep
) & srcmask
) == 0
1097 # store new srcstep / dststep
1098 self
.new_srcstep
= srcstep
1099 self
.pred_src_zero
= pred_src_zero
1100 log(" new srcstep", srcstep
)
1103 # dststep-skipping opportunity identified
1104 dststep
= self
.svstate
.dststep
1105 dstmask
= self
.dstmask
1106 pred_dst_zero
= self
.pred_dz
1107 vl
= self
.svstate
.vl
1108 if self
.dststep_skip
:
1109 # cannot do this with sv.bc - XXX TODO
1112 while (((1 << dststep
) & dstmask
) == 0) and (dststep
!= vl
):
1113 log(" dskip", bin(1 << dststep
))
1116 # now work out if the relevant mask bits require zeroing
1118 pred_dst_zero
= ((1 << dststep
) & dstmask
) == 0
1120 # store new srcstep / dststep
1121 self
.new_dststep
= dststep
1122 self
.pred_dst_zero
= pred_dst_zero
1123 log(" new dststep", dststep
)
1126 class ISACaller(ISACallerHelper
, ISAFPHelpers
, StepLoop
):
1127 # decoder2 - an instance of power_decoder2
1128 # regfile - a list of initial values for the registers
1129 # initial_{etc} - initial values for SPRs, Condition Register, Mem, MSR
1130 # respect_pc - tracks the program counter. requires initial_insns
1131 def __init__(self
, decoder2
, regfile
, initial_sprs
=None, initial_cr
=0,
1132 initial_mem
=None, initial_msr
=0,
1144 self
.bigendian
= bigendian
1146 self
.is_svp64_mode
= False
1147 self
.respect_pc
= respect_pc
1148 if initial_sprs
is None:
1150 if initial_mem
is None:
1152 if fpregfile
is None:
1153 fpregfile
= [0] * 32
1154 if initial_insns
is None:
1156 assert self
.respect_pc
== False, "instructions required to honor pc"
1158 log("ISACaller insns", respect_pc
, initial_insns
, disassembly
)
1159 log("ISACaller initial_msr", initial_msr
)
1161 # "fake program counter" mode (for unit testing)
1165 if isinstance(initial_mem
, tuple):
1166 self
.fake_pc
= initial_mem
[0]
1167 disasm_start
= self
.fake_pc
1169 disasm_start
= initial_pc
1171 # disassembly: we need this for now (not given from the decoder)
1172 self
.disassembly
= {}
1174 for i
, code
in enumerate(disassembly
):
1175 self
.disassembly
[i
*4 + disasm_start
] = code
1177 # set up registers, instruction memory, data memory, PC, SPRs, MSR, CR
1178 self
.svp64rm
= SVP64RM()
1179 if initial_svstate
is None:
1181 if isinstance(initial_svstate
, int):
1182 initial_svstate
= SVP64State(initial_svstate
)
1183 # SVSTATE, MSR and PC
1184 StepLoop
.__init
__(self
, initial_svstate
)
1185 self
.msr
= SelectableInt(initial_msr
, 64) # underlying reg
1187 # GPR FPR SPR registers
1188 initial_sprs
= deepcopy(initial_sprs
) # so as not to get modified
1189 self
.gpr
= GPR(decoder2
, self
, self
.svstate
, regfile
)
1190 self
.fpr
= GPR(decoder2
, self
, self
.svstate
, fpregfile
)
1191 self
.spr
= SPR(decoder2
, initial_sprs
) # initialise SPRs before MMU
1193 # set up 4 dummy SVSHAPEs if they aren't already set up
1195 sname
= 'SVSHAPE%d' % i
1196 val
= self
.spr
.get(sname
, 0)
1197 # make sure it's an SVSHAPE
1198 self
.spr
[sname
] = SVSHAPE(val
, self
.gpr
)
1199 self
.last_op_svshape
= False
1202 self
.mem
= Mem(row_bytes
=8, initial_mem
=initial_mem
, misaligned_ok
=True)
1203 self
.mem
.log_fancy(kind
=LogKind
.InstrInOuts
)
1204 self
.imem
= Mem(row_bytes
=4, initial_mem
=initial_insns
)
1205 # MMU mode, redirect underlying Mem through RADIX
1207 self
.mem
= RADIX(self
.mem
, self
)
1209 self
.imem
= RADIX(self
.imem
, self
)
1211 # TODO, needed here:
1212 # FPR (same as GPR except for FP nums)
1213 # 4.2.2 p124 FPSCR (definitely "separate" - not in SPR)
1214 # note that mffs, mcrfs, mtfsf "manage" this FPSCR
1215 self
.fpscr
= FPSCRState(initial_fpscr
)
1217 # 2.3.1 CR (and sub-fields CR0..CR6 - CR0 SO comes from XER.SO)
1218 # note that mfocrf, mfcr, mtcr, mtocrf, mcrxrx "manage" CRs
1220 # 2.3.2 LR (actually SPR #8) -- Done
1221 # 2.3.3 CTR (actually SPR #9) -- Done
1222 # 2.3.4 TAR (actually SPR #815)
1223 # 3.2.2 p45 XER (actually SPR #1) -- Done
1224 # 3.2.3 p46 p232 VRSAVE (actually SPR #256)
1226 # create CR then allow portions of it to be "selectable" (below)
1227 self
.cr_fields
= CRFields(initial_cr
)
1228 self
.cr
= self
.cr_fields
.cr
1229 self
.cr_backup
= 0 # sigh, dreadful hack: for fail-first (VLi)
1231 # "undefined", just set to variable-bit-width int (use exts "max")
1232 # self.undefined = SelectableInt(0, 256) # TODO, not hard-code 256!
1235 self
.namespace
.update(self
.spr
)
1236 self
.namespace
.update({'GPR': self
.gpr
,
1240 'memassign': self
.memassign
,
1243 'SVSTATE': self
.svstate
,
1244 'SVSHAPE0': self
.spr
['SVSHAPE0'],
1245 'SVSHAPE1': self
.spr
['SVSHAPE1'],
1246 'SVSHAPE2': self
.spr
['SVSHAPE2'],
1247 'SVSHAPE3': self
.spr
['SVSHAPE3'],
1250 'FPSCR': self
.fpscr
,
1251 'undefined': undefined
,
1252 'mode_is_64bit': True,
1253 'XLEN': 64 # elwidth overrides
1256 # update pc to requested start point
1257 self
.set_pc(initial_pc
)
1259 # field-selectable versions of Condition Register
1260 self
.crl
= self
.cr_fields
.crl
1262 self
.namespace
["CR%d" % i
] = self
.crl
[i
]
1264 self
.decoder
= decoder2
.dec
1265 self
.dec2
= decoder2
1267 super().__init
__(XLEN
=self
.namespace
["XLEN"])
1271 return self
.namespace
["XLEN"]
1273 def call_trap(self
, trap_addr
, trap_bit
):
1274 """calls TRAP and sets up NIA to the new execution location.
1275 next instruction will begin at trap_addr.
1277 self
.TRAP(trap_addr
, trap_bit
)
1278 self
.namespace
['NIA'] = self
.trap_nia
1279 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1281 def TRAP(self
, trap_addr
=0x700, trap_bit
=PIb
.TRAP
):
1282 """TRAP> saves PC, MSR (and TODO SVSTATE), and updates MSR
1284 TRAP function is callable from inside the pseudocode itself,
1285 hence the default arguments. when calling from inside ISACaller
1286 it is best to use call_trap()
1288 # https://bugs.libre-soc.org/show_bug.cgi?id=859
1289 kaivb
= self
.spr
['KAIVB'].value
1290 msr
= self
.namespace
['MSR'].value
1291 log("TRAP:", hex(trap_addr
), hex(msr
), "kaivb", hex(kaivb
))
1292 # store CIA(+4?) in SRR0, set NIA to 0x700
1293 # store MSR in SRR1, set MSR to um errr something, have to check spec
1294 # store SVSTATE (if enabled) in SVSRR0
1295 self
.spr
['SRR0'].value
= self
.pc
.CIA
.value
1296 self
.spr
['SRR1'].value
= msr
1297 if self
.is_svp64_mode
:
1298 self
.spr
['SVSRR0'] = self
.namespace
['SVSTATE'].value
1299 self
.trap_nia
= SelectableInt(trap_addr |
(kaivb
& ~
0x1fff), 64)
1300 self
.spr
['SRR1'][trap_bit
] = 1 # change *copy* of MSR in SRR1
1302 # set exception bits. TODO: this should, based on the address
1303 # in figure 66 p1065 V3.0B and the table figure 65 p1063 set these
1304 # bits appropriately. however it turns out that *for now* in all
1305 # cases (all trap_addrs) the exact same thing is needed.
1306 self
.msr
[MSRb
.IR
] = 0
1307 self
.msr
[MSRb
.DR
] = 0
1308 self
.msr
[MSRb
.FE0
] = 0
1309 self
.msr
[MSRb
.FE1
] = 0
1310 self
.msr
[MSRb
.EE
] = 0
1311 self
.msr
[MSRb
.RI
] = 0
1312 self
.msr
[MSRb
.SF
] = 1
1313 self
.msr
[MSRb
.TM
] = 0
1314 self
.msr
[MSRb
.VEC
] = 0
1315 self
.msr
[MSRb
.VSX
] = 0
1316 self
.msr
[MSRb
.PR
] = 0
1317 self
.msr
[MSRb
.FP
] = 0
1318 self
.msr
[MSRb
.PMM
] = 0
1319 self
.msr
[MSRb
.TEs
] = 0
1320 self
.msr
[MSRb
.TEe
] = 0
1321 self
.msr
[MSRb
.UND
] = 0
1322 self
.msr
[MSRb
.LE
] = 1
1324 def memassign(self
, ea
, sz
, val
):
1325 self
.mem
.memassign(ea
, sz
, val
)
1327 def prep_namespace(self
, insn_name
, formname
, op_fields
, xlen
):
1328 # TODO: get field names from form in decoder*1* (not decoder2)
1329 # decoder2 is hand-created, and decoder1.sigform is auto-generated
1331 # then "yield" fields only from op_fields rather than hard-coded
1333 fields
= self
.decoder
.sigforms
[formname
]
1334 log("prep_namespace", formname
, op_fields
, insn_name
)
1335 for name
in op_fields
:
1336 # CR immediates. deal with separately. needs modifying
1338 if self
.is_svp64_mode
and name
in ['BI']: # TODO, more CRs
1339 # BI is a 5-bit, must reconstruct the value
1340 regnum
, is_vec
= yield from get_cr_in(self
.dec2
, name
)
1341 sig
= getattr(fields
, name
)
1343 # low 2 LSBs (CR field selector) remain same, CR num extended
1344 assert regnum
<= 7, "sigh, TODO, 128 CR fields"
1345 val
= (val
& 0b11) |
(regnum
<< 2)
1346 elif self
.is_svp64_mode
and name
in ['BF']: # TODO, more CRs
1347 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, "BF")
1348 log('hack %s' % name
, regnum
, is_vec
)
1351 sig
= getattr(fields
, name
)
1353 # these are all opcode fields involved in index-selection of CR,
1354 # and need to do "standard" arithmetic. CR[BA+32] for example
1355 # would, if using SelectableInt, only be 5-bit.
1356 if name
in ['BF', 'BFA', 'BC', 'BA', 'BB', 'BT', 'BI']:
1357 self
.namespace
[name
] = val
1359 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
1361 self
.namespace
['XER'] = self
.spr
['XER']
1362 self
.namespace
['CA'] = self
.spr
['XER'][XER_bits
['CA']].value
1363 self
.namespace
['CA32'] = self
.spr
['XER'][XER_bits
['CA32']].value
1364 self
.namespace
['OV'] = self
.spr
['XER'][XER_bits
['OV']].value
1365 self
.namespace
['OV32'] = self
.spr
['XER'][XER_bits
['OV32']].value
1366 self
.namespace
['XLEN'] = xlen
1368 # add some SVSTATE convenience variables
1369 vl
= self
.svstate
.vl
1370 srcstep
= self
.svstate
.srcstep
1371 self
.namespace
['VL'] = vl
1372 self
.namespace
['srcstep'] = srcstep
1374 # take a copy of the CR field value: if non-VLi fail-first fails
1375 # this is because the pseudocode writes *directly* to CR. sigh
1376 self
.cr_backup
= self
.cr
.value
1378 # sv.bc* need some extra fields
1379 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
1380 # blegh grab bits manually
1381 mode
= yield self
.dec2
.rm_dec
.rm_in
.mode
1382 # convert to SelectableInt before test
1383 mode
= SelectableInt(mode
, 5)
1384 bc_vlset
= mode
[SVP64MODEb
.BC_VLSET
] != 0
1385 bc_vli
= mode
[SVP64MODEb
.BC_VLI
] != 0
1386 bc_snz
= mode
[SVP64MODEb
.BC_SNZ
] != 0
1387 bc_vsb
= yield self
.dec2
.rm_dec
.bc_vsb
1388 bc_lru
= yield self
.dec2
.rm_dec
.bc_lru
1389 bc_gate
= yield self
.dec2
.rm_dec
.bc_gate
1390 sz
= yield self
.dec2
.rm_dec
.pred_sz
1391 self
.namespace
['mode'] = SelectableInt(mode
, 5)
1392 self
.namespace
['ALL'] = SelectableInt(bc_gate
, 1)
1393 self
.namespace
['VSb'] = SelectableInt(bc_vsb
, 1)
1394 self
.namespace
['LRu'] = SelectableInt(bc_lru
, 1)
1395 self
.namespace
['VLSET'] = SelectableInt(bc_vlset
, 1)
1396 self
.namespace
['VLI'] = SelectableInt(bc_vli
, 1)
1397 self
.namespace
['sz'] = SelectableInt(sz
, 1)
1398 self
.namespace
['SNZ'] = SelectableInt(bc_snz
, 1)
1400 def get_kludged_op_add_ca_ov(self
, inputs
, inp_ca_ov
):
1401 """ this was not at all necessary to do. this function massively
1402 duplicates - in a laborious and complex fashion - the contents of
1403 the CSV files that were extracted two years ago from microwatt's
1404 source code. A-inversion is the "inv A" column, output inversion
1405 is the "inv out" column, carry-in equal to 0 or 1 or CA is the
1408 all of that information is available in
1409 self.instrs[ins_name].op_fields
1410 where info is usually assigned to self.instrs[ins_name]
1412 https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=openpower/isatables/minor_31.csv;hb=HEAD
1414 the immediate constants are *also* decoded correctly and placed
1415 usually by DecodeIn2Imm into operand2, as part of power_decoder2.py
1417 def ca(a
, b
, ca_in
, width
):
1418 mask
= (1 << width
) - 1
1419 y
= (a
& mask
) + (b
& mask
) + ca_in
1422 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1423 insn
= insns
.get(asmcode
)
1424 SI
= yield self
.dec2
.dec
.SI
1427 inputs
= [i
.value
for i
in inputs
]
1430 if insn
in ("add", "addo", "addc", "addco"):
1434 elif insn
== "addic" or insn
== "addic.":
1438 elif insn
in ("subf", "subfo", "subfc", "subfco"):
1442 elif insn
== "subfic":
1446 elif insn
== "adde" or insn
== "addeo":
1450 elif insn
== "subfe" or insn
== "subfeo":
1454 elif insn
== "addme" or insn
== "addmeo":
1458 elif insn
== "addze" or insn
== "addzeo":
1462 elif insn
== "subfme" or insn
== "subfmeo":
1466 elif insn
== "subfze" or insn
== "subfzeo":
1470 elif insn
== "addex":
1471 # CA[32] aren't actually written, just generate so we have
1472 # something to return
1473 ca64
= ov64
= ca(inputs
[0], inputs
[1], OV
, 64)
1474 ca32
= ov32
= ca(inputs
[0], inputs
[1], OV
, 32)
1475 return ca64
, ca32
, ov64
, ov32
1476 elif insn
== "neg" or insn
== "nego":
1481 raise NotImplementedError(
1482 "op_add kludge unimplemented instruction: ", asmcode
, insn
)
1484 ca64
= ca(a
, b
, ca_in
, 64)
1485 ca32
= ca(a
, b
, ca_in
, 32)
1486 ov64
= ca64
!= ca(a
, b
, ca_in
, 63)
1487 ov32
= ca32
!= ca(a
, b
, ca_in
, 31)
1488 return ca64
, ca32
, ov64
, ov32
1490 def handle_carry_(self
, inputs
, output
, ca
, ca32
, inp_ca_ov
):
1491 op
= yield self
.dec2
.e
.do
.insn_type
1492 if op
== MicrOp
.OP_ADD
.value
and ca
is None and ca32
is None:
1493 retval
= yield from self
.get_kludged_op_add_ca_ov(
1495 ca
, ca32
, ov
, ov32
= retval
1496 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1497 if insns
.get(asmcode
) == 'addex':
1498 # TODO: if 32-bit mode, set ov to ov32
1499 self
.spr
['XER'][XER_bits
['OV']] = ov
1500 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1502 # TODO: if 32-bit mode, set ca to ca32
1503 self
.spr
['XER'][XER_bits
['CA']] = ca
1504 self
.spr
['XER'][XER_bits
['CA32']] = ca32
1506 inv_a
= yield self
.dec2
.e
.do
.invert_in
1508 inputs
[0] = ~inputs
[0]
1510 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1512 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1513 inputs
.append(SelectableInt(imm
, 64))
1516 log("gt input", x
, output
)
1517 gt
= (gtu(x
, output
))
1520 cy
= 1 if any(gts
) else 0
1522 if ca
is None: # already written
1523 self
.spr
['XER'][XER_bits
['CA']] = cy
1526 # ARGH... different for OP_ADD... *sigh*...
1527 op
= yield self
.dec2
.e
.do
.insn_type
1528 if op
== MicrOp
.OP_ADD
.value
:
1529 res32
= (output
.value
& (1 << 32)) != 0
1530 a32
= (inputs
[0].value
& (1 << 32)) != 0
1531 if len(inputs
) >= 2:
1532 b32
= (inputs
[1].value
& (1 << 32)) != 0
1535 cy32
= res32 ^ a32 ^ b32
1536 log("CA32 ADD", cy32
)
1540 log("input", x
, output
)
1541 log(" x[32:64]", x
, x
[32:64])
1542 log(" o[32:64]", output
, output
[32:64])
1543 gt
= (gtu(x
[32:64], output
[32:64])) == SelectableInt(1, 1)
1545 cy32
= 1 if any(gts
) else 0
1546 log("CA32", cy32
, gts
)
1547 if ca32
is None: # already written
1548 self
.spr
['XER'][XER_bits
['CA32']] = cy32
1550 def handle_overflow(self
, inputs
, output
, div_overflow
, inp_ca_ov
):
1551 op
= yield self
.dec2
.e
.do
.insn_type
1552 if op
== MicrOp
.OP_ADD
.value
:
1553 retval
= yield from self
.get_kludged_op_add_ca_ov(
1555 ca
, ca32
, ov
, ov32
= retval
1556 # TODO: if 32-bit mode, set ov to ov32
1557 self
.spr
['XER'][XER_bits
['OV']] = ov
1558 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1559 self
.spr
['XER'][XER_bits
['SO']] |
= ov
1561 if hasattr(self
.dec2
.e
.do
, "invert_in"):
1562 inv_a
= yield self
.dec2
.e
.do
.invert_in
1564 inputs
[0] = ~inputs
[0]
1566 imm_ok
= yield self
.dec2
.e
.do
.imm_data
.ok
1568 imm
= yield self
.dec2
.e
.do
.imm_data
.data
1569 inputs
.append(SelectableInt(imm
, 64))
1570 log("handle_overflow", inputs
, output
, div_overflow
)
1571 if len(inputs
) < 2 and div_overflow
is None:
1574 # div overflow is different: it's returned by the pseudo-code
1575 # because it's more complex than can be done by analysing the output
1576 if div_overflow
is not None:
1577 ov
, ov32
= div_overflow
, div_overflow
1578 # arithmetic overflow can be done by analysing the input and output
1579 elif len(inputs
) >= 2:
1581 input_sgn
= [exts(x
.value
, x
.bits
) < 0 for x
in inputs
]
1582 output_sgn
= exts(output
.value
, output
.bits
) < 0
1583 ov
= 1 if input_sgn
[0] == input_sgn
[1] and \
1584 output_sgn
!= input_sgn
[0] else 0
1587 input32_sgn
= [exts(x
.value
, 32) < 0 for x
in inputs
]
1588 output32_sgn
= exts(output
.value
, 32) < 0
1589 ov32
= 1 if input32_sgn
[0] == input32_sgn
[1] and \
1590 output32_sgn
!= input32_sgn
[0] else 0
1592 # now update XER OV/OV32/SO
1593 so
= self
.spr
['XER'][XER_bits
['SO']]
1594 new_so
= so | ov
# sticky overflow ORs in old with new
1595 self
.spr
['XER'][XER_bits
['OV']] = ov
1596 self
.spr
['XER'][XER_bits
['OV32']] = ov32
1597 self
.spr
['XER'][XER_bits
['SO']] = new_so
1598 log(" set overflow", ov
, ov32
, so
, new_so
)
1600 def handle_comparison(self
, out
, cr_idx
=0, overflow
=None, no_so
=False):
1601 assert isinstance(out
, SelectableInt
), \
1602 "out zero not a SelectableInt %s" % repr(outputs
)
1603 log("handle_comparison", out
.bits
, hex(out
.value
))
1604 # TODO - XXX *processor* in 32-bit mode
1605 # https://bugs.libre-soc.org/show_bug.cgi?id=424
1607 # o32 = exts(out.value, 32)
1608 # print ("handle_comparison exts 32 bit", hex(o32))
1609 out
= exts(out
.value
, out
.bits
)
1610 log("handle_comparison exts", hex(out
))
1611 # create the three main CR flags, EQ GT LT
1612 zero
= SelectableInt(out
== 0, 1)
1613 positive
= SelectableInt(out
> 0, 1)
1614 negative
= SelectableInt(out
< 0, 1)
1615 # get (or not) XER.SO. for setvl this is important *not* to read SO
1617 SO
= SelectableInt(1, 0)
1619 SO
= self
.spr
['XER'][XER_bits
['SO']]
1620 log("handle_comparison SO", SO
.value
,
1621 "overflow", overflow
,
1623 "+ve", positive
.value
,
1624 "-ve", negative
.value
)
1625 # alternative overflow checking (setvl mainly at the moment)
1626 if overflow
is not None and overflow
== 1:
1627 SO
= SelectableInt(1, 1)
1628 # create the four CR field values and set the required CR field
1629 cr_field
= selectconcat(negative
, positive
, zero
, SO
)
1630 log("handle_comparison cr_field", self
.cr
, cr_idx
, cr_field
)
1631 self
.crl
[cr_idx
].eq(cr_field
)
1633 def set_pc(self
, pc_val
):
1634 self
.namespace
['NIA'] = SelectableInt(pc_val
, 64)
1635 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
1637 def get_next_insn(self
):
1638 """check instruction
1641 pc
= self
.pc
.CIA
.value
1644 ins
= self
.imem
.ld(pc
, 4, False, True, instr_fetch
=True)
1646 raise KeyError("no instruction at 0x%x" % pc
)
1649 def setup_one(self
):
1650 """set up one instruction
1652 pc
, insn
= self
.get_next_insn()
1653 yield from self
.setup_next_insn(pc
, insn
)
1655 def setup_next_insn(self
, pc
, ins
):
1656 """set up next instruction
1659 log("setup: 0x%x 0x%x %s" % (pc
, ins
& 0xffffffff, bin(ins
)))
1660 log("CIA NIA", self
.respect_pc
, self
.pc
.CIA
.value
, self
.pc
.NIA
.value
)
1662 yield self
.dec2
.sv_rm
.eq(0)
1663 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff)
1664 yield self
.dec2
.dec
.bigendian
.eq(self
.bigendian
)
1665 yield self
.dec2
.state
.msr
.eq(self
.msr
.value
)
1666 yield self
.dec2
.state
.pc
.eq(pc
)
1667 if self
.svstate
is not None:
1668 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
1670 # SVP64. first, check if the opcode is EXT001, and SVP64 id bits set
1672 opcode
= yield self
.dec2
.dec
.opcode_in
1673 opcode
= SelectableInt(value
=opcode
, bits
=32)
1674 pfx
= SVP64Instruction
.Prefix(opcode
)
1675 log("prefix test: opcode:", pfx
.PO
, bin(pfx
.PO
), pfx
.id)
1676 self
.is_svp64_mode
= bool((pfx
.PO
== 0b000001) and (pfx
.id == 0b11))
1677 self
.pc
.update_nia(self
.is_svp64_mode
)
1679 yield self
.dec2
.is_svp64_mode
.eq(self
.is_svp64_mode
)
1680 self
.namespace
['NIA'] = self
.pc
.NIA
1681 self
.namespace
['SVSTATE'] = self
.svstate
1682 if not self
.is_svp64_mode
:
1685 # in SVP64 mode. decode/print out svp64 prefix, get v3.0B instruction
1686 log("svp64.rm", bin(pfx
.rm
))
1687 log(" svstate.vl", self
.svstate
.vl
)
1688 log(" svstate.mvl", self
.svstate
.maxvl
)
1689 ins
= self
.imem
.ld(pc
+4, 4, False, True, instr_fetch
=True)
1690 log(" svsetup: 0x%x 0x%x %s" % (pc
+4, ins
& 0xffffffff, bin(ins
)))
1691 yield self
.dec2
.dec
.raw_opcode_in
.eq(ins
& 0xffffffff) # v3.0B suffix
1692 yield self
.dec2
.sv_rm
.eq(int(pfx
.rm
)) # svp64 prefix
1695 def execute_one(self
):
1696 """execute one instruction
1698 # get the disassembly code for this instruction
1699 if not self
.disassembly
:
1700 code
= yield from self
.get_assembly_name()
1703 if self
.is_svp64_mode
:
1704 offs
, dbg
= 4, "svp64 "
1705 code
= self
.disassembly
[self
._pc
+offs
]
1706 log(" %s sim-execute" % dbg
, hex(self
._pc
), code
)
1707 opname
= code
.split(' ')[0]
1709 yield from self
.call(opname
) # execute the instruction
1710 except MemException
as e
: # check for memory errors
1711 if e
.args
[0] == 'unaligned': # alignment error
1712 # run a Trap but set DAR first
1713 print("memory unaligned exception, DAR", e
.dar
, repr(e
))
1714 self
.spr
['DAR'] = SelectableInt(e
.dar
, 64)
1715 self
.call_trap(0x600, PIb
.PRIV
) # 0x600, privileged
1717 elif e
.args
[0] == 'invalid': # invalid
1718 # run a Trap but set DAR first
1719 log("RADIX MMU memory invalid error, mode %s" % e
.mode
)
1720 if e
.mode
== 'EXECUTE':
1721 # XXX TODO: must set a few bits in SRR1,
1722 # see microwatt loadstore1.vhdl
1723 # if m_in.segerr = '0' then
1724 # v.srr1(47 - 33) := m_in.invalid;
1725 # v.srr1(47 - 35) := m_in.perm_error; -- noexec fault
1726 # v.srr1(47 - 44) := m_in.badtree;
1727 # v.srr1(47 - 45) := m_in.rc_error;
1728 # v.intr_vec := 16#400#;
1730 # v.intr_vec := 16#480#;
1731 self
.call_trap(0x400, PIb
.PRIV
) # 0x400, privileged
1733 self
.call_trap(0x300, PIb
.PRIV
) # 0x300, privileged
1735 # not supported yet:
1736 raise e
# ... re-raise
1738 log("gprs after code", code
)
1741 for i
in range(len(self
.crl
)):
1742 crs
.append(bin(self
.crl
[i
].asint()))
1743 log("crs", " ".join(crs
))
1744 log("vl,maxvl", self
.svstate
.vl
, self
.svstate
.maxvl
)
1746 # don't use this except in special circumstances
1747 if not self
.respect_pc
:
1750 log("execute one, CIA NIA", hex(self
.pc
.CIA
.value
),
1751 hex(self
.pc
.NIA
.value
))
1753 def get_assembly_name(self
):
1754 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1755 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1756 dec_insn
= yield self
.dec2
.e
.do
.insn
1757 insn_1_11
= yield self
.dec2
.e
.do
.insn
[1:11]
1758 asmcode
= yield self
.dec2
.dec
.op
.asmcode
1759 int_op
= yield self
.dec2
.dec
.op
.internal_op
1760 log("get assembly name asmcode", asmcode
, int_op
,
1761 hex(dec_insn
), bin(insn_1_11
))
1762 asmop
= insns
.get(asmcode
, None)
1764 # sigh reconstruct the assembly instruction name
1765 if hasattr(self
.dec2
.e
.do
, "oe"):
1766 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
1767 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
1771 if hasattr(self
.dec2
.e
.do
, "rc"):
1772 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
1773 rc_ok
= yield self
.dec2
.e
.do
.rc
.ok
1777 # annoying: ignore rc_ok if RC1 is set (for creating *assembly name*)
1778 RC1
= yield self
.dec2
.rm_dec
.RC1
1782 # grrrr have to special-case MUL op (see DecodeOE)
1783 log("ov %d en %d rc %d en %d op %d" %
1784 (ov_ok
, ov_en
, rc_ok
, rc_en
, int_op
))
1785 if int_op
in [MicrOp
.OP_MUL_H64
.value
, MicrOp
.OP_MUL_H32
.value
]:
1790 if not asmop
.endswith("."): # don't add "." to "andis."
1793 if hasattr(self
.dec2
.e
.do
, "lk"):
1794 lk
= yield self
.dec2
.e
.do
.lk
1797 log("int_op", int_op
)
1798 if int_op
in [MicrOp
.OP_B
.value
, MicrOp
.OP_BC
.value
]:
1799 AA
= yield self
.dec2
.dec
.fields
.FormI
.AA
[0:-1]
1803 spr_msb
= yield from self
.get_spr_msb()
1804 if int_op
== MicrOp
.OP_MFCR
.value
:
1809 # XXX TODO: for whatever weird reason this doesn't work
1810 # https://bugs.libre-soc.org/show_bug.cgi?id=390
1811 if int_op
== MicrOp
.OP_MTCRF
.value
:
1818 def reset_remaps(self
):
1819 self
.remap_loopends
= [0] * 4
1820 self
.remap_idxs
= [0, 1, 2, 3]
1822 def get_remap_indices(self
):
1823 """WARNING, this function stores remap_idxs and remap_loopends
1824 in the class for later use. this to avoid problems with yield
1826 # go through all iterators in lock-step, advance to next remap_idx
1827 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
1828 # get four SVSHAPEs. here we are hard-coding
1830 SVSHAPE0
= self
.spr
['SVSHAPE0']
1831 SVSHAPE1
= self
.spr
['SVSHAPE1']
1832 SVSHAPE2
= self
.spr
['SVSHAPE2']
1833 SVSHAPE3
= self
.spr
['SVSHAPE3']
1834 # set up the iterators
1835 remaps
= [(SVSHAPE0
, SVSHAPE0
.get_iterator()),
1836 (SVSHAPE1
, SVSHAPE1
.get_iterator()),
1837 (SVSHAPE2
, SVSHAPE2
.get_iterator()),
1838 (SVSHAPE3
, SVSHAPE3
.get_iterator()),
1842 for i
, (shape
, remap
) in enumerate(remaps
):
1843 # zero is "disabled"
1844 if shape
.value
== 0x0:
1845 self
.remap_idxs
[i
] = 0
1846 # pick src or dststep depending on reg num (0-2=in, 3-4=out)
1847 step
= dststep
if (i
in [3, 4]) else srcstep
1848 # this is terrible. O(N^2) looking for the match. but hey.
1849 for idx
, (remap_idx
, loopends
) in enumerate(remap
):
1852 self
.remap_idxs
[i
] = remap_idx
1853 self
.remap_loopends
[i
] = loopends
1854 dbg
.append((i
, step
, remap_idx
, loopends
))
1855 for (i
, step
, remap_idx
, loopends
) in dbg
:
1856 log("SVSHAPE %d idx, end" % i
, step
, remap_idx
, bin(loopends
))
1859 def get_spr_msb(self
):
1860 dec_insn
= yield self
.dec2
.e
.do
.insn
1861 return dec_insn
& (1 << 20) != 0 # sigh - XFF.spr[-1]?
1863 def call(self
, name
):
1864 """call(opcode) - the primary execution point for instructions
1866 self
.last_st_addr
= None # reset the last known store address
1867 self
.last_ld_addr
= None # etc.
1869 ins_name
= name
.strip() # remove spaces if not already done so
1871 log("halted - not executing", ins_name
)
1874 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
1875 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
1876 asmop
= yield from self
.get_assembly_name()
1877 log("call", ins_name
, asmop
)
1879 # sv.setvl is *not* a loop-function. sigh
1880 log("is_svp64_mode", self
.is_svp64_mode
, asmop
)
1883 int_op
= yield self
.dec2
.dec
.op
.internal_op
1884 spr_msb
= yield from self
.get_spr_msb()
1886 instr_is_privileged
= False
1887 if int_op
in [MicrOp
.OP_ATTN
.value
,
1888 MicrOp
.OP_MFMSR
.value
,
1889 MicrOp
.OP_MTMSR
.value
,
1890 MicrOp
.OP_MTMSRD
.value
,
1892 MicrOp
.OP_RFID
.value
]:
1893 instr_is_privileged
= True
1894 if int_op
in [MicrOp
.OP_MFSPR
.value
,
1895 MicrOp
.OP_MTSPR
.value
] and spr_msb
:
1896 instr_is_privileged
= True
1898 log("is priv", instr_is_privileged
, hex(self
.msr
.value
),
1900 # check MSR priv bit and whether op is privileged: if so, throw trap
1901 if instr_is_privileged
and self
.msr
[MSRb
.PR
] == 1:
1902 self
.call_trap(0x700, PIb
.PRIV
)
1905 # check halted condition
1906 if ins_name
== 'attn':
1910 # check illegal instruction
1912 if ins_name
not in ['mtcrf', 'mtocrf']:
1913 illegal
= ins_name
!= asmop
1915 # list of instructions not being supported by binutils (.long)
1916 dotstrp
= asmop
[:-1] if asmop
[-1] == '.' else asmop
1917 if dotstrp
in [*FPTRANS_INSNS
,
1918 'ffmadds', 'fdmadds', 'ffadds',
1920 'setvl', 'svindex', 'svremap', 'svstep',
1921 'svshape', 'svshape2',
1922 'grev', 'ternlogi', 'bmask', 'cprop',
1923 'absdu', 'absds', 'absdacs', 'absdacu', 'avgadd',
1924 'fmvis', 'fishmv', 'pcdec', "maddedu", "divmod2du",
1925 "dsld", "dsrd", "maddedus",
1926 "shadd", "shaddw", "shadduw",
1927 "fcvttg", "fcvttgo", "fcvttgs", "fcvttgso",
1929 "fcvtfg", "fcvtfgs",
1931 "maddsubrs", "maddrs"
1936 # branch-conditional redirects to sv.bc
1937 if asmop
.startswith('bc') and self
.is_svp64_mode
:
1938 ins_name
= 'sv.%s' % ins_name
1940 # ld-immediate-with-pi mode redirects to ld-with-postinc
1941 ldst_imm_postinc
= False
1942 if 'u' in ins_name
and self
.is_svp64_mode
:
1943 ldst_pi
= yield self
.dec2
.rm_dec
.ldst_postinc
1945 ins_name
= ins_name
.replace("u", "up")
1946 ldst_imm_postinc
= True
1947 log(" enable ld/st postinc", ins_name
)
1949 log(" post-processed name", dotstrp
, ins_name
, asmop
)
1951 # illegal instructions call TRAP at 0x700
1953 print("illegal", ins_name
, asmop
)
1954 self
.call_trap(0x700, PIb
.ILLEG
)
1955 print("name %s != %s - calling ILLEGAL trap, PC: %x" %
1956 (ins_name
, asmop
, self
.pc
.CIA
.value
))
1959 # this is for setvl "Vertical" mode: if set true,
1960 # srcstep/dststep is explicitly advanced. mode says which SVSTATE to
1961 # test for Rc=1 end condition. 3 bits of all 3 loops are put into CR0
1962 self
.allow_next_step_inc
= False
1963 self
.svstate_next_mode
= 0
1965 # nop has to be supported, we could let the actual op calculate
1966 # but PowerDecoder has a pattern for nop
1967 if ins_name
== 'nop':
1968 self
.update_pc_next()
1971 # get elwidths, defaults to 64
1975 if self
.is_svp64_mode
:
1976 ew_src
= yield self
.dec2
.rm_dec
.ew_src
1977 ew_dst
= yield self
.dec2
.rm_dec
.ew_dst
1978 ew_src
= 8 << (3-int(ew_src
)) # convert to bitlength
1979 ew_dst
= 8 << (3-int(ew_dst
)) # convert to bitlength
1980 xlen
= max(ew_src
, ew_dst
)
1981 log("elwdith", ew_src
, ew_dst
)
1982 log("XLEN:", self
.is_svp64_mode
, xlen
)
1984 # look up instruction in ISA.instrs, prepare namespace
1985 if ins_name
== 'pcdec': # grrrr yes there are others ("stbcx." etc.)
1986 info
= self
.instrs
[ins_name
+"."]
1987 elif asmop
[-1] == '.' and asmop
in self
.instrs
:
1988 info
= self
.instrs
[asmop
]
1990 info
= self
.instrs
[ins_name
]
1991 yield from self
.prep_namespace(ins_name
, info
.form
, info
.op_fields
,
1994 # preserve order of register names
1995 input_names
= create_args(list(info
.read_regs
) +
1996 list(info
.uninit_regs
))
1997 log("input names", input_names
)
1999 # get SVP64 entry for the current instruction
2000 sv_rm
= self
.svp64rm
.instrs
.get(ins_name
)
2001 if sv_rm
is not None:
2002 dest_cr
, src_cr
, src_byname
, dest_byname
= decode_extra(sv_rm
)
2004 dest_cr
, src_cr
, src_byname
, dest_byname
= False, False, {}, {}
2005 log("sv rm", sv_rm
, dest_cr
, src_cr
, src_byname
, dest_byname
)
2007 # see if srcstep/dststep need skipping over masked-out predicate bits
2008 # svstep also needs advancement because it calls SVSTATE_NEXT.
2009 # bit the remaps get computed just after pre_inc moves them on
2010 # with remap_set_steps substituting for PowerDecider2 not doing it,
2011 # and SVSTATE_NEXT not being able to.use yield, the preinc on
2012 # svstep is necessary for now.
2014 if (self
.is_svp64_mode
or ins_name
in ['svstep']):
2015 yield from self
.svstate_pre_inc()
2016 if self
.is_svp64_mode
:
2017 pre
= yield from self
.update_new_svstate_steps()
2019 self
.svp64_reset_loop()
2021 self
.update_pc_next()
2023 srcstep
, dststep
, ssubstep
, dsubstep
= self
.get_src_dststeps()
2024 pred_dst_zero
= self
.pred_dst_zero
2025 pred_src_zero
= self
.pred_src_zero
2026 vl
= self
.svstate
.vl
2027 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2029 # VL=0 in SVP64 mode means "do nothing: skip instruction"
2030 if self
.is_svp64_mode
and vl
== 0:
2031 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2032 log("SVP64: VL=0, end of call", self
.namespace
['CIA'],
2033 self
.namespace
['NIA'], kind
=LogKind
.InstrInOuts
)
2036 # for when SVREMAP is active, using pre-arranged schedule.
2037 # note: modifying PowerDecoder2 needs to "settle"
2038 remap_en
= self
.svstate
.SVme
2039 persist
= self
.svstate
.RMpst
2040 active
= (persist
or self
.last_op_svshape
) and remap_en
!= 0
2041 if self
.is_svp64_mode
:
2042 yield self
.dec2
.remap_active
.eq(remap_en
if active
else 0)
2044 if persist
or self
.last_op_svshape
:
2045 remaps
= self
.get_remap_indices()
2046 if self
.is_svp64_mode
and (persist
or self
.last_op_svshape
):
2047 yield from self
.remap_set_steps(remaps
)
2048 # after that, settle down (combinatorial) to let Vector reg numbers
2049 # work themselves out
2051 if self
.is_svp64_mode
:
2052 remap_active
= yield self
.dec2
.remap_active
2054 remap_active
= False
2055 log("remap active", bin(remap_active
))
2057 # main input registers (RT, RA ...)
2059 for name
in input_names
:
2060 regval
= (yield from self
.get_input(name
, ew_src
))
2061 log("regval name", name
, regval
)
2062 inputs
.append(regval
)
2064 # arrrrgh, awful hack, to get _RT into namespace
2065 if ins_name
in ['setvl', 'svstep']:
2067 RT
= yield self
.dec2
.dec
.RT
2068 self
.namespace
[regname
] = SelectableInt(RT
, 5)
2070 self
.namespace
["RT"] = SelectableInt(0, 5)
2071 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, "RT")
2072 log('hack input reg %s %s' % (name
, str(regnum
)), is_vec
)
2074 # in SVP64 mode for LD/ST work out immediate
2075 # XXX TODO: replace_ds for DS-Form rather than D-Form.
2076 # use info.form to detect
2077 if self
.is_svp64_mode
and not ldst_imm_postinc
:
2078 yield from self
.check_replace_d(info
, remap_active
)
2080 # "special" registers
2081 for special
in info
.special_regs
:
2082 if special
in special_sprs
:
2083 inputs
.append(self
.spr
[special
])
2085 inputs
.append(self
.namespace
[special
])
2087 # clear trap (trap) NIA
2088 self
.trap_nia
= None
2090 # check if this was an sv.bc* and create an indicator that
2091 # this is the last check to be made as a loop. combined with
2092 # the ALL/ANY mode we can early-exit
2093 if self
.is_svp64_mode
and ins_name
.startswith("sv.bc"):
2094 no_in_vec
= yield self
.dec2
.no_in_vec
# BI is scalar
2095 end_loop
= no_in_vec
or srcstep
== vl
-1 or dststep
== vl
-1
2096 self
.namespace
['end_loop'] = SelectableInt(end_loop
, 1)
2098 inp_ca_ov
= (self
.spr
['XER'][XER_bits
['CA']].value
,
2099 self
.spr
['XER'][XER_bits
['OV']].value
)
2101 # execute actual instruction here (finally)
2102 log("inputs", inputs
)
2103 results
= info
.func(self
, *inputs
)
2104 output_names
= create_args(info
.write_regs
)
2106 for out
, n
in zip(results
or [], output_names
):
2108 log("results", outs
)
2110 # "inject" decorator takes namespace from function locals: we need to
2111 # overwrite NIA being overwritten (sigh)
2112 if self
.trap_nia
is not None:
2113 self
.namespace
['NIA'] = self
.trap_nia
2115 log("after func", self
.namespace
['CIA'], self
.namespace
['NIA'])
2117 # check if op was a LD/ST so that debugging can check the
2119 if int_op
in [MicrOp
.OP_STORE
.value
,
2121 self
.last_st_addr
= self
.mem
.last_st_addr
2122 if int_op
in [MicrOp
.OP_LOAD
.value
,
2124 self
.last_ld_addr
= self
.mem
.last_ld_addr
2125 log("op", int_op
, MicrOp
.OP_STORE
.value
, MicrOp
.OP_LOAD
.value
,
2126 self
.last_st_addr
, self
.last_ld_addr
)
2128 # detect if CA/CA32 already in outputs (sra*, basically)
2130 ca32
= outs
.get("CA32")
2132 log("carry already done?", ca
, ca32
, output_names
)
2133 carry_en
= yield self
.dec2
.e
.do
.output_carry
2135 yield from self
.handle_carry_(
2136 inputs
, results
[0], ca
, ca32
, inp_ca_ov
=inp_ca_ov
)
2138 # get outout named "overflow" and "CR0"
2139 overflow
= outs
.get('overflow')
2140 cr0
= outs
.get('CR0')
2142 if not self
.is_svp64_mode
: # yeah just no. not in parallel processing
2143 # detect if overflow was in return result
2144 ov_en
= yield self
.dec2
.e
.do
.oe
.oe
2145 ov_ok
= yield self
.dec2
.e
.do
.oe
.ok
2146 log("internal overflow", ins_name
, overflow
, "en?", ov_en
, ov_ok
)
2148 yield from self
.handle_overflow(
2149 inputs
, results
[0], overflow
, inp_ca_ov
=inp_ca_ov
)
2151 # only do SVP64 dest predicated Rc=1 if dest-pred is not enabled
2153 if not self
.is_svp64_mode
or not pred_dst_zero
:
2154 if hasattr(self
.dec2
.e
.do
, "rc"):
2155 rc_en
= yield self
.dec2
.e
.do
.rc
.rc
2156 # don't do Rc=1 for svstep it is handled explicitly.
2157 # XXX TODO: now that CR0 is supported, sort out svstep's pseudocode
2158 # to write directly to CR0 instead of in ISACaller. hooyahh.
2159 if rc_en
and ins_name
not in ['svstep']:
2160 yield from self
.do_rc_ov(ins_name
, results
[0], overflow
, cr0
)
2163 ffirst_hit
= False, False
2164 if self
.is_svp64_mode
:
2165 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
2166 is_cr
= sv_mode
== SVMode
.CROP
.value
2167 chk
= rc_en
or is_cr
2168 ffirst_hit
= (yield from self
.check_ffirst(info
, chk
, srcstep
))
2170 # any modified return results?
2171 yield from self
.do_outregs_nia(asmop
, ins_name
, info
, outs
,
2172 carry_en
, rc_en
, ffirst_hit
, ew_dst
)
2174 def check_ffirst(self
, info
, rc_en
, srcstep
):
2175 """fail-first mode: checks a bit of Rc Vector, truncates VL
2177 rm_mode
= yield self
.dec2
.rm_dec
.mode
2178 ff_inv
= yield self
.dec2
.rm_dec
.inv
2179 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2180 RC1
= yield self
.dec2
.rm_dec
.RC1
2181 vli_
= yield self
.dec2
.rm_dec
.vli
# VL inclusive if truncated
2182 log(" ff rm_mode", rc_en
, rm_mode
, SVP64RMMode
.FFIRST
.value
)
2186 log(" cr_bit", cr_bit
)
2187 log(" rc_en", rc_en
)
2188 if not rc_en
or rm_mode
!= SVP64RMMode
.FFIRST
.value
:
2190 # get the CR vevtor, do BO-test
2192 log("asmregs", info
.asmregs
[0], info
.write_regs
)
2193 if 'CR' in info
.write_regs
and 'BF' in info
.asmregs
[0]:
2195 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, crf
)
2196 crtest
= self
.crl
[regnum
]
2197 ffirst_hit
= crtest
[cr_bit
] != ff_inv
2198 log("cr test", crf
, regnum
, int(crtest
), crtest
, cr_bit
, ff_inv
)
2199 log("cr test?", ffirst_hit
)
2202 # Fail-first activated, truncate VL
2203 vli
= SelectableInt(int(vli_
), 7)
2204 self
.svstate
.vl
= srcstep
+ vli
2205 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2206 yield Settle() # let decoder update
2209 def do_rc_ov(self
, ins_name
, result
, overflow
, cr0
):
2210 if ins_name
.startswith("f"):
2211 rc_reg
= "CR1" # not calculated correctly yet (not FP compares)
2214 regnum
, is_vec
= yield from get_cr_out(self
.dec2
, rc_reg
)
2215 # hang on... for `setvl` actually you want to test SVSTATE.VL
2216 is_setvl
= ins_name
in ('svstep', 'setvl')
2218 result
= SelectableInt(result
.vl
, 64)
2220 # overflow = None # do not override overflow except in setvl
2222 # if there was not an explicit CR0 in the pseudocode, do implicit Rc=1
2224 self
.handle_comparison(result
, regnum
, overflow
, no_so
=is_setvl
)
2226 # otherwise we just blat CR0 into the required regnum
2227 log("explicit rc0", cr0
)
2228 self
.crl
[regnum
].eq(cr0
)
2230 def do_outregs_nia(self
, asmop
, ins_name
, info
, outs
,
2231 carry_en
, rc_en
, ffirst_hit
, ew_dst
):
2232 ffirst_hit
, vli
= ffirst_hit
2233 # write out any regs for this instruction
2234 for name
, output
in outs
.items():
2235 yield from self
.check_write(info
, name
, output
, carry_en
, ew_dst
)
2236 # restore the CR value on non-VLI failfirst (from sv.cmp and others
2237 # which write directly to CR in the pseudocode (gah, what a mess)
2238 # if ffirst_hit and not vli:
2239 # self.cr.value = self.cr_backup
2242 self
.svp64_reset_loop()
2245 # check advancement of src/dst/sub-steps and if PC needs updating
2246 nia_update
= (yield from self
.check_step_increment(rc_en
,
2249 self
.update_pc_next()
2251 def check_replace_d(self
, info
, remap_active
):
2252 replace_d
= False # update / replace constant in pseudocode
2253 ldstmode
= yield self
.dec2
.rm_dec
.ldstmode
2254 vl
= self
.svstate
.vl
2255 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2256 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2257 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2258 if info
.form
== 'DS':
2259 # DS-Form, multiply by 4 then knock 2 bits off after
2260 imm
= yield self
.dec2
.dec
.fields
.FormDS
.DS
[0:14] * 4
2262 imm
= yield self
.dec2
.dec
.fields
.FormD
.D
[0:16]
2263 imm
= exts(imm
, 16) # sign-extend to integer
2264 # get the right step. LD is from srcstep, ST is dststep
2265 op
= yield self
.dec2
.e
.do
.insn_type
2267 if op
== MicrOp
.OP_LOAD
.value
:
2269 offsmul
= yield self
.dec2
.in1_step
2270 log("D-field REMAP src", imm
, offsmul
, ldstmode
)
2272 offsmul
= (srcstep
* (subvl
+1)) + ssubstep
2273 log("D-field src", imm
, offsmul
, ldstmode
)
2274 elif op
== MicrOp
.OP_STORE
.value
:
2275 # XXX NOTE! no bit-reversed STORE! this should not ever be used
2276 offsmul
= (dststep
* (subvl
+1)) + dsubstep
2277 log("D-field dst", imm
, offsmul
, ldstmode
)
2278 # Unit-Strided LD/ST adds offset*width to immediate
2279 if ldstmode
== SVP64LDSTmode
.UNITSTRIDE
.value
:
2280 ldst_len
= yield self
.dec2
.e
.do
.data_len
2281 imm
= SelectableInt(imm
+ offsmul
* ldst_len
, 32)
2283 # Element-strided multiplies the immediate by element step
2284 elif ldstmode
== SVP64LDSTmode
.ELSTRIDE
.value
:
2285 imm
= SelectableInt(imm
* offsmul
, 32)
2288 ldst_ra_vec
= yield self
.dec2
.rm_dec
.ldst_ra_vec
2289 ldst_imz_in
= yield self
.dec2
.rm_dec
.ldst_imz_in
2290 log("LDSTmode", SVP64LDSTmode(ldstmode
),
2291 offsmul
, imm
, ldst_ra_vec
, ldst_imz_in
)
2292 # new replacement D... errr.. DS
2294 if info
.form
== 'DS':
2295 # TODO: assert 2 LSBs are zero?
2296 log("DS-Form, TODO, assert 2 LSBs zero?", bin(imm
.value
))
2297 imm
.value
= imm
.value
>> 2
2298 self
.namespace
['DS'] = imm
2300 self
.namespace
['D'] = imm
2302 def get_input(self
, name
, ew_src
):
2303 # using PowerDecoder2, first, find the decoder index.
2304 # (mapping name RA RB RC RS to in1, in2, in3)
2305 regnum
, is_vec
= yield from get_idx_in(self
.dec2
, name
, True)
2307 # doing this is not part of svp64, it's because output
2308 # registers, to be modified, need to be in the namespace.
2309 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2311 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
, True)
2313 if isinstance(regnum
, tuple):
2314 (regnum
, base
, offs
) = regnum
2316 base
, offs
= regnum
, 0 # temporary HACK
2318 # in case getting the register number is needed, _RA, _RB
2319 # (HACK: only in straight non-svp64-mode for now, or elwidth == 64)
2320 regname
= "_" + name
2321 if not self
.is_svp64_mode
or ew_src
== 64:
2322 self
.namespace
[regname
] = regnum
2323 elif regname
in self
.namespace
:
2324 del self
.namespace
[regname
]
2326 if not self
.is_svp64_mode
or not self
.pred_src_zero
:
2327 log('reading reg %s %s' % (name
, str(regnum
)), is_vec
)
2329 reg_val
= SelectableInt(self
.fpr(base
, is_vec
, offs
, ew_src
))
2330 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2331 elif name
is not None:
2332 reg_val
= SelectableInt(self
.gpr(base
, is_vec
, offs
, ew_src
))
2333 log("read reg %d/%d: 0x%x" % (base
, offs
, reg_val
.value
))
2335 log('zero input reg %s %s' % (name
, str(regnum
)), is_vec
)
2336 reg_val
= SelectableInt(0, ew_src
)
2339 def remap_set_steps(self
, remaps
):
2340 """remap_set_steps sets up the in1/2/3 and out1/2 steps.
2341 they work in concert with PowerDecoder2 at the moment,
2342 there is no HDL implementation of REMAP. therefore this
2343 function, because ISACaller still uses PowerDecoder2,
2344 will *explicitly* write the dec2.XX_step values. this has
2347 # just some convenient debug info
2349 sname
= 'SVSHAPE%d' % i
2350 shape
= self
.spr
[sname
]
2351 log(sname
, bin(shape
.value
))
2352 log(" lims", shape
.lims
)
2353 log(" mode", shape
.mode
)
2354 log(" skip", shape
.skip
)
2356 # set up the list of steps to remap
2357 mi0
= self
.svstate
.mi0
2358 mi1
= self
.svstate
.mi1
2359 mi2
= self
.svstate
.mi2
2360 mo0
= self
.svstate
.mo0
2361 mo1
= self
.svstate
.mo1
2362 steps
= [[self
.dec2
.in1_step
, mi0
], # RA
2363 [self
.dec2
.in2_step
, mi1
], # RB
2364 [self
.dec2
.in3_step
, mi2
], # RC
2365 [self
.dec2
.o_step
, mo0
], # RT
2366 [self
.dec2
.o2_step
, mo1
], # EA
2369 rnames
= ['RA', 'RB', 'RC', 'RT', 'RS']
2370 for i
, reg
in enumerate(rnames
):
2371 idx
= yield from get_idx_map(self
.dec2
, reg
)
2373 idx
= yield from get_idx_map(self
.dec2
, "F"+reg
)
2375 steps
[i
][0] = self
.dec2
.in1_step
2377 steps
[i
][0] = self
.dec2
.in2_step
2379 steps
[i
][0] = self
.dec2
.in3_step
2380 log("remap step", i
, reg
, idx
, steps
[i
][1])
2381 remap_idxs
= self
.remap_idxs
2383 # now cross-index the required SHAPE for each of 3-in 2-out regs
2384 rnames
= ['RA', 'RB', 'RC', 'RT', 'EA']
2385 for i
, (dstep
, shape_idx
) in enumerate(steps
):
2386 (shape
, remap
) = remaps
[shape_idx
]
2387 remap_idx
= remap_idxs
[shape_idx
]
2388 # zero is "disabled"
2389 if shape
.value
== 0x0:
2391 # now set the actual requested step to the current index
2392 if dstep
is not None:
2393 yield dstep
.eq(remap_idx
)
2395 # debug printout info
2396 rremaps
.append((shape
.mode
, hex(shape
.value
), dstep
,
2397 i
, rnames
[i
], shape_idx
, remap_idx
))
2399 log("shape remap", x
)
2401 def check_write(self
, info
, name
, output
, carry_en
, ew_dst
):
2402 if name
== 'overflow': # ignore, done already (above)
2404 if name
== 'CR0': # ignore, done already (above)
2406 if isinstance(output
, int):
2407 output
= SelectableInt(output
, 256)
2409 if name
in ['CA', 'CA32']:
2411 log("writing %s to XER" % name
, output
)
2412 log("write XER %s 0x%x" % (name
, output
.value
))
2413 self
.spr
['XER'][XER_bits
[name
]] = output
.value
2415 log("NOT writing %s to XER" % name
, output
)
2417 # write special SPRs
2418 if name
in info
.special_regs
:
2419 log('writing special %s' % name
, output
, special_sprs
)
2420 log("write reg %s 0x%x" % (name
, output
.value
))
2421 if name
in special_sprs
:
2422 self
.spr
[name
] = output
2424 self
.namespace
[name
].eq(output
)
2426 log('msr written', hex(self
.msr
.value
))
2428 # find out1/out2 PR/FPR
2429 regnum
, is_vec
= yield from get_idx_out(self
.dec2
, name
, True)
2431 regnum
, is_vec
= yield from get_idx_out2(self
.dec2
, name
, True)
2433 # temporary hack for not having 2nd output
2434 regnum
= yield getattr(self
.decoder
, name
)
2436 # convenient debug prefix
2441 # check zeroing due to predicate bit being zero
2442 if self
.is_svp64_mode
and self
.pred_dst_zero
:
2443 log('zeroing reg %s %s' % (str(regnum
), str(output
)), is_vec
)
2444 output
= SelectableInt(0, 256)
2445 log("write reg %s%s 0x%x ew %d" % (reg_prefix
, str(regnum
),
2446 output
.value
, ew_dst
),
2447 kind
=LogKind
.InstrInOuts
)
2448 # zero-extend tov64 bit begore storing (should use EXT oh well)
2449 if output
.bits
> 64:
2450 output
= SelectableInt(output
.value
, 64)
2452 self
.fpr
.write(regnum
, output
, is_vec
, ew_dst
)
2454 self
.gpr
.write(regnum
, output
, is_vec
, ew_dst
)
2456 def check_step_increment(self
, rc_en
, asmop
, ins_name
):
2457 # check if it is the SVSTATE.src/dest step that needs incrementing
2458 # this is our Sub-Program-Counter loop from 0 to VL-1
2459 if not self
.allow_next_step_inc
:
2460 if self
.is_svp64_mode
:
2461 return (yield from self
.svstate_post_inc(ins_name
))
2463 # XXX only in non-SVP64 mode!
2464 # record state of whether the current operation was an svshape,
2466 # to be able to know if it should apply in the next instruction.
2467 # also (if going to use this instruction) should disable ability
2468 # to interrupt in between. sigh.
2469 self
.last_op_svshape
= asmop
in ['svremap', 'svindex',
2476 log("SVSTATE_NEXT: inc requested, mode",
2477 self
.svstate_next_mode
, self
.allow_next_step_inc
)
2478 yield from self
.svstate_pre_inc()
2479 pre
= yield from self
.update_new_svstate_steps()
2481 # reset at end of loop including exit Vertical Mode
2482 log("SVSTATE_NEXT: end of loop, reset")
2483 self
.svp64_reset_loop()
2484 self
.svstate
.vfirst
= 0
2488 self
.handle_comparison(SelectableInt(0, 64)) # CR0
2490 if self
.allow_next_step_inc
== 2:
2491 log("SVSTATE_NEXT: read")
2492 nia_update
= (yield from self
.svstate_post_inc(ins_name
))
2494 log("SVSTATE_NEXT: post-inc")
2495 # use actual (cached) src/dst-step here to check end
2496 remaps
= self
.get_remap_indices()
2497 remap_idxs
= self
.remap_idxs
2498 vl
= self
.svstate
.vl
2499 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2500 if self
.allow_next_step_inc
!= 2:
2501 yield from self
.advance_svstate_steps()
2502 #self.namespace['SVSTATE'] = self.svstate.spr
2503 # set CR0 (if Rc=1) based on end
2504 endtest
= 1 if self
.at_loopend() else 0
2506 #results = [SelectableInt(endtest, 64)]
2507 # self.handle_comparison(results) # CR0
2509 # see if svstep was requested, if so, which SVSTATE
2511 if self
.svstate_next_mode
> 0:
2512 shape_idx
= self
.svstate_next_mode
.value
-1
2513 endings
= self
.remap_loopends
[shape_idx
]
2514 cr_field
= SelectableInt((~endings
) << 1 | endtest
, 4)
2515 log("svstep Rc=1, CR0", cr_field
, endtest
)
2516 self
.crl
[0].eq(cr_field
) # CR0
2518 # reset at end of loop including exit Vertical Mode
2519 log("SVSTATE_NEXT: after increments, reset")
2520 self
.svp64_reset_loop()
2521 self
.svstate
.vfirst
= 0
2524 def SVSTATE_NEXT(self
, mode
, submode
):
2525 """explicitly moves srcstep/dststep on to next element, for
2526 "Vertical-First" mode. this function is called from
2527 setvl pseudo-code, as a pseudo-op "svstep"
2529 WARNING: this function uses information that was created EARLIER
2530 due to it being in the middle of a yield, but this function is
2531 *NOT* called from yield (it's called from compiled pseudocode).
2533 self
.allow_next_step_inc
= submode
.value
+ 1
2534 log("SVSTATE_NEXT mode", mode
, submode
, self
.allow_next_step_inc
)
2535 self
.svstate_next_mode
= mode
2536 if self
.svstate_next_mode
> 0 and self
.svstate_next_mode
< 5:
2537 shape_idx
= self
.svstate_next_mode
.value
-1
2538 return SelectableInt(self
.remap_idxs
[shape_idx
], 7)
2539 if self
.svstate_next_mode
== 5:
2540 self
.svstate_next_mode
= 0
2541 return SelectableInt(self
.svstate
.srcstep
, 7)
2542 if self
.svstate_next_mode
== 6:
2543 self
.svstate_next_mode
= 0
2544 return SelectableInt(self
.svstate
.dststep
, 7)
2545 if self
.svstate_next_mode
== 7:
2546 self
.svstate_next_mode
= 0
2547 return SelectableInt(self
.svstate
.ssubstep
, 7)
2548 if self
.svstate_next_mode
== 8:
2549 self
.svstate_next_mode
= 0
2550 return SelectableInt(self
.svstate
.dsubstep
, 7)
2551 return SelectableInt(0, 7)
2553 def get_src_dststeps(self
):
2554 """gets srcstep, dststep, and ssubstep, dsubstep
2556 return (self
.new_srcstep
, self
.new_dststep
,
2557 self
.new_ssubstep
, self
.new_dsubstep
)
2559 def update_svstate_namespace(self
, overwrite_svstate
=True):
2560 if overwrite_svstate
:
2561 # note, do not get the bit-reversed srcstep here!
2562 srcstep
, dststep
= self
.new_srcstep
, self
.new_dststep
2563 ssubstep
, dsubstep
= self
.new_ssubstep
, self
.new_dsubstep
2565 # update SVSTATE with new srcstep
2566 self
.svstate
.srcstep
= srcstep
2567 self
.svstate
.dststep
= dststep
2568 self
.svstate
.ssubstep
= ssubstep
2569 self
.svstate
.dsubstep
= dsubstep
2570 self
.namespace
['SVSTATE'] = self
.svstate
2571 yield self
.dec2
.state
.svstate
.eq(self
.svstate
.value
)
2572 yield Settle() # let decoder update
2574 def update_new_svstate_steps(self
, overwrite_svstate
=True):
2575 yield from self
.update_svstate_namespace(overwrite_svstate
)
2576 srcstep
= self
.svstate
.srcstep
2577 dststep
= self
.svstate
.dststep
2578 ssubstep
= self
.svstate
.ssubstep
2579 dsubstep
= self
.svstate
.dsubstep
2580 pack
= self
.svstate
.pack
2581 unpack
= self
.svstate
.unpack
2582 vl
= self
.svstate
.vl
2583 sv_mode
= yield self
.dec2
.rm_dec
.sv_mode
2584 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2585 rm_mode
= yield self
.dec2
.rm_dec
.mode
2586 ff_inv
= yield self
.dec2
.rm_dec
.inv
2587 cr_bit
= yield self
.dec2
.rm_dec
.cr_sel
2588 log(" srcstep", srcstep
)
2589 log(" dststep", dststep
)
2591 log(" unpack", unpack
)
2592 log(" ssubstep", ssubstep
)
2593 log(" dsubstep", dsubstep
)
2595 log(" subvl", subvl
)
2596 log(" rm_mode", rm_mode
)
2597 log(" sv_mode", sv_mode
)
2599 log(" cr_bit", cr_bit
)
2601 # check if end reached (we let srcstep overrun, above)
2602 # nothing needs doing (TODO zeroing): just do next instruction
2605 return ((ssubstep
== subvl
and srcstep
== vl
) or
2606 (dsubstep
== subvl
and dststep
== vl
))
2608 def svstate_post_inc(self
, insn_name
, vf
=0):
2609 # check if SV "Vertical First" mode is enabled
2610 vfirst
= self
.svstate
.vfirst
2611 log(" SV Vertical First", vf
, vfirst
)
2612 if not vf
and vfirst
== 1:
2616 # check if it is the SVSTATE.src/dest step that needs incrementing
2617 # this is our Sub-Program-Counter loop from 0 to VL-1
2618 # XXX twin predication TODO
2619 vl
= self
.svstate
.vl
2620 subvl
= yield self
.dec2
.rm_dec
.rm_in
.subvl
2621 mvl
= self
.svstate
.maxvl
2622 srcstep
= self
.svstate
.srcstep
2623 dststep
= self
.svstate
.dststep
2624 ssubstep
= self
.svstate
.ssubstep
2625 dsubstep
= self
.svstate
.dsubstep
2626 pack
= self
.svstate
.pack
2627 unpack
= self
.svstate
.unpack
2628 rm_mode
= yield self
.dec2
.rm_dec
.mode
2629 reverse_gear
= yield self
.dec2
.rm_dec
.reverse_gear
2630 sv_ptype
= yield self
.dec2
.dec
.op
.SV_Ptype
2631 out_vec
= not (yield self
.dec2
.no_out_vec
)
2632 in_vec
= not (yield self
.dec2
.no_in_vec
)
2633 log(" svstate.vl", vl
)
2634 log(" svstate.mvl", mvl
)
2635 log(" rm.subvl", subvl
)
2636 log(" svstate.srcstep", srcstep
)
2637 log(" svstate.dststep", dststep
)
2638 log(" svstate.ssubstep", ssubstep
)
2639 log(" svstate.dsubstep", dsubstep
)
2640 log(" svstate.pack", pack
)
2641 log(" svstate.unpack", unpack
)
2642 log(" mode", rm_mode
)
2643 log(" reverse", reverse_gear
)
2644 log(" out_vec", out_vec
)
2645 log(" in_vec", in_vec
)
2646 log(" sv_ptype", sv_ptype
, sv_ptype
== SVPType
.P2
.value
)
2647 # check if this was an sv.bc* and if so did it succeed
2648 if self
.is_svp64_mode
and insn_name
.startswith("sv.bc"):
2649 end_loop
= self
.namespace
['end_loop']
2650 log("branch %s end_loop" % insn_name
, end_loop
)
2652 self
.svp64_reset_loop()
2653 self
.update_pc_next()
2655 # check if srcstep needs incrementing by one, stop PC advancing
2656 # but for 2-pred both src/dest have to be checked.
2657 # XXX this might not be true! it may just be LD/ST
2658 if sv_ptype
== SVPType
.P2
.value
:
2659 svp64_is_vector
= (out_vec
or in_vec
)
2661 svp64_is_vector
= out_vec
2662 # loops end at the first "hit" (source or dest)
2663 yield from self
.advance_svstate_steps()
2664 loopend
= self
.loopend
2665 log("loopend", svp64_is_vector
, loopend
)
2666 if not svp64_is_vector
or loopend
:
2667 # reset loop to zero and update NIA
2668 self
.svp64_reset_loop()
2673 # still looping, advance and update NIA
2674 self
.namespace
['SVSTATE'] = self
.svstate
2676 # not an SVP64 branch, so fix PC (NIA==CIA) for next loop
2677 # (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
2678 # this way we keep repeating the same instruction (with new steps)
2679 self
.pc
.NIA
.value
= self
.pc
.CIA
.value
2680 self
.namespace
['NIA'] = self
.pc
.NIA
2681 log("end of sub-pc call", self
.namespace
['CIA'], self
.namespace
['NIA'])
2682 return False # DO NOT allow PC update whilst Sub-PC loop running
2684 def update_pc_next(self
):
2685 # UPDATE program counter
2686 self
.pc
.update(self
.namespace
, self
.is_svp64_mode
)
2687 #self.svstate.spr = self.namespace['SVSTATE']
2688 log("end of call", self
.namespace
['CIA'],
2689 self
.namespace
['NIA'],
2690 self
.namespace
['SVSTATE'])
2692 def svp64_reset_loop(self
):
2693 self
.svstate
.srcstep
= 0
2694 self
.svstate
.dststep
= 0
2695 self
.svstate
.ssubstep
= 0
2696 self
.svstate
.dsubstep
= 0
2697 self
.loopend
= False
2698 log(" svstate.srcstep loop end (PC to update)")
2699 self
.namespace
['SVSTATE'] = self
.svstate
2701 def update_nia(self
):
2702 self
.pc
.update_nia(self
.is_svp64_mode
)
2703 self
.namespace
['NIA'] = self
.pc
.NIA
2707 """Decorator factory.
2709 this decorator will "inject" variables into the function's namespace,
2710 from the *dictionary* in self.namespace. it therefore becomes possible
2711 to make it look like a whole stack of variables which would otherwise
2712 need "self." inserted in front of them (*and* for those variables to be
2713 added to the instance) "appear" in the function.
2715 "self.namespace['SI']" for example becomes accessible as just "SI" but
2716 *only* inside the function, when decorated.
2718 def variable_injector(func
):
2720 def decorator(*args
, **kwargs
):
2722 func_globals
= func
.__globals
__ # Python 2.6+
2723 except AttributeError:
2724 func_globals
= func
.func_globals
# Earlier versions.
2726 context
= args
[0].namespace
# variables to be injected
2727 saved_values
= func_globals
.copy() # Shallow copy of dict.
2728 log("globals before", context
.keys())
2729 func_globals
.update(context
)
2730 result
= func(*args
, **kwargs
)
2731 log("globals after", func_globals
['CIA'], func_globals
['NIA'])
2732 log("args[0]", args
[0].namespace
['CIA'],
2733 args
[0].namespace
['NIA'],
2734 args
[0].namespace
['SVSTATE'])
2735 if 'end_loop' in func_globals
:
2736 log("args[0] end_loop", func_globals
['end_loop'])
2737 args
[0].namespace
= func_globals
2738 #exec (func.__code__, func_globals)
2741 # func_globals = saved_values # Undo changes.
2747 return variable_injector