identify SVP64 LD bit-reverse pattern as pseudo-assembler
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 25 Jun 2021 18:18:35 +0000 (19:18 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 25 Jun 2021 18:18:35 +0000 (19:18 +0100)
rewrite it before it gets too far into SVP64Asm
morph any "sv.ldxxxxbr" into "sv.ld/br" and rewrite the fields

openpower/isatables/LDSTRM-2P-2S1D.csv
openpower/isatables/svldst_major.csv [deleted file]
src/openpower/sv/sv_analysis.py
src/openpower/sv/trans/svp64.py

index ee2484c6db2fe4186a8d10fed53a88baaef14da4..9d489ad7379492fa9e98e4fbf3d0bea3eb6e782b 100644 (file)
@@ -20,24 +20,12 @@ lbzcix,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,RB,0,RT,0,0,0
 lfiwax,,2P,EXTRA2,d:FRT,s:RA,s:RB,0,RA_OR_ZERO,RB,0,FRT,0,0,0
 ldcix,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,RB,0,RT,0,0,0
 lfiwzx,,2P,EXTRA2,d:FRT,s:RA,s:RB,0,RA_OR_ZERO,RB,0,FRT,0,0,0
-lwzbr,SVP64BREV,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
-lbzbr,SVP64BREV,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
 stwu,,2P,EXTRA2,d:RA,s:RS,s:RA,0,RA_OR_ZERO,0,RS,0,0,0,RA
 stbu,,2P,EXTRA2,d:RA,s:RS,s:RA,0,RA_OR_ZERO,0,RS,0,0,0,RA
-lhzbr,SVP64BREV,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
-lhabr,SVP64BREV,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
 sthu,,2P,EXTRA2,d:RA,s:RS,s:RA,0,RA_OR_ZERO,0,RS,0,0,0,RA
-lfsbr,SVP64BREV,2P,EXTRA2,d:FRT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,FRT,0,0,0
-lfdbr,SVP64BREV,2P,EXTRA2,d:FRT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,FRT,0,0,0
 stfsu,,2P,EXTRA2,d:RA,s:FRS,s:RA,0,RA,0,FRS,0,0,0,RA
 stfdu,,2P,EXTRA2,d:RA,s:FRS,s:RA,0,RA,0,FRS,0,0,0,RA
 stdu,,2P,EXTRA2,d:RA,s:RS,s:RA,0,RA_OR_ZERO,0,RS,0,0,0,RA
-lwz,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
-lbz,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
-lhz,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
-lha,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
-lfs,,2P,EXTRA2,d:FRT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,FRT,0,0,0
-lfd,,2P,EXTRA2,d:FRT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,FRT,0,0,0
 ld,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
 lwa,,2P,EXTRA2,d:RT,s:RA,s:RB,0,RA_OR_ZERO,0,RC,RT,0,0,0
 ldux,,2P,EXTRA2,d:RT,d:RA,s:RB,0,RA_OR_ZERO,RB,0,RT,0,0,RA
diff --git a/openpower/isatables/svldst_major.csv b/openpower/isatables/svldst_major.csv
deleted file mode 100644 (file)
index 48231e1..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry out,ldst len,BR,sgn ext,upd,rsrv,32b,sgn,rc,lk,sgl pipe,comment,form,CONDITIONS
-34,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is1B,0,0,0,0,0,0,NONE,0,1,lbz,SVD,
-35,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is1B,0,0,1,0,0,0,NONE,0,1,lbzu,SVD,
-50,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,FRT,NONE,NONE,0,0,ZERO,0,is8B,0,0,0,0,0,0,NONE,0,1,lfd,SVD,
-51,LDST,OP_LOAD,RA,CONST_SVD,RC,FRT,NONE,NONE,0,0,ZERO,0,is8B,0,0,1,0,0,0,NONE,0,1,lfdu,SVD,
-48,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,FRT,NONE,NONE,0,0,ZERO,0,is4B,0,0,0,0,1,0,NONE,0,1,lfs,SVD,
-49,LDST,OP_LOAD,RA,CONST_SVD,RC,FRT,NONE,NONE,0,0,ZERO,0,is4B,0,0,1,0,1,0,NONE,0,1,lfsu,SVD,
-42,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is2B,0,1,0,0,0,0,NONE,0,1,lha,SVD,
-43,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is2B,0,1,1,0,0,0,NONE,0,1,lhau,SVD,
-40,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is2B,0,0,0,0,0,0,NONE,0,1,lhz,SVD,
-41,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is2B,0,0,1,0,0,0,NONE,0,1,lhzu,SVD,
-32,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is4B,0,0,0,0,0,0,NONE,0,1,lwz,SVD,
-33,LDST,OP_LOAD,RA_OR_ZERO,CONST_SVD,RC,RT,NONE,NONE,0,0,ZERO,0,is4B,0,0,1,0,0,0,NONE,0,1,lwzu,SVD,
index 175c3925123e1f3cb33bdda01ec49c765fce455a..4d1f7af6c8156252e25d79509819358340b12df8 100644 (file)
@@ -201,6 +201,8 @@ def process_csvs():
             insn_name = row['comment']
             condition = row['CONDITIONS']
             # skip instructions that are not suitable
+            if insn_name.startswith("l") and insn_name.endswith("br"):
+                continue # skip pseudo-alias lxxxbr
             if insn_name in ['mcrxr', 'mcrxrx', 'darn']:
                 continue
             if insn_name.startswith('bc') or 'rfid' in insn_name:
index c1fca22543e5665afe0443827d4579048bcd9b67..de30a3854b750d7efbc85b1acc7bbc93824ba8eb 100644 (file)
@@ -210,9 +210,51 @@ class SVP64Asm:
         if rc_mode:
             v30b_op = v30b_op[:-1]
 
+        # sigh again, have to recognised LD/ST bit-reverse instructions
+        # this has to be "processed" to fit into a v3.0B without the "br"
+        # e.g. ldbr is actually ld
+        ldst_bitreverse = v30b_op.startswith("l") and v30b_op.endswith("br")
+
         if v30b_op not in isa.instr:
             raise Exception("opcode %s of '%s' not supported" % \
                             (v30b_op, insn))
+
+        if ldst_bitreverse:
+            # okaay we need to process the fields and make this:
+            #     ldbr RT, SVD(RA), RC  - 11 bits for SVD, 5 for RC
+            # into this:
+            #     ld RT, D(RA)          - 16 bits
+            # likewise same for SVDS (9 bits for SVDS, 5 for RC, 14 bits for DS)
+            form = isa.instr[v30b_op].form # get form (SVD-Form, SVDS-Form)
+
+            newfields = []
+            for field in fields:
+                # identify if this is a ld/st immediate(reg) thing
+                ldst_imm = "(" in field and field[-1] == ')'
+                if ldst_imm:
+                    newfields.append(field[:-1].split("("))
+                else:
+                    newfields.append(field)
+
+            immed, RA = newfields[1]
+            immed = int(immed)
+            RC = int(newfields.pop(2)) # better be an integer number!
+            if form == 'SVD': # 16 bit: immed 11 bits, RC shift up 11
+                immed = (immed & 0b11111111111) | (RC<<11)
+                if immed & (1<<15): # should be negative
+                    immed -= 1<<16
+            if form == 'SVDS': # 14 bit: immed 9 bits, RC shift up 9
+                immed = (immed & 0b111111111) | (RC<<9)
+                if immed & (1<<13): # should be negative
+                    immed -= 1<<14
+            newfields[1] = "%d(%s)" % (immed, RA)
+            fields = newfields
+
+            # and strip off "br" from end, and add "br" to opmodes, instead
+            v30b_op = v30b_op[:-2]
+            opmodes.append("br")
+            log ("rewritten", v30b_op, opmodes, fields)
+
         if v30b_op not in svp64.instrs:
             raise Exception("opcode %s of '%s' not an svp64 instruction" % \
                             (v30b_op, insn))
@@ -481,7 +523,6 @@ class SVP64Asm:
 
         mapreduce = False
         reverse_gear = False
-        bitreverse = False
         mapreduce_crm = False
         mapreduce_svm = False
 
@@ -512,7 +553,7 @@ class SVP64Asm:
                 has_smask = True
             # bitreverse LD/ST
             elif encmode.startswith("br"):
-                bitreverse = True
+                ldst_bitreverse = True
             # vec2/3/4
             elif encmode.startswith("vec"):
                 subvl = decode_subvl(encmode[3:])
@@ -610,6 +651,11 @@ class SVP64Asm:
             assert has_pmask or mask_m_specified, \
                 "dest zeroing requires a dest predicate"
 
+        # check LDST bitreverse, only available in "normal" mode
+        if is_ldst and ldst_bitreverse:
+            assert sv_mode is None, \
+                "LD bit-reverse cannot have modes (%s) applied" % sv_mode
+
         ######################################
         # "normal" mode
         if sv_mode is None:
@@ -619,7 +665,7 @@ class SVP64Asm:
                 # TODO: for now, LD/ST-indexed is ignored.
                 mode |= ldst_elstride << SVP64MODE.ELS_NORMAL # element-strided
                 # bitreverse mode
-                if bitreverse:
+                if ldst_bitreverse:
                     mode |= 1 << SVP64MODE.LDST_BITREV
             else:
                 # TODO, reduce and subvector mode
@@ -744,6 +790,7 @@ class SVP64Asm:
         # fiinally yield the svp64 prefix and the thingy.  v3.0b opcode
         rc = '.' if rc_mode else ''
         yield ".long 0x%x" % svp64_prefix.insn.value
+        log(v30b_newfields)
         yield "%s %s" % (v30b_op+rc, ", ".join(v30b_newfields))
         log ("new v3.0B fields", v30b_op, v30b_newfields)
 
@@ -891,6 +938,7 @@ if __name__ == '__main__':
     lst = [
              'sv.addi win2.v, win.v, -1',
              'sv.add./mrr 5.v, 2.v, 1.v',
+             'sv.lhzbr 5.v, 11(9.v), 15',
     ]
     isa = SVP64Asm(lst, macros=macros)
     print ("list", list(isa))