oppc/code: drop explicit ctx argument
[openpower-isa.git] / src / openpower / consts.py
1 import enum
2
3
4 # Can't think of a better place to put these functions.
5 # Return an arbitrary subfield of a larger field.
6 def field_slice(msb0_start, msb0_end, field_width=64):
7 """field_slice
8
9 Answers with a subfield slice of the signal r ("register"),
10 where the start and end bits use IBM "MSB 0" conventions.
11
12 see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
13
14 * assertion: msb0_start < msb0_end.
15 * The range specified is inclusive on both ends.
16 * field_width specifies the total number of bits (note: not bits-1)
17 """
18 if msb0_start >= msb0_end:
19 raise ValueError(
20 "start ({}) must be less than end ({})".format(msb0_start, msb0_end)
21 )
22 # sigh. MSB0 (IBM numbering) is inverted. converting to python
23 # we *swap names* so as not to get confused by having "end, start"
24 lsb0_end = (field_width-1) - msb0_start
25 lsb0_start = (field_width-1) - msb0_end
26
27 return slice(lsb0_start, lsb0_end + 1)
28
29
30 def field(r, msb0_start, msb0_end=None, field_width=64):
31 """Answers with a subfield of the signal r ("register"), where
32 the start and end bits use IBM conventions. start < end, if
33 end is provided. The range specified is inclusive on both ends.
34
35 Answers with a subfield of the signal r ("register"),
36 where the start and end bits use IBM "MSB 0" conventions.
37 If end is not provided, a single bit subfield is returned.
38
39 see: https://en.wikipedia.org/wiki/Bit_numbering#MSB_0_bit_numbering
40
41 * assertion: msb0_start < msb0_end.
42 * The range specified is inclusive on both ends.
43 * field_width specifies the total number of bits (note: not bits-1)
44
45 Example usage:
46
47 comb += field(insn, 0, 6, field_width=32).eq(17)
48 # NOTE: NEVER DIRECTLY ACCESS OPCODE FIELDS IN INSTRUCTIONS.
49 # This example is purely for illustrative purposes only.
50 # Use self.fields.FormXYZ.etcetc instead.
51
52 comb += field(msr, MSRb.TEs, MSRb.TEe).eq(0)
53
54 Proof by substitution:
55
56 field(insn, 0, 6, field_width=32).eq(17)
57 == insn[field_slice(0, 6, field_width=32)].eq(17)
58 == insn[slice((31-6), (31-0)+1)].eq(17)
59 == insn[slice(25, 32)].eq(17)
60 == insn[25:32].eq(17)
61
62 field(msr, MSRb.TEs, MSRb.TEe).eq(0)
63 == field(msr, 53, 54).eq(0)
64 == msr[field_slice(53, 54)].eq(0)
65 == msr[slice((63-54), (63-53)+1)].eq(0) # note cross-over!
66 == msr[slice(9, 11)].eq(0)
67 == msr[9:11].eq(0)
68 """
69 if msb0_end is None:
70 return r[(field_width - 1) - msb0_start]
71 else:
72 return r[field_slice(msb0_start, msb0_end, field_width)]
73
74
75 # just... don't ask. MSB0 is a massive pain in the neck.
76 # this module, aside from creating various field constants,
77 # helps out by creating alternative (identical) classes with
78 # a "b" name to indicate "MSB0 big-endian".
79 class _Const(enum.IntEnum):
80 pass
81
82
83 class _ConstLEMeta(enum.EnumMeta):
84 def __call__(metacls, *args, **kwargs):
85 if len(args) > 1:
86 names = args[1]
87 else:
88 names = kwargs.pop("names")
89
90 if isinstance(names, type) and issubclass(names, enum.Enum):
91 names = dict(names.__members__)
92 if isinstance(names, dict):
93 names = tuple(names.items())
94
95 msb = kwargs.pop("msb")
96 names = {key:(msb - value) for (key, value) in names}
97
98 return super().__call__(*args, names=names, **kwargs)
99
100
101 class _ConstLE(_Const, metaclass=_ConstLEMeta):
102 pass
103
104
105 # Listed in V3.0B Book III Chap 4.2.1
106 # MSR bit numbers, *bigendian* order (PowerISA format)
107 # use this in the simulator
108 class MSRb(_Const):
109 SF = 0 # Sixty-Four bit mode
110 HV = 3 # Hypervisor state
111 UND = 5 # Undefined behavior state (see Bk 2, Sect. 3.2.1)
112 TSs = 29 # Transactional State (subfield)
113 TSe = 30 # Transactional State (subfield)
114 TM = 31 # Transactional Memory Available
115 VEC = 38 # Vector Available
116 VSX = 40 # VSX Available
117 S = 41 # Secure state
118 EE = 48 # External interrupt Enable
119 PR = 49 # PRoblem state
120 FP = 50 # FP available
121 ME = 51 # Machine Check int enable
122 FE0 = 52 # Floating-Point Exception Mode 0
123 TEs = 53 # Trace Enable (subfield)
124 TEe = 54 # Trace Enable (subfield)
125 FE1 = 55 # Floating-Point Exception Mode 1
126 IR = 58 # Instruction Relocation
127 DR = 59 # Data Relocation
128 PMM = 60 # Performance Monitor Mark
129 RI = 62 # Recoverable Interrupt
130 LE = 63 # Little Endian
131
132 # use this inside the HDL (where everything is little-endian)
133 MSR = _ConstLE("MSR", names=MSRb, msb=63)
134
135 # default MSR value for unit tests, since 0 isn't a good default
136 DEFAULT_MSR = sum(1 << i for i in (
137 MSR.SF, MSR.HV, MSR.FP, MSR.FE0, MSR.FE1, MSR.RI, MSR.LE))
138
139 # Listed in V3.0B Book III 7.5.9 "Program Interrupt"
140
141 # note that these correspond to trap_input_record.traptype bits 0,1,2,3,4
142 # (TODO: add more?)
143 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
144 # to expand traptype to cope with the increased range
145
146 # use this in the simulator
147 class PIb(_Const):
148 INVALID = 33 # 1 for an invalid mem err
149 PERMERR = 35 # 1 for an permanent mem err
150 TM_BAD_THING = 42 # 1 for a TM Bad Thing type interrupt
151 FP = 43 # 1 if FP exception
152 ILLEG = 44 # 1 if illegal instruction (not doing hypervisor)
153 PRIV = 45 # 1 if privileged interrupt
154 TRAP = 46 # 1 if exception is "trap" type
155 ADR = 47 # 0 if SRR0 = address of instruction causing exception
156
157 # and use this in the HDL
158 PI = _ConstLE("PI", names=PIb, msb=63)
159
160
161 # see traptype (and trap main_stage.py)
162 # IMPORTANT: when adding extra bits here it is CRITICALLY IMPORTANT
163 # to expand traptype to cope with the increased range
164
165 class TT:
166 FP = 1<<0
167 PRIV = 1<<1
168 TRAP = 1<<2
169 ADDR = 1<<3
170 EINT = 1<<4 # external interrupt
171 DEC = 1<<5 # decrement counter
172 MEMEXC = 1<<6 # LD/ST exception
173 ILLEG = 1<<7 # currently the max
174 # TODO: support for TM_BAD_THING (not included yet in trap main_stage.py)
175 size = 8 # MUST update this to contain the full number of Trap Types
176
177
178 # EXTRA3 3-bit subfield (spec)
179 class SPECb(_Const):
180 VEC = 0 # 1 for vector, 0 for scalar
181 MSB = 1 # augmented register number, MSB
182 LSB = 2 # augmented register number, LSB
183
184
185 SPEC_SIZE = 3
186 SPEC_AUG_SIZE = 2 # augmented subfield size (MSB+LSB above)
187 SPEC = _ConstLE("SPEC", names=SPECb, msb=SPEC_SIZE-1)
188
189
190
191 # EXTRA field, with EXTRA2 subfield encoding
192 class EXTRA2b(_Const):
193 IDX0_VEC = 0
194 IDX0_MSB = 1
195 IDX1_VEC = 2
196 IDX1_MSB = 3
197 IDX2_VEC = 4
198 IDX2_MSB = 5
199 IDX3_VEC = 6
200 IDX3_MSB = 7
201 RESERVED = 8
202
203
204 EXTRA2_SIZE = 9
205 EXTRA2 = _ConstLE("EXTRA2", names=EXTRA2b, msb=EXTRA2_SIZE-1)
206
207 # sigh, make these convenience-modifications afterwards (aliases)
208 # see RM-2P-1S1D-PU in https://libre-soc.org/openpower/sv/svp64
209 EXTRA2b.PACK_en = EXTRA2b.IDX2_VEC
210 EXTRA2b.UNPACK_en = EXTRA2b.IDX2_MSB
211 EXTRA2.PACK_en = EXTRA2.IDX2_VEC
212 EXTRA2.UNPACK_en = EXTRA2.IDX2_MSB
213
214
215 # EXTRA field, with EXTRA3 subfield encoding
216 class EXTRA3:
217 IDX0 = [0, 1, 2]
218 IDX1 = [3, 4, 5]
219 IDX2 = [6, 7, 8]
220 MASK = [6, 7, 8]
221
222
223 EXTRA3_SIZE = 9
224
225
226 # SVP64 ReMapped Field (from v3.1 EXT001 Prefix)
227 class SVP64P:
228 OPC = range(0, 6)
229 SVP64_7_9 = [7, 9]
230 RM = [6, 8] + list(range(10, 32))
231
232 # 24 bits in RM
233 SVP64P_SIZE = 24
234
235
236 # CR SVP64 offsets
237 class SVP64CROffs:
238 CR0 = 0 # TODO: increase when CRs are expanded to 128
239 CR1 = 1 # TODO: increase when CRs are expanded to 128
240 CRPred = 4 # TODO: increase when CRs are expanded to 128
241
242
243 class SVP64MODEb(_Const):
244 # mode bits
245 MOD2_MSB = 0
246 MOD2_LSB = 1
247 MOD3 = 3
248 SEA = 2
249 # when predicate not set: 0=ignore/skip 1=zero
250 DZ = 3 # for destination
251 SZ = 4 # for source
252 ZZ = 3 # for both sz/dz, on all but CR-ops, which, whoops, is RM bit 6.
253 # for branch-conditional
254 BC_SNZ = 3 # for branch-conditional mode
255 BC_VLI = 2 # for VL include/exclude on VLSET mode
256 BC_VLSET = 1 # VLSET mode
257 BC_CTRTEST = 0 # CTR-test mode
258 # reduce mode
259 REDUCE = 2 # 0=normal predication 1=reduce mode
260 CRM = 4 # CR mode on reduce (Rc=1) 0=some 1=all
261 RG = 4 # Reverse-gear on reduce
262 CROP_RG = 3 # Reverse-gear on reduce CR-ops
263 # saturation mode
264 N = 2 # saturation signed mode 0=signed 1=unsigned
265 # ffirst and predicate result modes
266 INV = 2 # invert CR sense 0=set 1=unset
267 CR_MSB = 3 # CR bit to update (with Rc=1)
268 CR_LSB = 4
269 VLI = 0
270 RC1 = 4 # update CR as if Rc=1 (when Rc=0)
271 # LD immediate els (element-stride) locations, depending on mode
272 ELS_NORMAL = 4
273 ELS_FFIRST_PRED = 3
274 LDI_PI = 2 # LD-Immediate Post-Increment
275 LDI_FF = 4 # LD-Immediate Fault-First
276 # LDST element-strided
277 LDST_ELS = 0 # Indexed element-strided
278 # LDST VLI for ffirst is in bit 0
279 LDST_VLI = 0
280 # BO bits
281 BO_MSB = 2
282 BO_LSB = 4
283
284
285 SVP64MODE_SIZE = 5
286
287
288 SVP64MODE = _ConstLE("SVP64MODE", names=SVP64MODEb, msb=SVP64MODE_SIZE-1)
289
290
291 # add subfields to use with nmutil.sel
292 SVP64MODE.MOD2 = [0, 1]
293 SVP64MODE.CR = [3, 4]
294
295
296 # CR sub-fields
297 class CRb(_Const):
298 LT = 0
299 GT = 1
300 EQ = 2
301 SO = 3
302
303
304 CR_SIZE = 4
305
306
307 CR = _ConstLE("CR", names=CRb, msb=CR_SIZE-1)
308
309
310 # POWER9 Register Files
311 # XXX these are specific to Libre-SOC's decoder. really, they
312 # should be in libre-soc. however... long story: because the
313 # PowerDecoder2 has been moved to openpower-isa, and its decoding
314 # depends on that, then... whoops.
315
316 # "State" Regfile
317 class StateRegsEnum:
318 PC = 0
319 MSR = 1
320 SVSTATE = 2
321 DEC = 3
322 TB = 4
323 N_REGS = 5 # maximum number of regs
324
325 # Fast SPRs Regfile
326 class FastRegsEnum:
327 LR = 0
328 CTR = 1
329 SRR0 = 2
330 SRR1 = 3
331 HSRR0 = 4
332 HSRR1 = 5
333 SPRG0 = 6
334 SPRG1 = 7
335 SPRG2 = 8
336 SPRG3 = 9
337 HSPRG0 = 10
338 HSPRG1 = 11
339 XER = 12 # non-XER bits
340 TAR = 13
341 SVSRR0 = 14
342 # only one spare!
343 N_REGS = 15 # maximum number of regs
344
345 # XER Regfile
346 class XERRegsEnum:
347 SO=0 # this is actually 2-bit but we ignore 1 bit of it
348 CA=1 # CA and CA32
349 OV=2 # OV and OV32
350 N_REGS = 3 # maximum number of regs
351
352
353 if __name__ == '__main__':
354 print("EXTRA2 pack", EXTRA2.PACK_en, EXTRA2.PACK_en.value)
355 for field in MSR:
356 if DEFAULT_MSR & (1 << field.value):
357 print(field)