- implemented ull -> float conversion for x87
[libfirm] / ir / be / ia32 / ia32_transform.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief       This file implements the IR transformation from firm into
23  *              ia32-Firm.
24  * @author      Christian Wuerdig, Matthias Braun
25  * @version     $Id$
26  */
27 #include "config.h"
28
29 #include <limits.h>
30 #include <stdbool.h>
31
32 #include "irargs_t.h"
33 #include "irnode_t.h"
34 #include "irgraph_t.h"
35 #include "irmode_t.h"
36 #include "iropt_t.h"
37 #include "irop_t.h"
38 #include "irprog_t.h"
39 #include "iredges_t.h"
40 #include "irgmod.h"
41 #include "irvrfy.h"
42 #include "ircons.h"
43 #include "irgwalk.h"
44 #include "irprintf.h"
45 #include "debug.h"
46 #include "irdom.h"
47 #include "archop.h"
48 #include "error.h"
49 #include "array_t.h"
50 #include "height.h"
51
52 #include "../benode_t.h"
53 #include "../besched.h"
54 #include "../beabi.h"
55 #include "../beutil.h"
56 #include "../beirg_t.h"
57 #include "../betranshlp.h"
58 #include "../be_t.h"
59
60 #include "bearch_ia32_t.h"
61 #include "ia32_common_transform.h"
62 #include "ia32_nodes_attr.h"
63 #include "ia32_transform.h"
64 #include "ia32_new_nodes.h"
65 #include "ia32_map_regs.h"
66 #include "ia32_dbg_stat.h"
67 #include "ia32_optimize.h"
68 #include "ia32_util.h"
69 #include "ia32_address_mode.h"
70 #include "ia32_architecture.h"
71
72 #include "gen_ia32_regalloc_if.h"
73
74 #define SFP_SIGN   "0x80000000"
75 #define DFP_SIGN   "0x8000000000000000"
76 #define SFP_ABS    "0x7FFFFFFF"
77 #define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
78 #define DFP_INTMAX "9223372036854775807"
79 #define ULL_BIAS   "18446744073709551616"
80
81 #define TP_SFP_SIGN "ia32_sfp_sign"
82 #define TP_DFP_SIGN "ia32_dfp_sign"
83 #define TP_SFP_ABS  "ia32_sfp_abs"
84 #define TP_DFP_ABS  "ia32_dfp_abs"
85 #define TP_INT_MAX  "ia32_int_max"
86 #define TP_ULL_BIAS "ia32_ull_bias"
87
88 #define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
89 #define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
90 #define ENT_SFP_ABS  ".LC_ia32_sfp_abs"
91 #define ENT_DFP_ABS  ".LC_ia32_dfp_abs"
92 #define ENT_INT_MAX  ".LC_ia32_int_max"
93 #define ENT_ULL_BIAS ".LC_ia32_ull_bias"
94
95 #define mode_vfp        (ia32_reg_classes[CLASS_ia32_vfp].mode)
96 #define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)
97
98 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
99
100 static ir_node         *initial_fpcw = NULL;
101
102 extern ir_op *get_op_Mulh(void);
103
104 typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
105         ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
106         ir_node *op2);
107
108 typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
109         ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
110         ir_node *flags);
111
112 typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
113         ir_node *op1, ir_node *op2);
114
115 typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
116         ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
117
118 typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
119         ir_node *base, ir_node *index, ir_node *mem);
120
121 typedef ir_node *construct_binop_float_func(dbg_info *db, ir_node *block,
122         ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
123         ir_node *fpcw);
124
125 typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
126
127 static ir_node *create_immediate_or_transform(ir_node *node,
128                                               char immediate_constraint_type);
129
130 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
131                                 dbg_info *dbgi, ir_node *block,
132                                 ir_node *op, ir_node *orig_node);
133
134 /** Return non-zero is a node represents the 0 constant. */
135 static bool is_Const_0(ir_node *node)
136 {
137         return is_Const(node) && is_Const_null(node);
138 }
139
140 /** Return non-zero is a node represents the 1 constant. */
141 static bool is_Const_1(ir_node *node)
142 {
143         return is_Const(node) && is_Const_one(node);
144 }
145
146 /** Return non-zero is a node represents the -1 constant. */
147 static bool is_Const_Minus_1(ir_node *node)
148 {
149         return is_Const(node) && is_Const_all_one(node);
150 }
151
152 /**
153  * returns true if constant can be created with a simple float command
154  */
155 static bool is_simple_x87_Const(ir_node *node)
156 {
157         tarval *tv = get_Const_tarval(node);
158         if (tarval_is_null(tv) || tarval_is_one(tv))
159                 return true;
160
161         /* TODO: match all the other float constants */
162         return false;
163 }
164
165 /**
166  * returns true if constant can be created with a simple float command
167  */
168 static bool is_simple_sse_Const(ir_node *node)
169 {
170         tarval  *tv   = get_Const_tarval(node);
171         ir_mode *mode = get_tarval_mode(tv);
172
173         if (mode == mode_F)
174                 return true;
175
176         if (tarval_is_null(tv) || tarval_is_one(tv))
177                 return true;
178
179         if (mode == mode_D) {
180                 unsigned val = get_tarval_sub_bits(tv, 0) |
181                         (get_tarval_sub_bits(tv, 1) << 8) |
182                         (get_tarval_sub_bits(tv, 2) << 16) |
183                         (get_tarval_sub_bits(tv, 3) << 24);
184                 if (val == 0)
185                         /* lower 32bit are zero, really a 32bit constant */
186                         return true;
187         }
188
189         /* TODO: match all the other float constants */
190         return false;
191 }
192
193 /**
194  * Transforms a Const.
195  */
196 static ir_node *gen_Const(ir_node *node)
197 {
198         ir_node  *old_block = get_nodes_block(node);
199         ir_node  *block     = be_transform_node(old_block);
200         dbg_info *dbgi      = get_irn_dbg_info(node);
201         ir_mode  *mode      = get_irn_mode(node);
202
203         assert(is_Const(node));
204
205         if (mode_is_float(mode)) {
206                 ir_node   *res   = NULL;
207                 ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
208                 ir_node   *nomem = new_NoMem();
209                 ir_node   *load;
210                 ir_entity *floatent;
211
212                 if (ia32_cg_config.use_sse2) {
213                         tarval *tv = get_Const_tarval(node);
214                         if (tarval_is_null(tv)) {
215                                 load = new_bd_ia32_xZero(dbgi, block);
216                                 set_ia32_ls_mode(load, mode);
217                                 res  = load;
218                         } else if (tarval_is_one(tv)) {
219                                 int     cnst  = mode == mode_F ? 26 : 55;
220                                 ir_node *imm1 = create_Immediate(NULL, 0, cnst);
221                                 ir_node *imm2 = create_Immediate(NULL, 0, 2);
222                                 ir_node *pslld, *psrld;
223
224                                 load = new_bd_ia32_xAllOnes(dbgi, block);
225                                 set_ia32_ls_mode(load, mode);
226                                 pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
227                                 set_ia32_ls_mode(pslld, mode);
228                                 psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
229                                 set_ia32_ls_mode(psrld, mode);
230                                 res = psrld;
231                         } else if (mode == mode_F) {
232                                 /* we can place any 32bit constant by using a movd gp, sse */
233                                 unsigned val = get_tarval_sub_bits(tv, 0) |
234                                                (get_tarval_sub_bits(tv, 1) << 8) |
235                                                (get_tarval_sub_bits(tv, 2) << 16) |
236                                                (get_tarval_sub_bits(tv, 3) << 24);
237                                 ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
238                                 load = new_bd_ia32_xMovd(dbgi, block, cnst);
239                                 set_ia32_ls_mode(load, mode);
240                                 res = load;
241                         } else {
242                                 if (mode == mode_D) {
243                                         unsigned val = get_tarval_sub_bits(tv, 0) |
244                                                 (get_tarval_sub_bits(tv, 1) << 8) |
245                                                 (get_tarval_sub_bits(tv, 2) << 16) |
246                                                 (get_tarval_sub_bits(tv, 3) << 24);
247                                         if (val == 0) {
248                                                 ir_node *imm32 = create_Immediate(NULL, 0, 32);
249                                                 ir_node *cnst, *psllq;
250
251                                                 /* fine, lower 32bit are zero, produce 32bit value */
252                                                 val = get_tarval_sub_bits(tv, 4) |
253                                                         (get_tarval_sub_bits(tv, 5) << 8) |
254                                                         (get_tarval_sub_bits(tv, 6) << 16) |
255                                                         (get_tarval_sub_bits(tv, 7) << 24);
256                                                 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
257                                                 load = new_bd_ia32_xMovd(dbgi, block, cnst);
258                                                 set_ia32_ls_mode(load, mode);
259                                                 psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
260                                                 set_ia32_ls_mode(psllq, mode);
261                                                 res = psllq;
262                                                 goto end;
263                                         }
264                                 }
265                                 floatent = create_float_const_entity(node);
266
267                                 load     = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem,
268                                                              mode);
269                                 set_ia32_op_type(load, ia32_AddrModeS);
270                                 set_ia32_am_sc(load, floatent);
271                                 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
272                                 res = new_r_Proj(current_ir_graph, block, load, mode_xmm, pn_ia32_xLoad_res);
273                         }
274                 } else {
275                         if (is_Const_null(node)) {
276                                 load = new_bd_ia32_vfldz(dbgi, block);
277                                 res  = load;
278                                 set_ia32_ls_mode(load, mode);
279                         } else if (is_Const_one(node)) {
280                                 load = new_bd_ia32_vfld1(dbgi, block);
281                                 res  = load;
282                                 set_ia32_ls_mode(load, mode);
283                         } else {
284                                 floatent = create_float_const_entity(node);
285
286                                 load     = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode);
287                                 set_ia32_op_type(load, ia32_AddrModeS);
288                                 set_ia32_am_sc(load, floatent);
289                                 arch_irn_add_flags(load, arch_irn_flags_rematerializable);
290                                 res = new_r_Proj(current_ir_graph, block, load, mode_vfp, pn_ia32_vfld_res);
291                                 /* take the mode from the entity */
292                                 set_ia32_ls_mode(load, get_type_mode(get_entity_type(floatent)));
293                         }
294                 }
295 end:
296                 SET_IA32_ORIG_NODE(load, node);
297
298                 be_dep_on_frame(load);
299                 return res;
300         } else { /* non-float mode */
301                 ir_node *cnst;
302                 tarval  *tv = get_Const_tarval(node);
303                 long     val;
304
305                 tv = tarval_convert_to(tv, mode_Iu);
306
307                 if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
308                     tv == NULL) {
309                         panic("couldn't convert constant tarval (%+F)", node);
310                 }
311                 val = get_tarval_long(tv);
312
313                 cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
314                 SET_IA32_ORIG_NODE(cnst, node);
315
316                 be_dep_on_frame(cnst);
317                 return cnst;
318         }
319 }
320
321 /**
322  * Transforms a SymConst.
323  */
324 static ir_node *gen_SymConst(ir_node *node)
325 {
326         ir_node  *old_block = get_nodes_block(node);
327         ir_node  *block = be_transform_node(old_block);
328         dbg_info *dbgi  = get_irn_dbg_info(node);
329         ir_mode  *mode  = get_irn_mode(node);
330         ir_node  *cnst;
331
332         if (mode_is_float(mode)) {
333                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
334                 ir_node *nomem = new_NoMem();
335
336                 if (ia32_cg_config.use_sse2)
337                         cnst = new_bd_ia32_xLoad(dbgi, block, noreg, noreg, nomem, mode_E);
338                 else
339                         cnst = new_bd_ia32_vfld(dbgi, block, noreg, noreg, nomem, mode_E);
340                 set_ia32_am_sc(cnst, get_SymConst_entity(node));
341                 set_ia32_use_frame(cnst);
342         } else {
343                 ir_entity *entity;
344
345                 if (get_SymConst_kind(node) != symconst_addr_ent) {
346                         panic("backend only support symconst_addr_ent (at %+F)", node);
347                 }
348                 entity = get_SymConst_entity(node);
349                 cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
350         }
351
352         SET_IA32_ORIG_NODE(cnst, node);
353
354         be_dep_on_frame(cnst);
355         return cnst;
356 }
357
358 /* Generates an entity for a known FP const (used for FP Neg + Abs) */
359 ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
360 {
361         static const struct {
362                 const char *tp_name;
363                 const char *ent_name;
364                 const char *cnst_str;
365                 char mode;
366                 char align;
367         } names [ia32_known_const_max] = {
368                 { TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN,   0, 16 },       /* ia32_SSIGN */
369                 { TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN,   1, 16 },       /* ia32_DSIGN */
370                 { TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS,    0, 16 },       /* ia32_SABS */
371                 { TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS,    1, 16 },       /* ia32_DABS */
372                 { TP_INT_MAX,  ENT_INT_MAX,  DFP_INTMAX, 2, 4 },        /* ia32_INTMAX */
373                 { TP_ULL_BIAS, ENT_ULL_BIAS, ULL_BIAS,   3, 4 }     /* ia32_ULLBIAS */
374         };
375         static ir_entity *ent_cache[ia32_known_const_max];
376
377         const char    *tp_name, *ent_name, *cnst_str;
378         ir_type       *tp;
379         ir_entity     *ent;
380         tarval        *tv;
381         ir_mode       *mode;
382
383         ent_name = names[kct].ent_name;
384         if (! ent_cache[kct]) {
385                 tp_name  = names[kct].tp_name;
386                 cnst_str = names[kct].cnst_str;
387
388                 switch (names[kct].mode) {
389                 case 0:  mode = mode_Iu; break;
390                 case 1:  mode = mode_Lu; break;
391                 default: mode = mode_F; break;
392                 }
393                 tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
394                 tp  = new_type_primitive(new_id_from_str(tp_name), mode);
395                 /* set the specified alignment */
396                 set_type_alignment_bytes(tp, names[kct].align);
397
398                 if (kct == ia32_ULLBIAS) {
399                         /* we are in the backend, construct a fixed type here */
400                         unsigned size = get_type_size_bytes(tp);
401                         tp = new_type_array(new_id_from_str(tp_name), 1, tp);
402                         set_type_alignment_bytes(tp, names[kct].align);
403                         set_type_size_bytes(tp, 2 * size);
404                         set_type_state(tp, layout_fixed);
405                 }
406                 ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
407
408                 set_entity_ld_ident(ent, get_entity_ident(ent));
409                 set_entity_visibility(ent, visibility_local);
410                 set_entity_variability(ent, variability_constant);
411                 set_entity_allocation(ent, allocation_static);
412
413                 if (kct == ia32_ULLBIAS) {
414                         ir_initializer_t *initializer = create_initializer_compound(2);
415
416                         set_initializer_compound_value(initializer, 0,
417                                 create_initializer_tarval(get_tarval_null(mode)));
418                         set_initializer_compound_value(initializer, 1,
419                                 create_initializer_tarval(tv));
420
421                         set_entity_initializer(ent, initializer);
422                 } else {
423                         set_entity_initializer(ent, create_initializer_tarval(tv));
424                 }
425
426                 /* cache the entry */
427                 ent_cache[kct] = ent;
428         }
429
430         return ent_cache[kct];
431 }
432
433 /**
434  * return true if the node is a Proj(Load) and could be used in source address
435  * mode for another node. Will return only true if the @p other node is not
436  * dependent on the memory of the Load (for binary operations use the other
437  * input here, for unary operations use NULL).
438  */
439 static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
440                                         ir_node *other, ir_node *other2, match_flags_t flags)
441 {
442         ir_node *load;
443         long     pn;
444
445         /* float constants are always available */
446         if (is_Const(node)) {
447                 ir_mode *mode = get_irn_mode(node);
448                 if (mode_is_float(mode)) {
449                         if (ia32_cg_config.use_sse2) {
450                                 if (is_simple_sse_Const(node))
451                                         return 0;
452                         } else {
453                                 if (is_simple_x87_Const(node))
454                                         return 0;
455                         }
456                         if (get_irn_n_edges(node) > 1)
457                                 return 0;
458                         return 1;
459                 }
460         }
461
462         if (!is_Proj(node))
463                 return 0;
464         load = get_Proj_pred(node);
465         pn   = get_Proj_proj(node);
466         if (!is_Load(load) || pn != pn_Load_res)
467                 return 0;
468         if (get_nodes_block(load) != block)
469                 return 0;
470         /* we only use address mode if we're the only user of the load */
471         if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
472                 return 0;
473         /* in some edge cases with address mode we might reach the load normally
474          * and through some AM sequence, if it is already materialized then we
475          * can't create an AM node from it */
476         if (be_is_transformed(node))
477                 return 0;
478
479         /* don't do AM if other node inputs depend on the load (via mem-proj) */
480         if (other != NULL && prevents_AM(block, load, other))
481                 return 0;
482
483         if (other2 != NULL && prevents_AM(block, load, other2))
484                 return 0;
485
486         return 1;
487 }
488
489 typedef struct ia32_address_mode_t ia32_address_mode_t;
490 struct ia32_address_mode_t {
491         ia32_address_t  addr;
492         ir_mode        *ls_mode;
493         ir_node        *mem_proj;
494         ir_node        *am_node;
495         ia32_op_type_t  op_type;
496         ir_node        *new_op1;
497         ir_node        *new_op2;
498         op_pin_state    pinned;
499         unsigned        commutative  : 1;
500         unsigned        ins_permuted : 1;
501 };
502
503 static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
504 {
505         ir_node *noreg_gp;
506
507         /* construct load address */
508         memset(addr, 0, sizeof(addr[0]));
509         ia32_create_address_mode(addr, ptr, 0);
510
511         noreg_gp    = ia32_new_NoReg_gp(env_cg);
512         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
513         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
514         addr->mem   = be_transform_node(mem);
515 }
516
517 static void build_address(ia32_address_mode_t *am, ir_node *node,
518                           ia32_create_am_flags_t flags)
519 {
520         ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
521         ia32_address_t *addr     = &am->addr;
522         ir_node        *load;
523         ir_node        *ptr;
524         ir_node        *mem;
525         ir_node        *new_mem;
526
527         if (is_Const(node)) {
528                 ir_entity *entity  = create_float_const_entity(node);
529                 addr->base         = noreg_gp;
530                 addr->index        = noreg_gp;
531                 addr->mem          = new_NoMem();
532                 addr->symconst_ent = entity;
533                 addr->use_frame    = 1;
534                 am->ls_mode        = get_type_mode(get_entity_type(entity));
535                 am->pinned         = op_pin_state_floats;
536                 return;
537         }
538
539         load         = get_Proj_pred(node);
540         ptr          = get_Load_ptr(load);
541         mem          = get_Load_mem(load);
542         new_mem      = be_transform_node(mem);
543         am->pinned   = get_irn_pinned(load);
544         am->ls_mode  = get_Load_mode(load);
545         am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
546         am->am_node  = node;
547
548         /* construct load address */
549         ia32_create_address_mode(addr, ptr, flags);
550
551         addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_gp;
552         addr->index = addr->index ? be_transform_node(addr->index) : noreg_gp;
553         addr->mem   = new_mem;
554 }
555
556 static void set_address(ir_node *node, const ia32_address_t *addr)
557 {
558         set_ia32_am_scale(node, addr->scale);
559         set_ia32_am_sc(node, addr->symconst_ent);
560         set_ia32_am_offs_int(node, addr->offset);
561         if (addr->symconst_sign)
562                 set_ia32_am_sc_sign(node);
563         if (addr->use_frame)
564                 set_ia32_use_frame(node);
565         set_ia32_frame_ent(node, addr->frame_entity);
566 }
567
568 /**
569  * Apply attributes of a given address mode to a node.
570  */
571 static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
572 {
573         set_address(node, &am->addr);
574
575         set_ia32_op_type(node, am->op_type);
576         set_ia32_ls_mode(node, am->ls_mode);
577         if (am->pinned == op_pin_state_pinned) {
578                 /* beware: some nodes are already pinned and did not allow to change the state */
579                 if (get_irn_pinned(node) != op_pin_state_pinned)
580                         set_irn_pinned(node, op_pin_state_pinned);
581         }
582         if (am->commutative)
583                 set_ia32_commutative(node);
584 }
585
586 /**
587  * Check, if a given node is a Down-Conv, ie. a integer Conv
588  * from a mode with a mode with more bits to a mode with lesser bits.
589  * Moreover, we return only true if the node has not more than 1 user.
590  *
591  * @param node   the node
592  * @return non-zero if node is a Down-Conv
593  */
594 static int is_downconv(const ir_node *node)
595 {
596         ir_mode *src_mode;
597         ir_mode *dest_mode;
598
599         if (!is_Conv(node))
600                 return 0;
601
602         /* we only want to skip the conv when we're the only user
603          * (not optimal but for now...)
604          */
605         if (get_irn_n_edges(node) > 1)
606                 return 0;
607
608         src_mode  = get_irn_mode(get_Conv_op(node));
609         dest_mode = get_irn_mode(node);
610         return
611                 ia32_mode_needs_gp_reg(src_mode)  &&
612                 ia32_mode_needs_gp_reg(dest_mode) &&
613                 get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
614 }
615
616 /* Skip all Down-Conv's on a given node and return the resulting node. */
617 ir_node *ia32_skip_downconv(ir_node *node)
618 {
619         while (is_downconv(node))
620                 node = get_Conv_op(node);
621
622         return node;
623 }
624
625 static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
626 {
627         ir_mode  *mode = get_irn_mode(node);
628         ir_node  *block;
629         ir_mode  *tgt_mode;
630         dbg_info *dbgi;
631
632         if (mode_is_signed(mode)) {
633                 tgt_mode = mode_Is;
634         } else {
635                 tgt_mode = mode_Iu;
636         }
637         block = get_nodes_block(node);
638         dbgi  = get_irn_dbg_info(node);
639
640         return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
641 }
642
643 /**
644  * matches operands of a node into ia32 addressing/operand modes. This covers
645  * usage of source address mode, immediates, operations with non 32-bit modes,
646  * ...
647  * The resulting data is filled into the @p am struct. block is the block
648  * of the node whose arguments are matched. op1, op2 are the first and second
649  * input that are matched (op1 may be NULL). other_op is another unrelated
650  * input that is not matched! but which is needed sometimes to check if AM
651  * for op1/op2 is legal.
652  * @p flags describes the supported modes of the operation in detail.
653  */
654 static void match_arguments(ia32_address_mode_t *am, ir_node *block,
655                             ir_node *op1, ir_node *op2, ir_node *other_op,
656                             match_flags_t flags)
657 {
658         ia32_address_t *addr      = &am->addr;
659         ir_mode        *mode      = get_irn_mode(op2);
660         int             mode_bits = get_mode_size_bits(mode);
661         ir_node        *noreg_gp, *new_op1, *new_op2;
662         int             use_am;
663         unsigned        commutative;
664         int             use_am_and_immediates;
665         int             use_immediate;
666
667         memset(am, 0, sizeof(am[0]));
668
669         commutative           = (flags & match_commutative) != 0;
670         use_am_and_immediates = (flags & match_am_and_immediates) != 0;
671         use_am                = (flags & match_am) != 0;
672         use_immediate         = (flags & match_immediate) != 0;
673         assert(!use_am_and_immediates || use_immediate);
674
675         assert(op2 != NULL);
676         assert(!commutative || op1 != NULL);
677         assert(use_am || !(flags & match_8bit_am));
678         assert(use_am || !(flags & match_16bit_am));
679
680         if ((mode_bits ==  8 && !(flags & match_8bit_am)) ||
681                         (mode_bits == 16 && !(flags & match_16bit_am))) {
682                 use_am = 0;
683         }
684
685         /* we can simply skip downconvs for mode neutral nodes: the upper bits
686          * can be random for these operations */
687         if (flags & match_mode_neutral) {
688                 op2 = ia32_skip_downconv(op2);
689                 if (op1 != NULL) {
690                         op1 = ia32_skip_downconv(op1);
691                 }
692         }
693
694         /* match immediates. firm nodes are normalized: constants are always on the
695          * op2 input */
696         new_op2 = NULL;
697         if (!(flags & match_try_am) && use_immediate) {
698                 new_op2 = try_create_Immediate(op2, 0);
699         }
700
701         noreg_gp = ia32_new_NoReg_gp(env_cg);
702         if (new_op2 == NULL &&
703             use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
704                 build_address(am, op2, 0);
705                 new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
706                 if (mode_is_float(mode)) {
707                         new_op2 = ia32_new_NoReg_vfp(env_cg);
708                 } else {
709                         new_op2 = noreg_gp;
710                 }
711                 am->op_type = ia32_AddrModeS;
712         } else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
713                        use_am &&
714                        ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
715                 ir_node *noreg;
716                 build_address(am, op1, 0);
717
718                 if (mode_is_float(mode)) {
719                         noreg = ia32_new_NoReg_vfp(env_cg);
720                 } else {
721                         noreg = noreg_gp;
722                 }
723
724                 if (new_op2 != NULL) {
725                         new_op1 = noreg;
726                 } else {
727                         new_op1 = be_transform_node(op2);
728                         new_op2 = noreg;
729                         am->ins_permuted = 1;
730                 }
731                 am->op_type = ia32_AddrModeS;
732         } else {
733                 am->op_type = ia32_Normal;
734
735                 if (flags & match_try_am) {
736                         am->new_op1 = NULL;
737                         am->new_op2 = NULL;
738                         return;
739                 }
740
741                 new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
742                 if (new_op2 == NULL)
743                         new_op2 = be_transform_node(op2);
744                 am->ls_mode =
745                         (flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
746         }
747         if (addr->base == NULL)
748                 addr->base = noreg_gp;
749         if (addr->index == NULL)
750                 addr->index = noreg_gp;
751         if (addr->mem == NULL)
752                 addr->mem = new_NoMem();
753
754         am->new_op1     = new_op1;
755         am->new_op2     = new_op2;
756         am->commutative = commutative;
757 }
758
759 static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
760 {
761         ir_mode  *mode;
762         ir_node  *load;
763
764         if (am->mem_proj == NULL)
765                 return node;
766
767         /* we have to create a mode_T so the old MemProj can attach to us */
768         mode = get_irn_mode(node);
769         load = get_Proj_pred(am->mem_proj);
770
771         be_set_transformed_node(load, node);
772
773         if (mode != mode_T) {
774                 set_irn_mode(node, mode_T);
775                 return new_rd_Proj(NULL, current_ir_graph, get_nodes_block(node), node, mode, pn_ia32_res);
776         } else {
777                 return node;
778         }
779 }
780
781 /**
782  * Construct a standard binary operation, set AM and immediate if required.
783  *
784  * @param node  The original node for which the binop is created
785  * @param op1   The first operand
786  * @param op2   The second operand
787  * @param func  The node constructor function
788  * @return The constructed ia32 node.
789  */
790 static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
791                           construct_binop_func *func, match_flags_t flags)
792 {
793         dbg_info            *dbgi;
794         ir_node             *block, *new_block, *new_node;
795         ia32_address_mode_t  am;
796         ia32_address_t      *addr = &am.addr;
797
798         block = get_nodes_block(node);
799         match_arguments(&am, block, op1, op2, NULL, flags);
800
801         dbgi      = get_irn_dbg_info(node);
802         new_block = be_transform_node(block);
803         new_node  = func(dbgi, new_block, addr->base, addr->index, addr->mem,
804                         am.new_op1, am.new_op2);
805         set_am_attributes(new_node, &am);
806         /* we can't use source address mode anymore when using immediates */
807         if (!(flags & match_am_and_immediates) &&
808             (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
809                 set_ia32_am_support(new_node, ia32_am_none);
810         SET_IA32_ORIG_NODE(new_node, node);
811
812         new_node = fix_mem_proj(new_node, &am);
813
814         return new_node;
815 }
816
817 enum {
818         n_ia32_l_binop_left,
819         n_ia32_l_binop_right,
820         n_ia32_l_binop_eflags
821 };
822 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Adc_left,       n_Adc_left)
823 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Adc_right,      n_Adc_right)
824 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Adc_eflags,     n_Adc_eflags)
825 COMPILETIME_ASSERT(n_ia32_l_binop_left   == n_ia32_l_Sbb_minuend,    n_Sbb_minuend)
826 COMPILETIME_ASSERT(n_ia32_l_binop_right  == n_ia32_l_Sbb_subtrahend, n_Sbb_subtrahend)
827 COMPILETIME_ASSERT(n_ia32_l_binop_eflags == n_ia32_l_Sbb_eflags,     n_Sbb_eflags)
828
829 /**
830  * Construct a binary operation which also consumes the eflags.
831  *
832  * @param node  The node to transform
833  * @param func  The node constructor function
834  * @param flags The match flags
835  * @return      The constructor ia32 node
836  */
837 static ir_node *gen_binop_flags(ir_node *node, construct_binop_flags_func *func,
838                                 match_flags_t flags)
839 {
840         ir_node             *src_block  = get_nodes_block(node);
841         ir_node             *op1        = get_irn_n(node, n_ia32_l_binop_left);
842         ir_node             *op2        = get_irn_n(node, n_ia32_l_binop_right);
843         ir_node             *eflags     = get_irn_n(node, n_ia32_l_binop_eflags);
844         dbg_info            *dbgi;
845         ir_node             *block, *new_node, *new_eflags;
846         ia32_address_mode_t  am;
847         ia32_address_t      *addr       = &am.addr;
848
849         match_arguments(&am, src_block, op1, op2, eflags, flags);
850
851         dbgi       = get_irn_dbg_info(node);
852         block      = be_transform_node(src_block);
853         new_eflags = be_transform_node(eflags);
854         new_node   = func(dbgi, block, addr->base, addr->index, addr->mem,
855                         am.new_op1, am.new_op2, new_eflags);
856         set_am_attributes(new_node, &am);
857         /* we can't use source address mode anymore when using immediates */
858         if (!(flags & match_am_and_immediates) &&
859             (is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2)))
860                 set_ia32_am_support(new_node, ia32_am_none);
861         SET_IA32_ORIG_NODE(new_node, node);
862
863         new_node = fix_mem_proj(new_node, &am);
864
865         return new_node;
866 }
867
868 static ir_node *get_fpcw(void)
869 {
870         ir_node *fpcw;
871         if (initial_fpcw != NULL)
872                 return initial_fpcw;
873
874         fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
875                                              &ia32_fp_cw_regs[REG_FPCW]);
876         initial_fpcw = be_transform_node(fpcw);
877
878         return initial_fpcw;
879 }
880
881 /**
882  * Construct a standard binary operation, set AM and immediate if required.
883  *
884  * @param op1   The first operand
885  * @param op2   The second operand
886  * @param func  The node constructor function
887  * @return The constructed ia32 node.
888  */
889 static ir_node *gen_binop_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
890                                     construct_binop_float_func *func)
891 {
892         ir_mode             *mode  = get_irn_mode(node);
893         dbg_info            *dbgi;
894         ir_node             *block, *new_block, *new_node;
895         ia32_address_mode_t  am;
896         ia32_address_t      *addr = &am.addr;
897         ia32_x87_attr_t     *attr;
898         /* All operations are considered commutative, because there are reverse
899          * variants */
900         match_flags_t        flags = match_commutative;
901
902         /* cannot use address mode with long double on x87 */
903         if (get_mode_size_bits(mode) <= 64)
904                 flags |= match_am;
905
906         block = get_nodes_block(node);
907         match_arguments(&am, block, op1, op2, NULL, flags);
908
909         dbgi      = get_irn_dbg_info(node);
910         new_block = be_transform_node(block);
911         new_node  = func(dbgi, new_block, addr->base, addr->index, addr->mem,
912                         am.new_op1, am.new_op2, get_fpcw());
913         set_am_attributes(new_node, &am);
914
915         attr = get_ia32_x87_attr(new_node);
916         attr->attr.data.ins_permuted = am.ins_permuted;
917
918         SET_IA32_ORIG_NODE(new_node, node);
919
920         new_node = fix_mem_proj(new_node, &am);
921
922         return new_node;
923 }
924
925 /**
926  * Construct a shift/rotate binary operation, sets AM and immediate if required.
927  *
928  * @param op1   The first operand
929  * @param op2   The second operand
930  * @param func  The node constructor function
931  * @return The constructed ia32 node.
932  */
933 static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
934                                 construct_shift_func *func,
935                                 match_flags_t flags)
936 {
937         dbg_info *dbgi;
938         ir_node  *block, *new_block, *new_op1, *new_op2, *new_node;
939
940         assert(! mode_is_float(get_irn_mode(node)));
941         assert(flags & match_immediate);
942         assert((flags & ~(match_mode_neutral | match_immediate)) == 0);
943
944         if (flags & match_mode_neutral) {
945                 op1     = ia32_skip_downconv(op1);
946                 new_op1 = be_transform_node(op1);
947         } else if (get_mode_size_bits(get_irn_mode(node)) != 32) {
948                 new_op1 = create_upconv(op1, node);
949         } else {
950                 new_op1 = be_transform_node(op1);
951         }
952
953         /* the shift amount can be any mode that is bigger than 5 bits, since all
954          * other bits are ignored anyway */
955         while (is_Conv(op2) && get_irn_n_edges(op2) == 1) {
956                 ir_node *const op = get_Conv_op(op2);
957                 if (mode_is_float(get_irn_mode(op)))
958                         break;
959                 op2 = op;
960                 assert(get_mode_size_bits(get_irn_mode(op2)) >= 5);
961         }
962         new_op2 = create_immediate_or_transform(op2, 0);
963
964         dbgi      = get_irn_dbg_info(node);
965         block     = get_nodes_block(node);
966         new_block = be_transform_node(block);
967         new_node  = func(dbgi, new_block, new_op1, new_op2);
968         SET_IA32_ORIG_NODE(new_node, node);
969
970         /* lowered shift instruction may have a dependency operand, handle it here */
971         if (get_irn_arity(node) == 3) {
972                 /* we have a dependency */
973                 ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
974                 add_irn_dep(new_node, new_dep);
975         }
976
977         return new_node;
978 }
979
980
981 /**
982  * Construct a standard unary operation, set AM and immediate if required.
983  *
984  * @param op    The operand
985  * @param func  The node constructor function
986  * @return The constructed ia32 node.
987  */
988 static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func,
989                          match_flags_t flags)
990 {
991         dbg_info *dbgi;
992         ir_node  *block, *new_block, *new_op, *new_node;
993
994         assert(flags == 0 || flags == match_mode_neutral);
995         if (flags & match_mode_neutral) {
996                 op = ia32_skip_downconv(op);
997         }
998
999         new_op    = be_transform_node(op);
1000         dbgi      = get_irn_dbg_info(node);
1001         block     = get_nodes_block(node);
1002         new_block = be_transform_node(block);
1003         new_node  = func(dbgi, new_block, new_op);
1004
1005         SET_IA32_ORIG_NODE(new_node, node);
1006
1007         return new_node;
1008 }
1009
1010 static ir_node *create_lea_from_address(dbg_info *dbgi, ir_node *block,
1011                                         ia32_address_t *addr)
1012 {
1013         ir_node *base, *index, *res;
1014
1015         base = addr->base;
1016         if (base == NULL) {
1017                 base = ia32_new_NoReg_gp(env_cg);
1018         } else {
1019                 base = be_transform_node(base);
1020         }
1021
1022         index = addr->index;
1023         if (index == NULL) {
1024                 index = ia32_new_NoReg_gp(env_cg);
1025         } else {
1026                 index = be_transform_node(index);
1027         }
1028
1029         res = new_bd_ia32_Lea(dbgi, block, base, index);
1030         set_address(res, addr);
1031
1032         return res;
1033 }
1034
1035 /**
1036  * Returns non-zero if a given address mode has a symbolic or
1037  * numerical offset != 0.
1038  */
1039 static int am_has_immediates(const ia32_address_t *addr)
1040 {
1041         return addr->offset != 0 || addr->symconst_ent != NULL
1042                 || addr->frame_entity || addr->use_frame;
1043 }
1044
1045 /**
1046  * Creates an ia32 Add.
1047  *
1048  * @return the created ia32 Add node
1049  */
1050 static ir_node *gen_Add(ir_node *node)
1051 {
1052         ir_mode  *mode = get_irn_mode(node);
1053         ir_node  *op1  = get_Add_left(node);
1054         ir_node  *op2  = get_Add_right(node);
1055         dbg_info *dbgi;
1056         ir_node  *block, *new_block, *new_node, *add_immediate_op;
1057         ia32_address_t       addr;
1058         ia32_address_mode_t  am;
1059
1060         if (mode_is_float(mode)) {
1061                 if (ia32_cg_config.use_sse2)
1062                         return gen_binop(node, op1, op2, new_bd_ia32_xAdd,
1063                                          match_commutative | match_am);
1064                 else
1065                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfadd);
1066         }
1067
1068         ia32_mark_non_am(node);
1069
1070         op2 = ia32_skip_downconv(op2);
1071         op1 = ia32_skip_downconv(op1);
1072
1073         /**
1074          * Rules for an Add:
1075          *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
1076          *   1. Add with immediate -> Lea
1077          *   2. Add with possible source address mode -> Add
1078          *   3. Otherwise -> Lea
1079          */
1080         memset(&addr, 0, sizeof(addr));
1081         ia32_create_address_mode(&addr, node, ia32_create_am_force);
1082         add_immediate_op = NULL;
1083
1084         dbgi      = get_irn_dbg_info(node);
1085         block     = get_nodes_block(node);
1086         new_block = be_transform_node(block);
1087
1088         /* a constant? */
1089         if (addr.base == NULL && addr.index == NULL) {
1090                 new_node = new_bd_ia32_Const(dbgi, new_block, addr.symconst_ent,
1091                                              addr.symconst_sign, addr.offset);
1092                 be_dep_on_frame(new_node);
1093                 SET_IA32_ORIG_NODE(new_node, node);
1094                 return new_node;
1095         }
1096         /* add with immediate? */
1097         if (addr.index == NULL) {
1098                 add_immediate_op = addr.base;
1099         } else if (addr.base == NULL && addr.scale == 0) {
1100                 add_immediate_op = addr.index;
1101         }
1102
1103         if (add_immediate_op != NULL) {
1104                 if (!am_has_immediates(&addr)) {
1105 #ifdef DEBUG_libfirm
1106                         ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
1107                                            node);
1108 #endif
1109                         return be_transform_node(add_immediate_op);
1110                 }
1111
1112                 new_node = create_lea_from_address(dbgi, new_block, &addr);
1113                 SET_IA32_ORIG_NODE(new_node, node);
1114                 return new_node;
1115         }
1116
1117         /* test if we can use source address mode */
1118         match_arguments(&am, block, op1, op2, NULL, match_commutative
1119                         | match_mode_neutral | match_am | match_immediate | match_try_am);
1120
1121         /* construct an Add with source address mode */
1122         if (am.op_type == ia32_AddrModeS) {
1123                 ia32_address_t *am_addr = &am.addr;
1124                 new_node = new_bd_ia32_Add(dbgi, new_block, am_addr->base,
1125                                          am_addr->index, am_addr->mem, am.new_op1,
1126                                          am.new_op2);
1127                 set_am_attributes(new_node, &am);
1128                 SET_IA32_ORIG_NODE(new_node, node);
1129
1130                 new_node = fix_mem_proj(new_node, &am);
1131
1132                 return new_node;
1133         }
1134
1135         /* otherwise construct a lea */
1136         new_node = create_lea_from_address(dbgi, new_block, &addr);
1137         SET_IA32_ORIG_NODE(new_node, node);
1138         return new_node;
1139 }
1140
1141 /**
1142  * Creates an ia32 Mul.
1143  *
1144  * @return the created ia32 Mul node
1145  */
1146 static ir_node *gen_Mul(ir_node *node)
1147 {
1148         ir_node *op1  = get_Mul_left(node);
1149         ir_node *op2  = get_Mul_right(node);
1150         ir_mode *mode = get_irn_mode(node);
1151
1152         if (mode_is_float(mode)) {
1153                 if (ia32_cg_config.use_sse2)
1154                         return gen_binop(node, op1, op2, new_bd_ia32_xMul,
1155                                          match_commutative | match_am);
1156                 else
1157                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfmul);
1158         }
1159         return gen_binop(node, op1, op2, new_bd_ia32_IMul,
1160                          match_commutative | match_am | match_mode_neutral |
1161                          match_immediate | match_am_and_immediates);
1162 }
1163
1164 /**
1165  * Creates an ia32 Mulh.
1166  * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
1167  * this result while Mul returns the lower 32 bit.
1168  *
1169  * @return the created ia32 Mulh node
1170  */
1171 static ir_node *gen_Mulh(ir_node *node)
1172 {
1173         ir_node              *block     = get_nodes_block(node);
1174         ir_node              *new_block = be_transform_node(block);
1175         dbg_info             *dbgi      = get_irn_dbg_info(node);
1176         ir_node              *op1       = get_Mulh_left(node);
1177         ir_node              *op2       = get_Mulh_right(node);
1178         ir_mode              *mode      = get_irn_mode(node);
1179         ir_node              *new_node;
1180         ir_node              *proj_res_high;
1181
1182         if (mode_is_signed(mode)) {
1183                 new_node = gen_binop(node, op1, op2, new_bd_ia32_IMul1OP, match_commutative | match_am);
1184                 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1185                                     mode_Iu, pn_ia32_IMul1OP_res_high);
1186         } else {
1187                 new_node = gen_binop(node, op1, op2, new_bd_ia32_Mul, match_commutative | match_am);
1188                 proj_res_high = new_rd_Proj(dbgi, current_ir_graph, new_block, new_node,
1189                                     mode_Iu, pn_ia32_Mul_res_high);
1190         }
1191         return proj_res_high;
1192 }
1193
1194 /**
1195  * Creates an ia32 And.
1196  *
1197  * @return The created ia32 And node
1198  */
1199 static ir_node *gen_And(ir_node *node)
1200 {
1201         ir_node *op1 = get_And_left(node);
1202         ir_node *op2 = get_And_right(node);
1203         assert(! mode_is_float(get_irn_mode(node)));
1204
1205         /* is it a zero extension? */
1206         if (is_Const(op2)) {
1207                 tarval   *tv    = get_Const_tarval(op2);
1208                 long      v     = get_tarval_long(tv);
1209
1210                 if (v == 0xFF || v == 0xFFFF) {
1211                         dbg_info *dbgi   = get_irn_dbg_info(node);
1212                         ir_node  *block  = get_nodes_block(node);
1213                         ir_mode  *src_mode;
1214                         ir_node  *res;
1215
1216                         if (v == 0xFF) {
1217                                 src_mode = mode_Bu;
1218                         } else {
1219                                 assert(v == 0xFFFF);
1220                                 src_mode = mode_Hu;
1221                         }
1222                         res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
1223
1224                         return res;
1225                 }
1226         }
1227         return gen_binop(node, op1, op2, new_bd_ia32_And,
1228                         match_commutative | match_mode_neutral | match_am | match_immediate);
1229 }
1230
1231
1232
1233 /**
1234  * Creates an ia32 Or.
1235  *
1236  * @return The created ia32 Or node
1237  */
1238 static ir_node *gen_Or(ir_node *node)
1239 {
1240         ir_node *op1 = get_Or_left(node);
1241         ir_node *op2 = get_Or_right(node);
1242
1243         assert (! mode_is_float(get_irn_mode(node)));
1244         return gen_binop(node, op1, op2, new_bd_ia32_Or, match_commutative
1245                         | match_mode_neutral | match_am | match_immediate);
1246 }
1247
1248
1249
1250 /**
1251  * Creates an ia32 Eor.
1252  *
1253  * @return The created ia32 Eor node
1254  */
1255 static ir_node *gen_Eor(ir_node *node)
1256 {
1257         ir_node *op1 = get_Eor_left(node);
1258         ir_node *op2 = get_Eor_right(node);
1259
1260         assert(! mode_is_float(get_irn_mode(node)));
1261         return gen_binop(node, op1, op2, new_bd_ia32_Xor, match_commutative
1262                         | match_mode_neutral | match_am | match_immediate);
1263 }
1264
1265
1266 /**
1267  * Creates an ia32 Sub.
1268  *
1269  * @return The created ia32 Sub node
1270  */
1271 static ir_node *gen_Sub(ir_node *node)
1272 {
1273         ir_node  *op1  = get_Sub_left(node);
1274         ir_node  *op2  = get_Sub_right(node);
1275         ir_mode  *mode = get_irn_mode(node);
1276
1277         if (mode_is_float(mode)) {
1278                 if (ia32_cg_config.use_sse2)
1279                         return gen_binop(node, op1, op2, new_bd_ia32_xSub, match_am);
1280                 else
1281                         return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfsub);
1282         }
1283
1284         if (is_Const(op2)) {
1285                 ir_fprintf(stderr, "Optimisation warning: found sub with const (%+F)\n",
1286                            node);
1287         }
1288
1289         return gen_binop(node, op1, op2, new_bd_ia32_Sub, match_mode_neutral
1290                         | match_am | match_immediate);
1291 }
1292
1293 static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block,
1294                                  ir_node  *const src_val,
1295                                  ir_node  *const src_mem,
1296                                  ir_node  *const am_mem)
1297 {
1298         if (is_NoMem(am_mem)) {
1299                 return be_transform_node(src_mem);
1300         } else if (is_Proj(src_val) &&
1301                    is_Proj(src_mem) &&
1302                    get_Proj_pred(src_val) == get_Proj_pred(src_mem)) {
1303                 /* avoid memory loop */
1304                 return am_mem;
1305         } else if (is_Proj(src_val) && is_Sync(src_mem)) {
1306                 ir_node  *const ptr_pred = get_Proj_pred(src_val);
1307                 int       const arity    = get_Sync_n_preds(src_mem);
1308                 int             n        = 0;
1309                 ir_node **      ins;
1310                 int             i;
1311
1312                 NEW_ARR_A(ir_node*, ins, arity + 1);
1313
1314                 /* NOTE: This sometimes produces dead-code because the old sync in
1315                  * src_mem might not be used anymore, we should detect this case
1316                  * and kill the sync... */
1317                 for (i = arity - 1; i >= 0; --i) {
1318                         ir_node *const pred = get_Sync_pred(src_mem, i);
1319
1320                         /* avoid memory loop */
1321                         if (is_Proj(pred) && get_Proj_pred(pred) == ptr_pred)
1322                                 continue;
1323
1324                         ins[n++] = be_transform_node(pred);
1325                 }
1326
1327                 ins[n++] = am_mem;
1328
1329                 return new_r_Sync(irg, block, n, ins);
1330         } else {
1331                 ir_node *ins[2];
1332
1333                 ins[0] = be_transform_node(src_mem);
1334                 ins[1] = am_mem;
1335                 return new_r_Sync(irg, block, 2, ins);
1336         }
1337 }
1338
1339 static ir_node *create_sex_32_64(dbg_info *dbgi, ir_node *block,
1340                                  ir_node *val, const ir_node *orig)
1341 {
1342         ir_node *res;
1343
1344         (void)orig;
1345         if (ia32_cg_config.use_short_sex_eax) {
1346                 ir_node *pval = new_bd_ia32_ProduceVal(dbgi, block);
1347                 be_dep_on_frame(pval);
1348                 res = new_bd_ia32_Cltd(dbgi, block, val, pval);
1349         } else {
1350                 ir_node *imm31 = create_Immediate(NULL, 0, 31);
1351                 res = new_bd_ia32_Sar(dbgi, block, val, imm31);
1352         }
1353         SET_IA32_ORIG_NODE(res, orig);
1354         return res;
1355 }
1356
1357 /**
1358  * Generates an ia32 DivMod with additional infrastructure for the
1359  * register allocator if needed.
1360  */
1361 static ir_node *create_Div(ir_node *node)
1362 {
1363         dbg_info *dbgi      = get_irn_dbg_info(node);
1364         ir_node  *block     = get_nodes_block(node);
1365         ir_node  *new_block = be_transform_node(block);
1366         ir_node  *mem;
1367         ir_node  *new_mem;
1368         ir_node  *op1;
1369         ir_node  *op2;
1370         ir_node  *new_node;
1371         ir_mode  *mode;
1372         ir_node  *sign_extension;
1373         ia32_address_mode_t  am;
1374         ia32_address_t      *addr = &am.addr;
1375
1376         /* the upper bits have random contents for smaller modes */
1377         switch (get_irn_opcode(node)) {
1378         case iro_Div:
1379                 op1     = get_Div_left(node);
1380                 op2     = get_Div_right(node);
1381                 mem     = get_Div_mem(node);
1382                 mode    = get_Div_resmode(node);
1383                 break;
1384         case iro_Mod:
1385                 op1     = get_Mod_left(node);
1386                 op2     = get_Mod_right(node);
1387                 mem     = get_Mod_mem(node);
1388                 mode    = get_Mod_resmode(node);
1389                 break;
1390         case iro_DivMod:
1391                 op1     = get_DivMod_left(node);
1392                 op2     = get_DivMod_right(node);
1393                 mem     = get_DivMod_mem(node);
1394                 mode    = get_DivMod_resmode(node);
1395                 break;
1396         default:
1397                 panic("invalid divmod node %+F", node);
1398         }
1399
1400         match_arguments(&am, block, op1, op2, NULL, match_am);
1401
1402         /* Beware: We don't need a Sync, if the memory predecessor of the Div node
1403            is the memory of the consumed address. We can have only the second op as address
1404            in Div nodes, so check only op2. */
1405         new_mem = transform_AM_mem(current_ir_graph, block, op2, mem, addr->mem);
1406
1407         if (mode_is_signed(mode)) {
1408                 sign_extension = create_sex_32_64(dbgi, new_block, am.new_op1, node);
1409                 new_node       = new_bd_ia32_IDiv(dbgi, new_block, addr->base,
1410                                 addr->index, new_mem, am.new_op2, am.new_op1, sign_extension);
1411         } else {
1412                 sign_extension = new_bd_ia32_Const(dbgi, new_block, NULL, 0, 0);
1413                 be_dep_on_frame(sign_extension);
1414
1415                 new_node = new_bd_ia32_Div(dbgi, new_block, addr->base,
1416                                            addr->index, new_mem, am.new_op2,
1417                                            am.new_op1, sign_extension);
1418         }
1419
1420         set_irn_pinned(new_node, get_irn_pinned(node));
1421
1422         set_am_attributes(new_node, &am);
1423         SET_IA32_ORIG_NODE(new_node, node);
1424
1425         new_node = fix_mem_proj(new_node, &am);
1426
1427         return new_node;
1428 }
1429
1430
1431 static ir_node *gen_Mod(ir_node *node)
1432 {
1433         return create_Div(node);
1434 }
1435
1436 static ir_node *gen_Div(ir_node *node)
1437 {
1438         return create_Div(node);
1439 }
1440
1441 static ir_node *gen_DivMod(ir_node *node)
1442 {
1443         return create_Div(node);
1444 }
1445
1446
1447
1448 /**
1449  * Creates an ia32 floating Div.
1450  *
1451  * @return The created ia32 xDiv node
1452  */
1453 static ir_node *gen_Quot(ir_node *node)
1454 {
1455         ir_node *op1 = get_Quot_left(node);
1456         ir_node *op2 = get_Quot_right(node);
1457
1458         if (ia32_cg_config.use_sse2) {
1459                 return gen_binop(node, op1, op2, new_bd_ia32_xDiv, match_am);
1460         } else {
1461                 return gen_binop_x87_float(node, op1, op2, new_bd_ia32_vfdiv);
1462         }
1463 }
1464
1465
1466 /**
1467  * Creates an ia32 Shl.
1468  *
1469  * @return The created ia32 Shl node
1470  */
1471 static ir_node *gen_Shl(ir_node *node)
1472 {
1473         ir_node *left  = get_Shl_left(node);
1474         ir_node *right = get_Shl_right(node);
1475
1476         return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
1477                                match_mode_neutral | match_immediate);
1478 }
1479
1480 /**
1481  * Creates an ia32 Shr.
1482  *
1483  * @return The created ia32 Shr node
1484  */
1485 static ir_node *gen_Shr(ir_node *node)
1486 {
1487         ir_node *left  = get_Shr_left(node);
1488         ir_node *right = get_Shr_right(node);
1489
1490         return gen_shift_binop(node, left, right, new_bd_ia32_Shr, match_immediate);
1491 }
1492
1493
1494
1495 /**
1496  * Creates an ia32 Sar.
1497  *
1498  * @return The created ia32 Shrs node
1499  */
1500 static ir_node *gen_Shrs(ir_node *node)
1501 {
1502         ir_node *left  = get_Shrs_left(node);
1503         ir_node *right = get_Shrs_right(node);
1504         ir_mode *mode  = get_irn_mode(node);
1505
1506         if (is_Const(right) && mode == mode_Is) {
1507                 tarval *tv = get_Const_tarval(right);
1508                 long val = get_tarval_long(tv);
1509                 if (val == 31) {
1510                         /* this is a sign extension */
1511                         dbg_info *dbgi   = get_irn_dbg_info(node);
1512                         ir_node  *block  = be_transform_node(get_nodes_block(node));
1513                         ir_node  *new_op = be_transform_node(left);
1514
1515                         return create_sex_32_64(dbgi, block, new_op, node);
1516                 }
1517         }
1518
1519         /* 8 or 16 bit sign extension? */
1520         if (is_Const(right) && is_Shl(left) && mode == mode_Is) {
1521                 ir_node *shl_left  = get_Shl_left(left);
1522                 ir_node *shl_right = get_Shl_right(left);
1523                 if (is_Const(shl_right)) {
1524                         tarval *tv1 = get_Const_tarval(right);
1525                         tarval *tv2 = get_Const_tarval(shl_right);
1526                         if (tv1 == tv2 && tarval_is_long(tv1)) {
1527                                 long val = get_tarval_long(tv1);
1528                                 if (val == 16 || val == 24) {
1529                                         dbg_info *dbgi   = get_irn_dbg_info(node);
1530                                         ir_node  *block  = get_nodes_block(node);
1531                                         ir_mode  *src_mode;
1532                                         ir_node  *res;
1533
1534                                         if (val == 24) {
1535                                                 src_mode = mode_Bs;
1536                                         } else {
1537                                                 assert(val == 16);
1538                                                 src_mode = mode_Hs;
1539                                         }
1540                                         res = create_I2I_Conv(src_mode, mode_Is, dbgi, block,
1541                                                               shl_left, node);
1542
1543                                         return res;
1544                                 }
1545                         }
1546                 }
1547         }
1548
1549         return gen_shift_binop(node, left, right, new_bd_ia32_Sar, match_immediate);
1550 }
1551
1552
1553
1554 /**
1555  * Creates an ia32 Rol.
1556  *
1557  * @param op1   The first operator
1558  * @param op2   The second operator
1559  * @return The created ia32 RotL node
1560  */
1561 static ir_node *gen_Rol(ir_node *node, ir_node *op1, ir_node *op2)
1562 {
1563         return gen_shift_binop(node, op1, op2, new_bd_ia32_Rol, match_immediate);
1564 }
1565
1566
1567
1568 /**
1569  * Creates an ia32 Ror.
1570  * NOTE: There is no RotR with immediate because this would always be a RotL
1571  *       "imm-mode_size_bits" which can be pre-calculated.
1572  *
1573  * @param op1   The first operator
1574  * @param op2   The second operator
1575  * @return The created ia32 RotR node
1576  */
1577 static ir_node *gen_Ror(ir_node *node, ir_node *op1, ir_node *op2)
1578 {
1579         return gen_shift_binop(node, op1, op2, new_bd_ia32_Ror, match_immediate);
1580 }
1581
1582
1583
1584 /**
1585  * Creates an ia32 RotR or RotL (depending on the found pattern).
1586  *
1587  * @return The created ia32 RotL or RotR node
1588  */
1589 static ir_node *gen_Rotl(ir_node *node)
1590 {
1591         ir_node *rotate = NULL;
1592         ir_node *op1    = get_Rotl_left(node);
1593         ir_node *op2    = get_Rotl_right(node);
1594
1595         /* Firm has only RotL, so we are looking for a right (op2)
1596                  operand "-e+mode_size_bits" (it's an already modified "mode_size_bits-e",
1597                  that means we can create a RotR instead of an Add and a RotL */
1598
1599         if (is_Add(op2)) {
1600                 ir_node *add = op2;
1601                 ir_node *left = get_Add_left(add);
1602                 ir_node *right = get_Add_right(add);
1603                 if (is_Const(right)) {
1604                         tarval  *tv   = get_Const_tarval(right);
1605                         ir_mode *mode = get_irn_mode(node);
1606                         long     bits = get_mode_size_bits(mode);
1607
1608                         if (is_Minus(left) &&
1609                             tarval_is_long(tv)       &&
1610                             get_tarval_long(tv) == bits &&
1611                             bits                == 32)
1612                         {
1613                                 DB((dbg, LEVEL_1, "RotL into RotR ... "));
1614                                 rotate = gen_Ror(node, op1, get_Minus_op(left));
1615                         }
1616                 }
1617         }
1618
1619         if (rotate == NULL) {
1620                 rotate = gen_Rol(node, op1, op2);
1621         }
1622
1623         return rotate;
1624 }
1625
1626
1627
1628 /**
1629  * Transforms a Minus node.
1630  *
1631  * @return The created ia32 Minus node
1632  */
1633 static ir_node *gen_Minus(ir_node *node)
1634 {
1635         ir_node   *op    = get_Minus_op(node);
1636         ir_node   *block = be_transform_node(get_nodes_block(node));
1637         dbg_info  *dbgi  = get_irn_dbg_info(node);
1638         ir_mode   *mode  = get_irn_mode(node);
1639         ir_entity *ent;
1640         ir_node   *new_node;
1641         int        size;
1642
1643         if (mode_is_float(mode)) {
1644                 ir_node *new_op = be_transform_node(op);
1645                 if (ia32_cg_config.use_sse2) {
1646                         /* TODO: non-optimal... if we have many xXors, then we should
1647                          * rather create a load for the const and use that instead of
1648                          * several AM nodes... */
1649                         ir_node *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1650                         ir_node *noreg_xmm = ia32_new_NoReg_xmm(env_cg);
1651                         ir_node *nomem     = new_NoMem();
1652
1653                         new_node = new_bd_ia32_xXor(dbgi, block, noreg_gp, noreg_gp,
1654                                                     nomem, new_op, noreg_xmm);
1655
1656                         size = get_mode_size_bits(mode);
1657                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
1658
1659                         set_ia32_am_sc(new_node, ent);
1660                         set_ia32_op_type(new_node, ia32_AddrModeS);
1661                         set_ia32_ls_mode(new_node, mode);
1662                 } else {
1663                         new_node = new_bd_ia32_vfchs(dbgi, block, new_op);
1664                 }
1665         } else {
1666                 new_node = gen_unop(node, op, new_bd_ia32_Neg, match_mode_neutral);
1667         }
1668
1669         SET_IA32_ORIG_NODE(new_node, node);
1670
1671         return new_node;
1672 }
1673
1674 /**
1675  * Transforms a Not node.
1676  *
1677  * @return The created ia32 Not node
1678  */
1679 static ir_node *gen_Not(ir_node *node)
1680 {
1681         ir_node *op   = get_Not_op(node);
1682
1683         assert(get_irn_mode(node) != mode_b); /* should be lowered already */
1684         assert (! mode_is_float(get_irn_mode(node)));
1685
1686         return gen_unop(node, op, new_bd_ia32_Not, match_mode_neutral);
1687 }
1688
1689
1690
1691 /**
1692  * Transforms an Abs node.
1693  *
1694  * @return The created ia32 Abs node
1695  */
1696 static ir_node *gen_Abs(ir_node *node)
1697 {
1698         ir_node   *block     = get_nodes_block(node);
1699         ir_node   *new_block = be_transform_node(block);
1700         ir_node   *op        = get_Abs_op(node);
1701         dbg_info  *dbgi      = get_irn_dbg_info(node);
1702         ir_mode   *mode      = get_irn_mode(node);
1703         ir_node   *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1704         ir_node   *nomem     = new_NoMem();
1705         ir_node   *new_op;
1706         ir_node   *new_node;
1707         int        size;
1708         ir_entity *ent;
1709
1710         if (mode_is_float(mode)) {
1711                 new_op = be_transform_node(op);
1712
1713                 if (ia32_cg_config.use_sse2) {
1714                         ir_node *noreg_fp = ia32_new_NoReg_xmm(env_cg);
1715                         new_node = new_bd_ia32_xAnd(dbgi, new_block, noreg_gp, noreg_gp,
1716                                                     nomem, new_op, noreg_fp);
1717
1718                         size = get_mode_size_bits(mode);
1719                         ent  = ia32_gen_fp_known_const(size == 32 ? ia32_SABS : ia32_DABS);
1720
1721                         set_ia32_am_sc(new_node, ent);
1722
1723                         SET_IA32_ORIG_NODE(new_node, node);
1724
1725                         set_ia32_op_type(new_node, ia32_AddrModeS);
1726                         set_ia32_ls_mode(new_node, mode);
1727                 } else {
1728                         new_node = new_bd_ia32_vfabs(dbgi, new_block, new_op);
1729                         SET_IA32_ORIG_NODE(new_node, node);
1730                 }
1731         } else {
1732                 ir_node *xor, *sign_extension;
1733
1734                 if (get_mode_size_bits(mode) == 32) {
1735                         new_op = be_transform_node(op);
1736                 } else {
1737                         new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node);
1738                 }
1739
1740                 sign_extension = create_sex_32_64(dbgi, new_block, new_op, node);
1741
1742                 xor = new_bd_ia32_Xor(dbgi, new_block, noreg_gp, noreg_gp,
1743                                       nomem, new_op, sign_extension);
1744                 SET_IA32_ORIG_NODE(xor, node);
1745
1746                 new_node = new_bd_ia32_Sub(dbgi, new_block, noreg_gp, noreg_gp,
1747                                            nomem, xor, sign_extension);
1748                 SET_IA32_ORIG_NODE(new_node, node);
1749         }
1750
1751         return new_node;
1752 }
1753
1754 /**
1755  * Create a bt instruction for x & (1 << n) and place it into the block of cmp.
1756  */
1757 static ir_node *gen_bt(ir_node *cmp, ir_node *x, ir_node *n)
1758 {
1759         dbg_info *dbgi      = get_irn_dbg_info(cmp);
1760         ir_node  *block     = get_nodes_block(cmp);
1761         ir_node  *new_block = be_transform_node(block);
1762         ir_node  *op1       = be_transform_node(x);
1763         ir_node  *op2       = be_transform_node(n);
1764
1765         return new_bd_ia32_Bt(dbgi, new_block, op1, op2);
1766 }
1767
1768 /**
1769  * Transform a node returning a "flag" result.
1770  *
1771  * @param node     the node to transform
1772  * @param pnc_out  the compare mode to use
1773  */
1774 static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out)
1775 {
1776         ir_node  *flags;
1777         ir_node  *new_op;
1778         ir_node  *noreg;
1779         ir_node  *nomem;
1780         ir_node  *new_block;
1781         dbg_info *dbgi;
1782
1783         /* we have a Cmp as input */
1784         if (is_Proj(node)) {
1785                 ir_node *pred = get_Proj_pred(node);
1786                 if (is_Cmp(pred)) {
1787                         pn_Cmp pnc = get_Proj_proj(node);
1788                         if (ia32_cg_config.use_bt && (pnc == pn_Cmp_Lg || pnc == pn_Cmp_Eq)) {
1789                                 ir_node *l = get_Cmp_left(pred);
1790                                 ir_node *r = get_Cmp_right(pred);
1791                                 if (is_And(l)) {
1792                                         ir_node *la = get_And_left(l);
1793                                         ir_node *ra = get_And_right(l);
1794                                         if (is_Shl(la)) {
1795                                                 ir_node *c = get_Shl_left(la);
1796                                                 if (is_Const_1(c) && (is_Const_0(r) || r == la)) {
1797                                                         /* (1 << n) & ra) */
1798                                                         ir_node *n = get_Shl_right(la);
1799                                                         flags    = gen_bt(pred, ra, n);
1800                                                         /* we must generate a Jc/Jnc jump */
1801                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1802                                                         if (r == la)
1803                                                                 pnc ^= pn_Cmp_Leg;
1804                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1805                                                         return flags;
1806                                                 }
1807                                         }
1808                                         if (is_Shl(ra)) {
1809                                                 ir_node *c = get_Shl_left(ra);
1810                                                 if (is_Const_1(c) && (is_Const_0(r) || r == ra)) {
1811                                                         /* la & (1 << n)) */
1812                                                         ir_node *n = get_Shl_right(ra);
1813                                                         flags    = gen_bt(pred, la, n);
1814                                                         /* we must generate a Jc/Jnc jump */
1815                                                         pnc = pnc == pn_Cmp_Lg ? pn_Cmp_Lt : pn_Cmp_Ge;
1816                                                         if (r == ra)
1817                                                                 pnc ^= pn_Cmp_Leg;
1818                                                         *pnc_out = ia32_pn_Cmp_unsigned | pnc;
1819                                                         return flags;
1820                                                 }
1821                                         }
1822                                 }
1823                         }
1824                         flags    = be_transform_node(pred);
1825                         *pnc_out = pnc;
1826                         return flags;
1827                 }
1828         }
1829
1830         /* a mode_b value, we have to compare it against 0 */
1831         dbgi      = get_irn_dbg_info(node);
1832         new_block = be_transform_node(get_nodes_block(node));
1833         new_op    = be_transform_node(node);
1834         noreg     = ia32_new_NoReg_gp(env_cg);
1835         nomem     = new_NoMem();
1836         flags     = new_bd_ia32_Test(dbgi, new_block, noreg, noreg, nomem, new_op,
1837                         new_op, /*is_permuted=*/0, /*cmp_unsigned=*/0);
1838         *pnc_out  = pn_Cmp_Lg;
1839         return flags;
1840 }
1841
1842 /**
1843  * Transforms a Load.
1844  *
1845  * @return the created ia32 Load node
1846  */
1847 static ir_node *gen_Load(ir_node *node)
1848 {
1849         ir_node  *old_block = get_nodes_block(node);
1850         ir_node  *block   = be_transform_node(old_block);
1851         ir_node  *ptr     = get_Load_ptr(node);
1852         ir_node  *mem     = get_Load_mem(node);
1853         ir_node  *new_mem = be_transform_node(mem);
1854         ir_node  *base;
1855         ir_node  *index;
1856         dbg_info *dbgi    = get_irn_dbg_info(node);
1857         ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
1858         ir_mode  *mode    = get_Load_mode(node);
1859         ir_mode  *res_mode;
1860         ir_node  *new_node;
1861         ia32_address_t addr;
1862
1863         /* construct load address */
1864         memset(&addr, 0, sizeof(addr));
1865         ia32_create_address_mode(&addr, ptr, 0);
1866         base  = addr.base;
1867         index = addr.index;
1868
1869         if (base == NULL) {
1870                 base = noreg;
1871         } else {
1872                 base = be_transform_node(base);
1873         }
1874
1875         if (index == NULL) {
1876                 index = noreg;
1877         } else {
1878                 index = be_transform_node(index);
1879         }
1880
1881         if (mode_is_float(mode)) {
1882                 if (ia32_cg_config.use_sse2) {
1883                         new_node = new_bd_ia32_xLoad(dbgi, block, base, index, new_mem,
1884                                                      mode);
1885                         res_mode = mode_xmm;
1886                 } else {
1887                         new_node = new_bd_ia32_vfld(dbgi, block, base, index, new_mem,
1888                                                     mode);
1889                         res_mode = mode_vfp;
1890                 }
1891         } else {
1892                 assert(mode != mode_b);
1893
1894                 /* create a conv node with address mode for smaller modes */
1895                 if (get_mode_size_bits(mode) < 32) {
1896                         new_node = new_bd_ia32_Conv_I2I(dbgi, block, base, index,
1897                                                         new_mem, noreg, mode);
1898                 } else {
1899                         new_node = new_bd_ia32_Load(dbgi, block, base, index, new_mem);
1900                 }
1901                 res_mode = mode_Iu;
1902         }
1903
1904         set_irn_pinned(new_node, get_irn_pinned(node));
1905         set_ia32_op_type(new_node, ia32_AddrModeS);
1906         set_ia32_ls_mode(new_node, mode);
1907         set_address(new_node, &addr);
1908
1909         if (get_irn_pinned(node) == op_pin_state_floats) {
1910                 assert(pn_ia32_xLoad_res == pn_ia32_vfld_res
1911                                 && pn_ia32_vfld_res == pn_ia32_Load_res
1912                                 && pn_ia32_Load_res == pn_ia32_res);
1913                 arch_irn_add_flags(new_node, arch_irn_flags_rematerializable);
1914         }
1915
1916         SET_IA32_ORIG_NODE(new_node, node);
1917
1918         be_dep_on_frame(new_node);
1919         return new_node;
1920 }
1921
1922 static int use_dest_am(ir_node *block, ir_node *node, ir_node *mem,
1923                        ir_node *ptr, ir_node *other)
1924 {
1925         ir_node *load;
1926
1927         if (!is_Proj(node))
1928                 return 0;
1929
1930         /* we only use address mode if we're the only user of the load */
1931         if (get_irn_n_edges(node) > 1)
1932                 return 0;
1933
1934         load = get_Proj_pred(node);
1935         if (!is_Load(load))
1936                 return 0;
1937         if (get_nodes_block(load) != block)
1938                 return 0;
1939
1940         /* store should have the same pointer as the load */
1941         if (get_Load_ptr(load) != ptr)
1942                 return 0;
1943
1944         /* don't do AM if other node inputs depend on the load (via mem-proj) */
1945         if (other != NULL                   &&
1946             get_nodes_block(other) == block &&
1947             heights_reachable_in_block(heights, other, load)) {
1948                 return 0;
1949         }
1950
1951         if (prevents_AM(block, load, mem))
1952                 return 0;
1953         /* Store should be attached to the load via mem */
1954         assert(heights_reachable_in_block(heights, mem, load));
1955
1956         return 1;
1957 }
1958
1959 static ir_node *dest_am_binop(ir_node *node, ir_node *op1, ir_node *op2,
1960                               ir_node *mem, ir_node *ptr, ir_mode *mode,
1961                               construct_binop_dest_func *func,
1962                               construct_binop_dest_func *func8bit,
1963                                                           match_flags_t flags)
1964 {
1965         ir_node  *src_block = get_nodes_block(node);
1966         ir_node  *block;
1967         ir_node  *noreg_gp  = ia32_new_NoReg_gp(env_cg);
1968         dbg_info *dbgi;
1969         ir_node  *new_mem;
1970         ir_node  *new_node;
1971         ir_node  *new_op;
1972         ir_node  *mem_proj;
1973         int       commutative;
1974         ia32_address_mode_t  am;
1975         ia32_address_t      *addr = &am.addr;
1976         memset(&am, 0, sizeof(am));
1977
1978         assert(flags & match_immediate); /* there is no destam node without... */
1979         commutative = (flags & match_commutative) != 0;
1980
1981         if (use_dest_am(src_block, op1, mem, ptr, op2)) {
1982                 build_address(&am, op1, ia32_create_am_double_use);
1983                 new_op = create_immediate_or_transform(op2, 0);
1984         } else if (commutative && use_dest_am(src_block, op2, mem, ptr, op1)) {
1985                 build_address(&am, op2, ia32_create_am_double_use);
1986                 new_op = create_immediate_or_transform(op1, 0);
1987         } else {
1988                 return NULL;
1989         }
1990
1991         if (addr->base == NULL)
1992                 addr->base = noreg_gp;
1993         if (addr->index == NULL)
1994                 addr->index = noreg_gp;
1995         if (addr->mem == NULL)
1996                 addr->mem = new_NoMem();
1997
1998         dbgi    = get_irn_dbg_info(node);
1999         block   = be_transform_node(src_block);
2000         new_mem = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2001
2002         if (get_mode_size_bits(mode) == 8) {
2003                 new_node = func8bit(dbgi, block, addr->base, addr->index, new_mem, new_op);
2004         } else {
2005                 new_node = func(dbgi, block, addr->base, addr->index, new_mem, new_op);
2006         }
2007         set_address(new_node, addr);
2008         set_ia32_op_type(new_node, ia32_AddrModeD);
2009         set_ia32_ls_mode(new_node, mode);
2010         SET_IA32_ORIG_NODE(new_node, node);
2011
2012         be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2013         mem_proj = be_transform_node(am.mem_proj);
2014         be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2015
2016         return new_node;
2017 }
2018
2019 static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem,
2020                              ir_node *ptr, ir_mode *mode,
2021                              construct_unop_dest_func *func)
2022 {
2023         ir_node  *src_block = get_nodes_block(node);
2024         ir_node  *block;
2025         dbg_info *dbgi;
2026         ir_node  *new_mem;
2027         ir_node  *new_node;
2028         ir_node  *mem_proj;
2029         ia32_address_mode_t  am;
2030         ia32_address_t *addr = &am.addr;
2031
2032         if (!use_dest_am(src_block, op, mem, ptr, NULL))
2033                 return NULL;
2034
2035         memset(&am, 0, sizeof(am));
2036         build_address(&am, op, ia32_create_am_double_use);
2037
2038         dbgi     = get_irn_dbg_info(node);
2039         block    = be_transform_node(src_block);
2040         new_mem  = transform_AM_mem(current_ir_graph, block, am.am_node, mem, addr->mem);
2041         new_node = func(dbgi, block, addr->base, addr->index, new_mem);
2042         set_address(new_node, addr);
2043         set_ia32_op_type(new_node, ia32_AddrModeD);
2044         set_ia32_ls_mode(new_node, mode);
2045         SET_IA32_ORIG_NODE(new_node, node);
2046
2047         be_set_transformed_node(get_Proj_pred(am.mem_proj), new_node);
2048         mem_proj = be_transform_node(am.mem_proj);
2049         be_set_transformed_node(mem_proj ? mem_proj : am.mem_proj, new_node);
2050
2051         return new_node;
2052 }
2053
2054 static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem)
2055 {
2056         ir_mode  *mode        = get_irn_mode(node);
2057         ir_node  *mux_true    = get_Mux_true(node);
2058         ir_node  *mux_false   = get_Mux_false(node);
2059         ir_node  *cond;
2060         ir_node  *new_mem;
2061         dbg_info *dbgi;
2062         ir_node  *block;
2063         ir_node  *new_block;
2064         ir_node  *flags;
2065         ir_node  *new_node;
2066         int       negated;
2067         pn_Cmp    pnc;
2068         ia32_address_t addr;
2069
2070         if (get_mode_size_bits(mode) != 8)
2071                 return NULL;
2072
2073         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2074                 negated = 0;
2075         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2076                 negated = 1;
2077         } else {
2078                 return NULL;
2079         }
2080
2081         build_address_ptr(&addr, ptr, mem);
2082
2083         dbgi      = get_irn_dbg_info(node);
2084         block     = get_nodes_block(node);
2085         new_block = be_transform_node(block);
2086         cond      = get_Mux_sel(node);
2087         flags     = get_flags_node(cond, &pnc);
2088         new_mem   = be_transform_node(mem);
2089         new_node  = new_bd_ia32_SetMem(dbgi, new_block, addr.base,
2090                                        addr.index, addr.mem, flags, pnc, negated);
2091         set_address(new_node, &addr);
2092         set_ia32_op_type(new_node, ia32_AddrModeD);
2093         set_ia32_ls_mode(new_node, mode);
2094         SET_IA32_ORIG_NODE(new_node, node);
2095
2096         return new_node;
2097 }
2098
2099 static ir_node *try_create_dest_am(ir_node *node)
2100 {
2101         ir_node  *val  = get_Store_value(node);
2102         ir_node  *mem  = get_Store_mem(node);
2103         ir_node  *ptr  = get_Store_ptr(node);
2104         ir_mode  *mode = get_irn_mode(val);
2105         unsigned  bits = get_mode_size_bits(mode);
2106         ir_node  *op1;
2107         ir_node  *op2;
2108         ir_node  *new_node;
2109
2110         /* handle only GP modes for now... */
2111         if (!ia32_mode_needs_gp_reg(mode))
2112                 return NULL;
2113
2114         for (;;) {
2115                 /* store must be the only user of the val node */
2116                 if (get_irn_n_edges(val) > 1)
2117                         return NULL;
2118                 /* skip pointless convs */
2119                 if (is_Conv(val)) {
2120                         ir_node *conv_op   = get_Conv_op(val);
2121                         ir_mode *pred_mode = get_irn_mode(conv_op);
2122                         if (!ia32_mode_needs_gp_reg(pred_mode))
2123                                 break;
2124                         if (pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) {
2125                                 val = conv_op;
2126                                 continue;
2127                         }
2128                 }
2129                 break;
2130         }
2131
2132         /* value must be in the same block */
2133         if (get_nodes_block(node) != get_nodes_block(val))
2134                 return NULL;
2135
2136         switch (get_irn_opcode(val)) {
2137         case iro_Add:
2138                 op1      = get_Add_left(val);
2139                 op2      = get_Add_right(val);
2140                 if (ia32_cg_config.use_incdec) {
2141                         if (is_Const_1(op2)) {
2142                                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_IncMem);
2143                                 break;
2144                         } else if (is_Const_Minus_1(op2)) {
2145                                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_DecMem);
2146                                 break;
2147                         }
2148                 }
2149                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2150                                          new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
2151                                          match_commutative | match_immediate);
2152                 break;
2153         case iro_Sub:
2154                 op1      = get_Sub_left(val);
2155                 op2      = get_Sub_right(val);
2156                 if (is_Const(op2)) {
2157                         ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
2158                 }
2159                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2160                                          new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
2161                                          match_immediate);
2162                 break;
2163         case iro_And:
2164                 op1      = get_And_left(val);
2165                 op2      = get_And_right(val);
2166                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2167                                          new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
2168                                          match_commutative | match_immediate);
2169                 break;
2170         case iro_Or:
2171                 op1      = get_Or_left(val);
2172                 op2      = get_Or_right(val);
2173                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2174                                          new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
2175                                          match_commutative | match_immediate);
2176                 break;
2177         case iro_Eor:
2178                 op1      = get_Eor_left(val);
2179                 op2      = get_Eor_right(val);
2180                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2181                                          new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
2182                                          match_commutative | match_immediate);
2183                 break;
2184         case iro_Shl:
2185                 op1      = get_Shl_left(val);
2186                 op2      = get_Shl_right(val);
2187                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2188                                          new_bd_ia32_ShlMem, new_bd_ia32_ShlMem,
2189                                          match_immediate);
2190                 break;
2191         case iro_Shr:
2192                 op1      = get_Shr_left(val);
2193                 op2      = get_Shr_right(val);
2194                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2195                                          new_bd_ia32_ShrMem, new_bd_ia32_ShrMem,
2196                                          match_immediate);
2197                 break;
2198         case iro_Shrs:
2199                 op1      = get_Shrs_left(val);
2200                 op2      = get_Shrs_right(val);
2201                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2202                                          new_bd_ia32_SarMem, new_bd_ia32_SarMem,
2203                                          match_immediate);
2204                 break;
2205         case iro_Rotl:
2206                 op1      = get_Rotl_left(val);
2207                 op2      = get_Rotl_right(val);
2208                 new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
2209                                          new_bd_ia32_RolMem, new_bd_ia32_RolMem,
2210                                          match_immediate);
2211                 break;
2212         /* TODO: match ROR patterns... */
2213         case iro_Mux:
2214                 new_node = try_create_SetMem(val, ptr, mem);
2215                 break;
2216         case iro_Minus:
2217                 op1      = get_Minus_op(val);
2218                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NegMem);
2219                 break;
2220         case iro_Not:
2221                 /* should be lowered already */
2222                 assert(mode != mode_b);
2223                 op1      = get_Not_op(val);
2224                 new_node = dest_am_unop(val, op1, mem, ptr, mode, new_bd_ia32_NotMem);
2225                 break;
2226         default:
2227                 return NULL;
2228         }
2229
2230         if (new_node != NULL) {
2231                 if (get_irn_pinned(new_node) != op_pin_state_pinned &&
2232                                 get_irn_pinned(node) == op_pin_state_pinned) {
2233                         set_irn_pinned(new_node, op_pin_state_pinned);
2234                 }
2235         }
2236
2237         return new_node;
2238 }
2239
2240 static bool possible_int_mode_for_fp(ir_mode *mode)
2241 {
2242         unsigned size;
2243
2244         if (!mode_is_signed(mode))
2245                 return false;
2246         size = get_mode_size_bits(mode);
2247         if (size != 16 && size != 32)
2248                 return false;
2249         return true;
2250 }
2251
2252 static int is_float_to_int_conv(const ir_node *node)
2253 {
2254         ir_mode  *mode = get_irn_mode(node);
2255         ir_node  *conv_op;
2256         ir_mode  *conv_mode;
2257
2258         if (!possible_int_mode_for_fp(mode))
2259                 return 0;
2260
2261         if (!is_Conv(node))
2262                 return 0;
2263         conv_op   = get_Conv_op(node);
2264         conv_mode = get_irn_mode(conv_op);
2265
2266         if (!mode_is_float(conv_mode))
2267                 return 0;
2268
2269         return 1;
2270 }
2271
2272 /**
2273  * Transform a Store(floatConst) into a sequence of
2274  * integer stores.
2275  *
2276  * @return the created ia32 Store node
2277  */
2278 static ir_node *gen_float_const_Store(ir_node *node, ir_node *cns)
2279 {
2280         ir_mode        *mode      = get_irn_mode(cns);
2281         unsigned        size      = get_mode_size_bytes(mode);
2282         tarval         *tv        = get_Const_tarval(cns);
2283         ir_node        *block     = get_nodes_block(node);
2284         ir_node        *new_block = be_transform_node(block);
2285         ir_node        *ptr       = get_Store_ptr(node);
2286         ir_node        *mem       = get_Store_mem(node);
2287         dbg_info       *dbgi      = get_irn_dbg_info(node);
2288         int             ofs       = 0;
2289         size_t          i         = 0;
2290         ir_node        *ins[4];
2291         ia32_address_t  addr;
2292
2293         assert(size % 4 ==  0);
2294         assert(size     <= 16);
2295
2296         build_address_ptr(&addr, ptr, mem);
2297
2298         do {
2299                 unsigned val =
2300                          get_tarval_sub_bits(tv, ofs)            |
2301                         (get_tarval_sub_bits(tv, ofs + 1) <<  8) |
2302                         (get_tarval_sub_bits(tv, ofs + 2) << 16) |
2303                         (get_tarval_sub_bits(tv, ofs + 3) << 24);
2304                 ir_node *imm = create_Immediate(NULL, 0, val);
2305
2306                 ir_node *new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2307                         addr.index, addr.mem, imm);
2308
2309                 set_irn_pinned(new_node, get_irn_pinned(node));
2310                 set_ia32_op_type(new_node, ia32_AddrModeD);
2311                 set_ia32_ls_mode(new_node, mode_Iu);
2312                 set_address(new_node, &addr);
2313                 SET_IA32_ORIG_NODE(new_node, node);
2314
2315                 assert(i < 4);
2316                 ins[i++] = new_node;
2317
2318                 size        -= 4;
2319                 ofs         += 4;
2320                 addr.offset += 4;
2321         } while (size != 0);
2322
2323         if (i > 1) {
2324                 return new_rd_Sync(dbgi, current_ir_graph, new_block, i, ins);
2325         } else {
2326                 return ins[0];
2327         }
2328 }
2329
2330 /**
2331  * Generate a vfist or vfisttp instruction.
2332  */
2333 static ir_node *gen_vfist(dbg_info *dbgi, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index,
2334                           ir_node *mem,  ir_node *val, ir_node **fist)
2335 {
2336         ir_node *new_node;
2337
2338         if (ia32_cg_config.use_fisttp) {
2339                 /* Note: fisttp ALWAYS pop the tos. We have to ensure here that the value is copied
2340                 if other users exists */
2341                 const arch_register_class_t *reg_class = &ia32_reg_classes[CLASS_ia32_vfp];
2342                 ir_node *vfisttp = new_bd_ia32_vfisttp(dbgi, block, base, index, mem, val);
2343                 ir_node *value   = new_r_Proj(irg, block, vfisttp, mode_E, pn_ia32_vfisttp_res);
2344                 be_new_Keep(reg_class, irg, block, 1, &value);
2345
2346                 new_node = new_r_Proj(irg, block, vfisttp, mode_M, pn_ia32_vfisttp_M);
2347                 *fist    = vfisttp;
2348         } else {
2349                 ir_node *trunc_mode = ia32_new_Fpu_truncate(env_cg);
2350
2351                 /* do a fist */
2352                 new_node = new_bd_ia32_vfist(dbgi, block, base, index, mem, val, trunc_mode);
2353                 *fist    = new_node;
2354         }
2355         return new_node;
2356 }
2357 /**
2358  * Transforms a general (no special case) Store.
2359  *
2360  * @return the created ia32 Store node
2361  */
2362 static ir_node *gen_general_Store(ir_node *node)
2363 {
2364         ir_node  *val       = get_Store_value(node);
2365         ir_mode  *mode      = get_irn_mode(val);
2366         ir_node  *block     = get_nodes_block(node);
2367         ir_node  *new_block = be_transform_node(block);
2368         ir_node  *ptr       = get_Store_ptr(node);
2369         ir_node  *mem       = get_Store_mem(node);
2370         dbg_info *dbgi      = get_irn_dbg_info(node);
2371         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
2372         ir_node  *new_val, *new_node, *store;
2373         ia32_address_t addr;
2374
2375         /* check for destination address mode */
2376         new_node = try_create_dest_am(node);
2377         if (new_node != NULL)
2378                 return new_node;
2379
2380         /* construct store address */
2381         memset(&addr, 0, sizeof(addr));
2382         ia32_create_address_mode(&addr, ptr, 0);
2383
2384         if (addr.base == NULL) {
2385                 addr.base = noreg;
2386         } else {
2387                 addr.base = be_transform_node(addr.base);
2388         }
2389
2390         if (addr.index == NULL) {
2391                 addr.index = noreg;
2392         } else {
2393                 addr.index = be_transform_node(addr.index);
2394         }
2395         addr.mem = be_transform_node(mem);
2396
2397         if (mode_is_float(mode)) {
2398                 /* Convs (and strict-Convs) before stores are unnecessary if the mode
2399                    is the same. */
2400                 while (is_Conv(val) && mode == get_irn_mode(val)) {
2401                         ir_node *op = get_Conv_op(val);
2402                         if (!mode_is_float(get_irn_mode(op)))
2403                                 break;
2404                         val = op;
2405                 }
2406                 new_val = be_transform_node(val);
2407                 if (ia32_cg_config.use_sse2) {
2408                         new_node = new_bd_ia32_xStore(dbgi, new_block, addr.base,
2409                                                       addr.index, addr.mem, new_val);
2410                 } else {
2411                         new_node = new_bd_ia32_vfst(dbgi, new_block, addr.base,
2412                                                     addr.index, addr.mem, new_val, mode);
2413                 }
2414                 store = new_node;
2415         } else if (!ia32_cg_config.use_sse2 && is_float_to_int_conv(val)) {
2416                 val = get_Conv_op(val);
2417
2418                 /* TODO: is this optimisation still necessary at all (middleend)? */
2419                 /* We can skip ALL float->float up-Convs (and strict-up-Convs) before stores. */
2420                 while (is_Conv(val)) {
2421                         ir_node *op = get_Conv_op(val);
2422                         if (!mode_is_float(get_irn_mode(op)))
2423                                 break;
2424                         if (get_mode_size_bits(get_irn_mode(op)) > get_mode_size_bits(get_irn_mode(val)))
2425                                 break;
2426                         val = op;
2427                 }
2428                 new_val  = be_transform_node(val);
2429                 new_node = gen_vfist(dbgi, current_ir_graph, new_block, addr.base, addr.index, addr.mem, new_val, &store);
2430         } else {
2431                 new_val = create_immediate_or_transform(val, 0);
2432                 assert(mode != mode_b);
2433
2434                 if (get_mode_size_bits(mode) == 8) {
2435                         new_node = new_bd_ia32_Store8Bit(dbgi, new_block, addr.base,
2436                                                          addr.index, addr.mem, new_val);
2437                 } else {
2438                         new_node = new_bd_ia32_Store(dbgi, new_block, addr.base,
2439                                                      addr.index, addr.mem, new_val);
2440                 }
2441                 store = new_node;
2442         }
2443
2444         set_irn_pinned(store, get_irn_pinned(node));
2445         set_ia32_op_type(store, ia32_AddrModeD);
2446         set_ia32_ls_mode(store, mode);
2447
2448         set_address(store, &addr);
2449         SET_IA32_ORIG_NODE(store, node);
2450
2451         return new_node;
2452 }
2453
2454 /**
2455  * Transforms a Store.
2456  *
2457  * @return the created ia32 Store node
2458  */
2459 static ir_node *gen_Store(ir_node *node)
2460 {
2461         ir_node  *val  = get_Store_value(node);
2462         ir_mode  *mode = get_irn_mode(val);
2463
2464         if (mode_is_float(mode) && is_Const(val)) {
2465                 /* We can transform every floating const store
2466                    into a sequence of integer stores.
2467                    If the constant is already in a register,
2468                    it would be better to use it, but we don't
2469                    have this information here. */
2470                 return gen_float_const_Store(node, val);
2471         }
2472         return gen_general_Store(node);
2473 }
2474
2475 /**
2476  * Transforms a Switch.
2477  *
2478  * @return the created ia32 SwitchJmp node
2479  */
2480 static ir_node *create_Switch(ir_node *node)
2481 {
2482         dbg_info *dbgi       = get_irn_dbg_info(node);
2483         ir_node  *block      = be_transform_node(get_nodes_block(node));
2484         ir_node  *sel        = get_Cond_selector(node);
2485         ir_node  *new_sel    = be_transform_node(sel);
2486         int       switch_min = INT_MAX;
2487         int       switch_max = INT_MIN;
2488         long      default_pn = get_Cond_defaultProj(node);
2489         ir_node  *new_node;
2490         const ir_edge_t *edge;
2491
2492         assert(get_mode_size_bits(get_irn_mode(sel)) == 32);
2493
2494         /* determine the smallest switch case value */
2495         foreach_out_edge(node, edge) {
2496                 ir_node *proj = get_edge_src_irn(edge);
2497                 long     pn   = get_Proj_proj(proj);
2498                 if (pn == default_pn)
2499                         continue;
2500
2501                 if (pn < switch_min)
2502                         switch_min = pn;
2503                 if (pn > switch_max)
2504                         switch_max = pn;
2505         }
2506
2507         if ((unsigned) (switch_max - switch_min) > 256000) {
2508                 panic("Size of switch %+F bigger than 256000", node);
2509         }
2510
2511         if (switch_min != 0) {
2512                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2513
2514                 /* if smallest switch case is not 0 we need an additional sub */
2515                 new_sel = new_bd_ia32_Lea(dbgi, block, new_sel, noreg);
2516                 add_ia32_am_offs_int(new_sel, -switch_min);
2517                 set_ia32_op_type(new_sel, ia32_AddrModeS);
2518
2519                 SET_IA32_ORIG_NODE(new_sel, node);
2520         }
2521
2522         new_node = new_bd_ia32_SwitchJmp(dbgi, block, new_sel, default_pn);
2523         SET_IA32_ORIG_NODE(new_node, node);
2524
2525         return new_node;
2526 }
2527
2528 /**
2529  * Transform a Cond node.
2530  */
2531 static ir_node *gen_Cond(ir_node *node)
2532 {
2533         ir_node  *block     = get_nodes_block(node);
2534         ir_node  *new_block = be_transform_node(block);
2535         dbg_info *dbgi      = get_irn_dbg_info(node);
2536         ir_node  *sel       = get_Cond_selector(node);
2537         ir_mode  *sel_mode  = get_irn_mode(sel);
2538         ir_node  *flags     = NULL;
2539         ir_node  *new_node;
2540         pn_Cmp    pnc;
2541
2542         if (sel_mode != mode_b) {
2543                 return create_Switch(node);
2544         }
2545
2546         /* we get flags from a Cmp */
2547         flags = get_flags_node(sel, &pnc);
2548
2549         new_node = new_bd_ia32_Jcc(dbgi, new_block, flags, pnc);
2550         SET_IA32_ORIG_NODE(new_node, node);
2551
2552         return new_node;
2553 }
2554
2555 static ir_node *gen_be_Copy(ir_node *node)
2556 {
2557         ir_node *new_node = be_duplicate_node(node);
2558         ir_mode *mode     = get_irn_mode(new_node);
2559
2560         if (ia32_mode_needs_gp_reg(mode)) {
2561                 set_irn_mode(new_node, mode_Iu);
2562         }
2563
2564         return new_node;
2565 }
2566
2567 static ir_node *create_Fucom(ir_node *node)
2568 {
2569         dbg_info *dbgi      = get_irn_dbg_info(node);
2570         ir_node  *block     = get_nodes_block(node);
2571         ir_node  *new_block = be_transform_node(block);
2572         ir_node  *left      = get_Cmp_left(node);
2573         ir_node  *new_left  = be_transform_node(left);
2574         ir_node  *right     = get_Cmp_right(node);
2575         ir_node  *new_right;
2576         ir_node  *new_node;
2577
2578         if (ia32_cg_config.use_fucomi) {
2579                 new_right = be_transform_node(right);
2580                 new_node  = new_bd_ia32_vFucomi(dbgi, new_block, new_left,
2581                                                 new_right, 0);
2582                 set_ia32_commutative(new_node);
2583                 SET_IA32_ORIG_NODE(new_node, node);
2584         } else {
2585                 if (ia32_cg_config.use_ftst && is_Const_0(right)) {
2586                         new_node = new_bd_ia32_vFtstFnstsw(dbgi, new_block, new_left, 0);
2587                 } else {
2588                         new_right = be_transform_node(right);
2589                         new_node  = new_bd_ia32_vFucomFnstsw(dbgi, new_block, new_left, new_right, 0);
2590                 }
2591
2592                 set_ia32_commutative(new_node);
2593
2594                 SET_IA32_ORIG_NODE(new_node, node);
2595
2596                 new_node = new_bd_ia32_Sahf(dbgi, new_block, new_node);
2597                 SET_IA32_ORIG_NODE(new_node, node);
2598         }
2599
2600         return new_node;
2601 }
2602
2603 static ir_node *create_Ucomi(ir_node *node)
2604 {
2605         dbg_info *dbgi      = get_irn_dbg_info(node);
2606         ir_node  *src_block = get_nodes_block(node);
2607         ir_node  *new_block = be_transform_node(src_block);
2608         ir_node  *left      = get_Cmp_left(node);
2609         ir_node  *right     = get_Cmp_right(node);
2610         ir_node  *new_node;
2611         ia32_address_mode_t  am;
2612         ia32_address_t      *addr = &am.addr;
2613
2614         match_arguments(&am, src_block, left, right, NULL,
2615                         match_commutative | match_am);
2616
2617         new_node = new_bd_ia32_Ucomi(dbgi, new_block, addr->base, addr->index,
2618                                      addr->mem, am.new_op1, am.new_op2,
2619                                      am.ins_permuted);
2620         set_am_attributes(new_node, &am);
2621
2622         SET_IA32_ORIG_NODE(new_node, node);
2623
2624         new_node = fix_mem_proj(new_node, &am);
2625
2626         return new_node;
2627 }
2628
2629 /**
2630  * helper function: checks whether all Cmp projs are Lg or Eq which is needed
2631  * to fold an and into a test node
2632  */
2633 static bool can_fold_test_and(ir_node *node)
2634 {
2635         const ir_edge_t *edge;
2636
2637         /** we can only have eq and lg projs */
2638         foreach_out_edge(node, edge) {
2639                 ir_node *proj = get_edge_src_irn(edge);
2640                 pn_Cmp   pnc  = get_Proj_proj(proj);
2641                 if (pnc != pn_Cmp_Eq && pnc != pn_Cmp_Lg)
2642                         return false;
2643         }
2644
2645         return true;
2646 }
2647
2648 /**
2649  * returns true if it is assured, that the upper bits of a node are "clean"
2650  * which means for a 16 or 8 bit value, that the upper bits in the register
2651  * are 0 for unsigned and a copy of the last significant bit for signed
2652  * numbers.
2653  */
2654 static bool upper_bits_clean(ir_node *transformed_node, ir_mode *mode)
2655 {
2656         assert(ia32_mode_needs_gp_reg(mode));
2657         if (get_mode_size_bits(mode) >= 32)
2658                 return true;
2659
2660         if (is_Proj(transformed_node))
2661                 return upper_bits_clean(get_Proj_pred(transformed_node), mode);
2662
2663         switch (get_ia32_irn_opcode(transformed_node)) {
2664                 case iro_ia32_Conv_I2I:
2665                 case iro_ia32_Conv_I2I8Bit: {
2666                         ir_mode *smaller_mode = get_ia32_ls_mode(transformed_node);
2667                         if (mode_is_signed(smaller_mode) != mode_is_signed(mode))
2668                                 return false;
2669                         if (get_mode_size_bits(smaller_mode) > get_mode_size_bits(mode))
2670                                 return false;
2671
2672                         return true;
2673                 }
2674
2675                 case iro_ia32_Shr:
2676                         if (mode_is_signed(mode)) {
2677                                 return false; /* TODO handle signed modes */
2678                         } else {
2679                                 ir_node *right = get_irn_n(transformed_node, n_ia32_Shr_count);
2680                                 if (is_ia32_Immediate(right) || is_ia32_Const(right)) {
2681                                         const ia32_immediate_attr_t *attr
2682                                                 = get_ia32_immediate_attr_const(right);
2683                                         if (attr->symconst == 0 &&
2684                                                         (unsigned)attr->offset >= 32 - get_mode_size_bits(mode)) {
2685                                                 return true;
2686                                         }
2687                                 }
2688                                 return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Shr_val), mode);
2689                         }
2690
2691                 case iro_ia32_Sar:
2692                         /* TODO too conservative if shift amount is constant */
2693                         return upper_bits_clean(get_irn_n(transformed_node, n_ia32_Sar_val), mode);
2694
2695                 case iro_ia32_And:
2696                         if (!mode_is_signed(mode)) {
2697                                 return
2698                                         upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_right), mode) ||
2699                                         upper_bits_clean(get_irn_n(transformed_node, n_ia32_And_left),  mode);
2700                         }
2701                         /* TODO if one is known to be zero extended, then || is sufficient */
2702                         /* FALLTHROUGH */
2703                 case iro_ia32_Or:
2704                 case iro_ia32_Xor:
2705                         return
2706                                 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_right), mode) &&
2707                                 upper_bits_clean(get_irn_n(transformed_node, n_ia32_binary_left),  mode);
2708
2709                 case iro_ia32_Const:
2710                 case iro_ia32_Immediate: {
2711                         const ia32_immediate_attr_t *attr =
2712                                 get_ia32_immediate_attr_const(transformed_node);
2713                         if (mode_is_signed(mode)) {
2714                                 long shifted = attr->offset >> (get_mode_size_bits(mode) - 1);
2715                                 return shifted == 0 || shifted == -1;
2716                         } else {
2717                                 unsigned long shifted = (unsigned long)attr->offset;
2718                                 shifted >>= get_mode_size_bits(mode);
2719                                 return shifted == 0;
2720                         }
2721                 }
2722
2723                 default:
2724                         return false;
2725         }
2726 }
2727
2728 /**
2729  * Generate code for a Cmp.
2730  */
2731 static ir_node *gen_Cmp(ir_node *node)
2732 {
2733         dbg_info *dbgi      = get_irn_dbg_info(node);
2734         ir_node  *block     = get_nodes_block(node);
2735         ir_node  *new_block = be_transform_node(block);
2736         ir_node  *left      = get_Cmp_left(node);
2737         ir_node  *right     = get_Cmp_right(node);
2738         ir_mode  *cmp_mode  = get_irn_mode(left);
2739         ir_node  *new_node;
2740         ia32_address_mode_t  am;
2741         ia32_address_t      *addr = &am.addr;
2742         int                  cmp_unsigned;
2743
2744         if (mode_is_float(cmp_mode)) {
2745                 if (ia32_cg_config.use_sse2) {
2746                         return create_Ucomi(node);
2747                 } else {
2748                         return create_Fucom(node);
2749                 }
2750         }
2751
2752         assert(ia32_mode_needs_gp_reg(cmp_mode));
2753
2754         /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */
2755         cmp_unsigned = !mode_is_signed(cmp_mode);
2756         if (is_Const_0(right)          &&
2757             is_And(left)               &&
2758             get_irn_n_edges(left) == 1 &&
2759             can_fold_test_and(node)) {
2760                 /* Test(and_left, and_right) */
2761                 ir_node *and_left  = get_And_left(left);
2762                 ir_node *and_right = get_And_right(left);
2763
2764                 /* matze: code here used mode instead of cmd_mode, I think it is always
2765                  * the same as cmp_mode, but I leave this here to see if this is really
2766                  * true...
2767                  */
2768                 assert(get_irn_mode(and_left) == cmp_mode);
2769
2770                 match_arguments(&am, block, and_left, and_right, NULL,
2771                                                                                 match_commutative |
2772                                                                                 match_am | match_8bit_am | match_16bit_am |
2773                                                                                 match_am_and_immediates | match_immediate);
2774
2775                 /* use 32bit compare mode if possible since the opcode is smaller */
2776                 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2777                     upper_bits_clean(am.new_op2, cmp_mode)) {
2778                         cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2779                 }
2780
2781                 if (get_mode_size_bits(cmp_mode) == 8) {
2782                         new_node = new_bd_ia32_Test8Bit(dbgi, new_block, addr->base,
2783                                         addr->index, addr->mem, am.new_op1, am.new_op2, am.ins_permuted,
2784                                         cmp_unsigned);
2785                 } else {
2786                         new_node = new_bd_ia32_Test(dbgi, new_block, addr->base, addr->index,
2787                                         addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2788                 }
2789         } else {
2790                 /* Cmp(left, right) */
2791                 match_arguments(&am, block, left, right, NULL,
2792                                 match_commutative | match_am | match_8bit_am |
2793                                 match_16bit_am | match_am_and_immediates |
2794                                 match_immediate);
2795                 /* use 32bit compare mode if possible since the opcode is smaller */
2796                 if (upper_bits_clean(am.new_op1, cmp_mode) &&
2797                     upper_bits_clean(am.new_op2, cmp_mode)) {
2798                         cmp_mode = mode_is_signed(cmp_mode) ? mode_Is : mode_Iu;
2799                 }
2800
2801                 if (get_mode_size_bits(cmp_mode) == 8) {
2802                         new_node = new_bd_ia32_Cmp8Bit(dbgi, new_block, addr->base,
2803                                                        addr->index, addr->mem, am.new_op1,
2804                                                        am.new_op2, am.ins_permuted,
2805                                                        cmp_unsigned);
2806                 } else {
2807                         new_node = new_bd_ia32_Cmp(dbgi, new_block, addr->base, addr->index,
2808                                         addr->mem, am.new_op1, am.new_op2, am.ins_permuted, cmp_unsigned);
2809                 }
2810         }
2811         set_am_attributes(new_node, &am);
2812         set_ia32_ls_mode(new_node, cmp_mode);
2813
2814         SET_IA32_ORIG_NODE(new_node, node);
2815
2816         new_node = fix_mem_proj(new_node, &am);
2817
2818         return new_node;
2819 }
2820
2821 static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags,
2822                             pn_Cmp pnc)
2823 {
2824         dbg_info            *dbgi          = get_irn_dbg_info(node);
2825         ir_node             *block         = get_nodes_block(node);
2826         ir_node             *new_block     = be_transform_node(block);
2827         ir_node             *val_true      = get_Mux_true(node);
2828         ir_node             *val_false     = get_Mux_false(node);
2829         ir_node             *new_node;
2830         ia32_address_mode_t  am;
2831         ia32_address_t      *addr;
2832
2833         assert(ia32_cg_config.use_cmov);
2834         assert(ia32_mode_needs_gp_reg(get_irn_mode(val_true)));
2835
2836         addr = &am.addr;
2837
2838         match_arguments(&am, block, val_false, val_true, flags,
2839                         match_commutative | match_am | match_16bit_am | match_mode_neutral);
2840
2841         new_node = new_bd_ia32_CMov(dbgi, new_block, addr->base, addr->index,
2842                                     addr->mem, am.new_op1, am.new_op2, new_flags,
2843                                     am.ins_permuted, pnc);
2844         set_am_attributes(new_node, &am);
2845
2846         SET_IA32_ORIG_NODE(new_node, node);
2847
2848         new_node = fix_mem_proj(new_node, &am);
2849
2850         return new_node;
2851 }
2852
2853 /**
2854  * Creates a ia32 Setcc instruction.
2855  */
2856 static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block,
2857                                  ir_node *flags, pn_Cmp pnc, ir_node *orig_node,
2858                                  int ins_permuted)
2859 {
2860         ir_node *noreg = ia32_new_NoReg_gp(env_cg);
2861         ir_node *nomem = new_NoMem();
2862         ir_mode *mode  = get_irn_mode(orig_node);
2863         ir_node *new_node;
2864
2865         new_node = new_bd_ia32_Set(dbgi, new_block, flags, pnc, ins_permuted);
2866         SET_IA32_ORIG_NODE(new_node, orig_node);
2867
2868         /* we might need to conv the result up */
2869         if (get_mode_size_bits(mode) > 8) {
2870                 new_node = new_bd_ia32_Conv_I2I8Bit(dbgi, new_block, noreg, noreg,
2871                                                     nomem, new_node, mode_Bu);
2872                 SET_IA32_ORIG_NODE(new_node, orig_node);
2873         }
2874
2875         return new_node;
2876 }
2877
2878 /**
2879  * Create instruction for an unsigned Difference or Zero.
2880  */
2881 static ir_node *create_Doz(ir_node *psi, ir_node *a, ir_node *b)
2882 {
2883         ir_graph *irg   = current_ir_graph;
2884         ir_mode  *mode  = get_irn_mode(psi);
2885         ir_node  *new_node, *sub, *sbb, *eflags, *block, *noreg, *tmpreg, *nomem;
2886         dbg_info *dbgi;
2887
2888         new_node = gen_binop(psi, a, b, new_bd_ia32_Sub,
2889                 match_mode_neutral | match_am | match_immediate | match_two_users);
2890
2891         block = get_nodes_block(new_node);
2892
2893         if (is_Proj(new_node)) {
2894                 sub = get_Proj_pred(new_node);
2895                 assert(is_ia32_Sub(sub));
2896         } else {
2897                 sub = new_node;
2898                 set_irn_mode(sub, mode_T);
2899                 new_node = new_rd_Proj(NULL, irg, block, sub, mode, pn_ia32_res);
2900         }
2901         eflags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
2902
2903         dbgi   = get_irn_dbg_info(psi);
2904         noreg  = ia32_new_NoReg_gp(env_cg);
2905         tmpreg = new_bd_ia32_ProduceVal(dbgi, block);
2906         nomem  = new_NoMem();
2907         sbb    = new_bd_ia32_Sbb(dbgi, block, noreg, noreg, nomem, tmpreg, tmpreg, eflags);
2908
2909         new_node = new_bd_ia32_And(dbgi, block, noreg, noreg, nomem, new_node, sbb);
2910         set_ia32_commutative(new_node);
2911         return new_node;
2912 }
2913
2914 /**
2915  * Transforms a Mux node into CMov.
2916  *
2917  * @return The transformed node.
2918  */
2919 static ir_node *gen_Mux(ir_node *node)
2920 {
2921         dbg_info *dbgi        = get_irn_dbg_info(node);
2922         ir_node  *block       = get_nodes_block(node);
2923         ir_node  *new_block   = be_transform_node(block);
2924         ir_node  *mux_true    = get_Mux_true(node);
2925         ir_node  *mux_false   = get_Mux_false(node);
2926         ir_node  *cond        = get_Mux_sel(node);
2927         ir_mode  *mode        = get_irn_mode(node);
2928         pn_Cmp   pnc;
2929
2930         assert(get_irn_mode(cond) == mode_b);
2931
2932         /* Note: a Mux node uses a Load two times IFF it's used in the compare AND in the result */
2933         if (mode_is_float(mode)) {
2934                 ir_node  *cmp         = get_Proj_pred(cond);
2935                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2936                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2937                 pn_Cmp   pnc          = get_Proj_proj(cond);
2938
2939                 if (ia32_cg_config.use_sse2) {
2940                         if (pnc == pn_Cmp_Lt || pnc == pn_Cmp_Le) {
2941                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2942                                         /* Mux(a <= b, a, b) => MIN */
2943                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2944                                          match_commutative | match_am | match_two_users);
2945                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2946                                         /* Mux(a <= b, b, a) => MAX */
2947                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2948                                          match_commutative | match_am | match_two_users);
2949                                 }
2950                         } else if (pnc == pn_Cmp_Gt || pnc == pn_Cmp_Ge) {
2951                                 if (cmp_left == mux_true && cmp_right == mux_false) {
2952                                         /* Mux(a >= b, a, b) => MAX */
2953                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMax,
2954                                          match_commutative | match_am | match_two_users);
2955                                 } else if (cmp_left == mux_false && cmp_right == mux_true) {
2956                                         /* Mux(a >= b, b, a) => MIN */
2957                                         return gen_binop(node, cmp_left, cmp_right, new_bd_ia32_xMin,
2958                                          match_commutative | match_am | match_two_users);
2959                                 }
2960                         }
2961                 }
2962                 panic("cannot transform floating point Mux");
2963
2964         } else {
2965                 ir_node *flags;
2966                 ir_node *new_node;
2967
2968                 assert(ia32_mode_needs_gp_reg(mode));
2969
2970                 if (is_Proj(cond)) {
2971                         ir_node *cmp = get_Proj_pred(cond);
2972                         if (is_Cmp(cmp)) {
2973                                 ir_node  *cmp_left    = get_Cmp_left(cmp);
2974                                 ir_node  *cmp_right   = get_Cmp_right(cmp);
2975                                 pn_Cmp   pnc          = get_Proj_proj(cond);
2976
2977                                 /* check for unsigned Doz first */
2978                                 if ((pnc & pn_Cmp_Gt) && !mode_is_signed(mode) &&
2979                                         is_Const_0(mux_false) && is_Sub(mux_true) &&
2980                                         get_Sub_left(mux_true) == cmp_left && get_Sub_right(mux_true) == cmp_right) {
2981                                         /* Mux(a >=u b, a - b, 0) unsigned Doz */
2982                                         return create_Doz(node, cmp_left, cmp_right);
2983                                 } else if ((pnc & pn_Cmp_Lt) && !mode_is_signed(mode) &&
2984                                         is_Const_0(mux_true) && is_Sub(mux_false) &&
2985                                         get_Sub_left(mux_false) == cmp_left && get_Sub_right(mux_false) == cmp_right) {
2986                                         /* Mux(a <=u b, 0, a - b) unsigned Doz */
2987                                         return create_Doz(node, cmp_left, cmp_right);
2988                                 }
2989                         }
2990                 }
2991
2992                 flags = get_flags_node(cond, &pnc);
2993
2994                 if (is_Const(mux_true) && is_Const(mux_false)) {
2995                         /* both are const, good */
2996                         if (is_Const_1(mux_true) && is_Const_0(mux_false)) {
2997                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/0);
2998                         } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) {
2999                                 new_node = create_set_32bit(dbgi, new_block, flags, pnc, node, /*is_premuted=*/1);
3000                         } else {
3001                                 /* Not that simple. */
3002                                 goto need_cmov;
3003                         }
3004                 } else {
3005 need_cmov:
3006                         new_node = create_CMov(node, cond, flags, pnc);
3007                 }
3008                 return new_node;
3009         }
3010 }
3011
3012
3013 /**
3014  * Create a conversion from x87 state register to general purpose.
3015  */
3016 static ir_node *gen_x87_fp_to_gp(ir_node *node)
3017 {
3018         ir_node         *block      = be_transform_node(get_nodes_block(node));
3019         ir_node         *op         = get_Conv_op(node);
3020         ir_node         *new_op     = be_transform_node(op);
3021         ia32_code_gen_t *cg         = env_cg;
3022         ir_graph        *irg        = current_ir_graph;
3023         dbg_info        *dbgi       = get_irn_dbg_info(node);
3024         ir_node         *noreg      = ia32_new_NoReg_gp(cg);
3025         ir_mode         *mode       = get_irn_mode(node);
3026         ir_node         *fist, *load, *mem;
3027
3028         mem = gen_vfist(dbgi, irg, block, get_irg_frame(irg), noreg, new_NoMem(), new_op, &fist);
3029         set_irn_pinned(fist, op_pin_state_floats);
3030         set_ia32_use_frame(fist);
3031         set_ia32_op_type(fist, ia32_AddrModeD);
3032
3033         assert(get_mode_size_bits(mode) <= 32);
3034         /* exception we can only store signed 32 bit integers, so for unsigned
3035            we store a 64bit (signed) integer and load the lower bits */
3036         if (get_mode_size_bits(mode) == 32 && !mode_is_signed(mode)) {
3037                 set_ia32_ls_mode(fist, mode_Ls);
3038         } else {
3039                 set_ia32_ls_mode(fist, mode_Is);
3040         }
3041         SET_IA32_ORIG_NODE(fist, node);
3042
3043         /* do a Load */
3044         load = new_bd_ia32_Load(dbgi, block, get_irg_frame(irg), noreg, mem);
3045
3046         set_irn_pinned(load, op_pin_state_floats);
3047         set_ia32_use_frame(load);
3048         set_ia32_op_type(load, ia32_AddrModeS);
3049         set_ia32_ls_mode(load, mode_Is);
3050         if (get_ia32_ls_mode(fist) == mode_Ls) {
3051                 ia32_attr_t *attr = get_ia32_attr(load);
3052                 attr->data.need_64bit_stackent = 1;
3053         } else {
3054                 ia32_attr_t *attr = get_ia32_attr(load);
3055                 attr->data.need_32bit_stackent = 1;
3056         }
3057         SET_IA32_ORIG_NODE(load, node);
3058
3059         return new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3060 }
3061
3062 /**
3063  * Creates a x87 strict Conv by placing a Store and a Load
3064  */
3065 static ir_node *gen_x87_strict_conv(ir_mode *tgt_mode, ir_node *node)
3066 {
3067         ir_node  *block    = get_nodes_block(node);
3068         ir_graph *irg      = current_ir_graph;
3069         dbg_info *dbgi     = get_irn_dbg_info(node);
3070         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3071         ir_node  *nomem    = new_NoMem();
3072         ir_node  *frame    = get_irg_frame(irg);
3073         ir_node  *store, *load;
3074         ir_node  *new_node;
3075
3076         store = new_bd_ia32_vfst(dbgi, block, frame, noreg, nomem, node, tgt_mode);
3077         set_ia32_use_frame(store);
3078         set_ia32_op_type(store, ia32_AddrModeD);
3079         SET_IA32_ORIG_NODE(store, node);
3080
3081         load = new_bd_ia32_vfld(dbgi, block, frame, noreg, store, tgt_mode);
3082         set_ia32_use_frame(load);
3083         set_ia32_op_type(load, ia32_AddrModeS);
3084         SET_IA32_ORIG_NODE(load, node);
3085
3086         new_node = new_r_Proj(irg, block, load, mode_E, pn_ia32_vfld_res);
3087         return new_node;
3088 }
3089
3090 static ir_node *create_Conv_I2I(dbg_info *dbgi, ir_node *block, ir_node *base,
3091                 ir_node *index, ir_node *mem, ir_node *val, ir_mode *mode)
3092 {
3093         ir_node *(*func)(dbg_info*, ir_node*, ir_node*, ir_node*, ir_node*, ir_node*, ir_mode*);
3094
3095         func = get_mode_size_bits(mode) == 8 ?
3096                 new_bd_ia32_Conv_I2I8Bit : new_bd_ia32_Conv_I2I;
3097         return func(dbgi, block, base, index, mem, val, mode);
3098 }
3099
3100 /**
3101  * Create a conversion from general purpose to x87 register
3102  */
3103 static ir_node *gen_x87_gp_to_fp(ir_node *node, ir_mode *src_mode)
3104 {
3105         ir_node  *src_block = get_nodes_block(node);
3106         ir_node  *block     = be_transform_node(src_block);
3107         ir_graph *irg       = current_ir_graph;
3108         dbg_info *dbgi      = get_irn_dbg_info(node);
3109         ir_node  *op        = get_Conv_op(node);
3110         ir_node  *new_op    = NULL;
3111         ir_node  *noreg;
3112         ir_node  *nomem;
3113         ir_mode  *mode;
3114         ir_mode  *store_mode;
3115         ir_node  *fild;
3116         ir_node  *store;
3117         ir_node  *new_node;
3118
3119         /* fild can use source AM if the operand is a signed 16bit or 32bit integer */
3120         if (possible_int_mode_for_fp(src_mode)) {
3121                 ia32_address_mode_t am;
3122
3123                 match_arguments(&am, src_block, NULL, op, NULL, match_am | match_try_am | match_16bit_am);
3124                 if (am.op_type == ia32_AddrModeS) {
3125                         ia32_address_t *addr = &am.addr;
3126
3127                         fild     = new_bd_ia32_vfild(dbgi, block, addr->base, addr->index,
3128                                         addr->mem);
3129                         new_node = new_r_Proj(irg, block, fild, mode_vfp,
3130                                               pn_ia32_vfild_res);
3131
3132                         set_am_attributes(fild, &am);
3133                         SET_IA32_ORIG_NODE(fild, node);
3134
3135                         fix_mem_proj(fild, &am);
3136
3137                         return new_node;
3138                 }
3139         }
3140         if (new_op == NULL) {
3141                 new_op = be_transform_node(op);
3142         }
3143
3144         noreg  = ia32_new_NoReg_gp(env_cg);
3145         nomem  = new_NoMem();
3146         mode   = get_irn_mode(op);
3147
3148         /* first convert to 32 bit signed if necessary */
3149         if (get_mode_size_bits(src_mode) < 32) {
3150                 if (!upper_bits_clean(new_op, src_mode)) {
3151                         new_op = create_Conv_I2I(dbgi, block, noreg, noreg, nomem, new_op, src_mode);
3152                         SET_IA32_ORIG_NODE(new_op, node);
3153                 }
3154                 mode = mode_Is;
3155         }
3156
3157         assert(get_mode_size_bits(mode) == 32);
3158
3159         /* do a store */
3160         store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg), noreg, nomem,
3161                                   new_op);
3162
3163         set_ia32_use_frame(store);
3164         set_ia32_op_type(store, ia32_AddrModeD);
3165         set_ia32_ls_mode(store, mode_Iu);
3166
3167         /* exception for 32bit unsigned, do a 64bit spill+load */
3168         if (!mode_is_signed(mode)) {
3169                 ir_node *in[2];
3170                 /* store a zero */
3171                 ir_node *zero_const = create_Immediate(NULL, 0, 0);
3172
3173                 ir_node *zero_store = new_bd_ia32_Store(dbgi, block, get_irg_frame(irg),
3174                                 noreg, nomem, zero_const);
3175
3176                 set_ia32_use_frame(zero_store);
3177                 set_ia32_op_type(zero_store, ia32_AddrModeD);
3178                 add_ia32_am_offs_int(zero_store, 4);
3179                 set_ia32_ls_mode(zero_store, mode_Iu);
3180
3181                 in[0] = zero_store;
3182                 in[1] = store;
3183
3184                 store      = new_rd_Sync(dbgi, irg, block, 2, in);
3185                 store_mode = mode_Ls;
3186         } else {
3187                 store_mode = mode_Is;
3188         }
3189
3190         /* do a fild */
3191         fild = new_bd_ia32_vfild(dbgi, block, get_irg_frame(irg), noreg, store);
3192
3193         set_ia32_use_frame(fild);
3194         set_ia32_op_type(fild, ia32_AddrModeS);
3195         set_ia32_ls_mode(fild, store_mode);
3196
3197         new_node = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3198
3199         return new_node;
3200 }
3201
3202 /**
3203  * Create a conversion from one integer mode into another one
3204  */
3205 static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
3206                                 dbg_info *dbgi, ir_node *block, ir_node *op,
3207                                 ir_node *node)
3208 {
3209         ir_node             *new_block = be_transform_node(block);
3210         ir_node             *new_node;
3211         ir_mode             *smaller_mode;
3212         ia32_address_mode_t  am;
3213         ia32_address_t      *addr = &am.addr;
3214
3215         (void) node;
3216         if (get_mode_size_bits(src_mode) < get_mode_size_bits(tgt_mode)) {
3217                 smaller_mode = src_mode;
3218         } else {
3219                 smaller_mode = tgt_mode;
3220         }
3221
3222 #ifdef DEBUG_libfirm
3223         if (is_Const(op)) {
3224                 ir_fprintf(stderr, "Optimisation warning: conv after constant %+F\n",
3225                            op);
3226         }
3227 #endif
3228
3229         match_arguments(&am, block, NULL, op, NULL,
3230                         match_am | match_8bit_am | match_16bit_am);
3231
3232         if (upper_bits_clean(am.new_op2, smaller_mode)) {
3233                 /* unnecessary conv. in theory it shouldn't have been AM */
3234                 assert(is_ia32_NoReg_GP(addr->base));
3235                 assert(is_ia32_NoReg_GP(addr->index));
3236                 assert(is_NoMem(addr->mem));
3237                 assert(am.addr.offset == 0);
3238                 assert(am.addr.symconst_ent == NULL);
3239                 return am.new_op2;
3240         }
3241
3242         new_node = create_Conv_I2I(dbgi, new_block, addr->base, addr->index,
3243                         addr->mem, am.new_op2, smaller_mode);
3244         set_am_attributes(new_node, &am);
3245         /* match_arguments assume that out-mode = in-mode, this isn't true here
3246          * so fix it */
3247         set_ia32_ls_mode(new_node, smaller_mode);
3248         SET_IA32_ORIG_NODE(new_node, node);
3249         new_node = fix_mem_proj(new_node, &am);
3250         return new_node;
3251 }
3252
3253 /**
3254  * Transforms a Conv node.
3255  *
3256  * @return The created ia32 Conv node
3257  */
3258 static ir_node *gen_Conv(ir_node *node)
3259 {
3260         ir_node  *block     = get_nodes_block(node);
3261         ir_node  *new_block = be_transform_node(block);
3262         ir_node  *op        = get_Conv_op(node);
3263         ir_node  *new_op    = NULL;
3264         dbg_info *dbgi      = get_irn_dbg_info(node);
3265         ir_mode  *src_mode  = get_irn_mode(op);
3266         ir_mode  *tgt_mode  = get_irn_mode(node);
3267         int       src_bits  = get_mode_size_bits(src_mode);
3268         int       tgt_bits  = get_mode_size_bits(tgt_mode);
3269         ir_node  *noreg     = ia32_new_NoReg_gp(env_cg);
3270         ir_node  *nomem     = new_NoMem();
3271         ir_node  *res       = NULL;
3272
3273         assert(!mode_is_int(src_mode) || src_bits <= 32);
3274         assert(!mode_is_int(tgt_mode) || tgt_bits <= 32);
3275
3276         if (src_mode == mode_b) {
3277                 assert(mode_is_int(tgt_mode) || mode_is_reference(tgt_mode));
3278                 /* nothing to do, we already model bools as 0/1 ints */
3279                 return be_transform_node(op);
3280         }
3281
3282         if (src_mode == tgt_mode) {
3283                 if (get_Conv_strict(node)) {
3284                         if (ia32_cg_config.use_sse2) {
3285                                 /* when we are in SSE mode, we can kill all strict no-op conversion */
3286                                 return be_transform_node(op);
3287                         }
3288                 } else {
3289                         /* this should be optimized already, but who knows... */
3290                         DEBUG_ONLY(ir_fprintf(stderr, "Debug warning: conv %+F is pointless\n", node));
3291                         DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3292                         return be_transform_node(op);
3293                 }
3294         }
3295
3296         if (mode_is_float(src_mode)) {
3297                 new_op = be_transform_node(op);
3298                 /* we convert from float ... */
3299                 if (mode_is_float(tgt_mode)) {
3300                         if (src_mode == mode_E && tgt_mode == mode_D
3301                                         && !get_Conv_strict(node)) {
3302                                 DB((dbg, LEVEL_1, "killed Conv(mode, mode) ..."));
3303                                 return new_op;
3304                         }
3305
3306                         /* ... to float */
3307                         if (ia32_cg_config.use_sse2) {
3308                                 DB((dbg, LEVEL_1, "create Conv(float, float) ..."));
3309                                 res = new_bd_ia32_Conv_FP2FP(dbgi, new_block, noreg, noreg,
3310                                                              nomem, new_op);
3311                                 set_ia32_ls_mode(res, tgt_mode);
3312                         } else {
3313                                 if (get_Conv_strict(node)) {
3314                                         res = gen_x87_strict_conv(tgt_mode, new_op);
3315                                         SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3316                                         return res;
3317                                 }
3318                                 DB((dbg, LEVEL_1, "killed Conv(float, float) ..."));
3319                                 return new_op;
3320                         }
3321                 } else {
3322                         /* ... to int */
3323                         DB((dbg, LEVEL_1, "create Conv(float, int) ..."));
3324                         if (ia32_cg_config.use_sse2) {
3325                                 res = new_bd_ia32_Conv_FP2I(dbgi, new_block, noreg, noreg,
3326                                                             nomem, new_op);
3327                                 set_ia32_ls_mode(res, src_mode);
3328                         } else {
3329                                 return gen_x87_fp_to_gp(node);
3330                         }
3331                 }
3332         } else {
3333                 /* we convert from int ... */
3334                 if (mode_is_float(tgt_mode)) {
3335                         /* ... to float */
3336                         DB((dbg, LEVEL_1, "create Conv(int, float) ..."));
3337                         if (ia32_cg_config.use_sse2) {
3338                                 new_op = be_transform_node(op);
3339                                 res = new_bd_ia32_Conv_I2FP(dbgi, new_block, noreg, noreg,
3340                                                             nomem, new_op);
3341                                 set_ia32_ls_mode(res, tgt_mode);
3342                         } else {
3343                                 res = gen_x87_gp_to_fp(node, src_mode);
3344                                 if (get_Conv_strict(node)) {
3345                                         /* The strict-Conv is only necessary, if the int mode has more bits
3346                                          * than the float mantissa */
3347                                         size_t int_mantissa = get_mode_size_bits(src_mode) - (mode_is_signed(src_mode) ? 1 : 0);
3348                                         size_t float_mantissa;
3349                                         /* FIXME There is no way to get the mantissa size of a mode */
3350                                         switch (get_mode_size_bits(tgt_mode)) {
3351                                                 case 32: float_mantissa = 23 + 1; break; // + 1 for implicit 1
3352                                                 case 64: float_mantissa = 52 + 1; break;
3353                                                 case 80:
3354                                                 case 96: float_mantissa = 64;     break;
3355                                                 default: float_mantissa = 0;      break;
3356                                         }
3357                                         if (float_mantissa < int_mantissa) {
3358                                                 res = gen_x87_strict_conv(tgt_mode, res);
3359                                                 SET_IA32_ORIG_NODE(get_Proj_pred(res), node);
3360                                         }
3361                                 }
3362                                 return res;
3363                         }
3364                 } else if (tgt_mode == mode_b) {
3365                         /* mode_b lowering already took care that we only have 0/1 values */
3366                         DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3367                             src_mode, tgt_mode));
3368                         return be_transform_node(op);
3369                 } else {
3370                         /* to int */
3371                         if (src_bits == tgt_bits) {
3372                                 DB((dbg, LEVEL_1, "omitting unnecessary Conv(%+F, %+F) ...",
3373                                     src_mode, tgt_mode));
3374                                 return be_transform_node(op);
3375                         }
3376
3377                         res = create_I2I_Conv(src_mode, tgt_mode, dbgi, block, op, node);
3378                         return res;
3379                 }
3380         }
3381
3382         return res;
3383 }
3384
3385 static ir_node *create_immediate_or_transform(ir_node *node,
3386                                               char immediate_constraint_type)
3387 {
3388         ir_node *new_node = try_create_Immediate(node, immediate_constraint_type);
3389         if (new_node == NULL) {
3390                 new_node = be_transform_node(node);
3391         }
3392         return new_node;
3393 }
3394
3395 /**
3396  * Transforms a FrameAddr into an ia32 Add.
3397  */
3398 static ir_node *gen_be_FrameAddr(ir_node *node)
3399 {
3400         ir_node  *block  = be_transform_node(get_nodes_block(node));
3401         ir_node  *op     = be_get_FrameAddr_frame(node);
3402         ir_node  *new_op = be_transform_node(op);
3403         dbg_info *dbgi   = get_irn_dbg_info(node);
3404         ir_node  *noreg  = ia32_new_NoReg_gp(env_cg);
3405         ir_node  *new_node;
3406
3407         new_node = new_bd_ia32_Lea(dbgi, block, new_op, noreg);
3408         set_ia32_frame_ent(new_node, arch_get_frame_entity(node));
3409         set_ia32_use_frame(new_node);
3410
3411         SET_IA32_ORIG_NODE(new_node, node);
3412
3413         return new_node;
3414 }
3415
3416 /**
3417  * In case SSE is used we need to copy the result from XMM0 to FPU TOS before return.
3418  */
3419 static ir_node *gen_be_Return(ir_node *node)
3420 {
3421         ir_graph  *irg     = current_ir_graph;
3422         ir_node   *ret_val = get_irn_n(node, be_pos_Return_val);
3423         ir_node   *ret_mem = get_irn_n(node, be_pos_Return_mem);
3424         ir_entity *ent     = get_irg_entity(irg);
3425         ir_type   *tp      = get_entity_type(ent);
3426         dbg_info  *dbgi;
3427         ir_node   *block;
3428         ir_type   *res_type;
3429         ir_mode   *mode;
3430         ir_node   *frame, *sse_store, *fld, *mproj, *barrier;
3431         ir_node   *new_barrier, *new_ret_val, *new_ret_mem;
3432         ir_node   *noreg;
3433         ir_node   **in;
3434         int       pn_ret_val, pn_ret_mem, arity, i;
3435
3436         assert(ret_val != NULL);
3437         if (be_Return_get_n_rets(node) < 1 || ! ia32_cg_config.use_sse2) {
3438                 return be_duplicate_node(node);
3439         }
3440
3441         res_type = get_method_res_type(tp, 0);
3442
3443         if (! is_Primitive_type(res_type)) {
3444                 return be_duplicate_node(node);
3445         }
3446
3447         mode = get_type_mode(res_type);
3448         if (! mode_is_float(mode)) {
3449                 return be_duplicate_node(node);
3450         }
3451
3452         assert(get_method_n_ress(tp) == 1);
3453
3454         pn_ret_val = get_Proj_proj(ret_val);
3455         pn_ret_mem = get_Proj_proj(ret_mem);
3456
3457         /* get the Barrier */
3458         barrier = get_Proj_pred(ret_val);
3459
3460         /* get result input of the Barrier */
3461         ret_val     = get_irn_n(barrier, pn_ret_val);
3462         new_ret_val = be_transform_node(ret_val);
3463
3464         /* get memory input of the Barrier */
3465         ret_mem     = get_irn_n(barrier, pn_ret_mem);
3466         new_ret_mem = be_transform_node(ret_mem);
3467
3468         frame = get_irg_frame(irg);
3469
3470         dbgi  = get_irn_dbg_info(barrier);
3471         block = be_transform_node(get_nodes_block(barrier));
3472
3473         noreg = ia32_new_NoReg_gp(env_cg);
3474
3475         /* store xmm0 onto stack */
3476         sse_store = new_bd_ia32_xStoreSimple(dbgi, block, frame, noreg,
3477                                              new_ret_mem, new_ret_val);
3478         set_ia32_ls_mode(sse_store, mode);
3479         set_ia32_op_type(sse_store, ia32_AddrModeD);
3480         set_ia32_use_frame(sse_store);
3481
3482         /* load into x87 register */
3483         fld = new_bd_ia32_vfld(dbgi, block, frame, noreg, sse_store, mode);
3484         set_ia32_op_type(fld, ia32_AddrModeS);
3485         set_ia32_use_frame(fld);
3486
3487         mproj = new_r_Proj(irg, block, fld, mode_M, pn_ia32_vfld_M);
3488         fld   = new_r_Proj(irg, block, fld, mode_vfp, pn_ia32_vfld_res);
3489
3490         /* create a new barrier */
3491         arity = get_irn_arity(barrier);
3492         in    = ALLOCAN(ir_node*, arity);
3493         for (i = 0; i < arity; ++i) {
3494                 ir_node *new_in;
3495
3496                 if (i == pn_ret_val) {
3497                         new_in = fld;
3498                 } else if (i == pn_ret_mem) {
3499                         new_in = mproj;
3500                 } else {
3501                         ir_node *in = get_irn_n(barrier, i);
3502                         new_in = be_transform_node(in);
3503                 }
3504                 in[i] = new_in;
3505         }
3506
3507         new_barrier = new_ir_node(dbgi, irg, block,
3508                                   get_irn_op(barrier), get_irn_mode(barrier),
3509                                   arity, in);
3510         copy_node_attr(barrier, new_barrier);
3511         be_duplicate_deps(barrier, new_barrier);
3512         be_set_transformed_node(barrier, new_barrier);
3513
3514         /* transform normally */
3515         return be_duplicate_node(node);
3516 }
3517
3518 /**
3519  * Transform a be_AddSP into an ia32_SubSP.
3520  */
3521 static ir_node *gen_be_AddSP(ir_node *node)
3522 {
3523         ir_node  *sz = get_irn_n(node, be_pos_AddSP_size);
3524         ir_node  *sp = get_irn_n(node, be_pos_AddSP_old_sp);
3525
3526         return gen_binop(node, sp, sz, new_bd_ia32_SubSP,
3527                          match_am | match_immediate);
3528 }
3529
3530 /**
3531  * Transform a be_SubSP into an ia32_AddSP
3532  */
3533 static ir_node *gen_be_SubSP(ir_node *node)
3534 {
3535         ir_node  *sz = get_irn_n(node, be_pos_SubSP_size);
3536         ir_node  *sp = get_irn_n(node, be_pos_SubSP_old_sp);
3537
3538         return gen_binop(node, sp, sz, new_bd_ia32_AddSP,
3539                          match_am | match_immediate);
3540 }
3541
3542 /**
3543  * Change some phi modes
3544  */
3545 static ir_node *gen_Phi(ir_node *node)
3546 {
3547         ir_node  *block = be_transform_node(get_nodes_block(node));
3548         ir_graph *irg   = current_ir_graph;
3549         dbg_info *dbgi  = get_irn_dbg_info(node);
3550         ir_mode  *mode  = get_irn_mode(node);
3551         ir_node  *phi;
3552
3553         if (ia32_mode_needs_gp_reg(mode)) {
3554                 /* we shouldn't have any 64bit stuff around anymore */
3555                 assert(get_mode_size_bits(mode) <= 32);
3556                 /* all integer operations are on 32bit registers now */
3557                 mode = mode_Iu;
3558         } else if (mode_is_float(mode)) {
3559                 if (ia32_cg_config.use_sse2) {
3560                         mode = mode_xmm;
3561                 } else {
3562                         mode = mode_vfp;
3563                 }
3564         }
3565
3566         /* phi nodes allow loops, so we use the old arguments for now
3567          * and fix this later */
3568         phi = new_ir_node(dbgi, irg, block, op_Phi, mode, get_irn_arity(node),
3569                           get_irn_in(node) + 1);
3570         copy_node_attr(node, phi);
3571         be_duplicate_deps(node, phi);
3572
3573         be_enqueue_preds(node);
3574
3575         return phi;
3576 }
3577
3578 /**
3579  * Transform IJmp
3580  */
3581 static ir_node *gen_IJmp(ir_node *node)
3582 {
3583         ir_node  *block     = get_nodes_block(node);
3584         ir_node  *new_block = be_transform_node(block);
3585         dbg_info *dbgi      = get_irn_dbg_info(node);
3586         ir_node  *op        = get_IJmp_target(node);
3587         ir_node  *new_node;
3588         ia32_address_mode_t  am;
3589         ia32_address_t      *addr = &am.addr;
3590
3591         assert(get_irn_mode(op) == mode_P);
3592
3593         match_arguments(&am, block, NULL, op, NULL, match_am | match_immediate);
3594
3595         new_node = new_bd_ia32_IJmp(dbgi, new_block, addr->base, addr->index,
3596                         addr->mem, am.new_op2);
3597         set_am_attributes(new_node, &am);
3598         SET_IA32_ORIG_NODE(new_node, node);
3599
3600         new_node = fix_mem_proj(new_node, &am);
3601
3602         return new_node;
3603 }
3604
3605 /**
3606  * Transform a Bound node.
3607  */
3608 static ir_node *gen_Bound(ir_node *node)
3609 {
3610         ir_node  *new_node;
3611         ir_node  *lower = get_Bound_lower(node);
3612         dbg_info *dbgi  = get_irn_dbg_info(node);
3613
3614         if (is_Const_0(lower)) {
3615                 /* typical case for Java */
3616                 ir_node  *sub, *res, *flags, *block;
3617                 ir_graph *irg  = current_ir_graph;
3618
3619                 res = gen_binop(node, get_Bound_index(node), get_Bound_upper(node),
3620                         new_bd_ia32_Sub, match_mode_neutral     | match_am | match_immediate);
3621
3622                 block = get_nodes_block(res);
3623                 if (! is_Proj(res)) {
3624                         sub = res;
3625                         set_irn_mode(sub, mode_T);
3626                         res = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_res);
3627                 } else {
3628                         sub = get_Proj_pred(res);
3629                 }
3630                 flags = new_rd_Proj(NULL, irg, block, sub, mode_Iu, pn_ia32_Sub_flags);
3631                 new_node = new_bd_ia32_Jcc(dbgi, block, flags, pn_Cmp_Lt | ia32_pn_Cmp_unsigned);
3632                 SET_IA32_ORIG_NODE(new_node, node);
3633         } else {
3634                 panic("generic Bound not supported in ia32 Backend");
3635         }
3636         return new_node;
3637 }
3638
3639
3640 static ir_node *gen_ia32_l_ShlDep(ir_node *node)
3641 {
3642         ir_node *left  = get_irn_n(node, n_ia32_l_ShlDep_val);
3643         ir_node *right = get_irn_n(node, n_ia32_l_ShlDep_count);
3644
3645         return gen_shift_binop(node, left, right, new_bd_ia32_Shl,
3646                                match_immediate | match_mode_neutral);
3647 }
3648
3649 static ir_node *gen_ia32_l_ShrDep(ir_node *node)
3650 {
3651         ir_node *left  = get_irn_n(node, n_ia32_l_ShrDep_val);
3652         ir_node *right = get_irn_n(node, n_ia32_l_ShrDep_count);
3653         return gen_shift_binop(node, left, right, new_bd_ia32_Shr,
3654                                match_immediate);
3655 }
3656
3657 static ir_node *gen_ia32_l_SarDep(ir_node *node)
3658 {
3659         ir_node *left  = get_irn_n(node, n_ia32_l_SarDep_val);
3660         ir_node *right = get_irn_n(node, n_ia32_l_SarDep_count);
3661         return gen_shift_binop(node, left, right, new_bd_ia32_Sar,
3662                                match_immediate);
3663 }
3664
3665 static ir_node *gen_ia32_l_Add(ir_node *node)
3666 {
3667         ir_node *left    = get_irn_n(node, n_ia32_l_Add_left);
3668         ir_node *right   = get_irn_n(node, n_ia32_l_Add_right);
3669         ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Add,
3670                         match_commutative | match_am | match_immediate |
3671                         match_mode_neutral);
3672
3673         if (is_Proj(lowered)) {
3674                 lowered = get_Proj_pred(lowered);
3675         } else {
3676                 assert(is_ia32_Add(lowered));
3677                 set_irn_mode(lowered, mode_T);
3678         }
3679
3680         return lowered;
3681 }
3682
3683 static ir_node *gen_ia32_l_Adc(ir_node *node)
3684 {
3685         return gen_binop_flags(node, new_bd_ia32_Adc,
3686                         match_commutative | match_am | match_immediate |
3687                         match_mode_neutral);
3688 }
3689
3690 /**
3691  * Transforms a l_MulS into a "real" MulS node.
3692  *
3693  * @return the created ia32 Mul node
3694  */
3695 static ir_node *gen_ia32_l_Mul(ir_node *node)
3696 {
3697         ir_node *left  = get_binop_left(node);
3698         ir_node *right = get_binop_right(node);
3699
3700         return gen_binop(node, left, right, new_bd_ia32_Mul,
3701                          match_commutative | match_am | match_mode_neutral);
3702 }
3703
3704 /**
3705  * Transforms a l_IMulS into a "real" IMul1OPS node.
3706  *
3707  * @return the created ia32 IMul1OP node
3708  */
3709 static ir_node *gen_ia32_l_IMul(ir_node *node)
3710 {
3711         ir_node  *left  = get_binop_left(node);
3712         ir_node  *right = get_binop_right(node);
3713
3714         return gen_binop(node, left, right, new_bd_ia32_IMul1OP,
3715                          match_commutative | match_am | match_mode_neutral);
3716 }
3717
3718 static ir_node *gen_ia32_l_Sub(ir_node *node)
3719 {
3720         ir_node *left    = get_irn_n(node, n_ia32_l_Sub_minuend);
3721         ir_node *right   = get_irn_n(node, n_ia32_l_Sub_subtrahend);
3722         ir_node *lowered = gen_binop(node, left, right, new_bd_ia32_Sub,
3723                         match_am | match_immediate | match_mode_neutral);
3724
3725         if (is_Proj(lowered)) {
3726                 lowered = get_Proj_pred(lowered);
3727         } else {
3728                 assert(is_ia32_Sub(lowered));
3729                 set_irn_mode(lowered, mode_T);
3730         }
3731
3732         return lowered;
3733 }
3734
3735 static ir_node *gen_ia32_l_Sbb(ir_node *node)
3736 {
3737         return gen_binop_flags(node, new_bd_ia32_Sbb,
3738                         match_am | match_immediate | match_mode_neutral);
3739 }
3740
3741 /**
3742  * Transforms a l_ShlD/l_ShrD into a ShlD/ShrD. Those nodes have 3 data inputs:
3743  * op1 - target to be shifted
3744  * op2 - contains bits to be shifted into target
3745  * op3 - shift count
3746  * Only op3 can be an immediate.
3747  */
3748 static ir_node *gen_lowered_64bit_shifts(ir_node *node, ir_node *high,
3749                                          ir_node *low, ir_node *count)
3750 {
3751         ir_node  *block     = get_nodes_block(node);
3752         ir_node  *new_block = be_transform_node(block);
3753         dbg_info *dbgi      = get_irn_dbg_info(node);
3754         ir_node  *new_high  = be_transform_node(high);
3755         ir_node  *new_low   = be_transform_node(low);
3756         ir_node  *new_count;
3757         ir_node  *new_node;
3758
3759         /* the shift amount can be any mode that is bigger than 5 bits, since all
3760          * other bits are ignored anyway */
3761         while (is_Conv(count)              &&
3762                get_irn_n_edges(count) == 1 &&
3763                mode_is_int(get_irn_mode(count))) {
3764                 assert(get_mode_size_bits(get_irn_mode(count)) >= 5);
3765                 count = get_Conv_op(count);
3766         }
3767         new_count = create_immediate_or_transform(count, 0);
3768
3769         if (is_ia32_l_ShlD(node)) {
3770                 new_node = new_bd_ia32_ShlD(dbgi, new_block, new_high, new_low,
3771                                             new_count);
3772         } else {
3773                 new_node = new_bd_ia32_ShrD(dbgi, new_block, new_high, new_low,
3774                                             new_count);
3775         }
3776         SET_IA32_ORIG_NODE(new_node, node);
3777
3778         return new_node;
3779 }
3780
3781 static ir_node *gen_ia32_l_ShlD(ir_node *node)
3782 {
3783         ir_node *high  = get_irn_n(node, n_ia32_l_ShlD_val_high);
3784         ir_node *low   = get_irn_n(node, n_ia32_l_ShlD_val_low);
3785         ir_node *count = get_irn_n(node, n_ia32_l_ShlD_count);
3786         return gen_lowered_64bit_shifts(node, high, low, count);
3787 }
3788
3789 static ir_node *gen_ia32_l_ShrD(ir_node *node)
3790 {
3791         ir_node *high  = get_irn_n(node, n_ia32_l_ShrD_val_high);
3792         ir_node *low   = get_irn_n(node, n_ia32_l_ShrD_val_low);
3793         ir_node *count = get_irn_n(node, n_ia32_l_ShrD_count);
3794         return gen_lowered_64bit_shifts(node, high, low, count);
3795 }
3796
3797 static ir_entity *get_ull2flt_array(void) {}
3798
3799 static ir_node *gen_ia32_l_LLtoFloat(ir_node *node)
3800 {
3801         ir_node  *src_block    = get_nodes_block(node);
3802         ir_node  *block        = be_transform_node(src_block);
3803         ir_graph *irg          = current_ir_graph;
3804         dbg_info *dbgi         = get_irn_dbg_info(node);
3805         ir_node  *frame        = get_irg_frame(irg);
3806         ir_node  *noreg        = ia32_new_NoReg_gp(env_cg);
3807         ir_node  *nomem        = new_NoMem();
3808         ir_node  *val_low      = get_irn_n(node, n_ia32_l_LLtoFloat_val_low);
3809         ir_node  *val_high     = get_irn_n(node, n_ia32_l_LLtoFloat_val_high);
3810         ir_node  *new_val_low  = be_transform_node(val_low);
3811         ir_node  *new_val_high = be_transform_node(val_high);
3812         ir_node  *in[2];
3813         ir_node  *sync, *fild, *res;
3814         ir_node  *store_low, *store_high;
3815
3816         if (ia32_cg_config.use_sse2) {
3817                 panic("ia32_l_LLtoFloat not implemented for SSE2");
3818         }
3819
3820         /* do a store */
3821         store_low = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3822                                       new_val_low);
3823         store_high = new_bd_ia32_Store(dbgi, block, frame, noreg, nomem,
3824                                        new_val_high);
3825         SET_IA32_ORIG_NODE(store_low,  node);
3826         SET_IA32_ORIG_NODE(store_high, node);
3827
3828         set_ia32_use_frame(store_low);
3829         set_ia32_use_frame(store_high);
3830         set_ia32_op_type(store_low, ia32_AddrModeD);
3831         set_ia32_op_type(store_high, ia32_AddrModeD);
3832         set_ia32_ls_mode(store_low, mode_Iu);
3833         set_ia32_ls_mode(store_high, mode_Is);
3834         add_ia32_am_offs_int(store_high, 4);
3835
3836         in[0] = store_low;
3837         in[1] = store_high;
3838         sync  = new_rd_Sync(dbgi, irg, block, 2, in);
3839
3840         /* do a fild */
3841         fild = new_bd_ia32_vfild(dbgi, block, frame, noreg, sync);
3842
3843         set_ia32_use_frame(fild);
3844         set_ia32_op_type(fild, ia32_AddrModeS);
3845         set_ia32_ls_mode(fild, mode_Ls);
3846
3847         SET_IA32_ORIG_NODE(fild, node);
3848
3849         res = new_r_Proj(irg, block, fild, mode_vfp, pn_ia32_vfild_res);
3850
3851         if (! mode_is_signed(get_irn_mode(val_high))) {
3852                 ia32_address_mode_t  am;
3853
3854                 ir_node *count = create_Immediate(NULL, 0, 31);
3855                 ir_node *fadd;
3856
3857                 am.addr.base          = ia32_new_NoReg_gp(env_cg);
3858                 am.addr.index         = new_bd_ia32_Shr(dbgi, block, new_val_high, count);
3859                 am.addr.mem           = nomem;
3860                 am.addr.offset        = 0;
3861                 am.addr.scale         = 2;
3862                 am.addr.symconst_ent  = ia32_gen_fp_known_const(ia32_ULLBIAS);
3863                 am.addr.use_frame     = 0;
3864                 am.addr.frame_entity  = NULL;
3865                 am.addr.symconst_sign = 0;
3866                 am.ls_mode            = mode_F;
3867                 am.mem_proj           = nomem;
3868                 am.op_type            = ia32_AddrModeS;
3869                 am.new_op1            = res;
3870                 am.new_op2            = ia32_new_NoReg_vfp(env_cg);
3871                 am.pinned             = op_pin_state_floats;
3872                 am.commutative        = 1;
3873                 am.ins_permuted       = 0;
3874
3875                 fadd  = new_bd_ia32_vfadd(dbgi, block, am.addr.base, am.addr.index, am.addr.mem,
3876                         am.new_op1, am.new_op2, get_fpcw());
3877                 set_am_attributes(fadd, &am);
3878
3879                 set_irn_mode(fadd, mode_T);
3880                 res = new_rd_Proj(NULL, irg, block, fadd, mode_vfp, pn_ia32_res);
3881         }
3882         return res;
3883 }
3884
3885 static ir_node *gen_ia32_l_FloattoLL(ir_node *node)
3886 {
3887         ir_node  *src_block  = get_nodes_block(node);
3888         ir_node  *block      = be_transform_node(src_block);
3889         ir_graph *irg        = current_ir_graph;
3890         dbg_info *dbgi       = get_irn_dbg_info(node);
3891         ir_node  *frame      = get_irg_frame(irg);
3892         ir_node  *noreg      = ia32_new_NoReg_gp(env_cg);
3893         ir_node  *nomem      = new_NoMem();
3894         ir_node  *val        = get_irn_n(node, n_ia32_l_FloattoLL_val);
3895         ir_node  *new_val    = be_transform_node(val);
3896         ir_node  *fist, *mem;
3897
3898         mem = gen_vfist(dbgi, irg, block, frame, noreg, nomem, new_val, &fist);
3899         SET_IA32_ORIG_NODE(fist, node);
3900         set_ia32_use_frame(fist);
3901         set_ia32_op_type(fist, ia32_AddrModeD);
3902         set_ia32_ls_mode(fist, mode_Ls);
3903
3904         return mem;
3905 }
3906
3907 /**
3908  * the BAD transformer.
3909  */
3910 static ir_node *bad_transform(ir_node *node)
3911 {
3912         panic("No transform function for %+F available.", node);
3913         return NULL;
3914 }
3915
3916 static ir_node *gen_Proj_l_FloattoLL(ir_node *node)
3917 {
3918         ir_graph *irg      = current_ir_graph;
3919         ir_node  *block    = be_transform_node(get_nodes_block(node));
3920         ir_node  *pred     = get_Proj_pred(node);
3921         ir_node  *new_pred = be_transform_node(pred);
3922         ir_node  *frame    = get_irg_frame(irg);
3923         ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
3924         dbg_info *dbgi     = get_irn_dbg_info(node);
3925         long      pn       = get_Proj_proj(node);
3926         ir_node  *load;
3927         ir_node  *proj;
3928         ia32_attr_t *attr;
3929
3930         load = new_bd_ia32_Load(dbgi, block, frame, noreg, new_pred);
3931         SET_IA32_ORIG_NODE(load, node);
3932         set_ia32_use_frame(load);
3933         set_ia32_op_type(load, ia32_AddrModeS);
3934         set_ia32_ls_mode(load, mode_Iu);
3935         /* we need a 64bit stackslot (fist stores 64bit) even though we only load
3936          * 32 bit from it with this particular load */
3937         attr = get_ia32_attr(load);
3938         attr->data.need_64bit_stackent = 1;
3939
3940         if (pn == pn_ia32_l_FloattoLL_res_high) {
3941                 add_ia32_am_offs_int(load, 4);
3942         } else {
3943                 assert(pn == pn_ia32_l_FloattoLL_res_low);
3944         }
3945
3946         proj = new_r_Proj(irg, block, load, mode_Iu, pn_ia32_Load_res);
3947
3948         return proj;
3949 }
3950
3951 /**
3952  * Transform the Projs of an AddSP.
3953  */
3954 static ir_node *gen_Proj_be_AddSP(ir_node *node)
3955 {
3956         ir_node  *block    = be_transform_node(get_nodes_block(node));
3957         ir_node  *pred     = get_Proj_pred(node);
3958         ir_node  *new_pred = be_transform_node(pred);
3959         ir_graph *irg      = current_ir_graph;
3960         dbg_info *dbgi     = get_irn_dbg_info(node);
3961         long     proj      = get_Proj_proj(node);
3962
3963         if (proj == pn_be_AddSP_sp) {
3964                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3965                                            pn_ia32_SubSP_stack);
3966                 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3967                 return res;
3968         } else if (proj == pn_be_AddSP_res) {
3969                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3970                                    pn_ia32_SubSP_addr);
3971         } else if (proj == pn_be_AddSP_M) {
3972                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_SubSP_M);
3973         }
3974
3975         panic("No idea how to transform proj->AddSP");
3976 }
3977
3978 /**
3979  * Transform the Projs of a SubSP.
3980  */
3981 static ir_node *gen_Proj_be_SubSP(ir_node *node)
3982 {
3983         ir_node  *block    = be_transform_node(get_nodes_block(node));
3984         ir_node  *pred     = get_Proj_pred(node);
3985         ir_node  *new_pred = be_transform_node(pred);
3986         ir_graph *irg      = current_ir_graph;
3987         dbg_info *dbgi     = get_irn_dbg_info(node);
3988         long     proj      = get_Proj_proj(node);
3989
3990         if (proj == pn_be_SubSP_sp) {
3991                 ir_node *res = new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu,
3992                                            pn_ia32_AddSP_stack);
3993                 arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
3994                 return res;
3995         } else if (proj == pn_be_SubSP_M) {
3996                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_AddSP_M);
3997         }
3998
3999         panic("No idea how to transform proj->SubSP");
4000 }
4001
4002 /**
4003  * Transform and renumber the Projs from a Load.
4004  */
4005 static ir_node *gen_Proj_Load(ir_node *node)
4006 {
4007         ir_node  *new_pred;
4008         ir_node  *block    = be_transform_node(get_nodes_block(node));
4009         ir_node  *pred     = get_Proj_pred(node);
4010         ir_graph *irg      = current_ir_graph;
4011         dbg_info *dbgi     = get_irn_dbg_info(node);
4012         long     proj      = get_Proj_proj(node);
4013
4014         /* loads might be part of source address mode matches, so we don't
4015          * transform the ProjMs yet (with the exception of loads whose result is
4016          * not used)
4017          */
4018         if (is_Load(pred) && proj == pn_Load_M && get_irn_n_edges(pred) > 1) {
4019                 ir_node *res;
4020
4021                 /* this is needed, because sometimes we have loops that are only
4022                    reachable through the ProjM */
4023                 be_enqueue_preds(node);
4024                 /* do it in 2 steps, to silence firm verifier */
4025                 res = new_rd_Proj(dbgi, irg, block, pred, mode_M, pn_Load_M);
4026                 set_Proj_proj(res, pn_ia32_mem);
4027                 return res;
4028         }
4029
4030         /* renumber the proj */
4031         new_pred = be_transform_node(pred);
4032         if (is_ia32_Load(new_pred)) {
4033                 switch (proj) {
4034                 case pn_Load_res:
4035                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Load_res);
4036                 case pn_Load_M:
4037                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Load_M);
4038                 case pn_Load_X_regular:
4039                         return new_rd_Jmp(dbgi, irg, block);
4040                 case pn_Load_X_except:
4041                         /* This Load might raise an exception. Mark it. */
4042                         set_ia32_exc_label(new_pred, 1);
4043                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Load_X_exc);
4044                 default:
4045                         break;
4046                 }
4047         } else if (is_ia32_Conv_I2I(new_pred) ||
4048                    is_ia32_Conv_I2I8Bit(new_pred)) {
4049                 set_irn_mode(new_pred, mode_T);
4050                 if (proj == pn_Load_res) {
4051                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_res);
4052                 } else if (proj == pn_Load_M) {
4053                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_mem);
4054                 }
4055         } else if (is_ia32_xLoad(new_pred)) {
4056                 switch (proj) {
4057                 case pn_Load_res:
4058                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xLoad_res);
4059                 case pn_Load_M:
4060                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xLoad_M);
4061                 case pn_Load_X_regular:
4062                         return new_rd_Jmp(dbgi, irg, block);
4063                 case pn_Load_X_except:
4064                         /* This Load might raise an exception. Mark it. */
4065                         set_ia32_exc_label(new_pred, 1);
4066                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4067                 default:
4068                         break;
4069                 }
4070         } else if (is_ia32_vfld(new_pred)) {
4071                 switch (proj) {
4072                 case pn_Load_res:
4073                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfld_res);
4074                 case pn_Load_M:
4075                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfld_M);
4076                 case pn_Load_X_regular:
4077                         return new_rd_Jmp(dbgi, irg, block);
4078                 case pn_Load_X_except:
4079                         /* This Load might raise an exception. Mark it. */
4080                         set_ia32_exc_label(new_pred, 1);
4081                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_xLoad_X_exc);
4082                 default:
4083                         break;
4084                 }
4085         } else {
4086                 /* can happen for ProJMs when source address mode happened for the
4087                    node */
4088
4089                 /* however it should not be the result proj, as that would mean the
4090                    load had multiple users and should not have been used for
4091                    SourceAM */
4092                 if (proj != pn_Load_M) {
4093                         panic("internal error: transformed node not a Load");
4094                 }
4095                 return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, 1);
4096         }
4097
4098         panic("No idea how to transform proj");
4099 }
4100
4101 /**
4102  * Transform and renumber the Projs from a DivMod like instruction.
4103  */
4104 static ir_node *gen_Proj_DivMod(ir_node *node)
4105 {
4106         ir_node  *block    = be_transform_node(get_nodes_block(node));
4107         ir_node  *pred     = get_Proj_pred(node);
4108         ir_node  *new_pred = be_transform_node(pred);
4109         ir_graph *irg      = current_ir_graph;
4110         dbg_info *dbgi     = get_irn_dbg_info(node);
4111         long     proj      = get_Proj_proj(node);
4112
4113         assert(is_ia32_Div(new_pred) || is_ia32_IDiv(new_pred));
4114
4115         switch (get_irn_opcode(pred)) {
4116         case iro_Div:
4117                 switch (proj) {
4118                 case pn_Div_M:
4119                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4120                 case pn_Div_res:
4121                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4122                 case pn_Div_X_regular:
4123                         return new_rd_Jmp(dbgi, irg, block);
4124                 case pn_Div_X_except:
4125                         set_ia32_exc_label(new_pred, 1);
4126                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4127                 default:
4128                         break;
4129                 }
4130                 break;
4131         case iro_Mod:
4132                 switch (proj) {
4133                 case pn_Mod_M:
4134                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4135                 case pn_Mod_res:
4136                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4137                 case pn_Mod_X_except:
4138                         set_ia32_exc_label(new_pred, 1);
4139                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4140                 default:
4141                         break;
4142                 }
4143                 break;
4144         case iro_DivMod:
4145                 switch (proj) {
4146                 case pn_DivMod_M:
4147                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_Div_M);
4148                 case pn_DivMod_res_div:
4149                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_div_res);
4150                 case pn_DivMod_res_mod:
4151                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_Iu, pn_ia32_Div_mod_res);
4152                 case pn_DivMod_X_regular:
4153                         return new_rd_Jmp(dbgi, irg, block);
4154                 case pn_DivMod_X_except:
4155                         set_ia32_exc_label(new_pred, 1);
4156                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_X, pn_ia32_Div_X_exc);
4157                 default:
4158                         break;
4159                 }
4160                 break;
4161         default:
4162                 break;
4163         }
4164
4165         panic("No idea how to transform proj->DivMod");
4166 }
4167
4168 /**
4169  * Transform and renumber the Projs from a CopyB.
4170  */
4171 static ir_node *gen_Proj_CopyB(ir_node *node)
4172 {
4173         ir_node  *block    = be_transform_node(get_nodes_block(node));
4174         ir_node  *pred     = get_Proj_pred(node);
4175         ir_node  *new_pred = be_transform_node(pred);
4176         ir_graph *irg      = current_ir_graph;
4177         dbg_info *dbgi     = get_irn_dbg_info(node);
4178         long     proj      = get_Proj_proj(node);
4179
4180         switch (proj) {
4181         case pn_CopyB_M_regular:
4182                 if (is_ia32_CopyB_i(new_pred)) {
4183                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_i_M);
4184                 } else if (is_ia32_CopyB(new_pred)) {
4185                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_CopyB_M);
4186                 }
4187                 break;
4188         default:
4189                 break;
4190         }
4191
4192         panic("No idea how to transform proj->CopyB");
4193 }
4194
4195 /**
4196  * Transform and renumber the Projs from a Quot.
4197  */
4198 static ir_node *gen_Proj_Quot(ir_node *node)
4199 {
4200         ir_node  *block    = be_transform_node(get_nodes_block(node));
4201         ir_node  *pred     = get_Proj_pred(node);
4202         ir_node  *new_pred = be_transform_node(pred);
4203         ir_graph *irg      = current_ir_graph;
4204         dbg_info *dbgi     = get_irn_dbg_info(node);
4205         long     proj      = get_Proj_proj(node);
4206
4207         switch (proj) {
4208         case pn_Quot_M:
4209                 if (is_ia32_xDiv(new_pred)) {
4210                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_xDiv_M);
4211                 } else if (is_ia32_vfdiv(new_pred)) {
4212                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_M, pn_ia32_vfdiv_M);
4213                 }
4214                 break;
4215         case pn_Quot_res:
4216                 if (is_ia32_xDiv(new_pred)) {
4217                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_xmm, pn_ia32_xDiv_res);
4218                 } else if (is_ia32_vfdiv(new_pred)) {
4219                         return new_rd_Proj(dbgi, irg, block, new_pred, mode_vfp, pn_ia32_vfdiv_res);
4220                 }
4221                 break;
4222         case pn_Quot_X_regular:
4223         case pn_Quot_X_except:
4224         default:
4225                 break;
4226         }
4227
4228         panic("No idea how to transform proj->Quot");
4229 }
4230
4231 static ir_node *gen_be_Call(ir_node *node)
4232 {
4233         dbg_info       *const dbgi      = get_irn_dbg_info(node);
4234         ir_graph       *const irg       = current_ir_graph;
4235         ir_node        *const src_block = get_nodes_block(node);
4236         ir_node        *const block     = be_transform_node(src_block);
4237         ir_node        *const src_mem   = get_irn_n(node, be_pos_Call_mem);
4238         ir_node        *const src_sp    = get_irn_n(node, be_pos_Call_sp);
4239         ir_node        *const sp        = be_transform_node(src_sp);
4240         ir_node        *const src_ptr   = get_irn_n(node, be_pos_Call_ptr);
4241         ir_node        *const noreg     = ia32_new_NoReg_gp(env_cg);
4242         ia32_address_mode_t   am;
4243         ia32_address_t *const addr      = &am.addr;
4244         ir_node        *      mem;
4245         ir_node        *      call;
4246         int                   i;
4247         ir_node        *      fpcw;
4248         ir_node        *      eax       = noreg;
4249         ir_node        *      ecx       = noreg;
4250         ir_node        *      edx       = noreg;
4251         unsigned        const pop       = be_Call_get_pop(node);
4252         ir_type        *const call_tp   = be_Call_get_type(node);
4253
4254         /* Run the x87 simulator if the call returns a float value */
4255         if (get_method_n_ress(call_tp) > 0) {
4256                 ir_type *const res_type = get_method_res_type(call_tp, 0);
4257                 ir_mode *const res_mode = get_type_mode(res_type);
4258
4259                 if (res_mode != NULL && mode_is_float(res_mode)) {
4260                         env_cg->do_x87_sim = 1;
4261                 }
4262         }
4263
4264         /* We do not want be_Call direct calls */
4265         assert(be_Call_get_entity(node) == NULL);
4266
4267         match_arguments(&am, src_block, NULL, src_ptr, src_mem,
4268                         match_am | match_immediate);
4269
4270         i    = get_irn_arity(node) - 1;
4271         fpcw = be_transform_node(get_irn_n(node, i--));
4272         for (; i >= be_pos_Call_first_arg; --i) {
4273                 arch_register_req_t const *const req = arch_get_register_req(node, i);
4274                 ir_node *const reg_parm = be_transform_node(get_irn_n(node, i));
4275
4276                 assert(req->type == arch_register_req_type_limited);
4277                 assert(req->cls == &ia32_reg_classes[CLASS_ia32_gp]);
4278
4279                 switch (*req->limited) {
4280                         case 1 << REG_EAX: assert(eax == noreg); eax = reg_parm; break;
4281                         case 1 << REG_ECX: assert(ecx == noreg); ecx = reg_parm; break;
4282                         case 1 << REG_EDX: assert(edx == noreg); edx = reg_parm; break;
4283                         default: panic("Invalid GP register for register parameter");
4284                 }
4285         }
4286
4287         mem  = transform_AM_mem(irg, block, src_ptr, src_mem, addr->mem);
4288         call = new_bd_ia32_Call(dbgi, block, addr->base, addr->index, mem,
4289                                 am.new_op2, sp, fpcw, eax, ecx, edx, pop, call_tp);
4290         set_am_attributes(call, &am);
4291         call = fix_mem_proj(call, &am);
4292
4293         if (get_irn_pinned(node) == op_pin_state_pinned)
4294                 set_irn_pinned(call, op_pin_state_pinned);
4295
4296         SET_IA32_ORIG_NODE(call, node);
4297         return call;
4298 }
4299
4300 static ir_node *gen_be_IncSP(ir_node *node)
4301 {
4302         ir_node *res = be_duplicate_node(node);
4303         arch_irn_add_flags(res, arch_irn_flags_modify_flags);
4304
4305         return res;
4306 }
4307
4308 /**
4309  * Transform the Projs from a be_Call.
4310  */
4311 static ir_node *gen_Proj_be_Call(ir_node *node)
4312 {
4313         ir_node  *block       = be_transform_node(get_nodes_block(node));
4314         ir_node  *call        = get_Proj_pred(node);
4315         ir_node  *new_call    = be_transform_node(call);
4316         ir_graph *irg         = current_ir_graph;
4317         dbg_info *dbgi        = get_irn_dbg_info(node);
4318         ir_type  *method_type = be_Call_get_type(call);
4319         int       n_res       = get_method_n_ress(method_type);
4320         long      proj        = get_Proj_proj(node);
4321         ir_mode  *mode        = get_irn_mode(node);
4322         ir_node  *sse_load;
4323         ir_node  *res;
4324
4325         /* The following is kinda tricky: If we're using SSE, then we have to
4326          * move the result value of the call in floating point registers to an
4327          * xmm register, we therefore construct a GetST0 -> xLoad sequence
4328          * after the call, we have to make sure to correctly make the
4329          * MemProj and the result Proj use these 2 nodes
4330          */
4331         if (proj == pn_be_Call_M_regular) {
4332                 // get new node for result, are we doing the sse load/store hack?
4333                 ir_node *call_res = be_get_Proj_for_pn(call, pn_be_Call_first_res);
4334                 ir_node *call_res_new;
4335                 ir_node *call_res_pred = NULL;
4336
4337                 if (call_res != NULL) {
4338                         call_res_new  = be_transform_node(call_res);
4339                         call_res_pred = get_Proj_pred(call_res_new);
4340                 }
4341
4342                 if (call_res_pred == NULL || is_ia32_Call(call_res_pred)) {
4343                         return new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4344                                            n_ia32_Call_mem);
4345                 } else {
4346                         assert(is_ia32_xLoad(call_res_pred));
4347                         return new_rd_Proj(dbgi, irg, block, call_res_pred, mode_M,
4348                                            pn_ia32_xLoad_M);
4349                 }
4350         }
4351         if (ia32_cg_config.use_sse2 && proj >= pn_be_Call_first_res
4352                         && proj < (pn_be_Call_first_res + n_res) && mode_is_float(mode)) {
4353                 ir_node *fstp;
4354                 ir_node *frame = get_irg_frame(irg);
4355                 ir_node *noreg = ia32_new_NoReg_gp(env_cg);
4356                 //ir_node *p;
4357                 ir_node *call_mem = be_get_Proj_for_pn(call, pn_be_Call_M_regular);
4358                 ir_node *call_res;
4359
4360                 /* in case there is no memory output: create one to serialize the copy
4361                    FPU -> SSE */
4362                 call_mem = new_rd_Proj(dbgi, irg, block, new_call, mode_M,
4363                                        pn_be_Call_M_regular);
4364                 call_res = new_rd_Proj(dbgi, irg, block, new_call, mode,
4365                                        pn_be_Call_first_res);
4366
4367                 /* store st(0) onto stack */
4368                 fstp = new_bd_ia32_vfst(dbgi, block, frame, noreg, call_mem,
4369                                         call_res, mode);
4370                 set_ia32_op_type(fstp, ia32_AddrModeD);
4371                 set_ia32_use_frame(fstp);
4372
4373                 /* load into SSE register */
4374                 sse_load = new_bd_ia32_xLoad(dbgi, block, frame, noreg, fstp, mode);
4375                 set_ia32_op_type(sse_load, ia32_AddrModeS);
4376                 set_ia32_use_frame(sse_load);
4377
4378                 sse_load = new_rd_Proj(dbgi, irg, block, sse_load, mode_xmm,
4379                                        pn_ia32_xLoad_res);
4380
4381                 return sse_load;
4382         }
4383
4384         /* transform call modes */
4385         if (mode_is_data(mode)) {
4386                 const arch_register_class_t *cls = arch_get_irn_reg_class_out(node);
4387                 mode = cls->mode;
4388         }
4389
4390         /* Map from be_Call to ia32_Call proj number */
4391         if (proj == pn_be_Call_sp) {
4392                 proj = pn_ia32_Call_stack;
4393         } else if (proj == pn_be_Call_M_regular) {
4394                 proj = pn_ia32_Call_M;
4395         } else {
4396                 arch_register_req_t const *const req    = arch_get_register_req_out(node);
4397                 int                        const n_outs = arch_irn_get_n_outs(new_call);
4398                 int                              i;
4399
4400                 assert(proj      >= pn_be_Call_first_res);
4401                 assert(req->type & arch_register_req_type_limited);
4402
4403                 for (i = 0; i < n_outs; ++i) {
4404                         arch_register_req_t const *const new_req = get_ia32_out_req(new_call, i);
4405
4406                         if (!(new_req->type & arch_register_req_type_limited) ||
4407                             new_req->cls      != req->cls                     ||
4408                             *new_req->limited != *req->limited)
4409                                 continue;
4410
4411                         proj = i;
4412                         break;
4413                 }
4414                 assert(i < n_outs);
4415         }
4416
4417         res = new_rd_Proj(dbgi, irg, block, new_call, mode, proj);
4418
4419         /* TODO arch_set_irn_register() only operates on Projs, need variant with index */
4420         switch (proj) {
4421                 case pn_ia32_Call_stack:
4422                         arch_set_irn_register(res, &ia32_gp_regs[REG_ESP]);
4423                         break;
4424
4425                 case pn_ia32_Call_fpcw:
4426                         arch_set_irn_register(res, &ia32_fp_cw_regs[REG_FPCW]);
4427                         break;
4428         }
4429
4430         return res;
4431 }
4432
4433 /**
4434  * Transform the Projs from a Cmp.
4435  */
4436 static ir_node *gen_Proj_Cmp(ir_node *node)
4437 {
4438         /* this probably means not all mode_b nodes were lowered... */
4439         panic("trying to directly transform Proj_Cmp %+F (mode_b not lowered?)",
4440               node);
4441 }
4442
4443 /**
4444  * Transform the Projs from a Bound.
4445  */
4446 static ir_node *gen_Proj_Bound(ir_node *node)
4447 {
4448         ir_node *new_node, *block;
4449         ir_node *pred = get_Proj_pred(node);
4450
4451         switch (get_Proj_proj(node)) {
4452         case pn_Bound_M:
4453                 return be_transform_node(get_Bound_mem(pred));
4454         case pn_Bound_X_regular:
4455                 new_node = be_transform_node(pred);
4456                 block    = get_nodes_block(new_node);
4457                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_true);
4458         case pn_Bound_X_except:
4459                 new_node = be_transform_node(pred);
4460                 block    = get_nodes_block(new_node);
4461                 return new_r_Proj(current_ir_graph, block, new_node, mode_X, pn_ia32_Jcc_false);
4462         case pn_Bound_res:
4463                 return be_transform_node(get_Bound_index(pred));
4464         default:
4465                 panic("unsupported Proj from Bound");
4466         }
4467 }
4468
4469 static ir_node *gen_Proj_ASM(ir_node *node)
4470 {
4471         ir_node *pred;
4472         ir_node *new_pred;
4473         ir_node *block;
4474
4475         if (get_irn_mode(node) != mode_M)
4476                 return be_duplicate_node(node);
4477
4478         pred     = get_Proj_pred(node);
4479         new_pred = be_transform_node(pred);
4480         block    = get_nodes_block(new_pred);
4481         return new_r_Proj(current_ir_graph, block, new_pred, mode_M,
4482                         arch_irn_get_n_outs(new_pred) + 1);
4483 }
4484
4485 /**
4486  * Transform and potentially renumber Proj nodes.
4487  */
4488 static ir_node *gen_Proj(ir_node *node)
4489 {
4490         ir_node *pred = get_Proj_pred(node);
4491         long    proj;
4492
4493         switch (get_irn_opcode(pred)) {
4494         case iro_Store:
4495                 proj = get_Proj_proj(node);
4496                 if (proj == pn_Store_M) {
4497                         return be_transform_node(pred);
4498                 } else {
4499                         panic("No idea how to transform proj->Store");
4500                 }
4501         case iro_Load:
4502                 return gen_Proj_Load(node);
4503         case iro_ASM:
4504                 return gen_Proj_ASM(node);
4505         case iro_Div:
4506         case iro_Mod:
4507         case iro_DivMod:
4508                 return gen_Proj_DivMod(node);
4509         case iro_CopyB:
4510                 return gen_Proj_CopyB(node);
4511         case iro_Quot:
4512                 return gen_Proj_Quot(node);
4513         case beo_SubSP:
4514                 return gen_Proj_be_SubSP(node);
4515         case beo_AddSP:
4516                 return gen_Proj_be_AddSP(node);
4517         case beo_Call:
4518                 return gen_Proj_be_Call(node);
4519         case iro_Cmp:
4520                 return gen_Proj_Cmp(node);
4521         case iro_Bound:
4522                 return gen_Proj_Bound(node);
4523         case iro_Start:
4524                 proj = get_Proj_proj(node);
4525                 switch (proj) {
4526                         case pn_Start_X_initial_exec: {
4527                                 ir_node  *block     = get_nodes_block(pred);
4528                                 ir_node  *new_block = be_transform_node(block);
4529                                 dbg_info *dbgi      = get_irn_dbg_info(node);
4530                                 /* we exchange the ProjX with a jump */
4531                                 ir_node  *jump      = new_rd_Jmp(dbgi, current_ir_graph, new_block);
4532
4533                                 return jump;
4534                         }
4535
4536                         case pn_Start_P_tls:
4537                                 return gen_Proj_tls(node);
4538                 }
4539                 break;
4540
4541         default:
4542                 if (is_ia32_l_FloattoLL(pred)) {
4543                         return gen_Proj_l_FloattoLL(node);
4544 #ifdef FIRM_EXT_GRS
4545                 } else if (!is_ia32_irn(pred)) { // Quick hack for SIMD optimization
4546 #else
4547                 } else {
4548 #endif
4549                         ir_mode *mode = get_irn_mode(node);
4550                         if (ia32_mode_needs_gp_reg(mode)) {
4551                                 ir_node *new_pred = be_transform_node(pred);
4552                                 ir_node *block    = be_transform_node(get_nodes_block(node));
4553                                 ir_node *new_proj = new_r_Proj(current_ir_graph, block, new_pred,
4554                                                                                            mode_Iu, get_Proj_proj(node));
4555 #ifdef DEBUG_libfirm
4556                                 new_proj->node_nr = node->node_nr;
4557 #endif
4558                                 return new_proj;
4559                         }
4560                 }
4561         }
4562         return be_duplicate_node(node);
4563 }
4564
4565 /**
4566  * Enters all transform functions into the generic pointer
4567  */
4568 static void register_transformers(void)
4569 {
4570         ir_op *op_Mulh;
4571
4572         /* first clear the generic function pointer for all ops */
4573         clear_irp_opcodes_generic_func();
4574
4575 #define GEN(a)   { be_transform_func *func = gen_##a; op_##a->ops.generic = (op_func) func; }
4576 #define BAD(a)   op_##a->ops.generic = (op_func)bad_transform
4577
4578         GEN(Add);
4579         GEN(Sub);
4580         GEN(Mul);
4581         GEN(And);
4582         GEN(Or);
4583         GEN(Eor);
4584
4585         GEN(Shl);
4586         GEN(Shr);
4587         GEN(Shrs);
4588         GEN(Rotl);
4589
4590         GEN(Quot);
4591
4592         GEN(Div);
4593         GEN(Mod);
4594         GEN(DivMod);
4595
4596         GEN(Minus);
4597         GEN(Conv);
4598         GEN(Abs);
4599         GEN(Not);
4600
4601         GEN(Load);
4602         GEN(Store);
4603         GEN(Cond);
4604
4605         GEN(Cmp);
4606         GEN(ASM);
4607         GEN(CopyB);
4608         GEN(Mux);
4609         GEN(Proj);
4610         GEN(Phi);
4611         GEN(IJmp);
4612         GEN(Bound);
4613
4614         /* transform ops from intrinsic lowering */
4615         GEN(ia32_l_Add);
4616         GEN(ia32_l_Adc);
4617         GEN(ia32_l_Mul);
4618         GEN(ia32_l_IMul);
4619         GEN(ia32_l_ShlDep);
4620         GEN(ia32_l_ShrDep);
4621         GEN(ia32_l_SarDep);
4622         GEN(ia32_l_ShlD);
4623         GEN(ia32_l_ShrD);
4624         GEN(ia32_l_Sub);
4625         GEN(ia32_l_Sbb);
4626         GEN(ia32_l_LLtoFloat);
4627         GEN(ia32_l_FloattoLL);
4628
4629         GEN(Const);
4630         GEN(SymConst);
4631         GEN(Unknown);
4632
4633         /* we should never see these nodes */
4634         BAD(Raise);
4635         BAD(Sel);
4636         BAD(InstOf);
4637         BAD(Cast);
4638         BAD(Free);
4639         BAD(Tuple);
4640         BAD(Id);
4641         //BAD(Bad);
4642         BAD(Confirm);
4643         BAD(Filter);
4644         BAD(CallBegin);
4645         BAD(EndReg);
4646         BAD(EndExcept);
4647
4648         /* handle generic backend nodes */
4649         GEN(be_FrameAddr);
4650         GEN(be_Call);
4651         GEN(be_IncSP);
4652         GEN(be_Return);
4653         GEN(be_AddSP);
4654         GEN(be_SubSP);
4655         GEN(be_Copy);
4656
4657         op_Mulh = get_op_Mulh();
4658         if (op_Mulh)
4659                 GEN(Mulh);
4660
4661 #undef GEN
4662 #undef BAD
4663 }
4664
4665 /**
4666  * Pre-transform all unknown and noreg nodes.
4667  */
4668 static void ia32_pretransform_node(void)
4669 {
4670         ia32_code_gen_t *cg = env_cg;
4671
4672         cg->unknown_gp  = be_pre_transform_node(cg->unknown_gp);
4673         cg->unknown_vfp = be_pre_transform_node(cg->unknown_vfp);
4674         cg->unknown_xmm = be_pre_transform_node(cg->unknown_xmm);
4675         cg->noreg_gp    = be_pre_transform_node(cg->noreg_gp);
4676         cg->noreg_vfp   = be_pre_transform_node(cg->noreg_vfp);
4677         cg->noreg_xmm   = be_pre_transform_node(cg->noreg_xmm);
4678         get_fpcw();
4679 }
4680
4681 /**
4682  * Walker, checks if all ia32 nodes producing more than one result have their
4683  * Projs, otherwise creates new Projs and keeps them using a be_Keep node.
4684  */
4685 static void add_missing_keep_walker(ir_node *node, void *data)
4686 {
4687         int              n_outs, i;
4688         unsigned         found_projs = 0;
4689         const ir_edge_t *edge;
4690         ir_mode         *mode = get_irn_mode(node);
4691         ir_node         *last_keep;
4692         (void) data;
4693         if (mode != mode_T)
4694                 return;
4695         if (!is_ia32_irn(node))
4696                 return;
4697
4698         n_outs = arch_irn_get_n_outs(node);
4699         if (n_outs <= 0)
4700                 return;
4701         if (is_ia32_SwitchJmp(node))
4702                 return;
4703
4704         assert(n_outs < (int) sizeof(unsigned) * 8);
4705         foreach_out_edge(node, edge) {
4706                 ir_node *proj = get_edge_src_irn(edge);
4707                 int      pn;
4708
4709                 /* The node could be kept */
4710                 if (is_End(proj))
4711                         continue;
4712
4713                 if (get_irn_mode(proj) == mode_M)
4714                         continue;
4715
4716                 pn = get_Proj_proj(proj);
4717                 assert(pn < n_outs);
4718                 found_projs |= 1 << pn;
4719         }
4720
4721
4722         /* are keeps missing? */
4723         last_keep = NULL;
4724         for (i = 0; i < n_outs; ++i) {
4725                 ir_node                     *block;
4726                 ir_node                     *in[1];
4727                 const arch_register_req_t   *req;
4728                 const arch_register_class_t *cls;
4729
4730                 if (found_projs & (1 << i)) {
4731                         continue;
4732                 }
4733
4734                 req = get_ia32_out_req(node, i);
4735                 cls = req->cls;
4736                 if (cls == NULL) {
4737                         continue;
4738                 }
4739                 if (cls == &ia32_reg_classes[CLASS_ia32_flags]) {
4740                         continue;
4741                 }
4742
4743                 block = get_nodes_block(node);
4744                 in[0] = new_r_Proj(current_ir_graph, block, node,
4745                                    arch_register_class_mode(cls), i);
4746                 if (last_keep != NULL) {
4747                         be_Keep_add_node(last_keep, cls, in[0]);
4748                 } else {
4749                         last_keep = be_new_Keep(cls, current_ir_graph, block, 1, in);
4750                         if (sched_is_scheduled(node)) {
4751                                 sched_add_after(node, last_keep);
4752                         }
4753                 }
4754         }
4755 }
4756
4757 /**
4758  * Adds missing keeps to nodes. Adds missing Proj nodes for unused outputs
4759  * and keeps them.
4760  */
4761 void ia32_add_missing_keeps(ia32_code_gen_t *cg)
4762 {
4763         ir_graph *irg = be_get_birg_irg(cg->birg);
4764         irg_walk_graph(irg, add_missing_keep_walker, NULL, NULL);
4765 }
4766
4767 /* do the transformation */
4768 void ia32_transform_graph(ia32_code_gen_t *cg)
4769 {
4770         int cse_last;
4771
4772         register_transformers();
4773         env_cg       = cg;
4774         initial_fpcw = NULL;
4775
4776         BE_TIMER_PUSH(t_heights);
4777         heights      = heights_new(cg->irg);
4778         BE_TIMER_POP(t_heights);
4779         ia32_calculate_non_address_mode_nodes(cg->birg);
4780
4781         /* the transform phase is not safe for CSE (yet) because several nodes get
4782          * attributes set after their creation */
4783         cse_last = get_opt_cse();
4784         set_opt_cse(0);
4785
4786         be_transform_graph(cg->birg, ia32_pretransform_node);
4787
4788         set_opt_cse(cse_last);
4789
4790         ia32_free_non_address_mode_nodes();
4791         heights_free(heights);
4792         heights = NULL;
4793 }
4794
4795 void ia32_init_transform(void)
4796 {
4797         FIRM_DBG_REGISTER(dbg, "firm.be.ia32.transform");
4798 }