sigh read and write xer detection, fix spr and trap compunit tests
[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 (note however that XFX in MTCR is unary-masked!)
24
25 XER is implicitly-encoded based on whether the operation has carry or
26 overflow.
27
28 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
29 on the type of operation (see DecodeB for an example).
30
31 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
32 has to be "remapped".
33 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
34 """
35 from nmigen import Const
36 from soc.regfile.regfiles import XERRegs, FastRegs
37 from soc.decoder.power_enums import CryIn
38
39
40 def regspec_decode_read(e, regfile, name):
41 """regspec_decode_read
42 """
43
44 if regfile == 'INT':
45 # Int register numbering is *unary* encoded
46 if name == 'ra': # RA
47 return e.read_reg1.ok, 1<<e.read_reg1.data
48 if name == 'rb': # RB
49 return e.read_reg2.ok, 1<<e.read_reg2.data
50 if name == 'rc': # RS
51 return e.read_reg3.ok, 1<<e.read_reg3.data
52
53 if regfile == 'CR':
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)
64
65 if regfile == 'XER':
66 # XERRegs register numbering is *unary* encoded
67 SO = 1<<XERRegs.SO
68 CA = 1<<XERRegs.CA
69 OV = 1<<XERRegs.OV
70 if name == 'xer_so':
71 return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, SO
72 if name == 'xer_ov':
73 return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, OV
74 if name == 'xer_ca':
75 return (e.input_carry == CryIn.CA.value) | e.xer_in, CA
76
77 if regfile == 'FAST':
78 # FAST register numbering is *unary* encoded
79 PC = 1<<FastRegs.PC
80 MSR = 1<<FastRegs.MSR
81 CTR = 1<<FastRegs.CTR
82 LR = 1<<FastRegs.LR
83 TAR = 1<<FastRegs.TAR
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
88 if name == 'msr':
89 return Const(1), MSR # TODO: detect read-conditions
90 # TODO: remap the SPR numbers to FAST regs
91 if name == 'fast1':
92 return e.read_fast1.ok, 1<<e.read_fast1.data
93 if name == 'fast2':
94 return e.read_fast2.ok, 1<<e.read_fast2.data
95
96 if regfile == 'SPR':
97 # Int register numbering is *binary* encoded
98 if name == 'spr1':
99 return e.read_spr1.ok, e.read_spr1.data
100
101 assert False, "regspec not found %s %s" % (regfile, name)
102
103
104 def regspec_decode_write(e, regfile, name):
105 """regspec_decode_write
106 """
107
108 if regfile == 'INT':
109 # Int register numbering is *unary* encoded
110 if name == 'o': # RT
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
114
115 if regfile == 'CR':
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)
122
123 if regfile == 'XER':
124 # XERRegs register numbering is *unary* encoded
125 SO = 1<<XERRegs.SO
126 CA = 1<<XERRegs.CA
127 OV = 1<<XERRegs.OV
128 if name == 'xer_so':
129 return e.xer_out, SO # hmmm
130 if name == 'xer_ov':
131 return e.xer_out, OV # hmmm
132 if name == 'xer_ca':
133 return e.xer_out, CA # hmmm
134
135 if regfile == 'FAST':
136 # FAST register numbering is *unary* encoded
137 PC = 1<<FastRegs.PC
138 MSR = 1<<FastRegs.MSR
139 CTR = 1<<FastRegs.CTR
140 LR = 1<<FastRegs.LR
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
146 if name == 'msr':
147 return None, MSR # hmmm
148 # TODO: remap the SPR numbers to FAST regs
149 if name == 'fast1':
150 return e.write_fast1, 1<<e.write_fast1.data
151 if name == 'fast2':
152 return e.write_fast2, 1<<e.write_fast2.data
153
154 if regfile == 'SPR':
155 # Int register numbering is *binary* encoded
156 if name == 'spr1': # SPR1
157 return e.write_spr, e.write_spr.data
158
159 assert False, "regspec not found %s %s" % (regfile, name)
160