3 functions for the relationship between regspecs and Decode2Execute1Type
5 these functions encodes the understanding (relationship) between
6 Regfiles, Computation Units, and the Power ISA Decoder (PowerDecoder2).
8 based on the regspec, which contains the register file name and register
9 name, return a tuple of:
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
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).
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!
26 XER regs are implicitly-encoded (hard-coded) based on whether the
27 operation has carry or overflow.
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).
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
37 from nmigen
import Const
38 from openpower
.consts
import XERRegsEnum
, FastRegsEnum
, StateRegsEnum
39 from openpower
.decoder
.power_enums
import CryIn
42 def regspec_decode_read(e
, regfile
, name
):
43 """regspec_decode_read
49 # Int register numbering is *unary* encoded
51 return e
.read_reg1
.ok
, e
.read_reg1
.data
53 return e
.read_reg2
.ok
, e
.read_reg2
.data
55 return e
.read_reg3
.ok
, e
.read_reg3
.data
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
)
73 # XERRegsEnum register numbering is *unary* encoded
74 SO
= 1<<XERRegsEnum
.SO
75 CA
= 1<<XERRegsEnum
.CA
76 OV
= 1<<XERRegsEnum
.OV
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
83 return ((e
.do
.oe
.oe
[0] & e
.do
.oe
.ok
) |
84 (e
.xer_in
& CA
== CA
)), OV
86 return ((e
.do
.input_carry
== CryIn
.CA
.value
) |
87 (e
.xer_in
& OV
== OV
)), CA
91 if regfile
== 'STATE':
92 # STATE register numbering is *unary* encoded
93 PC
= 1<<StateRegsEnum
.PC
94 MSR
= 1<<StateRegsEnum
.MSR
95 SVSTATE
= 1<<StateRegsEnum
.SVSTATE
96 if name
in ['cia', 'nia']:
97 return Const(1), PC
# TODO: detect read-conditions
99 return Const(1), MSR
# TODO: detect read-conditions
100 if name
== 'svstate':
101 return Const(1), SVSTATE
# TODO: detect read-conditions
105 if regfile
== 'FAST':
106 # FAST register numbering is *unary* encoded
108 return e
.read_fast1
.ok
, e
.read_fast1
.data
110 return e
.read_fast2
.ok
, e
.read_fast2
.data
112 return e
.read_fast3
.ok
, e
.read_fast3
.data
117 # SPR register numbering is *binary* encoded
119 return e
.read_spr1
.ok
, e
.read_spr1
.data
121 assert False, "regspec not found %s %s" % (regfile
, name
)
124 def regspec_decode_write(e
, regfile
, name
):
125 """regspec_decode_write
131 # Int register numbering is *unary* encoded
133 return e
.write_reg
, e
.write_reg
.data
134 if name
== 'o1': # RA (update mode: LD/ST EA)
135 return e
.write_ea
, e
.write_ea
.data
140 # CRRegs register numbering is *unary* encoded
141 # *sigh*. numbering inverted on part-CRs. because POWER.
142 if name
== 'full_cr': # full CR (from FXM field)
143 return e
.do
.write_cr_whole
.ok
, e
.do
.write_cr_whole
.data
144 if name
== 'cr_a': # CR A
145 return e
.write_cr
, 1<<(7-e
.write_cr
.data
)
150 # XERRegsEnum register numbering is *unary* encoded
151 SO
= 1<<XERRegsEnum
.SO
152 CA
= 1<<XERRegsEnum
.CA
153 OV
= 1<<XERRegsEnum
.OV
155 return e
.xer_out
, SO
# hmmm
157 return e
.xer_out
, OV
# hmmm
159 return e
.xer_out
, CA
# hmmm
163 if regfile
== 'STATE':
164 # STATE register numbering is *unary* encoded
165 PC
= 1<<StateRegsEnum
.PC
166 MSR
= 1<<StateRegsEnum
.MSR
167 SVSTATE
= 1<<StateRegsEnum
.SVSTATE
168 if name
in ['cia', 'nia']:
169 return None, PC
# hmmm
171 return None, MSR
# hmmm
172 if name
== 'svstate':
173 return None, SVSTATE
# hmmm
177 if regfile
== 'FAST':
178 # FAST register numbering is *unary* encoded
180 return e
.write_fast1
, e
.write_fast1
.data
182 return e
.write_fast2
, e
.write_fast2
.data
184 return e
.write_fast3
, e
.write_fast3
.data
189 # SPR register numbering is *binary* encoded
190 if name
== 'spr1': # SPR1
191 return e
.write_spr
, e
.write_spr
.data
193 assert False, "regspec not found %s %s" % (regfile
, name
)