85fc39747f94538489c850de09f8c661e27c4293
1 # SPDX-License-Identifier: LGPLv3+
2 # Copyright (C) 2021 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
3 # Funded by NLnet http://nlnet.nl
5 from soc
.decoder
.power_enums
import get_csv
, find_wiki_dir
8 # identifies register by type
9 def is_CR_3bit(regname
):
10 return regname
in ['BF', 'BFA']
12 def is_CR_5bit(regname
):
13 return regname
in ['BA', 'BB', 'BC', 'BI', 'BT']
16 return regname
in ['RA', 'RB', 'RC', 'RS', 'RT']
18 def get_regtype(regname
):
19 if is_CR_3bit(regname
):
21 if is_CR_5bit(regname
):
27 def decode_extra(rm
, prefix
=''):
28 # first turn the svp64 rm into a "by name" dict, recording
29 # which position in the RM EXTRA it goes into
30 # also: record if the src or dest was a CR, for sanity-checking
31 # (elwidth overrides on CRs are banned)
32 dest_reg_cr
, src_reg_cr
= False, False
33 svp64_srcreg_byname
= {}
34 svp64_destreg_byname
= {}
37 rfield
= rm
[prefix
+str(i
)]
38 if not rfield
or rfield
== '0':
40 print ("EXTRA field", i
, rfield
)
41 rfield
= rfield
.split(";") # s:RA;d:CR1 etc.
44 # TODO: ignoring s/d makes it impossible to do
46 r
= r
[2:] # ignore s: and d:
48 svp64_destreg_byname
[r
] = i
# dest reg in EXTRA position 0-3
50 svp64_srcreg_byname
[r
] = i
# src reg in EXTRA position 0-3
51 # check the regtype (if CR, record that)
52 regtype
= get_regtype(r
)
53 if regtype
in ['CR_3bit', 'CR_5bit']:
59 return dest_reg_cr
, src_reg_cr
, svp64_srcreg_byname
, svp64_destreg_byname
62 # gets SVP64 ReMap information
67 for fname
in os
.listdir(pth
):
68 if fname
.startswith("RM") or fname
.startswith("LDSTRM"):
69 for entry
in get_csv(fname
):
70 self
.instrs
[entry
['insn']] = entry
73 def get_svp64_csv(self
, fname
):
74 # first get the v3.0B entries
77 # now add the RM fields (for each instruction)
79 # dummy (blank) fields, first
80 entry
.update({'EXTRA0': '0', 'EXTRA1': '0', 'EXTRA2': '0',
82 'SV_Ptype': 'NONE', 'SV_Etype': 'NONE'})
84 # is this SVP64-augmented?
85 asmcode
= entry
['comment']
86 if asmcode
not in self
.instrs
:
89 # start updating the fields, merge relevant info
90 svp64
= self
.instrs
[asmcode
]
91 for k
, v
in {'EXTRA0': '0', 'EXTRA1': '1', 'EXTRA2': '2',
93 'SV_Ptype': 'Ptype', 'SV_Etype': 'Etype'}.items():
96 # hmm, we need something more useful: a cross-association
97 # of the in1/2/3 and CR in/out with the EXTRA0-3 fields
98 decode
= decode_extra(entry
, "EXTRA")
99 dest_reg_cr
, src_reg_cr
, svp64_src
, svp64_dest
= decode
101 # now examine in1/2/3/out, create sv_in1/2/3/out
102 for fname
in ['in1', 'in2', 'in3', 'out']:
103 regfield
= entry
[fname
]
105 if regfield
== 'RA_OR_ZERO':
107 print (asmcode
, regfield
, fname
, svp64_dest
, svp64_src
)
108 # find the reg in the SVP64 extra map
109 if (fname
== 'out' and regfield
in svp64_dest
):
110 extra_index
= svp64_dest
[regfield
]
111 if (fname
!= 'out' and regfield
in svp64_src
):
112 extra_index
= svp64_src
[regfield
]
113 # ta-daa, we know in1/2/3/out's bit-offset
114 entry
['sv_%s' % fname
] = extra_index
116 # TODO: CRs a little tricky, the power_enums.CRInSel is a bit odd.
117 # ignore WHOLE_REG for now
118 cr_in
= entry
['CR in']
120 if cr_in
in svp64_src
:
121 entry
['sv_cr_in'] = svp64_src
[cr_in
]
122 elif cr_in
== 'BA_BB':
123 index1
= svp64_src
.get('BA', None)
124 index2
= svp64_src
.get('BB', None)
125 entry
['sv_cr_in'] = (index1
, index2
)
127 # CRout a lot easier. ignore WHOLE_REG for now
128 cr_out
= entry
['CR out']
129 entry
['sv_cr_out'] = svp64_dest
.get(cr_out
, None)
131 # more enum-friendly Ptype names. should have done this in
132 # sv_analysis.py, oh well
133 if entry
['SV_Ptype'] == '1P':
134 entry
['SV_Ptype'] = 'P1'
135 if entry
['SV_Ptype'] == '2P':
136 entry
['SV_Ptype'] = 'P2'
140 if __name__
== '__main__':
142 minor_30
= isa
.get_svp64_csv("minor_30.csv")
143 for entry
in minor_30
:
145 minor_19
= isa
.get_svp64_csv("minor_19.csv")
146 for entry
in minor_19
:
147 if entry
['comment'].startswith('cr'):