12 """This passe includes:
14 - Common logical identities
15 - Common binary identities
24 if op
in op_propag_cst:
25 while (len(args) >= 2
and
26 isinstance(args[-1], ExprInt)
and
27 isinstance(args[-2], ExprInt)):
45 x1 = mod_size2int[i1.arg.size](i1.arg)
46 x2 = mod_size2int[i2.arg.size](i2.arg)
47 o = mod_size2uint[i1.arg.size](x1 >> x2)
50 o = i1.arg >> i2.arg | i1.arg << (i1.size - i2.arg)
52 o = i1.arg << i2.arg | i1.arg >> (i1.size - i2.arg)
59 x1 = mod_size2int[i1.arg.size](i1.arg)
60 x2 = mod_size2int[i2.arg.size](i2.arg)
61 o = mod_size2uint[i1.arg.size](x1 / x2)
64 x1 = mod_size2int[i1.arg.size](i1.arg)
65 x2 = mod_size2int[i2.arg.size](i2.arg)
66 o = mod_size2uint[i1.arg.size](x1 % x2)
69 x1 = mod_size2uint[i1.arg.size](i1.arg)
70 x2 = mod_size2uint[i2.arg.size](i2.arg)
71 o = mod_size2uint[i1.arg.size](x1 % x2)
74 x1 = mod_size2uint[i1.arg.size](i1.arg)
75 x2 = mod_size2uint[i2.arg.size](i2.arg)
76 o = mod_size2uint[i1.arg.size](x1 / x2)
84 if op ==
"bsf" and isinstance(args[0], ExprInt)
and args[0].arg != 0:
86 while args[0].arg & (1 << i) == 0:
91 if op ==
"bsr" and isinstance(args[0], ExprInt)
and args[0].arg != 0:
93 while args[0].arg & (1 << i) == 0:
98 if op ==
'-' and len(args) == 1
and isinstance(args[0], ExprOp)
and \
99 args[0].op ==
'-' and len(args[0].args) == 1:
100 return args[0].args[0]
103 if op ==
'-' and len(args) == 1
and isinstance(args[0], ExprInt):
106 if op
in [
'+',
'|',
"^",
"<<",
">>",
"<<<",
">>>"]
and len(args) > 1:
107 if isinstance(args[-1], ExprInt)
and args[-1].arg == 0:
110 if op ==
'-' and len(args) > 1
and args[-1].arg == 0:
111 assert(len(args) == 2)
115 if op ==
"*" and len(args) > 1:
116 if isinstance(args[-1], ExprInt)
and args[-1].arg == 1:
121 if op ==
"*" and len(args) > 1:
122 if (isinstance(args[-1], ExprInt)
and
123 args[-1].arg == (1 << args[-1].size) - 1):
125 args[-1] = - args[-1]
128 if op
in [
'+',
'*',
'^',
'&',
'|',
'>>',
'<<',
129 'a>>',
'<<<',
'>>>',
'idiv',
'imod',
'umod',
'udiv']
and len(args) == 1:
133 if op ==
'-' and len(args) > 1:
136 'sanity check fail on expr -: should have one or 2 args ' +
138 return ExprOp(
'+', args[0], -args[1])
141 if op
in [
'&',
"*"]
and isinstance(args[1], ExprInt)
and args[1].arg == 0:
147 isinstance(args[0], ExprOp)
and
149 args = [-a
for a
in args[0].args]
156 isinstance(args[0], ExprCond)
and
157 isinstance(args[0].src1, ExprInt)
and
158 isinstance(args[0].src2, ExprInt)):
163 return ExprCond(args[0].cond, i1, i2)
166 while i < len(args) - 1:
170 if op ==
'^' and args[i] == args[j]:
175 if op ==
'+' and isinstance(args[j], ExprOp)
and args[j].op ==
"-":
176 if len(args[j].args) == 1
and args[i] == args[j].args[0]:
181 if op ==
'+' and isinstance(args[i], ExprOp)
and args[i].op ==
"-":
182 if len(args[i].args) == 1
and args[j] == args[i].args[0]:
187 if op ==
'|' and args[i] == args[j]:
191 if op ==
'&' and args[i] == args[j]:
197 if op
in [
'|',
'&',
'%',
'/']
and len(args) == 1:
201 if (op
in [
'<<<',
'>>>']
and
202 isinstance(args[1], ExprInt)
and
203 args[1].arg == args[0].size):
207 if (op
in [
'<<<',
'>>>']
and
208 isinstance(args[0], ExprOp)
and
209 args[0].op
in [
'<<<',
'>>>']):
214 args1 = args[0].args[1] + args[1]
217 args1 = args[0].args[1] - args[1]
219 args0 = args[0].args[0]
220 args = [args0, args1]
223 if (op
in [
'<<',
'>>']
and
224 isinstance(args[0], ExprOp)
and
226 args = [args[0].args[0], args[0].args[1] + args[1]]
229 if op ==
"&" and args[-1] == e.mask:
230 return ExprOp(
'&', *args[:-1])
233 if op ==
"|" and args[-1] == e.mask:
241 isinstance(args[1], ExprInt)
and
242 isinstance(args[0], ExprOp)
and args[0].op ==
"&"):
243 if (isinstance(args[0].args[1], ExprInt)
and
244 2 ** args[1].arg > args[0].args[1].arg):
248 if op ==
'parity' and isinstance(args[0], ExprInt):
252 if op ==
"*" and len(args) > 1:
256 if isinstance(a, ExprOp)
and a.op ==
'-' and len(a.args) == 1:
257 new_args.append(a.args[0])
262 return -
ExprOp(op, *new_args)
266 if op ==
"<<" and isinstance(args[0], ExprCompose)
and isinstance(args[1], ExprInt):
267 final_size = args[0].size
268 shift = int(args[1].arg)
271 for expr, start, stop
in args[0].args:
272 new_args.append((expr, start+shift, stop+shift))
275 min_index = final_size
276 for expr, start, stop
in new_args:
277 if start >= final_size:
279 if stop > final_size:
280 expr = expr[:expr.size - (stop - final_size)]
282 filter_args.append((expr, start, stop))
283 min_index = min(start, min_index)
286 filter_args = [(expr, 0, min_index)] + filter_args
290 if op ==
">>" and isinstance(args[0], ExprCompose)
and isinstance(args[1], ExprInt):
291 final_size = args[0].size
292 shift = int(args[1].arg)
295 for expr, start, stop
in args[0].args:
296 new_args.append((expr, start-shift, stop-shift))
300 for expr, start, stop
in new_args:
306 filter_args.append((expr, start, stop))
307 max_index = max(stop, max_index)
309 expr =
ExprInt(0, final_size - max_index)
310 filter_args += [(expr, max_index, final_size)]
315 if op
in [
'|',
'&',
'^']
and all([isinstance(arg, ExprCompose)
for arg
in args]):
318 bound = tuple([(start, stop)
for (expr, start, stop)
in arg.args])
321 bound = list(bounds)[0]
322 new_args = [[expr]
for (expr, start, stop)
in args[0].args]
323 for sub_arg
in args[1:]:
324 for i, (expr, start, stop)
in enumerate(sub_arg.args):
325 new_args[i].append(expr)
326 for i, arg
in enumerate(new_args):
327 new_args[i] =
ExprOp(op, *arg), bound[i][0], bound[i][1]