1ae31ce398417015763d6a1675b02f48f170ca70
1 # SPDX-License-Identifier: LGPLv3+
2 # Funded by NLnet https://nlnet.nl/
4 # XXX TODO: get this into openpower/consts.py instead.
5 # create the layout from an auto-created Enum FPSCRb
6 """ Record for FPSCR as defined in
7 Power ISA v3.1B Book I section 4.2.2 page 136(162)
11 |Bits |Mnemonic | Description |
12 |-----|---------|-------------------------------------------------------------|
13 |0:28 | | Reserved |
14 |29:31| DRN | Decimal Rounding Mode |
15 |32 | FX | FP Exception Summary |
16 |33 | FEX | FP Enabled Exception Summary |
17 |34 | VX | FP Invalid Operation Exception Summary |
18 |35 | OX | FP Overflow Exception |
19 |36 | UX | FP Underflow Exception |
20 |37 | ZX | FP Zero Divide Exception |
21 |38 | XX | FP Inexact Exception |
22 |39 | VXSNAN | FP Invalid Operation Exception (SNaN) |
23 |40 | VXISI | FP Invalid Operation Exception (∞ - ∞) |
24 |41 | VXIDI | FP Invalid Operation Exception (∞ ÷ ∞) |
25 |42 | VXZDZ | FP Invalid Operation Exception (0 ÷ 0) |
26 |43 | VXIMZ | FP Invalid Operation Exception (∞ × 0) |
27 |44 | VXVC | FP Invalid Operation Exception (Invalid Compare) |
28 |45 | FR | FP Fraction Rounded |
29 |46 | FI | FP Fraction Inexact |
30 |47:51| FPRF | FP Result Flags |
31 |47 | C | FP Result Class Descriptor |
32 |48:51| FPCC | FP Condition Code |
33 |48 | FL | FP Less Than or Negative |
34 |49 | FG | FP Greater Than or Positive |
35 |50 | FE | FP Equal or Zero |
36 |51 | FU | FP Unordered or NaN |
37 |52 | | Reserved |
38 |53 | VXSOFT | FP Invalid Operation Exception (Software-Defined Condition) |
39 |54 | VXSQRT | FP Invalid Operation Exception (Invalid Square Root) |
40 |55 | VXCVI | FP Invalid Operation Exception (Invalid Integer Convert) |
41 |56 | VE | FP Invalid Operation Exception Enable |
42 |57 | OE | FP Overflow Exception Enable |
43 |58 | UE | FP Underflow Exception Enable |
44 |59 | ZE | FP Zero Divide Exception Enable |
45 |60 | XE | FP Inexact Exception Enable |
46 |61 | NI | FP Non-IEEE Mode |
47 |62:63| RN | FP Rounding Control |
50 from nmigen
import Record
51 from copy
import deepcopy
52 from openpower
.util
import log
53 from openpower
.decoder
.selectable_int
import (
54 FieldSelectableInt
, SelectableInt
)
57 class FPSCRRecord(Record
):
97 def __init__(self
, name
=None):
98 super().__init
__(name
=name
, layout
=FPSCRRecord
.layout
)
101 class FPSCR_FPRF(FieldSelectableInt
):
102 """ special FieldSelectableInt instance to handle assigning strings to
105 Translation Table from:
106 PowerISA v3.1B Book I Section 4.2.2 Page 139(165)
107 Figure 47 Floating-Point Result Flags
109 TRANSLATION_TABLE
= (
110 ("Quiet NaN", 0b10001),
112 ("- Infinity", 0b01001),
113 ("- Normalized Number", 0b01000),
114 ("- Normal Number", 0b01000),
115 ("- Denormalized Number", 0b11000),
118 ("+ Denormalized Number", 0b10100),
119 ("+ Normalized Number", 0b00100),
120 ("+ Normal Number", 0b00100),
121 ("+ Infinity", 0b00101),
123 TRANSLATION_TABLE_DICT
= {k
.casefold(): v
for k
, v
in TRANSLATION_TABLE
}
126 if isinstance(b
, str):
127 b
= FPSCR_FPRF
.TRANSLATION_TABLE_DICT
[b
.casefold()]
131 class FPSCRState(SelectableInt
):
132 def __init__(self
, value
=0):
133 self
.__do
_update
_summary
_bits
= False
134 SelectableInt
.__init
__(self
, value
, 64)
137 # set up sub-fields from Record layout
139 l
= deepcopy(FPSCRRecord
.layout
)
141 for field
, width
in l
:
143 v
= FPSCR_FPRF(self
, tuple(range(47, 52)))
147 fs
= tuple(range(offs
, end
))
148 v
= FieldSelectableInt(self
, fs
)
151 # extra fields, temporarily explicitly added. TODO nested layout above
154 (range(48, 52), "FPCC"),
160 for offs
, field
in extras
:
161 if isinstance(offs
, int):
165 v
= FieldSelectableInt(self
, fs
)
167 self
.__update
_summary
_bits
()
174 def value(self
, value
):
176 if self
.__do
_update
_summary
_bits
:
177 self
.__update
_summary
_bits
()
179 def __update_summary_bits(self
):
180 self
.__do
_update
_summary
_bits
= False
182 # update summary bits -- FX is manually handled by pseudo-code,
183 # so we don't update it here
184 self
.VX
= (self
.VXSNAN |
193 self
.FEX
= ((self
.VX
& self
.VE
) |
194 (self
.OX
& self
.OE
) |
195 (self
.UX
& self
.UE
) |
196 (self
.ZX
& self
.ZE
) |
199 self
.__do
_update
_summary
_bits
= True
203 return self
.fsi
['DRN'].asint(msb0
=True)
206 def DRN(self
, value
):
207 self
.fsi
['DRN'].eq(value
)
211 return self
.fsi
['FX'].asint(msb0
=True)
215 self
.fsi
['FX'].eq(value
)
219 return self
.fsi
['FEX'].asint(msb0
=True)
222 def FEX(self
, value
):
223 self
.fsi
['FEX'].eq(value
)
227 return self
.fsi
['VX'].asint(msb0
=True)
231 self
.fsi
['VX'].eq(value
)
235 return self
.fsi
['OX'].asint(msb0
=True)
239 self
.fsi
['OX'].eq(value
)
243 return self
.fsi
['UX'].asint(msb0
=True)
247 self
.fsi
['UX'].eq(value
)
251 return self
.fsi
['ZX'].asint(msb0
=True)
255 self
.fsi
['ZX'].eq(value
)
259 return self
.fsi
['XX'].asint(msb0
=True)
263 self
.fsi
['XX'].eq(value
)
267 return self
.fsi
['VXSNAN'].asint(msb0
=True)
270 def VXSNAN(self
, value
):
271 self
.fsi
['VXSNAN'].eq(value
)
275 return self
.fsi
['VXISI'].asint(msb0
=True)
278 def VXISI(self
, value
):
279 self
.fsi
['VXISI'].eq(value
)
283 return self
.fsi
['VXIDI'].asint(msb0
=True)
286 def VXIDI(self
, value
):
287 self
.fsi
['VXIDI'].eq(value
)
291 return self
.fsi
['VXZDZ'].asint(msb0
=True)
294 def VXZDZ(self
, value
):
295 self
.fsi
['VXZDZ'].eq(value
)
299 return self
.fsi
['VXIMZ'].asint(msb0
=True)
302 def VXIMZ(self
, value
):
303 self
.fsi
['VXIMZ'].eq(value
)
307 return self
.fsi
['VXVC'].asint(msb0
=True)
310 def VXVC(self
, value
):
311 self
.fsi
['VXVC'].eq(value
)
315 return self
.fsi
['FR'].asint(msb0
=True)
319 self
.fsi
['FR'].eq(value
)
323 return self
.fsi
['FI'].asint(msb0
=True)
327 self
.fsi
['FI'].eq(value
)
331 return self
.fsi
['FPRF'].asint(msb0
=True)
334 def FPRF(self
, value
):
335 self
.fsi
['FPRF'].eq(value
)
339 return self
.fsi
['C'].asint(msb0
=True)
343 self
.fsi
['C'].eq(value
)
347 return self
.fsi
['FPCC'].asint(msb0
=True)
350 def FPCC(self
, value
):
351 self
.fsi
['FPCC'].eq(value
)
355 return self
.fsi
['FL'].asint(msb0
=True)
359 self
.fsi
['FL'].eq(value
)
363 return self
.fsi
['FG'].asint(msb0
=True)
367 self
.fsi
['FG'].eq(value
)
371 return self
.fsi
['FE'].asint(msb0
=True)
375 self
.fsi
['FE'].eq(value
)
379 return self
.fsi
['FU'].asint(msb0
=True)
383 self
.fsi
['FU'].eq(value
)
387 return self
.fsi
['VXSOFT'].asint(msb0
=True)
390 def VXSOFT(self
, value
):
391 self
.fsi
['VXSOFT'].eq(value
)
395 return self
.fsi
['VXSQRT'].asint(msb0
=True)
398 def VXSQRT(self
, value
):
399 self
.fsi
['VXSQRT'].eq(value
)
403 return self
.fsi
['VXCVI'].asint(msb0
=True)
406 def VXCVI(self
, value
):
407 self
.fsi
['VXCVI'].eq(value
)
411 return self
.fsi
['VE'].asint(msb0
=True)
415 self
.fsi
['VE'].eq(value
)
419 return self
.fsi
['OE'].asint(msb0
=True)
423 self
.fsi
['OE'].eq(value
)
427 return self
.fsi
['UE'].asint(msb0
=True)
431 self
.fsi
['UE'].eq(value
)
435 return self
.fsi
['ZE'].asint(msb0
=True)
439 self
.fsi
['ZE'].eq(value
)
443 return self
.fsi
['XE'].asint(msb0
=True)
447 self
.fsi
['XE'].eq(value
)
451 return self
.fsi
['NI'].asint(msb0
=True)
455 self
.fsi
['NI'].eq(value
)
459 return self
.fsi
['RN'].asint(msb0
=True)
463 self
.fsi
['RN'].eq(value
)
466 if __name__
== "__main__":
467 from pprint
import pprint
468 print("FPSCRRecord.layout:")
469 pprint(FPSCRRecord
.layout
)
470 print("FPSCRState.fsi:")
471 pprint(FPSCRState().fsi
)
473 # quick test of setter/getters
476 print(fpscr
.FPCC
, fpscr
.FL
, fpscr
.FG
, fpscr
.FE
, fpscr
.FU
)
478 print(fpscr
.FPCC
, fpscr
.FL
, fpscr
.FG
, fpscr
.FE
, fpscr
.FU
)
480 print(fpscr
.FPRF
, fpscr
.C
)