* ir_node *new_Cmp (ir_node *op1, ir_node *op2);
* ir_node *new_Conv (ir_node *op, ir_mode *mode);
* ir_node *new_Cast (ir_node *op, ir_type *to_tp);
+ * ir_node *new_Carry (ir_node *op1, ir_node *op2, ir_mode *mode);
+ * ir_node *new_Borrow (ir_node *op1, ir_node *op2, ir_mode *mode);
* ir_node *new_Load (ir_node *store, ir_node *addr, ir_mode *mode, ir_cons_flags flags);
* ir_node *new_Store (ir_node *store, ir_node *addr, ir_node *val, ir_cons_flags flags);
* ir_node *new_Alloc (ir_node *store, ir_node *count, ir_type *alloc_type,
*
* Rotates the operand to the left by k bits.
*
+ * ir_node *new_Carry (ir_node *op1, ir_node *op2, ir_mode *mode)
+ * ------------------------------------------------------------
+ *
+ * Calculates the Carry value for integer addition. Used only
+ * in lowering code.
+ *
+ * ir_node *new_Borrow (ir_node *op1, ir_node *op2, ir_mode *mode)
+ * ------------------------------------------------------------
+ *
+ * Calculates the Borrow value for integer substraction. Used only
+ * in lowering code.
+ *
* ir_node *new_Conv (ir_node *op, ir_mode *mode)
* ---------------------------------------------
*
FIRM_API ir_node *new_rd_Cast(dbg_info *db, ir_node *block,
ir_node *op, ir_type *to_tp);
+/** Constructor for a Carry node.
+ * Note: This node is not supported by the backends! Only use for program
+ * analysis tasks.
+ *
+ * @param *db A pointer for debug information.
+ * @param *block The IR block the node belongs to.
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_rd_Carry(dbg_info *db, ir_node *block,
+ ir_node *op1, ir_node *op2, ir_mode *mode);
+
+/** Constructor for a Borrow node.
+ * Note: This node is not supported by the backends! Only use for program
+ * analysis tasks.
+ *
+ * @param *db A pointer for debug information.
+ * @param *block The IR block the node belongs to.
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_rd_Borrow(dbg_info *db, ir_node *block,
+ ir_node *op1, ir_node *op2, ir_mode *mode);
+
/** Constructor for a Phi node.
*
* @param *db A pointer for debug information.
*/
FIRM_API ir_node *new_r_Cast(ir_node *block, ir_node *op, ir_type *to_tp);
+/** Constructor for a Carry node.
+ *
+ * @param *block The IR block the node belongs to.
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_r_Carry(ir_node *block, ir_node *op1, ir_node *op2,
+ ir_mode *mode);
+
+/**
+ * Constructor for a Borrow node.
+ *
+ * @param *block The IR block the node belongs to.
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the results.
+ */
+FIRM_API ir_node *new_r_Borrow(ir_node *block, ir_node *op1, ir_node *op2,
+ ir_mode *mode);
+
/** Constructor for a Phi node.
*
* @param *block The IR block the node belongs to.
*/
FIRM_API ir_node *new_d_Cast(dbg_info *db, ir_node *op, ir_type *to_tp);
+/** Constructor for a Carry node.
+ *
+ * Adds the node to the block in current_ir_block.
+ *
+ * @param *db A pointer for debug information.
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_d_Carry(dbg_info *db, ir_node *op1, ir_node *op2,
+ ir_mode *mode);
+
+/** Constructor for a Borrow node.
+ *
+ * Adds the node to the block in current_ir_block.
+ *
+ * @param *db A pointer for debug information.
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_d_Borrow(dbg_info *db, ir_node *op1, ir_node *op2,
+ ir_mode *mode);
+
/** Constructor for a Phi node.
*
* Adds the node to the block in current_ir_block.
*/
FIRM_API ir_node *new_Cast(ir_node *op, ir_type *to_tp);
+/** Constructor for a Carry node.
+ *
+ * Adds the node to the block in current_ir_block.
+ *
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_Carry(ir_node *op1, ir_node *op2, ir_mode *mode);
+
+/** Constructor for a Borrow node.
+ *
+ * Adds the node to the block in current_ir_block.
+ *
+ * @param *op1 The first operand.
+ * @param *op2 The second operand.
+ * @param *mode The mode of the operands and the result.
+ */
+FIRM_API ir_node *new_Borrow(ir_node *op1, ir_node *op2, ir_mode *mode);
+
/** Constructor for a Phi node.
*
* Adds the node to the block in current_ir_block.
FIRM_API int is_Bad(const ir_node *node);
/** Return true of the node is a Block node. */
FIRM_API int is_Block(const ir_node *node);
+/** Return true of the node is a Borrow node. */
+FIRM_API int is_Borrow(const ir_node *node);
/** Return true of the node is a Bound node. */
FIRM_API int is_Bound(const ir_node *node);
/** Return true of the node is a Builtin node. */
FIRM_API int is_Builtin(const ir_node *node);
/** Return true of the node is a Call node. */
FIRM_API int is_Call(const ir_node *node);
+/** Return true of the node is a Carry node. */
+FIRM_API int is_Carry(const ir_node *node);
/** Return true of the node is a Cast node. */
FIRM_API int is_Cast(const ir_node *node);
/** Return true of the node is a Cmp node. */
+FIRM_API ir_node *get_Borrow_left(const ir_node *node);
+void set_Borrow_left(ir_node *node, ir_node *left);
+FIRM_API ir_node *get_Borrow_right(const ir_node *node);
+void set_Borrow_right(ir_node *node, ir_node *right);
+
FIRM_API ir_node *get_Bound_mem(const ir_node *node);
void set_Bound_mem(ir_node *node, ir_node *mem);
FIRM_API ir_node *get_Bound_index(const ir_node *node);
FIRM_API unsigned get_Call_tail_call(const ir_node *node);
FIRM_API void set_Call_tail_call(ir_node *node, unsigned tail_call);
+FIRM_API ir_node *get_Carry_left(const ir_node *node);
+void set_Carry_left(ir_node *node, ir_node *left);
+FIRM_API ir_node *get_Carry_right(const ir_node *node);
+void set_Carry_right(ir_node *node, ir_node *right);
+
FIRM_API ir_node *get_Cast_op(const ir_node *node);
void set_Cast_op(ir_node *node, ir_node *op);
FIRM_API ir_type* get_Cast_type(const ir_node *node);
return tarval_bad;
} /* computed_value_Sub */
+/**
+ * Return the value of a Carry.
+ * Special : a op 0, 0 op b
+ */
+static tarval *computed_value_Carry(const ir_node *n)
+{
+ ir_node *a = get_binop_left(n);
+ ir_node *b = get_binop_right(n);
+ ir_mode *m = get_irn_mode(n);
+
+ tarval *ta = value_of(a);
+ tarval *tb = value_of(b);
+
+ if ((ta != tarval_bad) && (tb != tarval_bad)) {
+ tarval_add(ta, tb);
+ return tarval_carry() ? get_mode_one(m) : get_mode_null(m);
+ } else {
+ if (tarval_is_null(ta) || tarval_is_null(tb))
+ return get_mode_null(m);
+ }
+ return tarval_bad;
+} /* computed_value_Carry */
+
+/**
+ * Return the value of a Borrow.
+ * Special : a op 0
+ */
+static tarval *computed_value_Borrow(const ir_node *n)
+{
+ ir_node *a = get_binop_left(n);
+ ir_node *b = get_binop_right(n);
+ ir_mode *m = get_irn_mode(n);
+
+ tarval *ta = value_of(a);
+ tarval *tb = value_of(b);
+
+ if ((ta != tarval_bad) && (tb != tarval_bad)) {
+ return tarval_cmp(ta, tb) == pn_Cmp_Lt ? get_mode_one(m) : get_mode_null(m);
+ } else if (tarval_is_null(ta)) {
+ return get_mode_null(m);
+ }
+ return tarval_bad;
+} /* computed_value_Borrow */
+
/**
* Return the value of an unary Minus.
*/
CASE(SymConst);
CASE(Add);
CASE(Sub);
+ CASE(Carry);
+ CASE(Borrow);
CASE(Minus);
CASE(Mul);
CASE(Abs);