From c92b36e7bb5139373d820a5462770fd6b49cc2bf Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 25 Jun 2021 19:18:35 +0100 Subject: [PATCH] identify SVP64 LD bit-reverse pattern as pseudo-assembler 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 | 12 ------ openpower/isatables/svldst_major.csv | 13 ------- src/openpower/sv/sv_analysis.py | 2 + src/openpower/sv/trans/svp64.py | 54 ++++++++++++++++++++++++-- 4 files changed, 53 insertions(+), 28 deletions(-) delete mode 100644 openpower/isatables/svldst_major.csv diff --git a/openpower/isatables/LDSTRM-2P-2S1D.csv b/openpower/isatables/LDSTRM-2P-2S1D.csv index ee2484c6..9d489ad7 100644 --- a/openpower/isatables/LDSTRM-2P-2S1D.csv +++ b/openpower/isatables/LDSTRM-2P-2S1D.csv @@ -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 index 48231e1a..00000000 --- a/openpower/isatables/svldst_major.csv +++ /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, diff --git a/src/openpower/sv/sv_analysis.py b/src/openpower/sv/sv_analysis.py index 175c3925..4d1f7af6 100644 --- a/src/openpower/sv/sv_analysis.py +++ b/src/openpower/sv/sv_analysis.py @@ -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: diff --git a/src/openpower/sv/trans/svp64.py b/src/openpower/sv/trans/svp64.py index c1fca225..de30a385 100644 --- a/src/openpower/sv/trans/svp64.py +++ b/src/openpower/sv/trans/svp64.py @@ -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)) -- 2.30.2