def beq(arg1, arg2, arg3): "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq" dst = arg3 if m2_expr.ExprOp( m2_expr.TOK_EQUAL, arg1, arg2) else m2_expr.ExprLoc( ir.get_next_break_loc_key(instr), ir.IRDst.size) PC = dst ir.IRDst = dst
def slt(arg1, arg2, arg3): """If @arg2 is less than @arg3 (signed), @arg1 is set to one. It gets zero otherwise.""" arg1 = m2_expr.ExprCond( m2_expr.ExprOp(m2_expr.TOK_INF_SIGNED, arg2, arg3), m2_expr.ExprInt(1, arg1.size), m2_expr.ExprInt(0, arg1.size) )
def bgtzl(arg1, arg2): """Branches on @arg2 if the register @arg1 is greater than zero""" cond = m2_expr.ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, m2_expr.ExprInt(0, arg1.size)) dst_o = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if cond else arg2 PC = dst_o ir.IRDst = dst_o
def blezl(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than or equal to zero""" cond = m2_expr.ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, m2_expr.ExprInt(0, arg1.size)) dst_o = arg2 if cond else m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o
def bltzl(arg1, arg2): """Branches on @arg2 if the register @arg1 is less than zero""" dst_o = arg2 if m2_expr.ExprOp( m2_expr.TOK_INF_SIGNED, arg1, m2_expr.ExprInt( 0, arg1.size)) else m2_expr.ExprLoc( ir.get_next_delay_loc_key(instr), ir.IRDst.size) PC = dst_o ir.IRDst = dst_o
def bnel(arg1, arg2, arg3): """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT equal""" dst = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if m2_expr.ExprOp( m2_expr.TOK_EQUAL, arg1, arg2) else arg3 PC = dst ir.IRDst = dst
def bgezl(arg1, arg2): """Branches on @arg2 if the quantities of register @arg1 is greater than or equal to zero""" dst = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr), ir.IRDst.size) if m2_expr.ExprOp( m2_expr.TOK_INF_SIGNED, arg1, m2_expr.ExprInt(0, arg1.size)) else arg2 PC = dst ir.IRDst = dst
def ast_parse_op(tokens): if len(tokens) == 1: return tokens[0] if len(tokens) == 2: if tokens[0] in ['-', '+', '!']: return m2_expr.ExprOp(tokens[0], tokens[1]) if len(tokens) == 3: if tokens[1] == '-': # a - b => a + (-b) tokens[1] = '+' tokens[2] = - tokens[2] return m2_expr.ExprOp(tokens[1], tokens[0], tokens[2]) tokens = tokens[::-1] while len(tokens) >= 3: o1, op, o2 = tokens.pop(), tokens.pop(), tokens.pop() if op == '-': # a - b => a + (-b) op = '+' o2 = - o2 e = m2_expr.ExprOp(op, o1, o2) tokens.append(e) if len(tokens) != 1: raise NotImplementedError('strange op') return tokens[0]
def simp_add_mul(expr_simp, expr): "Naive Simplification: a + a + a == a * 3" # Match the expected form ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are ## attached to expression types if expr.op == "+" and \ len(expr.args) == 3 and \ expr.args.count(expr.args[0]) == len(expr.args): # Effective simplification return m2_expr.ExprOp("*", expr.args[0], m2_expr.ExprInt(3, expr.args[0].size)) else: # Do not simplify return expr
def operation(cls, size=32, depth=1): """Return an ExprOp @size: (optional) Operation size @depth: (optional) Expression depth """ operand_type = random.choice(list(cls.operations_by_args_number)) if isinstance(operand_type, str) and "+" in operand_type: number_args = random.randint(int(operand_type[:-1]), cls.operations_max_args_number) else: number_args = operand_type args = [ cls._gen(size=size, depth=depth - 1) for _ in range(number_args) ] operand = random.choice(cls.operations_by_args_number[operand_type]) return m2_expr.ExprOp(operand, *args)
def clz(ir, instr, rs, rd): e = [] e.append(m2_expr.ExprAssign(rd, m2_expr.ExprOp('cntleadzeros', rs))) return e, []
# Match the expected form ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are ## attached to expression types if expr.op == "+" and \ len(expr.args) == 3 and \ expr.args.count(expr.args[0]) == len(expr.args): # Effective simplification return m2_expr.ExprOp("*", expr.args[0], m2_expr.ExprInt(3, expr.args[0].size)) else: # Do not simplify return expr a = m2_expr.ExprId('a', 32) base_expr = a + a + a print("Without adding the simplification:") print("\t%s = %s" % (base_expr, expr_simp(base_expr))) # Enable pass expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]}) print("After adding the simplification:") print("\t%s = %s" % (base_expr, expr_simp(base_expr))) # Automatic fail assert (expr_simp(base_expr) == m2_expr.ExprOp("*", a, m2_expr.ExprInt(3, a.size)))
def possible_values(expr): """Return possible values for expression @expr, associated with their condition constraint as a ConstrainedValues instance @expr: Expr instance """ consvals = ConstrainedValues() # Terminal expression if (isinstance(expr, m2_expr.ExprInt) or isinstance(expr, m2_expr.ExprId) or isinstance(expr, m2_expr.ExprLoc)): consvals.add(ConstrainedValue(frozenset(), expr)) # Unary expression elif isinstance(expr, m2_expr.ExprSlice): consvals.update( ConstrainedValue(consval.constraints, consval.value[expr.start:expr.stop]) for consval in possible_values(expr.arg)) elif isinstance(expr, m2_expr.ExprMem): consvals.update( ConstrainedValue(consval.constraints, m2_expr.ExprMem(consval.value, expr.size)) for consval in possible_values(expr.ptr)) elif isinstance(expr, m2_expr.ExprAssign): consvals.update(possible_values(expr.src)) # Special case: constraint insertion elif isinstance(expr, m2_expr.ExprCond): src1cond = CondConstraintNotZero(expr.cond) src2cond = CondConstraintZero(expr.cond) consvals.update( ConstrainedValue(consval.constraints.union([src1cond]), consval.value) for consval in possible_values(expr.src1)) consvals.update( ConstrainedValue(consval.constraints.union([src2cond]), consval.value) for consval in possible_values(expr.src2)) # N-ary expression elif isinstance(expr, m2_expr.ExprOp): # For details, see ExprCompose consvals_args = [possible_values(arg) for arg in expr.args] for consvals_possibility in itertools.product(*consvals_args): args_value = [consval.value for consval in consvals_possibility] args_constraint = itertools.chain( *[consval.constraints for consval in consvals_possibility]) consvals.add( ConstrainedValue(frozenset(args_constraint), m2_expr.ExprOp(expr.op, *args_value))) elif isinstance(expr, m2_expr.ExprCompose): # Generate each possibility for sub-argument, associated with the start # and stop bit consvals_args = [list(possible_values(arg)) for arg in expr.args] for consvals_possibility in itertools.product(*consvals_args): # Merge constraint of each sub-element args_constraint = itertools.chain( *[consval.constraints for consval in consvals_possibility]) # Gen the corresponding constraints / ExprCompose args = [consval.value for consval in consvals_possibility] consvals.add( ConstrainedValue(frozenset(args_constraint), m2_expr.ExprCompose(*args))) else: raise RuntimeError("Unsupported type for expr: %s" % type(expr)) return consvals
def mn_cmp_unsigned(arg1, arg2, arg3): crf_dict[arg1]['LT'] = expr.ExprOp(expr.TOK_INF_UNSIGNED, arg2, arg3) crf_dict[arg1]['GT'] = expr.ExprOp(expr.TOK_INF_UNSIGNED, arg3, arg2) crf_dict[arg1]['EQ'] = expr.ExprOp(expr.TOK_EQUAL, arg2, arg3) crf_dict[arg1]['SO'] = XER_SO
def __ExprOp_cond(op, arg1, arg2): "Return an ExprOp standing for arg1 op arg2 with size to 1" ec = m2_expr.ExprOp(op, arg1, arg2) return ec
def divu(arg1, arg2): """Divide (unsigned) @arg1 by @arg2 and stores the remaining/result in $R_HI/$R_LO""" R_LO = m2_expr.ExprOp('udiv', arg1, arg2) R_HI = m2_expr.ExprOp('umod', arg1, arg2)