CR FXM becomes a full mask.
[soc.git] / src / soc / 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 soc.regfile.regfiles import XERRegs, FastRegs, StateRegs
39 from soc.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 # XERRegs register numbering is *unary* encoded
74 SO = 1<<XERRegs.SO
75 CA = 1<<XERRegs.CA
76 OV = 1<<XERRegs.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.oe_ok) | e.xer_in |
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.oe_ok) | e.xer_in, OV
84 if name == 'xer_ca':
85 return (e.do.input_carry == CryIn.CA.value) | e.xer_in, CA
86
87 # STATE regfile
88
89 if regfile == 'STATE':
90 # STATE register numbering is *unary* encoded
91 PC = 1<<StateRegs.PC
92 MSR = 1<<Stateegs.MSR
93 if name in ['cia', 'nia']:
94 return Const(1), PC # TODO: detect read-conditions
95 if name == 'msr':
96 return Const(1), MSR # TODO: detect read-conditions
97
98 # FAST regfile
99
100 if regfile == 'FAST':
101 # FAST register numbering is *unary* encoded
102 if name == 'fast1':
103 return e.read_fast1.ok, e.read_fast1.data
104 if name == 'fast2':
105 return e.read_fast2.ok, e.read_fast2.data
106
107 # SPR regfile
108
109 if regfile == 'SPR':
110 # SPR register numbering is *binary* encoded
111 if name == 'spr1':
112 return e.read_spr1.ok, e.read_spr1.data
113
114 assert False, "regspec not found %s %s" % (regfile, name)
115
116
117 def regspec_decode_write(e, regfile, name):
118 """regspec_decode_write
119 """
120
121 # INT regfile
122
123 if regfile == 'INT':
124 # Int register numbering is *unary* encoded
125 if name == 'o': # RT
126 return e.write_reg, e.write_reg.data
127 if name == 'o1': # RA (update mode: LD/ST EA)
128 return e.write_ea, e.write_ea.data
129
130 # CR regfile
131
132 if regfile == 'CR':
133 # CRRegs register numbering is *unary* encoded
134 # *sigh*. numbering inverted on part-CRs. because POWER.
135 if name == 'full_cr': # full CR (from FXM field)
136 return e.do.write_cr_whole.ok, e.do.write_cr_whole.data
137 if name == 'cr_a': # CR A
138 return e.write_cr, 1<<(7-e.write_cr.data)
139
140 # XER regfile
141
142 if regfile == 'XER':
143 # XERRegs register numbering is *unary* encoded
144 SO = 1<<XERRegs.SO
145 CA = 1<<XERRegs.CA
146 OV = 1<<XERRegs.OV
147 if name == 'xer_so':
148 return e.xer_out, SO # hmmm
149 if name == 'xer_ov':
150 return e.xer_out, OV # hmmm
151 if name == 'xer_ca':
152 return e.xer_out, CA # hmmm
153
154 # STATE regfile
155
156 if regfile == 'STATE':
157 # STATE register numbering is *unary* encoded
158 PC = 1<<StateRegs.PC
159 MSR = 1<<StateRegs.MSR
160 if name in ['cia', 'nia']:
161 return None, PC # hmmm
162 if name == 'msr':
163 return None, MSR # hmmm
164
165 # FAST regfile
166
167 if regfile == 'FAST':
168 # FAST register numbering is *unary* encoded
169 if name == 'fast1':
170 return e.write_fast1, e.write_fast1.data
171 if name == 'fast2':
172 return e.write_fast2, e.write_fast2.data
173
174 # SPR regfile
175
176 if regfile == 'SPR':
177 # SPR register numbering is *binary* encoded
178 if name == 'spr1': # SPR1
179 return e.write_spr, e.write_spr.data
180
181 assert False, "regspec not found %s %s" % (regfile, name)
182