X-Git-Url: https://git.libre-soc.org/?p=soc.git;a=blobdiff_plain;f=src%2Fsoc%2Fsv%2Ftrans%2Fsvp64.py;h=bc28c49b591e290e0d0c503220a57d91e6a0d367;hp=42f0963952c965557b5fa034a840f912db305fde;hb=7b60d5b7a11dd42db5e0d0bf34f165dd58c342ff;hpb=14f535998f425ff56fcb7e7967a77e40a8dbb52d diff --git a/src/soc/sv/trans/svp64.py b/src/soc/sv/trans/svp64.py index 42f09639..bc28c49b 100644 --- a/src/soc/sv/trans/svp64.py +++ b/src/soc/sv/trans/svp64.py @@ -15,11 +15,13 @@ Bugtracker: https://bugs.libre-soc.org/show_bug.cgi?id=578 """ import os, sys +from collections import OrderedDict from soc.decoder.pseudo.pagereader import ISA from soc.decoder.power_enums import get_csv, find_wiki_dir +# identifies register by type def is_CR_3bit(regname): return regname in ['BF', 'BFA'] @@ -28,7 +30,7 @@ def is_CR_5bit(regname): def is_GPR(regname): return regname in ['RA', 'RB', 'RC', 'RS', 'RT'] - + def get_regtype(regname): if is_CR_3bit(regname): return "CR_3bit" @@ -37,7 +39,33 @@ def get_regtype(regname): if is_GPR(regname): return "GPR" +# decode GPR into sv extra +def get_extra_gpr(etype, regmode, field): + if regmode == 'scalar': + # cut into 2-bits 5-bits SS FFFFF + sv_extra = field >> 5 + field = field & 0b11111 + else: + # cut into 5-bits 2-bits FFFFF SS + sv_extra = field & 0b11 + field = field >> 2 + return sv_extra, field + + +# decode 3-bit CR into sv extra +def get_extra_cr_3bit(etype, regmode, field): + if regmode == 'scalar': + # cut into 2-bits 3-bits SS FFF + sv_extra = field >> 3 + field = field & 0b111 + else: + # cut into 3-bits 4-bits FFF SSSS but will cut 2 zeros off later + sv_extra = field & 0b1111 + field = field >> 4 + return sv_extra, field + +# gets SVP64 ReMap information class SVP64RM: def __init__(self): self.instrs = {} @@ -48,6 +76,7 @@ class SVP64RM: self.instrs[entry['insn']] = entry +# decodes svp64 assembly listings and creates EXT001 svp64 prefixes class SVP64: def __init__(self, lst): self.lst = lst @@ -115,14 +144,149 @@ class SVP64: opregfields = zip(fields, v30b_regs) # err that was easy # now for each of those find its place in the EXTRA encoding - extras = {} - for field, regname in opregfields: - extra = svp64_reg_byname[regname] + extras = OrderedDict() + for idx, (field, regname) in enumerate(opregfields): + extra = svp64_reg_byname.get(regname, None) regtype = get_regtype(regname) - extras[extra] = (field, regname, regtype) + extras[extra] = (idx, field, regname, regtype) print (" ", extra, extras[extra]) + # great! got the extra fields in their associated positions: + # also we know the register type. now to create the EXTRA encodings etype = rm['Etype'] # Extra type: EXTRA3/EXTRA2 + extra_bits = 0 + v30b_newfields = [] + for extra_idx, (idx, field, regname, regtype) in extras.items(): + # is it a field we don't alter/examine? if so just put it + # into newfields + if regtype is None: + v30b_newfields.append(field) + + # first, decode the field number. "5.v" or "3.s" or "9" + field = field.split(".") + regmode = 'scalar' # default + if len(field) == 2: + if field[1] == 's': + regmode = 'scalar' + elif field[1] == 'v': + regmode = 'vector' + field = int(field[0]) # actual register number + print (" ", regmode, field, end=" ") + + # XXX TODO: the following is a bit of a laborious repeated + # mess, which could (and should) easily be parameterised. + + # encode SV-GPR field into extra, v3.0field + if regtype == 'GPR': + sv_extra, field = get_extra_gpr(etype, regmode, field) + # now sanity-check. EXTRA3 is ok, EXTRA2 has limits + # (and shrink to a single bit if ok) + if etype == 'EXTRA2': + if regmode == 'scalar': + # range is r0-r63 in increments of 1 + assert (sv_extra >> 1) == 0, \ + "scalar GPR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as scalar + sv_extra = sv_extra & 0b01 + else: + # range is r0-r127 in increments of 4 + assert sv_extra & 0b01 == 0, \ + "vector field %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as vector (bit 2 set) + sv_extra = 0b10 | (sv_extra >> 1) + elif regmode == 'vector': + # EXTRA3 vector bit needs marking + sv_extra |= 0b100 + + # encode SV-CR 3-bit field into extra, v3.0field + elif regtype == 'CR_3bit': + sv_extra, field = get_extra_cr_3bit(etype, regmode, field) + # now sanity-check (and shrink afterwards) + if etype == 'EXTRA2': + if regmode == 'scalar': + # range is CR0-CR15 in increments of 1 + assert (sv_extra >> 1) == 0, \ + "scalar CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as scalar + sv_extra = sv_extra & 0b01 + else: + # range is CR0-CR127 in increments of 16 + assert sv_extra & 0b111 == 0, \ + "vector CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as vector (bit 2 set) + sv_extra = 0b10 | (sv_extra >> 3) + else: + if regmode == 'scalar': + # range is CR0-CR31 in increments of 1 + assert (sv_extra >> 2) == 0, \ + "scalar CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as scalar + sv_extra = sv_extra & 0b11 + else: + # range is CR0-CR127 in increments of 8 + assert sv_extra & 0b11 == 0, \ + "vector CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as vector (bit 3 set) + sv_extra = 0b100 | (sv_extra >> 2) + + # encode SV-CR 5-bit field into extra, v3.0field + # *sigh* this is the same as 3-bit except the 2 LSBs are + # passed through + elif regtype == 'CR_5bit': + cr_subfield = field & 0b11 + field = field >> 2 # strip bottom 2 bits + sv_extra, field = get_extra_cr_3bit(etype, regmode, field) + # now sanity-check (and shrink afterwards) + if etype == 'EXTRA2': + if regmode == 'scalar': + # range is CR0-CR15 in increments of 1 + assert (sv_extra >> 1) == 0, \ + "scalar CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as scalar + sv_extra = sv_extra & 0b01 + else: + # range is CR0-CR127 in increments of 16 + assert sv_extra & 0b111 == 0, \ + "vector CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as vector (bit 2 set) + sv_extra = 0b10 | (sv_extra >> 3) + else: + if regmode == 'scalar': + # range is CR0-CR31 in increments of 1 + assert (sv_extra >> 2) == 0, \ + "scalar CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as scalar + sv_extra = sv_extra & 0b11 + else: + # range is CR0-CR127 in increments of 8 + assert sv_extra & 0b11 == 0, \ + "vector CR %s cannot fit into EXTRA2 %s" % \ + (regname, str(extras[extra_idx])) + # all good: encode as vector (bit 3 set) + sv_extra = 0b100 | (sv_extra >> 2) + + # reconstruct the actual 5-bit CR field + field = (field << 2) | cr_subfield + + # capture the extra field info + print ("=>", "%5s" % bin(sv_extra), field) + extras[extra_idx] = sv_extra + + # append altered field value to v3.0b + v30b_newfields.append(str(field)) + + print ("new v3.0B fields", v30b_op, v30b_newfields) + print ("extras", extras) + print () return res @@ -130,7 +294,8 @@ if __name__ == '__main__': isa = SVP64(['slw 3, 1, 4', 'extsw 5, 3', 'sv.extsw 5, 3', - 'sv.setb 5, 3', - 'sv.isel 5, 3, 2, 0' + 'sv.cmpi 5, 1, 3, 2', + 'sv.setb 5, 31', + 'sv.isel 64.v, 3, 2, 65.v' ]) csvs = SVP64RM()