code-morph regspecmap functions, split into separate read/write
[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 directly through to full_cr (TODO).
20
21 For the INT and CR numbering, these are expressed in binary in the
22 instruction (note however that XFX in MTCR is unary-masked!)
23
24 XER is implicitly-encoded based on whether the operation has carry or
25 overflow.
26
27 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
28 on the type of operation (see DecodeB for an example).
29
30 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
31 has to be "remapped".
32 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
33 """
34 from nmigen import Const
35 from soc.regfile.regfiles import XERRegs, FastRegs
36 from soc.decoder.power_enums import CryIn
37
38
39 def regspec_decode_read(e, regfile, name):
40 """regspec_decode_read
41 """
42
43 if regfile == 'INT':
44 # Int register numbering is *unary* encoded
45 if name == 'ra': # RA
46 return e.read_reg1.ok, 1<<e.read_reg1.data
47 if name == 'rb': # RB
48 return e.read_reg2.ok, 1<<e.read_reg2.data
49 if name == 'rc': # RS
50 return e.read_reg3.ok, 1<<e.read_reg3.data
51
52 if regfile == 'CR':
53 # CRRegs register numbering is *unary* encoded
54 # *sigh*. numbering inverted on part-CRs. because POWER.
55 if name == 'full_cr': # full CR
56 return e.read_cr_whole, 0b11111111
57 if name == 'cr_a': # CR A
58 return e.read_cr1.ok, 1<<(7-e.read_cr1.data)
59 if name == 'cr_b': # CR B
60 return e.read_cr2.ok, 1<<(7-e.read_cr2.data)
61 if name == 'cr_c': # CR C
62 return e.read_cr3.ok, 1<<(7-e.read_cr3.data)
63
64 if regfile == 'XER':
65 # XERRegs register numbering is *unary* encoded
66 SO = 1<<XERRegs.SO
67 CA = 1<<XERRegs.CA
68 OV = 1<<XERRegs.OV
69 if name == 'xer_so':
70 return e.oe.oe[0] & e.oe.oe_ok, SO
71 if name == 'xer_ov':
72 return e.oe.oe[0] & e.oe.oe_ok, OV
73 if name == 'xer_ca':
74 return (e.input_carry == CryIn.CA.value), CA
75
76 if regfile == 'FAST':
77 # FAST register numbering is *unary* encoded
78 PC = 1<<FastRegs.PC
79 MSR = 1<<FastRegs.MSR
80 CTR = 1<<FastRegs.CTR
81 LR = 1<<FastRegs.LR
82 TAR = 1<<FastRegs.TAR
83 SRR0 = 1<<FastRegs.SRR0
84 SRR1 = 1<<FastRegs.SRR1
85 if name in ['cia', 'nia']:
86 return Const(1), PC # TODO: detect read-conditions
87 if name == 'msr':
88 return Const(1), MSR # TODO: detect read-conditions
89 # TODO: remap the SPR numbers to FAST regs
90 if name == 'spr1':
91 return e.read_fast1.ok, 1<<e.read_fast1.data
92 if name == 'spr2':
93 return e.read_fast2.ok, 1<<e.read_fast2.data
94
95 if regfile == 'SPR':
96 assert False, "regfile TODO %s %s" % (regfile, name)
97 assert False, "regspec not found %s %s" % (regfile, name)
98
99
100 def regspec_decode_write(e, regfile, name):
101 """regspec_decode_write
102 """
103
104 if regfile == 'INT':
105 # Int register numbering is *unary* encoded
106 if name == 'o': # RT
107 return e.write_reg, 1<<e.write_reg.data
108 if name == 'o1': # RA (update mode: LD/ST EA)
109 return e.write_ea, 1<<e.write_ea.data
110
111 if regfile == 'CR':
112 # CRRegs register numbering is *unary* encoded
113 # *sigh*. numbering inverted on part-CRs. because POWER.
114 if name == 'full_cr': # full CR
115 return e.write_cr_whole, 0b11111111
116 if name == 'cr_a': # CR A
117 return e.write_cr, 1<<(7-e.write_cr.data)
118
119 if regfile == 'XER':
120 # XERRegs register numbering is *unary* encoded
121 SO = 1<<XERRegs.SO
122 CA = 1<<XERRegs.CA
123 OV = 1<<XERRegs.OV
124 if name == 'xer_so':
125 return None, SO # hmmm
126 if name == 'xer_ov':
127 return None, OV # hmmm
128 if name == 'xer_ca':
129 return None, CA # hmmm
130
131 if regfile == 'FAST':
132 # FAST register numbering is *unary* encoded
133 PC = 1<<FastRegs.PC
134 MSR = 1<<FastRegs.MSR
135 CTR = 1<<FastRegs.CTR
136 LR = 1<<FastRegs.LR
137 TAR = 1<<FastRegs.TAR
138 SRR0 = 1<<FastRegs.SRR0
139 SRR1 = 1<<FastRegs.SRR1
140 if name in ['cia', 'nia']:
141 return None, PC # hmmm
142 if name == 'msr':
143 return None, MSR # hmmm
144 # TODO: remap the SPR numbers to FAST regs
145 if name == 'spr1':
146 return e.write_fast1, 1<<e.write_fast1.data
147 if name == 'spr2':
148 return e.write_fast2, 1<<e.write_fast2.data
149
150 if regfile == 'SPR':
151 assert False, "regfile TODO %s %s" % (regfile, name)
152 assert False, "regspec not found %s %s" % (regfile, name)
153