bug 676: closer to working maxloc. a lot of cr ops
[openpower-isa.git] / src / openpower / decoder / power_regspec_map.py
1 """regspec_decode
2
3 functions for the relationship between regspecs and Decode2Execute1Type
4
5 these functions encodes the understanding (relationship) between
6 Regfiles, Computation Units, and the Power ISA Decoder (PowerDecoder2).
7
8 based on the regspec, which contains the register file name and register
9 name, return a tuple of:
10
11 * how the decoder should determine whether the Function Unit needs
12 access to a given Regport or not
13 * which Regfile number on that port should be read to get that data
14 * when it comes to writing: likewise, which Regfile num should be written
15
16 Note that some of the port numbering encoding is *unary*. in the case
17 of "Full Condition Register", it's a full 8-bit mask of read/write-enables.
18 This actually matches directly with the XFX field in MTCR, and at
19 some point that 8-bit mask from the instruction could actually be passed
20 directly through to full_cr (TODO).
21
22 For the INT and CR numbering, these are expressed in binary in the
23 instruction and need to be converted to unary (1<<read_reg1.data).
24 Note however that XFX in MTCR is unary-masked!
25
26 XER regs are implicitly-encoded (hard-coded) based on whether the
27 operation has carry or overflow.
28
29 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
30 on the type of operation (see DecodeB for an example, where fast_out
31 is set, then carried into read_fast2 in PowerDecode2).
32
33 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
34 has to be "remapped" to internal SPR Enum indices (see SPRMap in PowerDecode2)
35 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
36 """
37 from nmigen import Const, Signal
38 from openpower.consts import XERRegsEnum, FastRegsEnum, StateRegsEnum
39 from openpower.decoder.power_enums import CryIn
40 from openpower.util import log
41 from collections import namedtuple
42
43 RegDecodeInfo = namedtuple("RedDecodeInfo", ['okflag', 'regport', 'portlen'])
44
45 # XXX TODO: these portlen numbers *must* increase / adapt for SVP64.
46
47 def regspec_decode_read(m, e, regfile, name):
48 """regspec_decode_read
49 """
50
51 rd = None
52
53 # INT regfile
54
55 if regfile == 'INT':
56 # Int register numbering is *unary* encoded
57 if name == 'ra': # RA
58 rd = RegDecodeInfo(e.read_reg1.ok, e.read_reg1.data, 5)
59 if name == 'rb': # RB
60 rd = RegDecodeInfo(e.read_reg2.ok, e.read_reg2.data, 5)
61 if name == 'rc': # RS
62 rd = RegDecodeInfo(e.read_reg3.ok, e.read_reg3.data, 5)
63
64 # CR regfile
65
66 if regfile == 'CR':
67 # CRRegs register numbering is *unary* encoded
68 if name == 'full_cr': # full CR (from FXM field)
69 rd = RegDecodeInfo(e.do.read_cr_whole.ok,
70 e.do.read_cr_whole.data, 8)
71 if name == 'cr_a': # CR A
72 rd = RegDecodeInfo(e.read_cr1.ok, 1<<(7-e.read_cr1.data), 8)
73 if name == 'cr_b': # CR B
74 rd = RegDecodeInfo(e.read_cr2.ok, 1<<(7-e.read_cr2.data), 8)
75 if name == 'cr_c': # CR C
76 rd = RegDecodeInfo(e.read_cr3.ok, 1<<(7-e.read_cr3.data), 8)
77
78 # XER regfile
79
80 if regfile == 'XER':
81 # XERRegsEnum register numbering is *unary* encoded
82 SO = 1<<XERRegsEnum.SO
83 CA = 1<<XERRegsEnum.CA
84 OV = 1<<XERRegsEnum.OV
85 if name == 'xer_so':
86 # SO needs to be read for overflow *and* for creation
87 # of CR0 and also for MFSPR
88 rd = RegDecodeInfo(((e.do.oe.oe[0] & e.do.oe.ok) |
89 (e.xer_in & SO == SO)|
90 (e.do.rc.rc & e.do.rc.ok)), SO, 3)
91 if name == 'xer_ov':
92 rd = RegDecodeInfo(((e.do.oe.oe[0] & e.do.oe.ok) |
93 (e.xer_in & CA == CA)), OV, 3)
94 if name == 'xer_ca':
95 rd = RegDecodeInfo(((e.do.input_carry == CryIn.CA.value) |
96 (e.xer_in & OV == OV)), CA, 3)
97
98 # STATE regfile
99
100 if regfile == 'STATE':
101 # STATE register numbering is *unary* encoded
102 PC = 1<<StateRegsEnum.PC
103 MSR = 1<<StateRegsEnum.MSR
104 SVSTATE = 1<<StateRegsEnum.SVSTATE
105 if name in ['cia', 'nia']:
106 # TODO: detect read-conditions
107 rd = RegDecodeInfo(Const(1), PC, 5)
108 if name == 'msr':
109 # TODO: detect read-conditions
110 rd = RegDecodeInfo(Const(1), MSR, 5)
111 if name == 'svstate':
112 # TODO: detect read-conditions
113 rd = RegDecodeInfo(Const(1), SVSTATE, 5)
114 if name == 'state1':
115 rd = RegDecodeInfo(e.read_state1.ok, 1<<e.read_state1.data, 5)
116
117 # FAST regfile
118
119 if regfile == 'FAST':
120 # FAST register numbering is *binary* encoded
121 if name == 'fast1':
122 rd = RegDecodeInfo(e.read_fast1.ok, e.read_fast1.data, 4)
123 if name == 'fast2':
124 rd = RegDecodeInfo(e.read_fast2.ok, e.read_fast2.data, 4)
125 if name == 'fast3':
126 rd = RegDecodeInfo(e.read_fast3.ok, e.read_fast3.data, 4)
127
128 # SPR regfile
129
130 if regfile == 'SPR':
131 # SPR register numbering is *binary* encoded
132 if name == 'spr1':
133 rd = RegDecodeInfo(e.read_spr1.ok, e.read_spr1.data, 10)
134
135 assert rd is not None, "regspec not found %s %s" % (regfile, name)
136
137 rname="rd_decode_%s_%s" % (regfile, name)
138 ok = Signal(name=rname+"_ok", reset_less=True)
139 data = Signal(rd.portlen, name=rname+"_port", reset_less=True)
140 m.d.comb += ok.eq(rd.okflag)
141 m.d.comb += data.eq(rd.regport)
142
143 return RegDecodeInfo(ok, data, rd.portlen)
144
145
146 def regspec_decode_write(m, e, regfile, name):
147 """regspec_decode_write
148 """
149
150 #log("regspec_decode_write", regfile, name, e.__class__.__name__)
151 wr = None
152
153 # INT regfile
154
155 if regfile == 'INT':
156 # Int register numbering is *unary* encoded
157 if name == 'o': # RT
158 wr = RegDecodeInfo(e.write_reg.ok, e.write_reg.data, 5)
159 if name == 'o1': # RA (update mode: LD/ST EA)
160 wr = RegDecodeInfo(e.write_ea.ok, e.write_ea.data, 5)
161
162 # CR regfile
163
164 if regfile == 'CR':
165 # CRRegs register numbering is *unary* encoded
166 # *sigh*. numbering inverted on part-CRs. because POWER.
167 if name == 'full_cr': # full CR (from FXM field)
168 wr = RegDecodeInfo(e.do.write_cr_whole.ok,
169 e.do.write_cr_whole.data, 8)
170 if name == 'cr_a': # CR A
171 wr = RegDecodeInfo(e.write_cr.ok,
172 1<<(7-e.write_cr.data), 8)
173
174 # XER regfile
175
176 if regfile == 'XER':
177 # XERRegsEnum register numbering is *unary* encoded
178 SO = 1<<XERRegsEnum.SO
179 CA = 1<<XERRegsEnum.CA
180 OV = 1<<XERRegsEnum.OV
181 if name == 'xer_so':
182 wr = RegDecodeInfo(e.xer_out | (e.do.oe.oe[0] & e.do.oe.ok),
183 SO, 3) # hmmm
184 if name == 'xer_ov':
185 wr = RegDecodeInfo(e.xer_out | (e.do.oe.oe[0] & e.do.oe.ok),
186 OV, 3) # hmmm
187 if name == 'xer_ca':
188 wr = RegDecodeInfo(e.xer_out | (e.do.output_carry),
189 CA, 3) # hmmm
190
191 # STATE regfile
192
193 if regfile == 'STATE':
194 # STATE register numbering is *unary* encoded
195 PC = 1<<StateRegsEnum.PC
196 MSR = 1<<StateRegsEnum.MSR
197 SVSTATE = 1<<StateRegsEnum.SVSTATE
198 if name in ['cia', 'nia']:
199 wr = RegDecodeInfo(None, PC, 5) # hmmm
200 if name == 'msr':
201 wr = RegDecodeInfo(None, MSR, 5) # hmmm
202 if name == 'svstate':
203 wr = RegDecodeInfo(None, SVSTATE, 5) # hmmm
204 if name == 'state1':
205 wr = RegDecodeInfo(e.write_state1.ok, 1<<e.write_state1.data, 5)
206
207 # FAST regfile
208
209 if regfile == 'FAST':
210 # FAST register numbering is *binary* encoded
211 if name == 'fast1':
212 wr = RegDecodeInfo(e.write_fast1.ok, e.write_fast1.data, 4)
213 if name == 'fast2':
214 wr = RegDecodeInfo(e.write_fast2.ok, e.write_fast2.data, 4)
215 if name == 'fast3':
216 wr = RegDecodeInfo(e.write_fast3.ok, e.write_fast3.data, 4)
217
218 # SPR regfile
219
220 if regfile == 'SPR':
221 # SPR register numbering is *binary* encoded
222 if name == 'spr1': # SPR1
223 wr = RegDecodeInfo(e.write_spr.ok, e.write_spr.data, 10)
224
225 assert wr is not None, "regspec not found %s %s" % (regfile, name)
226
227 rname="wr_decode_%s_%s" % (regfile, name)
228 if wr.okflag is not None:
229 ok = Signal(name=rname+"_ok", reset_less=True)
230 m.d.comb += ok.eq(wr.okflag)
231 else:
232 # XXX urrrr, really do have to deal with this some time
233 ok = None
234 data = Signal(wr.portlen, name=rname+"_port", reset_less=True)
235 m.d.comb += data.eq(wr.regport)
236
237 return RegDecodeInfo(ok, data, wr.portlen)
238
239
240 def regspec_decode(m, readmode, e, regfile, name):
241 if readmode:
242 return regspec_decode_read(m, e, regfile, name)
243 return regspec_decode_write(m, e, regfile, name)
244