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 (note however that XFX in MTCR is unary-masked!)
25 XER is implicitly-encoded based on whether the operation has carry or
28 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
29 on the type of operation (see DecodeB for an example).
31 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
33 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
35 from nmigen
import Const
36 from soc
.regfile
.regfiles
import XERRegs
, FastRegs
37 from soc
.decoder
.power_enums
import CryIn
40 def regspec_decode_read(e
, regfile
, name
):
41 """regspec_decode_read
45 # Int register numbering is *unary* encoded
47 return e
.read_reg1
.ok
, 1<<e
.read_reg1
.data
49 return e
.read_reg2
.ok
, 1<<e
.read_reg2
.data
51 return e
.read_reg3
.ok
, 1<<e
.read_reg3
.data
54 # CRRegs register numbering is *unary* encoded
55 # *sigh*. numbering inverted on part-CRs. because POWER.
56 if name
== 'full_cr': # full CR
57 return e
.read_cr_whole
, 0b11111111
58 if name
== 'cr_a': # CR A
59 return e
.read_cr1
.ok
, 1<<(7-e
.read_cr1
.data
)
60 if name
== 'cr_b': # CR B
61 return e
.read_cr2
.ok
, 1<<(7-e
.read_cr2
.data
)
62 if name
== 'cr_c': # CR C
63 return e
.read_cr3
.ok
, 1<<(7-e
.read_cr3
.data
)
66 # XERRegs register numbering is *unary* encoded
71 return e
.oe
.oe
[0] & e
.oe
.oe_ok
, SO
73 return e
.oe
.oe
[0] & e
.oe
.oe_ok
, OV
75 return (e
.input_carry
== CryIn
.CA
.value
), CA
78 # FAST register numbering is *unary* encoded
84 SRR0
= 1<<FastRegs
.SRR0
85 SRR1
= 1<<FastRegs
.SRR1
86 if name
in ['cia', 'nia']:
87 return Const(1), PC
# TODO: detect read-conditions
89 return Const(1), MSR
# TODO: detect read-conditions
90 # TODO: remap the SPR numbers to FAST regs
92 return e
.read_fast1
.ok
, 1<<e
.read_fast1
.data
94 return e
.read_fast2
.ok
, 1<<e
.read_fast2
.data
97 # Int register numbering is *binary* encoded
99 return e
.read_spr1
.ok
, e
.read_spr1
.data
101 assert False, "regspec not found %s %s" % (regfile
, name
)
104 def regspec_decode_write(e
, regfile
, name
):
105 """regspec_decode_write
109 # Int register numbering is *unary* encoded
111 return e
.write_reg
, 1<<e
.write_reg
.data
112 if name
== 'o1': # RA (update mode: LD/ST EA)
113 return e
.write_ea
, 1<<e
.write_ea
.data
116 # CRRegs register numbering is *unary* encoded
117 # *sigh*. numbering inverted on part-CRs. because POWER.
118 if name
== 'full_cr': # full CR
119 return e
.write_cr_whole
, 0b11111111
120 if name
== 'cr_a': # CR A
121 return e
.write_cr
, 1<<(7-e
.write_cr
.data
)
124 # XERRegs register numbering is *unary* encoded
129 return None, SO
# hmmm
131 return None, OV
# hmmm
133 return None, CA
# hmmm
135 if regfile
== 'FAST':
136 # FAST register numbering is *unary* encoded
138 MSR
= 1<<FastRegs
.MSR
139 CTR
= 1<<FastRegs
.CTR
141 TAR
= 1<<FastRegs
.TAR
142 SRR0
= 1<<FastRegs
.SRR0
143 SRR1
= 1<<FastRegs
.SRR1
144 if name
in ['cia', 'nia']:
145 return None, PC
# hmmm
147 return None, MSR
# hmmm
148 # TODO: remap the SPR numbers to FAST regs
150 return e
.write_fast1
, 1<<e
.write_fast1
.data
152 return e
.write_fast2
, 1<<e
.write_fast2
.data
155 # Int register numbering is *binary* encoded
156 if name
== 'spr1': # SPR1
157 return e
.write_spr
, e
.write_spr
.data
159 assert False, "regspec not found %s %s" % (regfile
, name
)