diff options
| author | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2018-08-04 16:15:54 +0200 |
|---|---|---|
| committer | Fabrice Desclaux <fabrice.desclaux@cea.fr> | 2018-08-06 16:03:48 +0200 |
| commit | 17cccfe652b70eb09f239bbdef6db3a0bf35fe93 (patch) | |
| tree | 6329c3f1ba052a9c20dca498cc99357fae780b57 /miasm2/expression/simplifications_explicit.py | |
| parent | 11c0be1c8ee4ad5ad5c92ccddcb5842cbd2f0b31 (diff) | |
| download | miasm-17cccfe652b70eb09f239bbdef6db3a0bf35fe93.tar.gz miasm-17cccfe652b70eb09f239bbdef6db3a0bf35fe93.zip | |
Simplifications: add high level to low level reduction
Diffstat (limited to 'miasm2/expression/simplifications_explicit.py')
| -rw-r--r-- | miasm2/expression/simplifications_explicit.py | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/miasm2/expression/simplifications_explicit.py b/miasm2/expression/simplifications_explicit.py new file mode 100644 index 00000000..78e056ec --- /dev/null +++ b/miasm2/expression/simplifications_explicit.py @@ -0,0 +1,155 @@ +from miasm2.expression.modint import size2mask +from miasm2.expression.expression import ExprInt, ExprCond, ExprOp, \ + ExprCompose + + +def simp_ext(_, expr): + if expr.op.startswith('zeroExt_'): + arg = expr.args[0] + if expr.size == arg.size: + return arg + return ExprCompose(arg, ExprInt(0, expr.size - arg.size)) + + if expr.op.startswith("signExt_"): + arg = expr.args[0] + add_size = expr.size - arg.size + new_expr = ExprCompose( + arg, + ExprCond( + arg.msb(), + ExprInt(size2mask(add_size), add_size), + ExprInt(0, add_size) + ) + ) + return new_expr + return expr + + +def simp_flags(_, expr): + args = expr.args + + if expr.is_op("FLAG_EQ"): + return ExprCond(args[0], ExprInt(0, 1), ExprInt(1, 1)) + + elif expr.is_op("FLAG_EQ_AND"): + op1, op2 = args + return ExprCond(op1 & op2, ExprInt(0, 1), ExprInt(1, 1)) + + elif expr.is_op("FLAG_SIGN_SUB"): + return (args[0] - args[1]).msb() + + elif expr.is_op("FLAG_EQ_CMP"): + return ExprCond( + args[0] - args[1], + ExprInt(0, 1), + ExprInt(1, 1), + ) + + elif expr.is_op("FLAG_ADD_CF"): + op1, op2 = args + res = op1 + op2 + return (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb() + + elif expr.is_op("FLAG_SUB_CF"): + op1, op2 = args + res = op1 - op2 + return (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb() + + elif expr.is_op("FLAG_ADD_OF"): + op1, op2 = args + res = op1 + op2 + return (((op1 ^ res) & (~(op1 ^ op2)))).msb() + + elif expr.is_op("FLAG_SUB_OF"): + op1, op2 = args + res = op1 - op2 + return (((op1 ^ res) & (op1 ^ op2))).msb() + + elif expr.is_op("FLAG_EQ_ADDWC"): + op1, op2, op3 = args + return ExprCond( + op1 + op2 + op3.zeroExtend(op1.size), + ExprInt(0, 1), + ExprInt(1, 1), + ) + + elif expr.is_op("FLAG_ADDWC_OF"): + op1, op2, op3 = args + res = op1 + op2 + op3.zeroExtend(op1.size) + return (((op1 ^ res) & (~(op1 ^ op2)))).msb() + + elif expr.is_op("FLAG_SUBWC_OF"): + op1, op2, op3 = args + res = op1 - (op2 + op3.zeroExtend(op1.size)) + return (((op1 ^ res) & (op1 ^ op2))).msb() + + elif expr.is_op("FLAG_ADDWC_CF"): + op1, op2, op3 = args + res = op1 + op2 + op3.zeroExtend(op1.size) + return (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (~(op1 ^ op2)))).msb() + + elif expr.is_op("FLAG_SUBWC_CF"): + op1, op2, op3 = args + res = op1 - (op2 + op3.zeroExtend(op1.size)) + return (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb() + + elif expr.is_op("FLAG_SIGN_ADDWC"): + op1, op2, op3 = args + return (op1 + op2 + op3.zeroExtend(op1.size)).msb() + + elif expr.is_op("FLAG_SIGN_SUBWC"): + op1, op2, op3 = args + return (op1 - (op2 + op3.zeroExtend(op1.size))).msb() + + + elif expr.is_op("FLAG_EQ_SUBWC"): + op1, op2, op3 = args + res = op1 - (op2 + op3.zeroExtend(op1.size)) + return ExprCond(res, ExprInt(0, 1), ExprInt(1, 1)) + + elif expr.is_op("CC_U<="): + op_cf, op_zf = args + return op_cf | op_zf + + elif expr.is_op("CC_U>="): + op_cf, = args + return ~op_cf + + elif expr.is_op("CC_S<"): + op_nf, op_of = args + return op_nf ^ op_of + + elif expr.is_op("CC_S>"): + op_nf, op_of, op_zf = args + return ~(op_zf | (op_nf ^ op_of)) + + elif expr.is_op("CC_S<="): + op_nf, op_of, op_zf = args + return op_zf | (op_nf ^ op_of) + + elif expr.is_op("CC_S>="): + op_nf, op_of = args + return ~(op_nf ^ op_of) + + elif expr.is_op("CC_U>"): + op_cf, op_zf = args + return ~(op_cf | op_zf) + + elif expr.is_op("CC_U<"): + op_cf, = args + return op_cf + + elif expr.is_op("CC_NEG"): + op_nf, = args + return op_nf + + elif expr.is_op("CC_EQ"): + op_zf, = args + return op_zf + + elif expr.is_op("CC_NE"): + op_zf, = args + return ~op_zf + + return expr + |