From: Luke Kenneth Casson Leighton Date: Wed, 11 Aug 2021 16:00:28 +0000 (+0100) Subject: corrections to SVP64 Branch Conditional X-Git-Tag: xlen-bcd~142 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=441840b083c68177b6987831f096f3dbe1892b2e;p=openpower-isa.git corrections to SVP64 Branch Conditional add special extra fields for sv.bc* in ISACaller namespace --- diff --git a/openpower/isa/svbranch.mdwn b/openpower/isa/svbranch.mdwn new file mode 100644 index 00000000..7caa7d3f --- /dev/null +++ b/openpower/isa/svbranch.mdwn @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + +# Branch Conditional + +B-Form + +* sv.bc BO,BI,target_addr (AA=0 LK=0) +* sv.bca BO,BI,target_addr (AA=1 LK=0) +* sv.bcl BO,BI,target_addr (AA=0 LK=1) +* sv.bcla BO,BI,target_addr (AA=1 LK=1) + +Pseudo-code: + + # get SVP64 extended CR field 0..127 + # SVCRf = sVP64EXTRA(BI>>2) + # if svstep_mode then + # new_srcstep, CRbits = SVSTATE_NEXT(srcstep) + # else + # CRbits = CR{SVCRf} + # select predicate bit or zero/one + # XXX if predicate[srcstep] then + # XXX if BRc = 1 then # CR0 vectorised + # XXX CR{SVCRf+srcstep} = CRbits + # XXX testbit = CRbits[BI & 0b11] + if sz then + testbit = SNZ + else + testbit <- CR[BI+32] + # actual element test here + cond_ok <- BO[0] | ¬(testbit ^ BO[1]) + # test for VL to be set (and exit) + if VLSET & (cond_ok = VSb) then + if VLI then + SVSTATE[7:13] <- (srcstep+1) + else + SVSTATE[7:13] <- srcstep+1 + # XXX if svstep_mode then + # XXX SVSTATE.srcstep = new_srcstep + # actual branch + if (mode_is_64bit) then M <- 0 + else M <- 32 + if ¬BO[2] then CTR <- CTR - 1 + ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3]) + lr_ok <- LRu + if ctr_ok & cond_ok then + if AA then NIA <-iea EXTS(BD || 0b00) + else NIA <-iea CIA + EXTS(BD || 0b00) + lr_ok <- 0b1 + if LK & lr_ok then LR <-iea CIA + 4 + +Special Registers Altered: + + CTR (if BO2=0) + LR (if LK=1) + +# Branch Conditional to Link Register + +XL-Form + +* sv.bclr BO,BI,BH (LK=0) +* sv.bclrl BO,BI,BH (LK=1) + +Pseudo-code: + + if (mode_is_64bit) then M <- 0 + else M <- 32 + if ¬BO[2] then CTR <- CTR - 1 + ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3]) + cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1]) + lr_ok <- LRu + if ctr_ok & cond_ok then + NIA <-iea LR[0:61] || 0b00 + lr_ok <- 0b1 + if LK & lr_ok then LR <-iea CIA + 4 + +Special Registers Altered: + + CTR (if BO2=0) + LR (if LK=1) + diff --git a/src/openpower/consts.py b/src/openpower/consts.py index 08b9a611..934b4389 100644 --- a/src/openpower/consts.py +++ b/src/openpower/consts.py @@ -229,6 +229,8 @@ class SVP64MODEb: # for branch-conditional BC_SNZ = 3 # for branch-conditional mode BC_VLI = 2 # for VL include/exclude on VLSET mode + BC_VLSET = 1 # VLSET mode + BC_SVSTEP = 0 # svstep mode # reduce mode REDUCE = 2 # 0=normal predication 1=reduce mode PARALLEL = 3 # 1=parallel reduce, 0=scalar reduce diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 413494ca..8673d995 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -30,7 +30,9 @@ from openpower.decoder.power_enums import SVPtype from openpower.decoder.helpers import (exts, gtu, ltu, undefined) from openpower.consts import PIb, MSRb # big-endian (PowerISA versions) -from openpower.consts import SVP64CROffs +from openpower.consts import (SVP64MODE, + SVP64CROffs, + ) from openpower.decoder.power_svp64 import SVP64RM, decode_extra from openpower.decoder.isa.radixmmu import RADIX @@ -720,7 +722,7 @@ class ISACaller: def memassign(self, ea, sz, val): self.mem.memassign(ea, sz, val) - def prep_namespace(self, formname, op_fields): + def prep_namespace(self, insn_name, formname, op_fields): # TODO: get field names from form in decoder*1* (not decoder2) # decoder2 is hand-created, and decoder1.sigform is auto-generated # from spec @@ -752,6 +754,19 @@ class ISACaller: self.namespace['VL'] = vl self.namespace['srcstep'] = srcstep + # sv.bc* need some extra fields + if self.is_svp64_mode and insn_name.startswith("bc"): + # blegh grab bits manually + mode = yield self.dec2.rm_dec.rm_in.mode + bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0 + bc_vli = (mode & SVP64MODE.BC_VLI) != 0 + bc_vsb = yield self.dec2.rm_dec.bc_vsb + bc_lru = yield self.dec2.rm_dec.bc_lru + self.namespace['VSb'] = SelectableInt(bc_vsb, 1) + self.namespace['LRu'] = SelectableInt(bc_lru, 1) + self.namespace['VLSET'] = SelectableInt(bc_vlset, 1) + self.namespace['VLI'] = SelectableInt(bc_vli, 1) + def handle_carry_(self, inputs, outputs, already_done): inv_a = yield self.dec2.e.do.invert_in if inv_a: @@ -1180,7 +1195,7 @@ class ISACaller: return info = self.instrs[ins_name] - yield from self.prep_namespace(info.form, info.op_fields) + yield from self.prep_namespace(ins_name, info.form, info.op_fields) # preserve order of register names input_names = create_args(list(info.read_regs) + diff --git a/src/openpower/decoder/power_svp64_rm.py b/src/openpower/decoder/power_svp64_rm.py index 9af4c1fd..81527ad5 100644 --- a/src/openpower/decoder/power_svp64_rm.py +++ b/src/openpower/decoder/power_svp64_rm.py @@ -142,13 +142,13 @@ class SVP64RMModeDecode(Elaboratable): with m.If(is_bc): # Branch-Conditional is completely different # svstep mode - with m.If(mode2[0]): + with m.If(mode[SVP64MODE.BC_SVSTEP]): with m.If(self.rm_in.ewsrc[0]): comb += self.bc_step.eq(SVP64BCStep.STEP_RC) with m.Else(): comb += self.bc_step.eq(SVP64BCStep.STEP) # VLSET mode - with m.If(mode2[1]): + with m.If(mode[SVP64MODE.BC_VLSET]): with m.If(mode[SVP64MODE.BC_VLI]): comb += self.bc_vlset.eq(SVP64BCVLSETMode.VL_INCL) with m.Else():