from openpower.decoder.power_svp64_prefix import SVP64PrefixDecoder
from openpower.decoder.power_svp64_extra import SVP64CRExtra, SVP64RegExtra
-from openpower.decoder.power_svp64_rm import SVP64RMModeDecode
+from openpower.decoder.power_svp64_rm import (SVP64RMModeDecode,
+ sv_input_record_layout)
+from openpower.sv.svp64 import SVP64Rec
+
from openpower.decoder.power_regspec_map import regspec_decode_read
-from openpower.decoder.power_regspec_map import regspec_decode_write
from openpower.decoder.power_decoder import create_pdecode
from openpower.decoder.power_enums import (MicrOp, CryIn, Function,
CRInSel, CROutSel,
RC, LDSTMode,
SVEXTRA, SVEtype, SVPtype)
from openpower.decoder.decode2execute1 import (Decode2ToExecute1Type, Data,
- Decode2ToOperand)
-from openpower.sv.svp64 import SVP64Rec
+ Decode2ToOperand)
+
from openpower.consts import (MSR, SPEC, EXTRA2, EXTRA3, SVP64P, field,
- SPEC_SIZE, SPECb, SPEC_AUG_SIZE, SVP64CROffs)
+ SPEC_SIZE, SPECb, SPEC_AUG_SIZE, SVP64CROffs,
+ FastRegsEnum, XERRegsEnum, TT)
-from soc.regfile.regfiles import FastRegs
-from openpower.consts import TT
from openpower.state import CoreState
-
-# XXX these have to go
-from soc.regfile.util import spr_to_fast
-from soc.regfile.regfiles import XERRegs
-
+from openpower.util import spr_to_fast
def decode_spr_num(spr):
with m.Case(MicrOp.OP_BC):
with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
# constant: CTR
- comb += self.fast_out.data.eq(FastRegs.CTR)
+ comb += self.fast_out.data.eq(FastRegsEnum.CTR)
comb += self.fast_out.ok.eq(1)
with m.Case(MicrOp.OP_BCREG):
xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
xo5 = self.dec.FormXL.XO[5] # 3.0B p38
with m.If(xo9 & ~xo5):
# constant: CTR
- comb += self.fast_out.data.eq(FastRegs.CTR)
+ comb += self.fast_out.data.eq(FastRegsEnum.CTR)
comb += self.fast_out.ok.eq(1)
# MFSPR move from SPRs
xo9 = self.dec.FormXL.XO[9] # 3.0B p38 top bit of XO
xo5 = self.dec.FormXL.XO[5] # 3.0B p38
with m.If(~xo9):
- comb += self.fast_out.data.eq(FastRegs.LR)
+ comb += self.fast_out.data.eq(FastRegsEnum.LR)
comb += self.fast_out.ok.eq(1)
with m.Elif(xo5):
- comb += self.fast_out.data.eq(FastRegs.TAR)
+ comb += self.fast_out.data.eq(FastRegsEnum.TAR)
comb += self.fast_out.ok.eq(1)
return m
with m.Case(MicrOp.OP_BC, MicrOp.OP_BCREG):
with m.If(~self.dec.BO[2]): # 3.0B p38 BO2=0, use CTR reg
# constant: CTR
- comb += self.fast_out.data.eq(FastRegs.CTR)
+ comb += self.fast_out.data.eq(FastRegsEnum.CTR)
comb += self.fast_out.ok.eq(1)
# RFID 1st spr (fast)
with m.Case(MicrOp.OP_RFID):
- comb += self.fast_out.data.eq(FastRegs.SRR0) # constant: SRR0
+ comb += self.fast_out.data.eq(FastRegsEnum.SRR0) # SRR0
comb += self.fast_out.ok.eq(1)
return m
self.insn_in = Signal(32, reset_less=True)
self.reg_out = Data(5, "reg_o2")
self.fast_out = Data(3, "fast_o2")
+ self.fast_out3 = Data(3, "fast_o3")
def elaborate(self, platform):
m = Module()
# BC* implicit register (LR)
with m.Case(MicrOp.OP_BC, MicrOp.OP_B, MicrOp.OP_BCREG):
with m.If(self.lk): # "link" mode
- comb += self.fast_out.data.eq(FastRegs.LR) # constant: LR
+ comb += self.fast_out.data.eq(FastRegsEnum.LR) # LR
comb += self.fast_out.ok.eq(1)
- # RFID 2nd spr (fast)
+ # RFID 2nd and 3rd spr (fast)
with m.Case(MicrOp.OP_RFID):
- comb += self.fast_out.data.eq(FastRegs.SRR1) # constant: SRR1
+ comb += self.fast_out.data.eq(FastRegsEnum.SRR1) # SRR1
comb += self.fast_out.ok.eq(1)
+ comb += self.fast_out3.data.eq(FastRegsEnum.SVSRR0) # SVSRR0
+ comb += self.fast_out3.ok.eq(1)
return m
# to be decoded (this includes the single bit names)
record_names = {'insn_type': 'internal_op',
'fn_unit': 'function_unit',
+ 'SV_Ptype': 'SV_Ptype',
'rc': 'rc_sel',
'oe': 'rc_sel',
'zero_a': 'in1_sel',
self.regreduce_en = regreduce_en
if svp64_en:
self.sv_rm = SVP64Rec(name="dec_svp64") # SVP64 RM field
+ self.rm_dec = SVP64RMModeDecode("svp64_rm_dec")
self.sv_a_nz = Signal(1)
self.final = final
self.opkls = opkls
do = self.e_tmp.do
return hasattr(do, field) and self.op_get(op_field) is not None
- def do_copy(self, field, val, final=False):
+ def do_get(self, field, final=False):
if final or self.final:
do = self.do
else:
do = self.e_tmp.do
- if hasattr(do, field) and val is not None:
- return getattr(do, field).eq(val)
+ return getattr(do, field, None)
+
+ def do_copy(self, field, val, final=False):
+ df = self.do_get(field, final)
+ if df is not None and val is not None:
+ return df.eq(val)
return []
def op_get(self, op_field):
comb = m.d.comb
state = self.state
op, do = self.dec.op, self.do
- msr, cia = state.msr, state.pc
+ msr, cia, svstate = state.msr, state.pc, state.svstate
# fill in for a normal instruction (not an exception)
# copy over if non-exception, non-privileged etc. is detected
if not self.final:
m.submodules.dec_rc = self.dec_rc = dec_rc = DecodeRC(self.dec)
m.submodules.dec_oe = dec_oe = DecodeOE(self.dec)
+ if self.svp64_en:
+ # and SVP64 RM mode decoder
+ m.submodules.sv_rm_dec = rm_dec = self.rm_dec
+
# copy instruction through...
for i in [do.insn, dec_rc.insn_in, dec_oe.insn_in, ]:
comb += i.eq(self.dec.opcode_in)
# copy "state" over
comb += self.do_copy("msr", msr)
comb += self.do_copy("cia", cia)
+ comb += self.do_copy("svstate", svstate)
# set up instruction type
# no op: defaults to OP_ILLEGAL
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
+ if self.svp64_en:
+ # connect up SVP64 RM Mode decoding
+ fn = self.op_get("function_unit")
+ comb += rm_dec.fn_in.eq(fn) # decode needs to know if LD/ST type
+ comb += rm_dec.ptype_in.eq(op.SV_Ptype) # Single/Twin predicated
+ comb += rm_dec.rc_in.eq(rc_out) # Rc=1
+ comb += rm_dec.rm_in.eq(self.sv_rm) # SVP64 RM mode
+
# 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("sign_extend", self.op_get("sgn_ext"))
comb += self.do_copy("ldst_mode", self.op_get("upd")) # LD/ST mode
+ # copy over SVP64 input record fields (if they exist)
+ if self.svp64_en:
+ # TODO, really do we have to do these explicitly?? sigh
+ #for (field, _) in sv_input_record_layout:
+ # comb += self.do_copy(field, self.rm_dec.op_get(field))
+ comb += self.do_copy("sv_pred_sz", self.rm_dec.pred_sz)
+ comb += self.do_copy("sv_pred_dz", self.rm_dec.pred_dz)
+ comb += self.do_copy("sv_saturate", self.rm_dec.saturate)
+ comb += self.do_copy("sv_Ptype", self.rm_dec.ptype_in)
return m
state=None, svp64_en=True, regreduce_en=False):
super().__init__(dec, opkls, fn_name, final, state, svp64_en,
regreduce_en=False)
- self.exc = LDSTException("dec2_exc")
+ self.ldst_exc = LDSTException("dec2_exc")
if self.svp64_en:
self.cr_out_isvec = Signal(1, name="cr_out_isvec")
self.no_in_vec = Signal(1, name="no_in_vec") # no inputs vector
self.no_out_vec = Signal(1, name="no_out_vec") # no outputs vector
self.loop_continue = Signal(1, name="loop_continue")
- self.rm_dec = SVP64RMModeDecode("svp64_rm_dec")
else:
self.no_in_vec = Const(1, 1)
self.no_out_vec = Const(1, 1)
subset.add("sv_cr_out")
subset.add("SV_Etype")
subset.add("SV_Ptype")
+ # from SVP64RMModeDecode
+ for (field, _) in sv_input_record_layout:
+ subset.add(field)
subset.add("lk")
subset.add("internal_op")
subset.add("form")
# debug access to crout_svdec (used in get_pdecode_cr_out)
self.crout_svdec = crout_svdec
- # and SVP64 RM mode decoder
- m.submodules.sv_rm_dec = rm_dec = self.rm_dec
-
# get the 5-bit reg data before svp64-munging it into 7-bit plus isvec
reg = Signal(5, reset_less=True)
comb += e.read_spr1.eq(dec_a.spr_out)
comb += e.write_spr.eq(dec_o.spr_out)
- # Fast regs out
+ # Fast regs out including SRR0/1/SVSRR0
comb += e.read_fast1.eq(dec_a.fast_out)
comb += e.read_fast2.eq(dec_b.fast_out)
- comb += e.write_fast1.eq(dec_o.fast_out)
- comb += e.write_fast2.eq(dec_o2.fast_out)
-
- if self.svp64_en:
- # connect up SVP64 RM Mode decoding
- fn = self.op_get("function_unit")
- comb += rm_dec.fn_in.eq(fn) # decode needs to know if LD/ST type
- comb += rm_dec.ptype_in.eq(op.SV_Ptype) # Single/Twin predicated
- comb += rm_dec.rc_in.eq(rc_out) # Rc=1
- comb += rm_dec.rm_in.eq(self.sv_rm) # SVP64 RM mode
+ comb += e.write_fast1.eq(dec_o.fast_out) # SRR0 (OP_RFID)
+ comb += e.write_fast2.eq(dec_o2.fast_out) # SRR1 (ditto)
+ comb += e.write_fast3.eq(dec_o2.fast_out3) # SVSRR0 (ditto)
# sigh this is exactly the sort of thing for which the
# decoder is designed to not need. MTSPR, MFSPR and others need
with m.If(op.internal_op == MicrOp.OP_MFSPR):
comb += e.xer_in.eq(0b111) # SO, CA, OV
with m.If(op.internal_op == MicrOp.OP_CMP):
- comb += e.xer_in.eq(1<<XERRegs.SO) # SO
+ comb += e.xer_in.eq(1<<XERRegsEnum.SO) # SO
with m.If(op.internal_op == MicrOp.OP_MTSPR):
comb += e.xer_out.eq(1)
dec_irq_ok = Signal()
priv_ok = Signal()
illeg_ok = Signal()
- exc = self.exc
+ ldst_exc = self.ldst_exc
comb += ext_irq_ok.eq(ext_irq & msr[MSR.EE]) # v3.0B p944 (MSR.EE)
comb += dec_irq_ok.eq(dec_spr[63] & msr[MSR.EE]) # 6.5.11 p1076
# LD/ST exceptions. TestIssuer copies the exception info at us
# after a failed LD/ST.
- with m.If(exc.happened):
- with m.If(exc.alignment):
+ with m.If(ldst_exc.happened):
+ with m.If(ldst_exc.alignment):
self.trap(m, TT.PRIV, 0x600)
- with m.Elif(exc.instr_fault):
- with m.If(exc.segment_fault):
+ with m.Elif(ldst_exc.instr_fault):
+ with m.If(ldst_exc.segment_fault):
self.trap(m, TT.PRIV, 0x480)
with m.Else():
# pass exception info to trap to create SRR1
- self.trap(m, TT.MEMEXC, 0x400, exc)
+ self.trap(m, TT.MEMEXC, 0x400, ldst_exc)
with m.Else():
- with m.If(exc.segment_fault):
+ with m.If(ldst_exc.segment_fault):
self.trap(m, TT.PRIV, 0x380)
with m.Else():
self.trap(m, TT.PRIV, 0x300)
with m.If((do_out.insn_type == MicrOp.OP_TRAP) |
(do_out.insn_type == MicrOp.OP_SC)):
# TRAP write fast1 = SRR0
- comb += e_out.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
+ comb += e_out.write_fast1.data.eq(FastRegsEnum.SRR0) # SRR0
comb += e_out.write_fast1.ok.eq(1)
# TRAP write fast2 = SRR1
- comb += e_out.write_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
+ comb += e_out.write_fast2.data.eq(FastRegsEnum.SRR1) # SRR1
comb += e_out.write_fast2.ok.eq(1)
+ # TRAP write fast2 = SRR1
+ comb += e_out.write_fast3.data.eq(FastRegsEnum.SVSRR0) # SVSRR0
+ comb += e_out.write_fast3.ok.eq(1)
# RFID: needs to read SRR0/1
with m.If(do_out.insn_type == MicrOp.OP_RFID):
# TRAP read fast1 = SRR0
- comb += e_out.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
+ comb += e_out.read_fast1.data.eq(FastRegsEnum.SRR0) # SRR0
comb += e_out.read_fast1.ok.eq(1)
# TRAP read fast2 = SRR1
- comb += e_out.read_fast2.data.eq(FastRegs.SRR1) # constant: SRR1
+ comb += e_out.read_fast2.data.eq(FastRegsEnum.SRR1) # SRR1
comb += e_out.read_fast2.ok.eq(1)
+ # TRAP read fast2 = SVSRR0
+ comb += e_out.read_fast3.data.eq(FastRegsEnum.SVSRR0) # SVSRR0
+ comb += e_out.read_fast3.ok.eq(1)
# annoying simulator bug
if hasattr(e_out, "asmcode") and hasattr(self.dec.op, "asmcode"):
return m
- def trap(self, m, traptype, trapaddr, exc=None):
+ def trap(self, m, traptype, trapaddr, ldst_exc=None):
"""trap: this basically "rewrites" the decoded instruction as a trap
"""
comb = m.d.comb
comb += self.do_copy("fn_unit", Function.TRAP, True)
comb += self.do_copy("trapaddr", trapaddr >> 4, True) # bottom 4 bits
comb += self.do_copy("traptype", traptype, True) # request type
- comb += self.do_copy("ldst_exc", exc, True) # request type
+ comb += self.do_copy("ldst_exc", ldst_exc, True) # request type
comb += self.do_copy("msr", self.state.msr, True) # copy of MSR "state"
comb += self.do_copy("cia", self.state.pc, True) # copy of PC "state"
+ comb += self.do_copy("svstate", self.state.svstate, True) # SVSTATE