use the CSV "CR out" column to compute which mode to use for Rc=1
[openpower-isa.git] / src / openpower / util.py
1 from enum import Enum
2 from fnmatch import fnmatchcase
3 import os
4 import random
5 from openpower.consts import FastRegsEnum, StateRegsEnum
6 from openpower.decoder.power_enums import SPRfull as SPR, spr_dict
7 from functools import lru_cache
8
9
10 # note that we can get away with using SPRfull here because the values
11 # (numerical values) are what is used for lookup.
12 spr_to_fast = {
13 SPR.LR: FastRegsEnum.LR,
14 SPR.CTR: FastRegsEnum.CTR,
15 SPR.SRR0: FastRegsEnum.SRR0,
16 SPR.SRR1: FastRegsEnum.SRR1,
17 SPR.HSRR0: FastRegsEnum.HSRR0,
18 SPR.HSRR1: FastRegsEnum.HSRR1,
19 SPR.SPRG0_priv: FastRegsEnum.SPRG0,
20 SPR.SPRG1_priv: FastRegsEnum.SPRG1,
21 SPR.SPRG2_priv: FastRegsEnum.SPRG2,
22 SPR.SPRG3: FastRegsEnum.SPRG3,
23 SPR.HSPRG0: FastRegsEnum.HSPRG0,
24 SPR.HSPRG1: FastRegsEnum.HSPRG1,
25 SPR.XER: FastRegsEnum.XER,
26 SPR.TAR: FastRegsEnum.TAR,
27 SPR.SVSRR0: FastRegsEnum.SVSRR0,
28 }
29
30 spr_to_state = {SPR.DEC: StateRegsEnum.DEC,
31 SPR.TB: StateRegsEnum.TB,
32 }
33
34 sprstr_to_state = {}
35 state_to_spr = {}
36 for (k, v) in spr_to_state.items():
37 sprstr_to_state[k.name] = v
38 state_to_spr[v] = k
39
40
41 def state_reg_to_spr(spr_num):
42 return state_to_spr[spr_num].value
43
44
45 def spr_to_state_reg(spr_num):
46 if not isinstance(spr_num, str):
47 spr_num = spr_dict[spr_num].SPR
48 return sprstr_to_state.get(spr_num, None)
49
50
51 sprstr_to_fast = {}
52 fast_to_spr = {}
53 for (k, v) in spr_to_fast.items():
54 sprstr_to_fast[k.name] = v
55 fast_to_spr[v] = k
56
57
58 def fast_reg_to_spr(spr_num):
59 return fast_to_spr[spr_num].value
60
61
62 def spr_to_fast_reg(spr_num):
63 if not isinstance(spr_num, str):
64 spr_num = spr_dict[spr_num].SPR
65 return sprstr_to_fast.get(spr_num, None)
66
67
68 def slow_reg_to_spr(slow_reg):
69 for i, x in enumerate(SPR):
70 if slow_reg == i:
71 return x.value
72
73
74 def spr_to_slow_reg(spr_num):
75 for i, x in enumerate(SPR):
76 if spr_num == x.value:
77 return i
78
79
80 # TODO: make this a util routine (somewhere)
81 def mask_extend(x, nbits, repeat):
82 res = 0
83 extended = (1 << repeat)-1
84 for i in range(nbits):
85 if x & (1 << i):
86 res |= extended << (i*repeat)
87 return res
88
89
90 # makes a logarithmically-skewed random number
91 def log_rand(n, min_val=1):
92 logrange = random.randint(1, n)
93 return random.randint(min_val, (1 << logrange)-1)
94
95
96 class LogKind(Enum):
97 Default = "default"
98 InstrInOuts = "instr_in_outs"
99 SkipCase = "skip_case"
100
101
102 @lru_cache(typed=True)
103 def __parse_log_env_var(silencelog_raw):
104 if silencelog_raw is None:
105 return {k: False for k in LogKind}
106 silencelog = os.environ.decodevalue(silencelog_raw)
107 silencelog = silencelog.lower().split(",")
108 for i, v in enumerate(silencelog):
109 silencelog[i] = v.strip()
110 retval = {k: True for k in LogKind}
111 if len(silencelog) > 1 and silencelog[-1] == "":
112 # allow trailing comma
113 silencelog.pop()
114 if len(silencelog) == 1:
115 if silencelog[0] in ("0", "false"):
116 for k in LogKind:
117 retval[k] = False
118 silencelog.pop()
119 if silencelog[0] in ("1", "true", ""):
120 silencelog.pop()
121 for v in silencelog:
122 silenced = True
123 if v.startswith("!"):
124 v = v[1:]
125 silenced = False
126 matches = False
127 for k in LogKind:
128 if fnmatchcase(k.value, v):
129 matches = True
130 retval[k] = silenced
131 assert matches, (f"SILENCELOG: {v!r} did not match any known LogKind: "
132 f"LogKinds: {' '.join(i.value for i in LogKind)}")
133 # for k, v in retval.items():
134 # print(repr(k), "silenced" if v else "active")
135 return retval
136
137
138 __ENCODED_SILENCELOG = os.environ.encodekey("SILENCELOG")
139
140
141 def log(*args, kind=LogKind.Default, **kwargs):
142 """verbose printing, can be disabled by setting env var "SILENCELOG".
143 """
144 # look up in os.environ._data since it is a dict and hence won't raise
145 # internal exceptions to avoid triggering breakpoints on raised exceptions.
146 env_var = os.environ._data.get(__ENCODED_SILENCELOG, None)
147 silenced = __parse_log_env_var(env_var)
148 if silenced[kind]:
149 return
150 print(*args, **kwargs)