- IR nodes now have node numbers in RELEASE mode, this fixes problems in backend
[libfirm] / ir / be / ia32 / ia32_transform.c
index 6a585ec..bedcf49 100644 (file)
@@ -220,8 +220,8 @@ static ir_node *gen_Const(ir_node *node)
 #ifdef CONSTRUCT_SSE_CONST
                        } else if (tarval_is_one(tv)) {
                                int     cnst  = mode == mode_F ? 26 : 55;
-                               ir_node *imm1 = create_Immediate(NULL, 0, cnst);
-                               ir_node *imm2 = create_Immediate(NULL, 0, 2);
+                               ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
+                               ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
                                ir_node *pslld, *psrld;
 
                                load = new_bd_ia32_xAllOnes(dbgi, block);
@@ -250,7 +250,7 @@ static ir_node *gen_Const(ir_node *node)
                                                (get_tarval_sub_bits(tv, 2) << 16) |
                                                (get_tarval_sub_bits(tv, 3) << 24);
                                        if (val == 0) {
-                                               ir_node *imm32 = create_Immediate(NULL, 0, 32);
+                                               ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
                                                ir_node *cnst, *psllq;
 
                                                /* fine, lower 32bit are zero, produce 32bit value */
@@ -1466,7 +1466,7 @@ static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
                be_dep_on_frame(pval);
                res = new_bd_ia32_Cltd(dbgi, block, val, pval);
        } else {
-               ir_node *imm31 = create_Immediate(NULL, 0, 31);
+               ir_node *imm31 = ia32_create_Immediate(NULL, 0, 31);
                res = new_bd_ia32_Sar(dbgi, block, val, imm31);
        }
        SET_IA32_ORIG_NODE(res, orig);
@@ -2417,7 +2417,7 @@ static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
                        (get_tarval_sub_bits(tv, ofs + 1) <<  8) |
                        (get_tarval_sub_bits(tv, ofs + 2) << 16) |
                        (get_tarval_sub_bits(tv, ofs + 3) << 24);
-               ir_node *imm = create_Immediate(NULL, 0, val);
+               ir_node *imm = ia32_create_Immediate(NULL, 0, val);
 
                ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
                        addr.index, addr.mem, imm);
@@ -2600,7 +2600,7 @@ static ir_node *create_Switch(ir_node *node)
        ir_node  *new_sel    = be_transform_node(sel);
        long      switch_min = LONG_MAX;
        long      switch_max = LONG_MIN;
-       long      default_pn = get_Cond_defaultProj(node);
+       long      default_pn = get_Cond_default_proj(node);
        ir_node  *new_node;
        const ir_edge_t *edge;
 
@@ -3399,7 +3399,7 @@ static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
        if (!mode_is_signed(mode)) {
                ir_node *in[2];
                /* store a zero */
-               ir_node *zero_const = create_Immediate(NULL, 0, 0);
+               ir_node *zero_const = ia32_create_Immediate(NULL, 0, 0);
 
                ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
                                                        noreg_GP, nomem, zero_const);
@@ -4076,7 +4076,7 @@ static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
        if (! mode_is_signed(get_irn_mode(val_high))) {
                ia32_address_mode_t  am;
 
-               ir_node *count = create_Immediate(NULL, 0, 31);
+               ir_node *count = ia32_create_Immediate(NULL, 0, 31);
                ir_node *fadd;
 
                am.addr.base          = noreg_GP;
@@ -4782,7 +4782,7 @@ static ir_node *gen_ffs(ir_node *node)
        set_ia32_commutative(or);
 
        /* add 1 */
-       return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, create_Immediate(NULL, 0, 1));
+       return new_bd_ia32_Add(dbgi, block, noreg_GP, noreg_GP, nomem, or, ia32_create_Immediate(NULL, 0, 1));
 }
 
 /**
@@ -4794,7 +4794,7 @@ static ir_node *gen_clz(ir_node *node)
        ir_node  *real  = skip_Proj(bsr);
        dbg_info *dbgi  = get_irn_dbg_info(real);
        ir_node  *block = get_nodes_block(real);
-       ir_node  *imm   = create_Immediate(NULL, 0, 31);
+       ir_node  *imm   = ia32_create_Immediate(NULL, 0, 31);
 
        return new_bd_ia32_Xor(dbgi, block, noreg_GP, noreg_GP, nomem, bsr, imm);
 }
@@ -4826,7 +4826,7 @@ static ir_node *gen_parity(ir_node *node)
 
        /* cmp param, 0 */
        match_arguments(&am, block, NULL, param, NULL, match_am);
-       imm = create_Immediate(NULL, 0, 0);
+       imm = ia32_create_Immediate(NULL, 0, 0);
        cmp = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
                              addr->mem, imm, am.new_op2, am.ins_permuted, 0);
        set_am_attributes(cmp, &am);
@@ -4881,11 +4881,11 @@ static ir_node *gen_popcount(ir_node *node) {
        /* do the standard popcount algo */
 
        /* m1 = x & 0x55555555 */
-       imm = create_Immediate(NULL, 0, 0x55555555);
+       imm = ia32_create_Immediate(NULL, 0, 0x55555555);
        m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, new_param, imm);
 
        /* s1 = x >> 1 */
-       simm = create_Immediate(NULL, 0, 1);
+       simm = ia32_create_Immediate(NULL, 0, 1);
        s1 = new_bd_ia32_Shl(dbgi, new_block, new_param, simm);
 
        /* m2 = s1 & 0x55555555 */
@@ -4895,11 +4895,11 @@ static ir_node *gen_popcount(ir_node *node) {
        m3 = new_bd_ia32_Lea(dbgi, new_block, m2, m1);
 
        /* m4 = m3 & 0x33333333 */
-       imm = create_Immediate(NULL, 0, 0x33333333);
+       imm = ia32_create_Immediate(NULL, 0, 0x33333333);
        m4 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m3, imm);
 
        /* s2 = m3 >> 2 */
-       simm = create_Immediate(NULL, 0, 2);
+       simm = ia32_create_Immediate(NULL, 0, 2);
        s2 = new_bd_ia32_Shl(dbgi, new_block, m3, simm);
 
        /* m5 = s2 & 0x33333333 */
@@ -4909,11 +4909,11 @@ static ir_node *gen_popcount(ir_node *node) {
        m6 = new_bd_ia32_Lea(dbgi, new_block, m4, m5);
 
        /* m7 = m6 & 0x0F0F0F0F */
-       imm = create_Immediate(NULL, 0, 0x0F0F0F0F);
+       imm = ia32_create_Immediate(NULL, 0, 0x0F0F0F0F);
        m7 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m6, imm);
 
        /* s3 = m6 >> 4 */
-       simm = create_Immediate(NULL, 0, 4);
+       simm = ia32_create_Immediate(NULL, 0, 4);
        s3 = new_bd_ia32_Shl(dbgi, new_block, m6, simm);
 
        /* m8 = s3 & 0x0F0F0F0F */
@@ -4923,11 +4923,11 @@ static ir_node *gen_popcount(ir_node *node) {
        m9 = new_bd_ia32_Lea(dbgi, new_block, m7, m8);
 
        /* m10 = m9 & 0x00FF00FF */
-       imm = create_Immediate(NULL, 0, 0x00FF00FF);
+       imm = ia32_create_Immediate(NULL, 0, 0x00FF00FF);
        m10 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m9, imm);
 
        /* s4 = m9 >> 8 */
-       simm = create_Immediate(NULL, 0, 8);
+       simm = ia32_create_Immediate(NULL, 0, 8);
        s4 = new_bd_ia32_Shl(dbgi, new_block, m9, simm);
 
        /* m11 = s4 & 0x00FF00FF */
@@ -4937,11 +4937,11 @@ static ir_node *gen_popcount(ir_node *node) {
        m12 = new_bd_ia32_Lea(dbgi, new_block, m10, m11);
 
        /* m13 = m12 & 0x0000FFFF */
-       imm = create_Immediate(NULL, 0, 0x0000FFFF);
+       imm = ia32_create_Immediate(NULL, 0, 0x0000FFFF);
        m13 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, m12, imm);
 
        /* s5 = m12 >> 16 */
-       simm = create_Immediate(NULL, 0, 16);
+       simm = ia32_create_Immediate(NULL, 0, 16);
        s5 = new_bd_ia32_Shl(dbgi, new_block, m12, simm);
 
        /* res = m13 + s5 */
@@ -4967,18 +4967,18 @@ static ir_node *gen_bswap(ir_node *node) {
                        /* swap available */
                        return new_bd_ia32_Bswap(dbgi, new_block, param);
                }
-               s1 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
-               s2 = new_bd_ia32_Shl(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
+               s1 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
+               s2 = new_bd_ia32_Shl(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
 
-               m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, create_Immediate(NULL, 0, 0xFF00));
+               m1 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s2, ia32_create_Immediate(NULL, 0, 0xFF00));
                m2 = new_bd_ia32_Lea(dbgi, new_block, s1, m1);
 
-               s3 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 8));
+               s3 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 8));
 
-               m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, create_Immediate(NULL, 0, 0xFF0000));
+               m3 = new_bd_ia32_And(dbgi, new_block, noreg_GP, noreg_GP, nomem, s3, ia32_create_Immediate(NULL, 0, 0xFF0000));
                m4 = new_bd_ia32_Lea(dbgi, new_block, m2, m3);
 
-               s4 = new_bd_ia32_Shr(dbgi, new_block, param, create_Immediate(NULL, 0, 24));
+               s4 = new_bd_ia32_Shr(dbgi, new_block, param, ia32_create_Immediate(NULL, 0, 24));
                return new_bd_ia32_Lea(dbgi, new_block, m4, s4);
 
        case 16:
@@ -5026,6 +5026,95 @@ static ir_node *gen_inport(ir_node *node) {
        return res;
 }
 
+/**
+ * Transform a builtin inner trampoline
+ */
+static ir_node *gen_inner_trampoline(ir_node *node) {
+       ir_node  *ptr       = get_Builtin_param(node, 0);
+       ir_node  *callee    = get_Builtin_param(node, 1);
+       ir_node  *env       = be_transform_node(get_Builtin_param(node, 2));
+       ir_node  *mem       = get_Builtin_mem(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+       ir_node  *val;
+       ir_node  *store;
+       ir_node  *rel;
+       ir_node  *trampoline;
+       ir_node  *in[2];
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ia32_address_t addr;
+
+       /* construct store address */
+       memset(&addr, 0, sizeof(addr));
+       ia32_create_address_mode(&addr, ptr, 0);
+
+       if (addr.base == NULL) {
+               addr.base = noreg_GP;
+       } else {
+               addr.base = be_transform_node(addr.base);
+       }
+
+       if (addr.index == NULL) {
+               addr.index = noreg_GP;
+       } else {
+               addr.index = be_transform_node(addr.index);
+       }
+       addr.mem = be_transform_node(mem);
+
+       /* mov  ecx, <env> */
+       val   = ia32_create_Immediate(NULL, 0, 0xB9);
+       store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
+                                     addr.index, addr.mem, val);
+       set_irn_pinned(store, get_irn_pinned(node));
+       set_ia32_op_type(store, ia32_AddrModeD);
+       set_ia32_ls_mode(store, mode_Bu);
+       set_address(store, &addr);
+       addr.mem = store;
+       addr.offset += 1;
+
+       store = new_bd_ia32_Store(dbgi, new_block, addr.base,
+                                 addr.index, addr.mem, env);
+       set_irn_pinned(store, get_irn_pinned(node));
+       set_ia32_op_type(store, ia32_AddrModeD);
+       set_ia32_ls_mode(store, mode_Iu);
+       set_address(store, &addr);
+       addr.mem = store;
+       addr.offset += 4;
+
+       /* jmp rel <callee> */
+       val   = ia32_create_Immediate(NULL, 0, 0xE9);
+       store = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
+                                    addr.index, addr.mem, val);
+       set_irn_pinned(store, get_irn_pinned(node));
+       set_ia32_op_type(store, ia32_AddrModeD);
+       set_ia32_ls_mode(store, mode_Bu);
+       set_address(store, &addr);
+       addr.mem = store;
+       addr.offset += 1;
+
+       trampoline = be_transform_node(ptr);
+
+       /* the callee is typically an immediate */
+       if (is_SymConst(callee)) {
+               rel = new_bd_ia32_Const(dbgi, new_block, get_SymConst_entity(callee), 0, -10);
+       } else {
+               rel = new_bd_ia32_Lea(dbgi, new_block, be_transform_node(callee), ia32_create_Immediate(NULL, 0, -10));
+       }
+       rel = new_bd_ia32_Sub(dbgi, new_block, noreg_GP, noreg_GP, nomem, rel, trampoline);
+
+       store = new_bd_ia32_Store(dbgi, new_block, addr.base,
+                                 addr.index, addr.mem, rel);
+       set_irn_pinned(store, get_irn_pinned(node));
+       set_ia32_op_type(store, ia32_AddrModeD);
+       set_ia32_ls_mode(store, mode_Iu);
+       set_address(store, &addr);
+
+       in[0] = store;
+       in[1] = trampoline;
+
+       return new_r_Tuple(current_ir_graph, new_block, 2, in);
+}
+
 /**
  * Transform Builtin node.
  */
@@ -5059,6 +5148,8 @@ static ir_node *gen_Builtin(ir_node *node) {
                return gen_outport(node);
        case ir_bk_inport:
                return gen_inport(node);
+       case ir_bk_inner_trampoline:
+               return gen_inner_trampoline(node);
        }
        panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
 }
@@ -5097,6 +5188,13 @@ static ir_node *gen_Proj_Builtin(ir_node *proj) {
                        return new_r_Proj(current_ir_graph, get_nodes_block(new_node),
                                new_node, mode_M, pn_ia32_Inport_M);
                }
+       case ir_bk_inner_trampoline:
+               if (get_Proj_proj(proj) == pn_Builtin_1_result) {
+                       return get_Tuple_pred(new_node, 1);
+               } else {
+                       assert(get_Proj_proj(proj) == pn_Builtin_M);
+                       return get_Tuple_pred(new_node, 0);
+               }
        }
        panic("Builtin %s not implemented in IA32", get_builtin_kind_name(kind));
 }
@@ -5304,9 +5402,7 @@ static ir_node *gen_Proj(ir_node *node)
                                ir_node *block    = be_transform_node(get_nodes_block(node));
                                ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
                                                                                           mode_Iu, get_Proj_proj(node));
-#ifdef DEBUG_libfirm
                                new_proj->node_nr = node->node_nr;
-#endif
                                return new_proj;
                        }
                }