- implemented Builtin node to represent builtins ...
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 18 Dec 2008 15:31:11 +0000 (15:31 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Thu, 18 Dec 2008 15:31:11 +0000 (15:31 +0000)
[r24785]

13 files changed:
include/libfirm/firm_types.h
include/libfirm/ircons.h
include/libfirm/irnode.h
include/libfirm/irop.h
ir/be/arm/arm_transform.c
ir/be/ia32/ia32_transform.c
ir/be/ppc32/ppc32_transform.c
ir/ir/ircons.c
ir/ir/irdump.c
ir/ir/irnode.c
ir/ir/irnode_t.h
ir/ir/irop.c
ir/ir/irtypes.h

index 90736a7..2d0da67 100644 (file)
@@ -210,11 +210,18 @@ typedef enum {
        heap_alloc            /**< Alloc allocates the object on the heap. */
 } ir_where_alloc;
 
-/** A input/output constraint attribute */
+/** A input/output constraint attribute. */
 typedef struct {
        unsigned       pos;           /**< The inputs/output position for this constraint. */
        ident          *constraint;   /**< The constraint for this input/output. */
        ir_mode        *mode;         /**< The mode of the constraint. */
 } ir_asm_constraint;
 
+/** Supported libFirm builtins. */
+typedef enum {
+       ir_bk_return_address,         /**< GCC __builtin_return_address() */
+       ir_bk_frame_addess,           /**< GCC __builtin_frame_address() */
+       ir_bk_prefetch,               /**< GCC __builtin_prefetch() */
+} ir_builtin_kind;
+
 #endif
index 00aa8a0..ac1dd2b 100644 (file)
  *    ir_node *new_Sel    (ir_node *store, ir_node *objptr, int arity,
  *                         ir_node **in, ir_entity *ent);
  *    ir_node *new_Call   (ir_node *store, ir_node *callee, int arity,
- *                 ir_node **in, type_method *type);
+ *                         ir_node **in, type_method *type);
+ *    ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity,
+ *                         ir_node **in, type_method *type);
  *    ir_node *new_Add    (ir_node *op1, ir_node *op2, ir_mode *mode);
  *    ir_node *new_Sub    (ir_node *op1, ir_node *op2, ir_mode *mode);
  *    ir_node *new_Minus  (ir_node *op,  ir_mode *mode);
  *      A tuple containing the eventually changed store and the procedure
  *      results.
  *    Attributes:
- *      attr.call        Contains the type information for the procedure.
+ *      attr.call        Contains the attributes for the procedure.
  *
+ *    ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, ir_node **in,
+ *    -----------------------------------------------------------------------------------
+ *                       type_method *type)
+ *                       ------------------
+ *
+ *    Creates a builtin call.
+ *
+ *    Parameters
+ *      *store           The actual store.
+ *      kind             Describes the called builtin.
+ *      arity            The number of procedure parameters.
+ *      **in             An array with the pointers to the parameters.
+ *                       The constructor copies this array.
+ *      *type            Type information of the procedure called.
+ *
+ *    Inputs:
+ *      The store, the kind and the parameters.
+ *    Output:
+ *      A tuple containing the eventually changed store and the procedure
+ *      results.
+ *    Attributes:
+ *      attr.builtin     Contains the attributes for the called builtin.
  *
  *    ir_node *new_Add (ir_node *op1, ir_node *op2, ir_mode *mode)
  *    ------------------------------------------------------------
@@ -1422,7 +1446,7 @@ ir_node *new_rd_Sel    (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *st
 
 /** Constructor for a Call node.
  *
- *  Represents all kinds of method and function calls.
+ * Represents all kinds of method and function calls.
  *
  * @param   *db     A pointer for debug information.
  * @param   *irg    The IR graph the node  belongs to.
@@ -1436,6 +1460,22 @@ ir_node *new_rd_Sel    (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *st
 ir_node *new_rd_Call   (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
                                    ir_node *callee, int arity, ir_node *in[], ir_type *tp);
 
+/** Constructor for a ´Builtin node.
+ *
+ * Represents a call of a backend-specific builtin..
+ *
+ * @param   *db     A pointer for debug information.
+ * @param   *irg    The IR graph the node  belongs to.
+ * @param   *block  The IR block the node belongs to.
+ * @param   *store  The current memory state.
+ * @param   kind    The kind of the called builtin.
+ * @param   arity   The number of procedure parameters.
+ * @param   *in[]   An array with the procedure parameters. The constructor copies this array.
+ * @param   *tp     Type information of the procedure called.
+ */
+ir_node *new_rd_Builtin(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+                                   ir_builtin_kind kind, int arity, ir_node *in[], ir_type *tp);
+
 /** Constructor for a Add node.
  *
  * @param   *db    A pointer for debug information.
@@ -2250,7 +2290,7 @@ ir_node *new_r_Sel    (ir_graph *irg, ir_node *block, ir_node *store,
 
 /** Constructor for a Call node.
  *
- *  Represents all kinds of method and function calls.
+ * Represents all kinds of method and function calls.
  *
  * @param   *irg    The IR graph the node  belongs to.
  * @param   *block  The IR block the node belongs to.
@@ -2261,8 +2301,22 @@ ir_node *new_r_Sel    (ir_graph *irg, ir_node *block, ir_node *store,
  * @param   *tp     Type information of the procedure called.
  */
 ir_node *new_r_Call   (ir_graph *irg, ir_node *block, ir_node *store,
-               ir_node *callee, int arity, ir_node *in[],
-               ir_type *tp);
+                       ir_node *callee, int arity, ir_node *in[], ir_type *tp);
+
+/** Constructor for a Builtin node.
+ *
+ * Represents a call of a backend-specific builtin..
+ *
+ * @param   *irg    The IR graph the node  belongs to.
+ * @param   *block  The IR block the node belongs to.
+ * @param   *store  The actual store.
+ * @param   kind    The kind of the called builtin.
+ * @param   arity   The number of procedure parameters.
+ * @param   *in[]   An array with the pointers to the parameters. The constructor copies this array.
+ * @param   *tp     Type information of the procedure called.
+ */
+ir_node *new_r_Builtin(ir_graph *irg, ir_node *block, ir_node *store,
+                       ir_builtin_kind kind, int arity, ir_node *in[], ir_type *tp);
 
 /** Constructor for a Add node.
  *
@@ -3073,8 +3127,8 @@ ir_node *new_d_Sel    (dbg_info *db, ir_node *store, ir_node *objptr, int arity,
 
 /** Constructor for a Call node.
  *
- *  Represents all kinds of method and function calls.
- *  Adds the node to the block in current_ir_block.
+ * Represents all kinds of method and function calls.
+ * Adds the node to the block in current_ir_block.
  *
  * @param   *db     A pointer for debug information.
  * @param   *store  The actual store.
@@ -3084,7 +3138,22 @@ ir_node *new_d_Sel    (dbg_info *db, ir_node *store, ir_node *objptr, int arity,
  * @param   *tp     Type information of the procedure called.
  */
 ir_node *new_d_Call   (dbg_info *db, ir_node *store, ir_node *callee, int arity, ir_node *in[],
-             ir_type *tp);
+                       ir_type *tp);
+
+/** Constructor for a Builtin node.
+ *
+ * Represents a call of a backend-specific builtin..
+ * Adds the node to the block in current_ir_block.
+ *
+ * @param   *db     A pointer for debug information.
+ * @param   *store  The actual store.
+ * @param   kind    The kind of the called builtin.
+ * @param   arity   The number of procedure parameters.
+ * @param   *in[]   An array with the pointers to the parameters. The constructor copies this array.
+ * @param   *tp     Type information of the procedure called.
+ */
+ir_node *new_d_Builtin(dbg_info *db, ir_node *store, ir_builtin_kind kind, int arity, ir_node *in[],
+                       ir_type *tp);
 
 /** Constructor for a Add node.
  *
@@ -3884,8 +3953,8 @@ ir_node *new_Sel    (ir_node *store, ir_node *objptr, int arity, ir_node *in[],
 
 /** Constructor for a Call node.
  *
- *  Adds the node to the block in current_ir_block.
- *  Represents all kinds of method and function calls.
+ * Adds the node to the block in current_ir_block.
+ * Represents all kinds of method and function calls.
  *
  * @param   *store  The actual store.
  * @param   *callee A pointer to the called procedure.
@@ -3896,6 +3965,20 @@ ir_node *new_Sel    (ir_node *store, ir_node *objptr, int arity, ir_node *in[],
 ir_node *new_Call   (ir_node *store, ir_node *callee, int arity, ir_node *in[],
                      ir_type *tp);
 
+/** Constructor for a Builtin node.
+ *
+ * Represents a call of a backend-specific builtin..
+ * Represents all kinds of method and function calls.
+ *
+ * @param   *store  The actual store.
+ * @param   kind    The kind of the called builtin.
+ * @param   arity   The number of procedure parameters.
+ * @param   *in[]   An array with the pointers to the parameters. The constructor copies this array.
+ * @param   *tp     Type information of the procedure called.
+ */
+ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, ir_node *in[],
+                     ir_type *tp);
+
 /** Constructor for a CallBegin node.
  *
  * CallBegin represents control flow depending of the pointer value
index c24d777..14cbdc4 100644 (file)
@@ -620,8 +620,6 @@ void     set_Call_param(ir_node *node, int pos, ir_node *param);
 ir_type *get_Call_type(ir_node *node);
 /** Sets the type of a call. */
 void     set_Call_type(ir_node *node, ir_type *tp);
-/** Gets the arity of a call. Identical to get_Call_n_params(). */
-int      get_Call_arity(const ir_node *node);
 
 /**
  * Returns non-zero if a Call is surely a self-recursive Call.
@@ -656,6 +654,33 @@ ir_entity *get_Call_callee(const ir_node *node, int pos);
 void    set_Call_callee_arr(ir_node *node, const int n, ir_entity **arr);
 void    remove_Call_callee_arr(ir_node *node);
 
+/**
+ * Projection numbers for result of Builtin node: use for Proj nodes!
+ */
+typedef enum {
+       pn_Builtin_M        = pn_Generic_M_regular, /**< The memory result. */
+       pn_Builtin_T_result = pn_Generic_other,     /**< The tuple containing all (0, 1, 2, ...) results. */
+       pn_Builtin_max                              /**< number of projections from a Builtin */
+} pn_Builtin;   /* Projection numbers for Builtin. */
+
+ir_node         *get_Builtin_mem(const ir_node *node);
+void            set_Builtin_mem(ir_node *node, ir_node *mem);
+ir_builtin_kind get_Builtin_kind(const ir_node *node);
+void            set_Builtin_kind(ir_node *node, ir_builtin_kind kind);
+ir_node         **get_Builtin_param_arr(ir_node *node);
+/** Gets the number of parameters of a Builtin. */
+int             get_Builtin_n_params(const ir_node *node);
+/** Gets the Builtin parameter at position pos. */
+ir_node         *get_Builtin_param(const ir_node *node, int pos);
+/** Sets the Builtin parameter at position pos. */
+void            set_Builtin_param(ir_node *node, int pos, ir_node *param);
+/** Gets the type of a builtin. */
+ir_type         *get_Builtin_type(ir_node *node);
+/** Sets the type of a Builtin. */
+void            set_Builtin_type(ir_node *node, ir_type *tp);
+/** Returns a human readable string for the ir_builtin_kind. */
+const char *get_builtin_kind_name(ir_builtin_kind kind);
+
 ir_node  *get_CallBegin_ptr(const ir_node *node);
 void      set_CallBegin_ptr(ir_node *node, ir_node *ptr);
 ir_node  *get_CallBegin_call(const ir_node *node);
@@ -1237,6 +1262,8 @@ int      is_Unknown(const ir_node *node);
 int      is_Return(const ir_node *node);
 /** Returns true if node is a Call node. */
 int      is_Call(const ir_node *node);
+/** Returns true if node is a Builtin node. */
+int      is_Builtin(const ir_node *node);
 /** Returns true if node is a CallBegin node. */
 int      is_CallBegin(const ir_node *node);
 /** Returns true if node is a Sel node. */
index 0cca895..9920c81 100644 (file)
@@ -95,7 +95,7 @@ typedef enum {
        iro_NoMem, iro_Mux, iro_Min, iro_Max, iro_CopyB,
        iro_InstOf, iro_Raise, iro_Bound,
        iro_Pin,
-       iro_ASM,
+       iro_ASM, iro_Builtin,
        iro_Anchor,
        /* first not middleend node number */
        iro_Last = iro_Anchor,
@@ -197,6 +197,7 @@ extern ir_op *op_Bound;           ir_op *get_op_Bound     (void);
 extern ir_op *op_Pin;             ir_op *get_op_Pin       (void);
 
 extern ir_op *op_ASM;             ir_op *get_op_ASM       (void);
+extern ir_op *op_Builtin;         ir_op *get_op_Builtin   (void);
 
 extern ir_op *op_Anchor;          ir_op *get_op_Anchor    (void);
 
index 1d7ca7f..771943e 100644 (file)
@@ -1601,8 +1601,6 @@ static inline void set_transformer(ir_op *op, be_transform_func arm_transform_fu
  * Enters all transform functions into the generic pointer
  */
 static void arm_register_transformers(void) {
-       ir_op *op_Max, *op_Min, *op_Mulh;
-
        /* first clear the generic function pointer for all ops */
        clear_irp_opcodes_generic_func();
 
@@ -1612,6 +1610,7 @@ static void arm_register_transformers(void) {
        GEN(Add);
        GEN(Sub);
        GEN(Mul);
+       BAD(Mulh);      /* unsupported yet */
        GEN(And);
        GEN(Or);
        GEN(Eor);
@@ -1661,6 +1660,9 @@ static void arm_register_transformers(void) {
        BAD(EndReg);
        BAD(EndExcept);
 
+       /* handle builtins */
+       BAD(Builtin);
+
        /* handle generic backend nodes */
        GEN(be_FrameAddr);
        //GEN(be_Call);
@@ -1672,16 +1674,6 @@ static void arm_register_transformers(void) {
        /* set the register for all Unknown nodes */
        GEN(Unknown);
 
-       op_Max = get_op_Max();
-       if (op_Max)
-               BAD(Max);       /* unsupported yet */
-       op_Min = get_op_Min();
-       if (op_Min)
-               BAD(Min);       /* unsupported yet */
-       op_Mulh = get_op_Mulh();
-       if (op_Mulh)
-               BAD(Mulh);      /* unsupported yet */
-
 #undef GEN
 #undef BAD
 }
index 7c8d69b..8f2615e 100644 (file)
@@ -4790,8 +4790,6 @@ static ir_node *gen_Proj(ir_node *node)
  */
 static void register_transformers(void)
 {
-       ir_op *op_Mulh;
-
        /* first clear the generic function pointer for all ops */
        clear_irp_opcodes_generic_func();
 
@@ -4801,6 +4799,7 @@ static void register_transformers(void)
        GEN(Add);
        GEN(Sub);
        GEN(Mul);
+       GEN(Mulh);
        GEN(And);
        GEN(Or);
        GEN(Eor);
@@ -4868,6 +4867,9 @@ static void register_transformers(void)
        BAD(EndReg);
        BAD(EndExcept);
 
+       /* handle builtins */
+       BAD(Builtin);
+
        /* handle generic backend nodes */
        GEN(be_FrameAddr);
        GEN(be_Call);
@@ -4877,10 +4879,6 @@ static void register_transformers(void)
        GEN(be_SubSP);
        GEN(be_Copy);
 
-       op_Mulh = get_op_Mulh();
-       if (op_Mulh)
-               GEN(Mulh);
-
 #undef GEN
 #undef BAD
 }
index 6c4a6a6..91d17fa 100644 (file)
@@ -1245,8 +1245,6 @@ static ir_node *bad_transform(ppc32_transform_env_t *env) {
  * Enters all transform functions into the generic pointer
  */
 void ppc32_register_transformers(void) {
-       ir_op *op_Max, *op_Min, *op_Mulh;
-
        /* first clear the generic function pointer for all ops */
        clear_irp_opcodes_generic_func();
 
@@ -1256,6 +1254,7 @@ void ppc32_register_transformers(void) {
 
        FIRM_OP(Add);
        FIRM_OP(Mul);
+       FIRM_OP(Mulh);
        FIRM_OP(And);
        FIRM_OP(Or);
        FIRM_OP(Eor);
@@ -1315,16 +1314,11 @@ void ppc32_register_transformers(void) {
        BAD(EndReg);
        BAD(EndExcept);
 
+       /* handle builtins */
+       BAD(Builtin);
+
+       /* handle generic backend nodes */
        FIRM_OP(be_FrameAddr);
-       op_Mulh = get_op_Mulh();
-       if (op_Mulh)
-               FIRM_OP(Mulh);
-       op_Max = get_op_Max();
-       if (op_Max)
-               BAD(Max);
-       op_Min = get_op_Min();
-       if (op_Min)
-               BAD(Min);
 }
 
 typedef ir_node *(transform_func)(ppc32_transform_env_t *env);
index a0aaac5..4a32134 100644 (file)
@@ -479,7 +479,7 @@ new_bd_Call(dbg_info *db, ir_node *block, ir_node *store,
        int      r_arity;
        ir_graph *irg = current_ir_graph;
 
-       r_arity = arity+2;
+       r_arity = arity + 2;
        NEW_ARR_A(ir_node *, r_in, r_arity);
        r_in[0] = store;
        r_in[1] = callee;
@@ -496,6 +496,30 @@ new_bd_Call(dbg_info *db, ir_node *block, ir_node *store,
        return res;
 }  /* new_bd_Call */
 
+static ir_node *
+new_bd_Builtin(dbg_info *db, ir_node *block, ir_node *store,
+               ir_builtin_kind kind, int arity, ir_node **in, ir_type *tp) {
+       ir_node  **r_in;
+       ir_node  *res;
+       int      r_arity;
+       ir_graph *irg = current_ir_graph;
+
+       r_arity = arity + 1;
+       NEW_ARR_A(ir_node *, r_in, r_arity);
+       r_in[0] = store;
+       memcpy(&r_in[1], in, sizeof(ir_node *) * arity);
+
+       res = new_ir_node(db, irg, block, op_Builtin, mode_T, r_arity, r_in);
+
+       assert((get_unknown_type() == tp) || is_Method_type(tp));
+       res->attr.builtin.exc.pin_state = op_pin_state_pinned;
+       res->attr.builtin.kind          = kind;
+       res->attr.builtin.builtin_tp    = tp;
+       res = optimize_node(res);
+       IRN_VRFY_IRG(res, irg);
+       return res;
+}  /* new_bd_Buildin */
+
 static ir_node *
 new_bd_Return(dbg_info *db, ir_node *block,
               ir_node *store, int arity, ir_node **in) {
@@ -1125,6 +1149,19 @@ new_rd_Call(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
        return res;
 }  /* new_rd_Call */
 
+ir_node *
+new_rd_Builtin(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *store,
+               ir_builtin_kind kind, int arity, ir_node **in, ir_type *tp) {
+       ir_node  *res;
+       ir_graph *rem = current_ir_graph;
+
+       current_ir_graph = irg;
+       res = new_bd_Builtin(db, block, store, kind, arity, in, tp);
+       current_ir_graph = rem;
+
+       return res;
+}  /* new_rd_Builtin */
+
 ir_node *
 new_rd_Return(dbg_info *db, ir_graph *irg, ir_node *block,
               ir_node *store, int arity, ir_node **in) {
@@ -1509,6 +1546,11 @@ ir_node *new_r_Call(ir_graph *irg, ir_node *block, ir_node *store,
                     ir_type *tp) {
        return new_rd_Call(NULL, irg, block, store, callee, arity, in, tp);
 }
+ir_node *new_r_Builtin(ir_graph *irg, ir_node *block, ir_node *store,
+                       ir_builtin_kind kind, int arity, ir_node **in,
+                       ir_type *tp) {
+       return new_rd_Builtin(NULL, irg, block, store, kind, arity, in, tp);
+}
 #ifdef USE_ORIGINAL
 ir_node *new_r_Add(ir_graph *irg, ir_node *block,
                    ir_node *op1, ir_node *op2, ir_mode *mode) {
@@ -2497,6 +2539,12 @@ new_d_Call(dbg_info *db, ir_node *store, ir_node *callee, int arity, ir_node **i
        return res;
 }  /* new_d_Call */
 
+ir_node *
+new_d_Builtin(dbg_info *db, ir_node *store, ir_builtin_kind kind, int arity, ir_node **in,
+              ir_type *tp) {
+       return new_bd_Builtin(db, current_ir_graph->current_block, store, kind, arity, in, tp);
+}  /* new_d_Builtin */
+
 ir_node *
 new_d_Return(dbg_info *db, ir_node* store, int arity, ir_node **in) {
        return new_bd_Return(db, current_ir_graph->current_block,
@@ -2943,6 +2991,10 @@ ir_node *new_Call(ir_node *store, ir_node *callee, int arity, ir_node **in,
                   ir_type *tp) {
        return new_d_Call(NULL, store, callee, arity, in, tp);
 }
+ir_node *new_Builtin(ir_node *store, ir_builtin_kind kind, int arity, ir_node **in,
+                     ir_type *tp) {
+       return new_d_Builtin(NULL, store, kind, arity, in, tp);
+}
 #ifdef USE_ORIGINAL
 ir_node *new_Add(ir_node *op1, ir_node *op2, ir_mode *mode) {
        return new_d_Add(NULL, op1, op2, mode);
index 323f9fd..dcc187d 100644 (file)
@@ -828,6 +828,9 @@ int dump_node_opcode(FILE *F, ir_node *n)
        case iro_DivMod:
                fprintf(F, "%s[%s]", get_irn_opname(n), get_mode_name_ex(get_DivMod_resmode(n), &bad));
                break;
+       case iro_Builtin:
+               fprintf(F, "%s[%s]", get_irn_opname(n), get_builtin_kind_name(get_Builtin_kind(n)));
+               break;
 
        default:
 default_case:
index 0358e49..497fa3b 100644 (file)
@@ -48,7 +48,7 @@
 /* some constants fixing the positions of nodes predecessors
    in the in array */
 #define CALL_PARAM_OFFSET     2
-#define FUNCCALL_PARAM_OFFSET 1
+#define BUILDIN_PARAM_OFFSET  1
 #define SEL_INDEX_OFFSET      2
 #define RETURN_RESULT_OFFSET  1  /* mem is not a result */
 #define END_KEEPALIVE_OFFSET  0
@@ -1343,18 +1343,6 @@ get_Call_n_params(const ir_node *node)  {
        return (get_irn_arity(node) - CALL_PARAM_OFFSET);
 }
 
-int
-get_Call_arity(const ir_node *node) {
-       assert(is_Call(node));
-       return get_Call_n_params(node);
-}
-
-/* void
-set_Call_arity(ir_node *node, ir_node *arity) {
-       assert(is_Call(node));
-}
-*/
-
 ir_node *
 get_Call_param(const ir_node *node, int pos) {
        assert(is_Call(node));
@@ -1380,6 +1368,80 @@ set_Call_type(ir_node *node, ir_type *tp) {
        node->attr.call.cld_tp = tp;
 }
 
+ir_node *
+get_Builtin_mem(const ir_node *node) {
+       assert(is_Builtin(node));
+       return get_irn_n(node, 0);
+}
+
+void
+set_Builin_mem(ir_node *node, ir_node *mem) {
+       assert(is_Builtin(node));
+       set_irn_n(node, 0, mem);
+}
+
+ir_builtin_kind
+get_Builtin_kind(const ir_node *node) {
+       assert(is_Builtin(node));
+       return node->attr.builtin.kind;
+}
+
+void
+set_Builtin_kind(ir_node *node, ir_builtin_kind kind) {
+       assert(is_Builtin(node));
+       node->attr.builtin.kind = kind;
+}
+
+ir_node **
+get_Builtin_param_arr(ir_node *node) {
+       assert(is_Builtin(node));
+       return &get_irn_in(node)[BUILDIN_PARAM_OFFSET + 1];
+}
+
+int
+get_Builtin_n_params(const ir_node *node)  {
+       assert(is_Builtin(node));
+       return (get_irn_arity(node) - BUILDIN_PARAM_OFFSET);
+}
+
+ir_node *
+get_Builtin_param(const ir_node *node, int pos) {
+       assert(is_Builtin(node));
+       return get_irn_n(node, pos + BUILDIN_PARAM_OFFSET);
+}
+
+void
+set_Builtin_param(ir_node *node, int pos, ir_node *param) {
+       assert(is_Builtin(node));
+       set_irn_n(node, pos + BUILDIN_PARAM_OFFSET, param);
+}
+
+ir_type *
+get_Builtin_type(ir_node *node) {
+       assert(is_Builtin(node));
+       return node->attr.builtin.builtin_tp = skip_tid(node->attr.builtin.builtin_tp);
+}
+
+void
+set_Builtin_type(ir_node *node, ir_type *tp) {
+       assert(is_Builtin(node));
+       assert((get_unknown_type() == tp) || is_Method_type(tp));
+       node->attr.builtin.builtin_tp = tp;
+}
+
+/* Returns a human readable string for the ir_builtin_kind. */
+const char *get_builtin_kind_name(ir_builtin_kind kind) {
+#define X(a)    case a: return #a + 6;
+       switch (kind) {
+               X(ir_bk_return_address);
+               X(ir_bk_frame_addess);
+               X(ir_bk_prefetch);
+       }
+       return "<unknown>";
+#undef X
+}
+
+
 int Call_has_callees(const ir_node *node) {
        assert(is_Call(node));
        return ((get_irg_callee_info_state(get_irn_irg(node)) != irg_callee_info_none) &&
@@ -2771,6 +2833,12 @@ int
        return _is_Call(node);
 }
 
+/* returns true if node is a Builtin node. */
+int
+(is_Builtin)(const ir_node *node) {
+       return _is_Builtin(node);
+}
+
 /* returns true if node is a CallBegin node. */
 int
 (is_CallBegin)(const ir_node *node) {
index 51df6b6..d65b3aa 100644 (file)
@@ -627,6 +627,12 @@ _is_Call(const ir_node *node) {
        return (_get_irn_op(node) == op_Call);
 }
 
+static inline int
+_is_Builtin(const ir_node *node) {
+       assert(node);
+       return (_get_irn_op(node) == op_Builtin);
+}
+
 static inline int
 _is_CallBegin(const ir_node *node) {
        assert(node);
@@ -1037,6 +1043,7 @@ _is_arg_Proj(const ir_node *node) {
 #define is_Unknown(node)                      _is_Unknown(node)
 #define is_Return(node)                       _is_Return(node)
 #define is_Call(node)                         _is_Call(node)
+#define is_Builtin(node)                      _is_Builtin(node)
 #define is_CallBegin(node)                    _is_CallBegin(node)
 #define is_Sel(node)                          _is_Sel(node)
 #define is_Mul(node)                          _is_Mul(node)
index 6d18485..98b25af 100644 (file)
@@ -57,6 +57,7 @@ ir_op *op_Const;       ir_op *get_op_Const     (void) { return op_Const;     }
 ir_op *op_SymConst;    ir_op *get_op_SymConst  (void) { return op_SymConst;  }
 
 ir_op *op_Call;        ir_op *get_op_Call      (void) { return op_Call;      }
+ir_op *op_Builtin;     ir_op *get_op_Builtin   (void) { return op_Builtin;   }
 ir_op *op_Add;         ir_op *get_op_Add       (void) { return op_Add;       }
 ir_op *op_Sub;         ir_op *get_op_Sub       (void) { return op_Sub;       }
 ir_op *op_Minus;       ir_op *get_op_Minus     (void) { return op_Minus;     }
@@ -357,6 +358,7 @@ init_op(void)
        op_Pin       = new_ir_op(iro_Pin,       "Pin",       op_pin_state_pinned, H,       oparity_unary,    -1, 0, NULL);
 
        op_ASM       = new_ir_op(iro_ASM,       "ASM",       op_pin_state_mem_pinned, K|M, oparity_variable, -1, sizeof(asm_attr), NULL);
+       op_Builtin   = new_ir_op(iro_Builtin,   "Builtin",   op_pin_state_mem_pinned, M,   oparity_variable, -1, sizeof(builtin_attr), NULL);
 
        op_Anchor    = new_ir_op(iro_Anchor,    "Anchor",    op_pin_state_pinned, N|NB,    oparity_variable, -1, 0, NULL);
 
index b14a5da..22110a4 100644 (file)
@@ -194,6 +194,13 @@ typedef struct {
        ir_entity ** callee_arr;      /**< result of callee analysis */
 } call_attr;
 
+/** Builtin attributes. */
+typedef struct {
+       except_attr     exc;           /**< the exception attribute. MUST be the first one. */
+       ir_builtin_kind kind;          /**< kind of the called builtin procedure */
+       ir_type         *builtin_tp;   /**< type of called builtin procedure */
+} builtin_attr;
+
 /** Alloc attributes. */
 typedef struct {
        except_attr    exc;           /**< the exception attribute. MUST be the first one. */
@@ -305,7 +312,8 @@ typedef union {
        const_attr     con;           /**< For Const: contains the value of the constant and a type */
        symconst_attr  symc;          /**< For SymConst. */
        sel_attr       sel;           /**< For Sel. */
-       call_attr      call;          /**< For Call: pointer to the type of the method to call */
+       call_attr      call;          /**< For Call. */
+       builtin_attr   builtin;       /**< For Builtin. */
        callbegin_attr callbegin;     /**< For CallBegin. */
        alloc_attr     alloc;         /**< For Alloc. */
        free_attr      free;          /**< For Free. */