add compound parameter lower to lower_for_target
[libfirm] / ir / be / ia32 / ia32_intrinsics.c
index e527b90..2a522d7 100644 (file)
@@ -39,6 +39,7 @@
 #include "ia32_new_nodes.h"
 #include "bearch_ia32_t.h"
 #include "gen_ia32_regalloc_if.h"
+#include "begnuas.h"
 
 /** The array of all intrinsics that must be mapped. */
 static i_record *intrinsics;
@@ -111,7 +112,7 @@ static void resolve_call(ir_node *call, ir_node *l_res, ir_node *h_res, ir_graph
 
                foreach_out_edge_safe(call, edge, next) {
                        ir_node *proj = get_edge_src_irn(edge);
-                       pn_Call pn    = get_Proj_proj(proj);
+                       pn_Call pn    = (pn_Call)get_Proj_proj(proj);
 
                        switch (pn) {
                        case pn_Call_X_regular:
@@ -268,7 +269,8 @@ static int map_Shl(ir_node *call, void *ctx)
                /* the shift count is a const, create better code */
                ir_tarval *tv = get_Const_tarval(cnt);
 
-               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
+               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode))
+                               & (ir_relation_greater_equal)) {
                        /* simplest case: shift only the lower bits. Note that there is no
                           need to reduce the constant here, this is done by the hardware.  */
                        ir_node *conv = new_rd_Conv(dbg, block, a_l, h_mode);
@@ -299,8 +301,7 @@ static int map_Shl(ir_node *call, void *ctx)
        c_mode = get_irn_mode(cnt);
        irn    = new_r_Const_long(irg, c_mode, 32);
        irn    = new_rd_And(dbg, upper, cnt, irn, c_mode);
-       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)));
-       irn    = new_r_Proj(irn, mode_b, pn_Cmp_Eq);
+       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)), ir_relation_equal);
        cond   = new_rd_Cond(dbg, upper, irn);
 
        in[0]  = new_r_Proj(cond, mode_X, pn_Cond_true);
@@ -327,8 +328,10 @@ static int map_Shl(ir_node *call, void *ctx)
 
        /* move it down */
        set_nodes_block(call, block);
-       for (irn = get_irn_link(call); irn != NULL; irn = get_irn_link(irn))
+       for (irn = (ir_node*)get_irn_link(call); irn != NULL;
+            irn = (ir_node*)get_irn_link(irn)) {
                set_nodes_block(irn, block);
+       }
 
        resolve_call(call, l_res, h_res, irg, block);
        return 1;
@@ -357,7 +360,7 @@ static int map_Shr(ir_node *call, void *ctx)
                /* the shift count is a const, create better code */
                ir_tarval *tv = get_Const_tarval(cnt);
 
-               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
+               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (ir_relation_greater_equal)) {
                        /* simplest case: shift only the higher bits. Note that there is no
                           need to reduce the constant here, this is done by the hardware.  */
                        ir_node *conv = new_rd_Conv(dbg, block, a_h, l_mode);
@@ -386,8 +389,7 @@ static int map_Shr(ir_node *call, void *ctx)
        c_mode = get_irn_mode(cnt);
        irn    = new_r_Const_long(irg, c_mode, 32);
        irn    = new_rd_And(dbg, upper, cnt, irn, c_mode);
-       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)));
-       irn    = new_r_Proj(irn, mode_b, pn_Cmp_Eq);
+       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)), ir_relation_equal);
        cond   = new_rd_Cond(dbg, upper, irn);
 
        in[0]  = new_r_Proj(cond, mode_X, pn_Cond_true);
@@ -414,8 +416,10 @@ static int map_Shr(ir_node *call, void *ctx)
 
        /* move it down */
        set_nodes_block(call, block);
-       for (irn = get_irn_link(call); irn != NULL; irn = get_irn_link(irn))
+       for (irn = (ir_node*)get_irn_link(call); irn != NULL;
+            irn = (ir_node*)get_irn_link(irn)) {
                set_nodes_block(irn, block);
+       }
 
        resolve_call(call, l_res, h_res, irg, block);
        return 1;
@@ -444,7 +448,7 @@ static int map_Shrs(ir_node *call, void *ctx)
                /* the shift count is a const, create better code */
                ir_tarval *tv = get_Const_tarval(cnt);
 
-               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (pn_Cmp_Gt|pn_Cmp_Eq)) {
+               if (tarval_cmp(tv, new_tarval_from_long(32, l_mode)) & (ir_relation_greater_equal)) {
                        /* simplest case: shift only the higher bits. Note that there is no
                           need to reduce the constant here, this is done by the hardware.  */
                        ir_node *conv    = new_rd_Conv(dbg, block, a_h, l_mode);
@@ -475,8 +479,7 @@ static int map_Shrs(ir_node *call, void *ctx)
        c_mode = get_irn_mode(cnt);
        irn    = new_r_Const_long(irg, c_mode, 32);
        irn    = new_rd_And(dbg, upper, cnt, irn, c_mode);
-       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)));
-       irn    = new_r_Proj(irn, mode_b, pn_Cmp_Eq);
+       irn    = new_rd_Cmp(dbg, upper, irn, new_r_Const(irg, get_mode_null(c_mode)), ir_relation_equal);
        cond   = new_rd_Cond(dbg, upper, irn);
 
        in[0]  = new_r_Proj(cond, mode_X, pn_Cond_true);
@@ -503,8 +506,10 @@ static int map_Shrs(ir_node *call, void *ctx)
 
        /* move it down */
        set_nodes_block(call, block);
-       for (irn = get_irn_link(call); irn != NULL; irn = get_irn_link(irn))
+       for (irn = (ir_node*)get_irn_link(call); irn != NULL;
+            irn = (ir_node*)get_irn_link(irn)) {
                set_nodes_block(irn, block);
+       }
 
        resolve_call(call, l_res, h_res, irg, block);
        return 1;
@@ -676,12 +681,33 @@ static int map_Abs(ir_node *call, void *ctx)
 
 #define ID(x) new_id_from_chars(x, sizeof(x)-1)
 
+static ir_entity *create_compiler_lib_entity(const char *name, ir_type *type)
+{
+       ir_type   *glob   = get_glob_type();
+       ident     *id     = new_id_from_str(name);
+       ir_entity *entity;
+
+       /* Hack: we need to know the type of runtime library we use. Strictly
+          speaking it's not the same as the object-file-format. But in practice
+          the following should be enough */
+       if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O
+                       || be_gas_object_file_format == OBJECT_FILE_FORMAT_COFF) {
+               id = id_mangle3("___", id, "");
+       } else {
+               id = id_mangle3("__", id, "");
+       }
+       entity = new_entity(glob, id, type);
+       set_entity_visibility(entity, ir_visibility_local);
+       set_entity_ld_ident(entity, id);
+       return entity;
+}
+
 /**
  * Maps a Div. Change into a library call.
  */
 static int map_Div(ir_node *call, void *ctx)
 {
-       ia32_intrinsic_env_t *env = ctx;
+       ia32_intrinsic_env_t *env = (ia32_intrinsic_env_t*)ctx;
        ir_type   *method    = get_Call_type(call);
        ir_mode   *h_mode    = get_type_mode(get_method_res_type(method, 1));
        ir_node   *ptr;
@@ -693,19 +719,14 @@ static int map_Div(ir_node *call, void *ctx)
                /* 64bit signed Division */
                ent = env->divdi3;
                if (ent == NULL) {
-                       /* create library entity */
-                       ent = env->divdi3 = new_entity(get_glob_type(), ID("__divdi3"), method);
-                       set_entity_visibility(ent, ir_visibility_external);
-                       set_entity_ld_ident(ent, ID("__divdi3"));
+                       ent = env->divdi3 = create_compiler_lib_entity("divdi3", method);
                }
        } else {
                /* 64bit unsigned Division */
                ent = env->udivdi3;
                if (ent == NULL) {
                        /* create library entity */
-                       ent = env->udivdi3 = new_entity(get_glob_type(), ID("__udivdi3"), method);
-                       set_entity_visibility(ent, ir_visibility_external);
-                       set_entity_ld_ident(ent, ID("__udivdi3"));
+                       ent = env->udivdi3 = create_compiler_lib_entity("udivdi3", method);
                }
        }
 
@@ -722,7 +743,7 @@ static int map_Div(ir_node *call, void *ctx)
  */
 static int map_Mod(ir_node *call, void *ctx)
 {
-       ia32_intrinsic_env_t *env = ctx;
+       ia32_intrinsic_env_t *env = (ia32_intrinsic_env_t*)ctx;
        ir_type   *method    = get_Call_type(call);
        ir_mode   *h_mode    = get_type_mode(get_method_res_type(method, 1));
        ir_node   *ptr;
@@ -735,18 +756,14 @@ static int map_Mod(ir_node *call, void *ctx)
                ent = env->moddi3;
                if (ent == NULL) {
                        /* create library entity */
-                       ent = env->moddi3 = new_entity(get_glob_type(), ID("__moddi3"), method);
-                       set_entity_visibility(ent, ir_visibility_external);
-                       set_entity_ld_ident(ent, ID("__moddi3"));
+                       ent = env->moddi3 = create_compiler_lib_entity("moddi3", method);
                }
        } else {
                /* 64bit signed Modulo */
                ent = env->umoddi3;
                if (ent == NULL) {
                        /* create library entity */
-                       ent = env->umoddi3 = new_entity(get_glob_type(), ID("__umoddi3"), method);
-                       set_entity_visibility(ent, ir_visibility_external);
-                       set_entity_ld_ident(ent, ID("__umoddi3"));
+                       ent = env->umoddi3 = create_compiler_lib_entity("umoddi3", method);
                }
        }
 
@@ -803,9 +820,8 @@ static int map_Conv(ir_node *call, void *ctx)
                        part_block(call);
                        upper_blk = get_nodes_block(call);
 
-                       cmp   = new_rd_Cmp(dbg, upper_blk, a_f, flt_corr);
-                       proj  = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
-                       cond  = new_rd_Cond(dbg, upper_blk, proj);
+                       cmp   = new_rd_Cmp(dbg, upper_blk, a_f, flt_corr, ir_relation_less);
+                       cond  = new_rd_Cond(dbg, upper_blk, cmp);
                        in[0] = new_r_Proj(cond, mode_X, pn_Cond_true);
                        in[1] = new_r_Proj(cond, mode_X, pn_Cond_false);
                        blk   = new_r_Block(irg, 1, &in[1]);
@@ -841,8 +857,10 @@ static int map_Conv(ir_node *call, void *ctx)
                        /* move the call and its Proj's to the lower block */
                        set_nodes_block(call, lower_blk);
 
-                       for (proj = get_irn_link(call); proj != NULL; proj = get_irn_link(proj))
+                       for (proj = (ir_node*)get_irn_link(call); proj != NULL;
+                            proj = (ir_node*)get_irn_link(proj)) {
                                set_nodes_block(proj, lower_blk);
+                       }
                        block = lower_blk;
                }
                /* lower the call */