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