bring back Carry and Borrow (firm_decomp apparently uses it) and add a note that...
authorMatthias Braun <matze@braunis.de>
Fri, 30 Jul 2010 08:28:45 +0000 (08:28 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 30 Jul 2010 08:28:45 +0000 (08:28 +0000)
[r27849]

include/libfirm/ircons.h
include/libfirm/nodeops.h
include/libfirm/opcodes.h
ir/ana/vrp.c
ir/ir/iropt.c
scripts/ir_spec.py

index e4a33e9..cc98fdb 100644 (file)
  *    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)
  *    ---------------------------------------------
  *
@@ -1682,6 +1696,32 @@ FIRM_API ir_node *new_rd_strictConv(dbg_info *db, ir_node *block,
 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.
@@ -2394,6 +2434,27 @@ FIRM_API ir_node *new_r_strictConv(ir_node *block, ir_node *op, ir_mode *mode);
  */
 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.
@@ -3162,6 +3223,30 @@ FIRM_API ir_node *new_d_strictConv(dbg_info *db, ir_node *op, ir_mode *mode);
  */
 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.
@@ -3871,6 +3956,26 @@ FIRM_API ir_node *new_strictConv(ir_node *op, ir_mode *mode);
  */
 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.
index 68559b2..2a74f5d 100644 (file)
@@ -212,12 +212,16 @@ FIRM_API int is_And(const ir_node *node);
 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. */
@@ -342,6 +346,11 @@ void set_And_right(ir_node *node, ir_node *right);
 
 
 
+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);
@@ -367,6 +376,11 @@ FIRM_API void set_Call_type(ir_node *node, ir_type* type);
 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);
index 0926a9b..68d1f56 100644 (file)
@@ -13,9 +13,11 @@ typedef enum ir_opcode {
        iro_And,
        iro_Bad,
        iro_Block,
+       iro_Borrow,
        iro_Bound,
        iro_Builtin,
        iro_Call,
+       iro_Carry,
        iro_Cast,
        iro_Cmp,
        iro_Cond,
@@ -94,9 +96,11 @@ FIRM_API ir_op *op_Anchor;
 FIRM_API ir_op *op_And;
 FIRM_API ir_op *op_Bad;
 FIRM_API ir_op *op_Block;
+FIRM_API ir_op *op_Borrow;
 FIRM_API ir_op *op_Bound;
 FIRM_API ir_op *op_Builtin;
 FIRM_API ir_op *op_Call;
+FIRM_API ir_op *op_Carry;
 FIRM_API ir_op *op_Cast;
 FIRM_API ir_op *op_Cmp;
 FIRM_API ir_op *op_Cond;
@@ -151,9 +155,11 @@ FIRM_API ir_op *get_op_Anchor(void);
 FIRM_API ir_op *get_op_And(void);
 FIRM_API ir_op *get_op_Bad(void);
 FIRM_API ir_op *get_op_Block(void);
+FIRM_API ir_op *get_op_Borrow(void);
 FIRM_API ir_op *get_op_Bound(void);
 FIRM_API ir_op *get_op_Builtin(void);
 FIRM_API ir_op *get_op_Call(void);
+FIRM_API ir_op *get_op_Carry(void);
 FIRM_API ir_op *get_op_Cast(void);
 FIRM_API ir_op *get_op_Cmp(void);
 FIRM_API ir_op *get_op_Cond(void);
index fb2f0e9..6a623f0 100644 (file)
@@ -363,9 +363,9 @@ static int vrp_update_node(ir_node *node)
 
 
        /* TODO: Check, if there can be information derived from any of these:
-       is_Abs(node) is_Alloc(node) is_Anchor(node) is_Bound(node)
+       is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
        is_Break(node) is_Builtin(node) is_Call(node)
-       is_Cast(node) is_Cmp(node) is_Cond(node)
+       is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node)
        is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node)
        is_End(node) is_Free(node)
        is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node)
index 8abe0c2..ce18fcc 100644 (file)
@@ -159,6 +159,50 @@ static tarval *computed_value_Sub(const ir_node *n)
        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.
  */
@@ -686,6 +730,8 @@ static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops
        CASE(SymConst);
        CASE(Add);
        CASE(Sub);
+       CASE(Carry);
+       CASE(Borrow);
        CASE(Minus);
        CASE(Mul);
        CASE(Abs);
index d887f5f..12702c6 100755 (executable)
@@ -170,6 +170,9 @@ class Block(Op):
        }
        '''
 
+class Borrow(Binop):
+       flags = []
+
 class Bound(Op):
        ins    = [ "mem", "index", "lower", "upper" ]
        outs  = [
@@ -239,6 +242,9 @@ class Call(Op):
        assert((get_unknown_type() == type) || is_Method_type(type));
        '''
 
+class Carry(Binop):
+       flags = [ "commutative" ]
+
 class Cast(Unop):
        mode     = "get_irn_mode(irn_op)"
        flags    = [ "highlevel" ]