11 """This passe includes:
13 - Common logical identities
14 - Common binary identities
23 if op
in op_propag_cst:
24 while (len(args) >= 2
and
25 isinstance(args[-1], ExprInt)
and
26 isinstance(args[-2], ExprInt)):
44 x1 = mod_size2int[i1.arg.size](i1.arg)
45 x2 = mod_size2int[i2.arg.size](i2.arg)
46 o = mod_size2uint[i1.arg.size](x1 >> x2)
49 o = i1.arg >> i2.arg | i1.arg << (i1.size - i2.arg)
51 o = i1.arg << i2.arg | i1.arg >> (i1.size - i2.arg)
58 x1 = mod_size2int[i1.arg.size](i1.arg)
59 x2 = mod_size2int[i2.arg.size](i2.arg)
60 o = mod_size2uint[i1.arg.size](x1 / x2)
63 x1 = mod_size2int[i1.arg.size](i1.arg)
64 x2 = mod_size2int[i2.arg.size](i2.arg)
65 o = mod_size2uint[i1.arg.size](x1 % x2)
68 x1 = mod_size2uint[i1.arg.size](i1.arg)
69 x2 = mod_size2uint[i2.arg.size](i2.arg)
70 o = mod_size2uint[i1.arg.size](x1 % x2)
73 x1 = mod_size2uint[i1.arg.size](i1.arg)
74 x2 = mod_size2uint[i2.arg.size](i2.arg)
75 o = mod_size2uint[i1.arg.size](x1 / x2)
83 if op ==
"bsf" and isinstance(args[0], ExprInt)
and args[0].arg != 0:
85 while args[0].arg & (1 << i) == 0:
90 if op ==
"bsr" and isinstance(args[0], ExprInt)
and args[0].arg != 0:
92 while args[0].arg & (1 << i) == 0:
97 if op ==
'-' and len(args) == 1
and isinstance(args[0], ExprOp)
and \
98 args[0].op ==
'-' and len(args[0].args) == 1:
99 return args[0].args[0]
102 if op ==
'-' and len(args) == 1
and isinstance(args[0], ExprInt):
105 if op
in [
'+',
'|',
"^",
"<<",
">>",
"<<<",
">>>"]
and len(args) > 1:
106 if isinstance(args[-1], ExprInt)
and args[-1].arg == 0:
109 if op ==
'-' and len(args) > 1
and args[-1].arg == 0:
110 assert(len(args) == 2)
114 if op ==
"*" and len(args) > 1:
115 if isinstance(args[-1], ExprInt)
and args[-1].arg == 1:
120 if op ==
"*" and len(args) > 1:
121 if (isinstance(args[-1], ExprInt)
and
122 args[-1].arg == (1 << args[-1].size) - 1):
124 args[-1] = - args[-1]
127 if op
in [
'+',
'*',
'^',
'&',
'|',
'>>',
'<<',
128 'a>>',
'<<<',
'>>>',
'idiv',
'imod',
'umod',
'udiv']
and len(args) == 1:
132 if op ==
'-' and len(args) > 1:
135 'sanity check fail on expr -: should have one or 2 args ' +
137 return ExprOp(
'+', args[0], -args[1])
140 if op
in [
'&',
"*"]
and isinstance(args[1], ExprInt)
and args[1].arg == 0:
146 isinstance(args[0], ExprOp)
and
148 args = [-a
for a
in args[0].args]
155 isinstance(args[0], ExprCond)
and
156 isinstance(args[0].src1, ExprInt)
and
157 isinstance(args[0].src2, ExprInt)):
162 return ExprCond(args[0].cond, i1, i2)
165 while i < len(args) - 1:
169 if op ==
'^' and args[i] == args[j]:
174 if op ==
'+' and isinstance(args[j], ExprOp)
and args[j].op ==
"-":
175 if len(args[j].args) == 1
and args[i] == args[j].args[0]:
180 if op ==
'+' and isinstance(args[i], ExprOp)
and args[i].op ==
"-":
181 if len(args[i].args) == 1
and args[j] == args[i].args[0]:
186 if op ==
'|' and args[i] == args[j]:
190 if op ==
'&' and args[i] == args[j]:
196 if op
in [
'|',
'&',
'%',
'/']
and len(args) == 1:
200 if (op
in [
'<<<',
'>>>']
and
201 isinstance(args[1], ExprInt)
and
202 args[1].arg == args[0].size):
206 if (op
in [
'<<<',
'>>>']
and
207 isinstance(args[0], ExprOp)
and
208 args[0].op
in [
'<<<',
'>>>']):
213 args1 = args[0].args[1] + args[1]
216 args1 = args[0].args[1] - args[1]
218 args0 = args[0].args[0]
219 args = [args0, args1]
222 if (op
in [
'<<',
'>>']
and
223 isinstance(args[0], ExprOp)
and
225 args = [args[0].args[0], args[0].args[1] + args[1]]
228 if op ==
"&" and args[-1] == e.mask:
229 return ExprOp(
'&', *args[:-1])
232 if op ==
"|" and args[-1] == e.mask:
240 isinstance(args[1], ExprInt)
and
241 isinstance(args[0], ExprOp)
and args[0].op ==
"&"):
242 if (isinstance(args[0].args[1], ExprInt)
and
243 2 ** args[1].arg > args[0].args[1].arg):
247 if op ==
'parity' and isinstance(args[0], ExprInt):
251 if op ==
"*" and len(args) > 1:
255 if isinstance(a, ExprOp)
and a.op ==
'-' and len(a.args) == 1:
256 new_args.append(a.args[0])
261 return -
ExprOp(op, *new_args)
265 if op ==
"<<" and isinstance(args[0], ExprCompose)
and isinstance(args[1], ExprInt):
266 final_size = args[0].size
267 shift = int(args[1].arg)
270 for expr, start, stop
in args[0].args:
271 new_args.append((expr, start+shift, stop+shift))
274 min_index = final_size
275 for expr, start, stop
in new_args:
276 if start >= final_size:
278 if stop > final_size:
279 expr = expr[:expr.size - (stop - final_size)]
281 filter_args.append((expr, start, stop))
282 min_index = min(start, min_index)
285 filter_args = [(expr, 0, min_index)] + filter_args
289 if op ==
">>" and isinstance(args[0], ExprCompose)
and isinstance(args[1], ExprInt):
290 final_size = args[0].size
291 shift = int(args[1].arg)
294 for expr, start, stop
in args[0].args:
295 new_args.append((expr, start-shift, stop-shift))
299 for expr, start, stop
in new_args:
305 filter_args.append((expr, start, stop))
306 max_index = max(stop, max_index)
308 expr =
ExprInt(0, final_size - max_index)
309 filter_args += [(expr, max_index, final_size)]
314 if op
in [
'|',
'&',
'^']
and all([isinstance(arg, ExprCompose)
for arg
in args]):
317 bound = tuple([(start, stop)
for (expr, start, stop)
in arg.args])
320 bound = list(bounds)[0]
321 new_args = [[expr]
for (expr, start, stop)
in args[0].args]
322 for sub_arg
in args[1:]:
323 for i, (expr, start, stop)
in enumerate(sub_arg.args):
324 new_args[i].append(expr)
325 for i, arg
in enumerate(new_args):
326 new_args[i] =
ExprOp(op, *arg), bound[i][0], bound[i][1]
333 "Extract conditions from operations"
335 if not e.op
in [
"+",
"|",
"^",
"&",
"*",
'<<',
'>>',
'a>>']:
339 if not isinstance(e.args[-1], ExprInt):
343 for a
in e.args[:-1]:
344 if not isinstance(a, ExprCond):
351 ExprOp(e.op, c.src1, a_int),
352 ExprOp(e.op, c.src2, a_int))
354 new_e =
ExprOp(e.op, *conds)
359 "Merge similar conditions"
360 if not e.op
in [
"+",
"|",
"^",
"&",
"*",
'<<',
'>>',
'a>>']:
368 if not isinstance(a, ExprCond):
380 for c, vals
in conds.items():
381 new_src1 = [x.src1
for x
in vals]
382 new_src2 = [x.src2
for x
in vals]
383 src1 = e_s.expr_simp_wrapper(
ExprOp(e.op, *new_src1))
384 src2 = e_s.expr_simp_wrapper(
ExprOp(e.op, *new_src2))
385 c_out.append(
ExprCond(c, src1, src2))
390 new_e =
ExprOp(e.op, *c_out)
398 if e.start == 0
and e.stop == e.arg.size:
401 elif isinstance(e.arg, ExprInt):
402 total_bit = e.stop - e.start
403 mask = (1 << (e.stop - e.start)) - 1
404 return ExprInt(int((e.arg.arg >> e.start) & mask), total_bit)
406 elif isinstance(e.arg, ExprSlice):
407 if e.stop - e.start > e.arg.stop - e.arg.start:
408 raise ValueError(
'slice in slice: getting more val', str(e))
410 new_e =
ExprSlice(e.arg.arg, e.start + e.arg.start,
411 e.start + e.arg.start + (e.stop - e.start))
413 elif isinstance(e.arg, ExprCompose):
416 if a[1] <= e.start
and a[2] >= e.stop:
417 new_e = a[0][e.start - a[1]:e.stop - a[1]]
421 for arg, s_start, s_stop
in e.arg.args:
423 if e.start >= s_stop:
426 elif e.stop <= s_start:
429 elif e.start <= s_start
and s_stop <= e.stop:
430 out.append((arg, s_start - e.start, s_stop - e.start))
433 if e.start > s_start:
434 slice_start = e.start - s_start
439 a_start = s_start - e.start
442 slice_stop = arg.size + e.stop - s_stop - slice_start
443 a_stop = e.stop - e.start
445 slice_stop = arg.size
446 a_stop = s_stop - e.start
447 out.append((arg[slice_start:slice_stop], a_start, a_stop))
452 elif (isinstance(e.arg, ExprMem)
and
454 e.arg.size > e.stop
and e.stop % 8 == 0):
455 e =
ExprMem(e.arg.arg, size=e.stop)
459 elif (isinstance(e.arg, ExprOp)
and
461 isinstance(e.arg.args[-1], ExprInt)):
462 tmp = e_s.expr_simp_wrapper(e.arg.args[-1][e.start:e.stop])
463 if isinstance(tmp, ExprInt)
and tmp.arg == 0:
467 elif (isinstance(e.arg, ExprCond)
and
468 isinstance(e.arg.src1, ExprInt)
and
469 isinstance(e.arg.src2, ExprInt)):
470 src1 = e.arg.src1[e.start:e.stop]
471 src2 = e.arg.src2[e.start:e.stop]
472 e =
ExprCond(e.arg.cond, src1, src2)
475 elif (e.start == 0
and isinstance(e.arg, ExprOp)
and
476 e.arg.op ==
"*" and isinstance(e.arg.args[-1], ExprInt)):
477 args = [e_s.expr_simp_wrapper(a[e.start:e.stop])
for a
in e.arg.args]
478 e =
ExprOp(e.arg.op, *args)
482 elif (isinstance(e.arg, ExprOp)
and e.arg.op
in [
">>",
"<<"]
and
483 isinstance(e.arg.args[1], ExprInt)):
484 arg, shift = e.arg.args
485 shift = int(shift.arg)
487 if shift + e.stop <= arg.size:
488 return arg[e.start + shift:e.stop + shift]
489 elif e.arg.op ==
"<<":
490 if e.start - shift >= 0:
491 return arg[e.start - shift:e.stop - shift]
493 raise ValueError(
'Bad case')
499 "Commons simplification on ExprCompose"
504 if isinstance(a[0], ExprCompose):
505 for x, start, stop
in a[0].args:
506 out.append((x, start + a[1], stop + a[1]))
511 if len(args) == 1
and args[0][1] == 0
and args[0][2] == e.size:
515 if (len(args) == 2
and
516 isinstance(args[1][0], ExprInt)
and
517 args[1][0].arg == 0):
520 if (isinstance(a1[0], ExprSlice)
and
522 a1[0].stop == a1[0].arg.size
and
523 a2[1] == a1[0].size
and
524 a2[2] == a1[0].arg.size):
526 a1[0].start, a1[0].arg.size)
536 for i, a
in enumerate(args):
541 if isinstance(a[0], ExprCond):
542 if expr_cond
is not None:
547 if ok
and expr_cond
is not None:
550 for i, a
in enumerate(expr_ints):
552 src1.append((a[0].src1, a[1], a[2]))
553 src2.append((a[0].src2, a[1], a[2]))
559 if isinstance(src1, ExprInt)
and isinstance(src2, ExprInt):
560 return ExprCond(cond.cond, src1, src2)
565 "Common simplifications on ExprCond"
568 if (
not isinstance(e.cond, ExprInt))
and e.cond.size == 1:
569 src1 = e.src1.replace_expr({e.cond:
ExprInt1(1)})
570 src2 = e.src2.replace_expr({e.cond:
ExprInt1(0)})
571 if src1 != e.src1
or src2 != e.src2:
575 if (isinstance(e.cond, ExprOp)
and
577 len(e.cond.args) == 1):
578 e =
ExprCond(e.cond.args[0], e.src1, e.src2)
580 elif e.src1 == e.src2:
583 elif isinstance(e.cond, ExprInt):
589 elif isinstance(e.src1, ExprCond)
and e.cond == e.src1.cond:
590 e =
ExprCond(e.cond, e.src1.src1, e.src2)
592 elif isinstance(e.src2, ExprCond)
and e.cond == e.src2.cond:
593 e =
ExprCond(e.cond, e.src1, e.src2.src2)
595 elif (isinstance(e.cond, ExprOp)
and
597 isinstance(e.cond.args[1], ExprInt)
and
598 e.cond.args[1].arg != 0):
602 elif (isinstance(e.cond, ExprCond)
and
603 isinstance(e.cond.src1, ExprInt)
and
604 isinstance(e.cond.src2, ExprInt)):
605 int1 = e.cond.src1.arg.arg
606 int2 = e.cond.src2.arg.arg
609 elif int1 == 0
and int2 == 0:
611 elif int1 == 0
and int2:
612 e =
ExprCond(e.cond.cond, e.src2, e.src1)
613 elif int1
and int2 == 0:
614 e =
ExprCond(e.cond.cond, e.src1, e.src2)
def is_int_or_cond_src_int