From 379cc6df93eec26dae0fc523b18a1996f1e90d97 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 17 Mar 2021 15:20:02 +0000 Subject: [PATCH] add SVP64 INT-style predication to ISACaller --- src/soc/consts.py | 1 + src/soc/decoder/isa/caller.py | 82 ++++++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/soc/consts.py b/src/soc/consts.py index bdfca569..76b16f2b 100644 --- a/src/soc/consts.py +++ b/src/soc/consts.py @@ -212,6 +212,7 @@ SVP64P_SIZE = 24 class SVP64CROffs: CR0 = 0 # TODO: increase when CRs are expanded to 128 CR1 = 1 # TODO: increase when CRs are expanded to 128 + CRPred = 4 # TODO: increase when CRs are expanded to 128 class SVP64MODEb: diff --git a/src/soc/decoder/isa/caller.py b/src/soc/decoder/isa/caller.py index 2bc5b640..9f3cfc1b 100644 --- a/src/soc/decoder/isa/caller.py +++ b/src/soc/decoder/isa/caller.py @@ -21,12 +21,15 @@ from soc.decoder.selectable_int import (FieldSelectableInt, SelectableInt, selectconcat) from soc.decoder.power_enums import (spr_dict, spr_byname, XER_bits, insns, MicrOp, In1Sel, In2Sel, In3Sel, - OutSel, CROutSel) + OutSel, CROutSel, + SVP64RMMode, SVP64PredMode, + SVP64PredInt, SVP64PredCR) from soc.decoder.power_enums import SVPtype from soc.decoder.helpers import exts, gtu, ltu, undefined from soc.consts import PIb, MSRb # big-endian (PowerISA versions) +from soc.consts import SVP64CROffs from soc.decoder.power_svp64 import SVP64RM, decode_extra from soc.decoder.isa.radixmmu import RADIX @@ -204,6 +207,27 @@ SV64P_MAJOR_SIZE = len(SVP64PrefixFields().major.br) SV64P_PID_SIZE = len(SVP64PrefixFields().pid.br) SV64P_RM_SIZE = len(SVP64PrefixFields().rm.br) +# decode SVP64 predicate integer to reg number and invert +def get_predint(gpr, mask): + r10 = gpr(10) + r30 = gpr(30) + if mask == SVP64PredInt.ALWAYS.value: + return 0xffff_ffff_ffff_ffff + if mask == SVP64PredInt.R3_UNARY.value: + return 1 << (gpr(3).value & 0b111111) + if mask == SVP64PredInt.R3.value: + return gpr(3).value + if mask == SVP64PredInt.R3_N.value: + return ~gpr(3).value + if mask == SVP64PredInt.R10.value: + return gpr(10).value + if mask == SVP64PredInt.R10_N.value: + return ~gpr(10).value + if mask == SVP64PredInt.R30.value: + return gpr(30).value + if mask == SVP64PredInt.R30_N.value: + return ~gpr(30).value + class SPR(dict): def __init__(self, dec2, initial_sprs={}): @@ -864,6 +888,44 @@ class ISACaller: print ("SVP64: VL, srcstep, sv_a_nz, in1", vl, srcstep, sv_a_nz, in1) + # get predicate mask + srcmask = dstmask = 0xffff_ffff_ffff_ffff + if self.is_svp64_mode: + pmode = yield self.dec2.rm_dec.predmode + sv_ptype = yield self.dec2.dec.op.SV_Ptype + srcpred = yield self.dec2.rm_dec.srcpred + dstpred = yield self.dec2.rm_dec.dstpred + if pmode == SVP64PredMode.INT.value: + srcmask = dstmask = get_predint(self.gpr, dstpred) + if sv_ptype == SVPtype.P2.value: + srcmask = get_predint(srcpred) + print (" pmode", pmode) + print (" ptype", sv_ptype) + print (" srcmask", bin(srcmask)) + print (" dstmask", bin(dstmask)) + + # okaaay, so here we simply advance srcstep (TODO dststep) + # until the predicate mask has a "1" bit... or we run out of VL + # let srcstep==VL be the indicator to move to next instruction + while (((1<