+ # rc and oe out
+ comb += self.do_copy("rc", dec_rc.rc_out)
+ comb += self.do_copy("oe", dec_oe.oe_out)
+
+ # CR in/out
+ comb += self.do_copy("read_cr_whole", self.dec_cr_in.whole_reg)
+ comb += self.do_copy("write_cr_whole", self.dec_cr_out.whole_reg)
+ comb += self.do_copy("write_cr0", self.dec_cr_out.cr_bitfield.ok)
+
+ comb += self.do_copy("input_cr", self.op_get("cr_in")) # CR in
+ comb += self.do_copy("output_cr", self.op_get("cr_out")) # CR out
+
+ # decoded/selected instruction flags
+ comb += self.do_copy("data_len", self.op_get("ldst_len"))
+ comb += self.do_copy("invert_in", self.op_get("inv_a"))
+ comb += self.do_copy("invert_out", self.op_get("inv_out"))
+ comb += self.do_copy("input_carry", self.op_get("cry_in"))
+ comb += self.do_copy("output_carry", self.op_get("cry_out"))
+ comb += self.do_copy("is_32bit", self.op_get("is_32b"))
+ comb += self.do_copy("is_signed", self.op_get("sgn"))
+ lk = self.op_get("lk")
+ if lk is not None:
+ with m.If(lk):
+ comb += self.do_copy("lk", self.dec.LK) # XXX TODO: accessor
+
+ comb += self.do_copy("byte_reverse", self.op_get("br"))
+ comb += self.do_copy("sign_extend", self.op_get("sgn_ext"))
+ comb += self.do_copy("ldst_mode", self.op_get("upd")) # LD/ST mode
+
+ return m
+
+
+class PowerDecode2(PowerDecodeSubset):
+ """PowerDecode2: the main instruction decoder.
+
+ whilst PowerDecode is responsible for decoding the actual opcode, this
+ module encapsulates further specialist, sparse information and
+ expansion of fields that is inconvenient to have in the CSV files.
+ for example: the encoding of the immediates, which are detected
+ and expanded out to their full value from an annotated (enum)
+ representation.
+
+ implicit register usage is also set up, here. for example: OP_BC
+ requires implicitly reading CTR, OP_RFID requires implicitly writing
+ to SRR1 and so on.
+
+ in addition, PowerDecoder2 is responsible for detecting whether
+ instructions are illegal (or privileged) or not, and instead of
+ just leaving at that, *replacing* the instruction to execute with
+ a suitable alternative (trap).
+
+ LDSTExceptions are done the cycle _after_ they're detected (after
+ they come out of LDSTCompUnit). basically despite the instruction
+ being decoded, the results of the decode are completely ignored
+ and "exception.happened" used to set the "actual" instruction to
+ "OP_TRAP". the LDSTException data structure gets filled in,
+ in the CompTrapOpSubset and that's what it fills in SRR.
+
+ to make this work, TestIssuer must notice "exception.happened"
+ after the (failed) LD/ST and copies the LDSTException info from
+ the output, into here (PowerDecoder2). without incrementing PC.
+ """
+
+ def __init__(self, dec, opkls=None, fn_name=None, final=False, state=None):
+ super().__init__(dec, opkls, fn_name, final, state)
+ self.exc = LDSTException("dec2_exc")
+
+ def get_col_subset(self, opkls):
+ subset = super().get_col_subset(opkls)
+ subset.add("asmcode")
+ subset.add("in1_sel")
+ subset.add("in2_sel")
+ subset.add("in3_sel")
+ subset.add("out_sel")
+ subset.add("sv_in1")
+ subset.add("sv_in2")
+ subset.add("sv_in3")
+ subset.add("sv_out")
+ subset.add("SV_Etype")
+ subset.add("SV_Ptype")
+ subset.add("lk")
+ subset.add("internal_op")
+ subset.add("form")
+ return subset