corrections to SVP64 Branch Conditional
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 11 Aug 2021 16:00:28 +0000 (17:00 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 11 Aug 2021 16:00:28 +0000 (17:00 +0100)
add special extra fields for sv.bc* in ISACaller namespace

openpower/isa/svbranch.mdwn [new file with mode: 0644]
src/openpower/consts.py
src/openpower/decoder/isa/caller.py
src/openpower/decoder/power_svp64_rm.py

diff --git a/openpower/isa/svbranch.mdwn b/openpower/isa/svbranch.mdwn
new file mode 100644 (file)
index 0000000..7caa7d3
--- /dev/null
@@ -0,0 +1,100 @@
+<!-- Instructions here part of Draft SVP64 Vectorised Branch -->
+
+<!-- Section 2.4 Branch Instructions. Pages 33 - 39 -->
+
+<!-- The sequence of instruction execution can be changed by the Branch -->
+<!-- instructions. Because all instructions are on word boundaries, bits 62 and 63 -->
+<!-- of the generated branch target address are ignored by the processor in -->
+<!-- performing the branch. -->
+
+<!-- target_addr specifies the branch target address. -->
+
+<!-- If AA=0 then the branch target address is the sum of LI || 0b00 sign-extended -->
+<!-- and the address of this instruction, with the high-order 32 bits of the branch -->
+<!-- target address set to 0 in 32-bit mode. -->
+
+<!-- If AA=1 then the branch target address is the value LI || 0b00 sign-extended, -->
+<!-- with the high-order 32 bits of the branch target address set to 0 in 32-bit -->
+<!-- mode. -->
+
+<!-- If LK=1 then the effective address of the instruction following the Branch -->
+<!-- instruction is placed into the Link Register. -->
+
+# 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)
+
index 08b9a6112bf22b668e0f1270af2cedf001cba9ca..934b4389b1b2279dc612f4ab04c93dfc080eb631 100644 (file)
@@ -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
index 413494ca0a3d952c1c10fd0420eda7116694c141..8673d9957021954c5ca842afb887cf839309cb8f 100644 (file)
@@ -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) +
index 9af4c1fda24ea993d17822762558499e140e51f5..81527ad5a84b285856a5a11237d443881b94c69d 100644 (file)
@@ -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():