add module to regspec_decode_* and get_rdflags
[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
38 from openpower.consts import XERRegsEnum, FastRegsEnum, StateRegsEnum
39 from openpower.decoder.power_enums import CryIn
40 from openpower.util import log
41
42
43 def regspec_decode_read(m, e, regfile, name):
44 """regspec_decode_read
45 """
46
47 # INT regfile
48
49 if regfile == 'INT':
50 # Int register numbering is *unary* encoded
51 if name == 'ra': # RA
52 return e.read_reg1.ok, e.read_reg1.data
53 if name == 'rb': # RB
54 return e.read_reg2.ok, e.read_reg2.data
55 if name == 'rc': # RS
56 return e.read_reg3.ok, e.read_reg3.data
57
58 # CR regfile
59
60 if regfile == 'CR':
61 # CRRegs register numbering is *unary* encoded
62 if name == 'full_cr': # full CR (from FXM field)
63 return e.do.read_cr_whole.ok, e.do.read_cr_whole.data
64 if name == 'cr_a': # CR A
65 return e.read_cr1.ok, 1<<(7-e.read_cr1.data)
66 if name == 'cr_b': # CR B
67 return e.read_cr2.ok, 1<<(7-e.read_cr2.data)
68 if name == 'cr_c': # CR C
69 return e.read_cr3.ok, 1<<(7-e.read_cr3.data)
70
71 # XER regfile
72
73 if regfile == 'XER':
74 # XERRegsEnum register numbering is *unary* encoded
75 SO = 1<<XERRegsEnum.SO
76 CA = 1<<XERRegsEnum.CA
77 OV = 1<<XERRegsEnum.OV
78 if name == 'xer_so':
79 # SO needs to be read for overflow *and* for creation
80 # of CR0 and also for MFSPR
81 return ((e.do.oe.oe[0] & e.do.oe.ok) | (e.xer_in & SO == SO)|
82 (e.do.rc.rc & e.do.rc.ok)), SO
83 if name == 'xer_ov':
84 return ((e.do.oe.oe[0] & e.do.oe.ok) |
85 (e.xer_in & CA == CA)), OV
86 if name == 'xer_ca':
87 return ((e.do.input_carry == CryIn.CA.value) |
88 (e.xer_in & OV == OV)), CA
89
90 # STATE regfile
91
92 if regfile == 'STATE':
93 # STATE register numbering is *unary* encoded
94 PC = 1<<StateRegsEnum.PC
95 MSR = 1<<StateRegsEnum.MSR
96 SVSTATE = 1<<StateRegsEnum.SVSTATE
97 if name in ['cia', 'nia']:
98 return Const(1), PC # TODO: detect read-conditions
99 if name == 'msr':
100 return Const(1), MSR # TODO: detect read-conditions
101 if name == 'svstate':
102 return Const(1), SVSTATE # TODO: detect read-conditions
103
104 # FAST regfile
105
106 if regfile == 'FAST':
107 # FAST register numbering is *unary* encoded
108 if name == 'fast1':
109 return e.read_fast1.ok, e.read_fast1.data
110 if name == 'fast2':
111 return e.read_fast2.ok, e.read_fast2.data
112 if name == 'fast3':
113 return e.read_fast3.ok, e.read_fast3.data
114
115 # SPR regfile
116
117 if regfile == 'SPR':
118 # SPR register numbering is *binary* encoded
119 if name == 'spr1':
120 return e.read_spr1.ok, e.read_spr1.data
121
122 assert False, "regspec not found %s %s" % (regfile, name)
123
124
125 def regspec_decode_write(m, e, regfile, name):
126 """regspec_decode_write
127 """
128
129 #log("regspec_decode_write", regfile, name, e.__class__.__name__)
130
131 # INT regfile
132
133 if regfile == 'INT':
134 # Int register numbering is *unary* encoded
135 if name == 'o': # RT
136 return e.write_reg.ok, e.write_reg.data
137 if name == 'o1': # RA (update mode: LD/ST EA)
138 return e.write_ea.ok, e.write_ea.data
139
140 # CR regfile
141
142 if regfile == 'CR':
143 # CRRegs register numbering is *unary* encoded
144 # *sigh*. numbering inverted on part-CRs. because POWER.
145 if name == 'full_cr': # full CR (from FXM field)
146 return e.do.write_cr_whole.ok, e.do.write_cr_whole.data
147 if name == 'cr_a': # CR A
148 return e.write_cr.ok, (1<<(7-e.write_cr.data))[0:8]
149
150 # XER regfile
151
152 if regfile == 'XER':
153 # XERRegsEnum register numbering is *unary* encoded
154 SO = 1<<XERRegsEnum.SO
155 CA = 1<<XERRegsEnum.CA
156 OV = 1<<XERRegsEnum.OV
157 if name == 'xer_so':
158 return (e.xer_out | (e.do.oe.oe[0] & e.do.oe.ok),
159 SO) # hmmm
160 if name == 'xer_ov':
161 return (e.xer_out | (e.do.oe.oe[0] & e.do.oe.ok),
162 OV) # hmmm
163 if name == 'xer_ca':
164 return (e.xer_out | (e.do.output_carry),
165 CA) # hmmm
166
167 # STATE regfile
168
169 if regfile == 'STATE':
170 # STATE register numbering is *unary* encoded
171 PC = 1<<StateRegsEnum.PC
172 MSR = 1<<StateRegsEnum.MSR
173 SVSTATE = 1<<StateRegsEnum.SVSTATE
174 if name in ['cia', 'nia']:
175 return None, PC # hmmm
176 if name == 'msr':
177 return None, MSR # hmmm
178 if name == 'svstate':
179 return None, SVSTATE # hmmm
180
181 # FAST regfile
182
183 if regfile == 'FAST':
184 # FAST register numbering is *unary* encoded
185 if name == 'fast1':
186 return e.write_fast1.ok, e.write_fast1.data
187 if name == 'fast2':
188 return e.write_fast2.ok, e.write_fast2.data
189 if name == 'fast3':
190 return e.write_fast3.ok, e.write_fast3.data
191
192 # SPR regfile
193
194 if regfile == 'SPR':
195 # SPR register numbering is *binary* encoded
196 if name == 'spr1': # SPR1
197 return e.write_spr.ok, e.write_spr.data
198
199 assert False, "regspec not found %s %s" % (regfile, name)
200
201
202 def regspec_decode(m, readmode, e, regfile, name):
203 if readmode:
204 return regspec_decode_read(m, e, regfile, name)
205 return regspec_decode_write(m, e, regfile, name)
206